~ubuntu-branches/ubuntu/karmic/psi/karmic

« back to all changes in this revision

Viewing changes to third-party/qca/qca/src/qca_default.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-04-14 18:57:30 UTC
  • mfrom: (2.1.9 hardy)
  • Revision ID: james.westby@ubuntu.com-20080414185730-528re3zp0m2hdlhi
Tags: 0.11-8
* added CONFIG -= link_prl to .pro files and removed dependencies
  which are made unnecessary by this change
* Fix segfault when closing last chat tab with qt4.4
  (This is from upstream svn, rev. 1101) (Closes: Bug#476122)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2003-2007  Justin Karneges <justin@affinix.com>
 
3
 * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Lesser General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2.1 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Lesser General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
18
 *
 
19
 */
 
20
 
 
21
#include "qca_core.h"
 
22
 
 
23
#include <QMutex>
 
24
#include <QHash>
 
25
#include "qca_textfilter.h"
 
26
#include "qca_cert.h"
 
27
#include "qcaprovider.h"
 
28
 
 
29
#ifndef QCA_NO_SYSTEMSTORE
 
30
# include "qca_systemstore.h"
 
31
#endif
 
32
 
 
33
#define FRIENDLY_NAMES
 
34
 
 
35
namespace QCA {
 
36
 
 
37
class DefaultShared
 
38
{
 
39
private:
 
40
        mutable QMutex m;
 
41
        bool _use_system;
 
42
        QString _roots_file;
 
43
        QStringList _skip_plugins;
 
44
        QStringList _plugin_priorities;
 
45
 
 
46
public:
 
47
        DefaultShared() : _use_system(true)
 
48
        {
 
49
        }
 
50
 
 
51
        bool use_system() const
 
52
        {
 
53
                QMutexLocker locker(&m);
 
54
                return _use_system;
 
55
        }
 
56
 
 
57
        QString roots_file() const
 
58
        {
 
59
                QMutexLocker locker(&m);
 
60
                return _roots_file;
 
61
        }
 
62
 
 
63
        QStringList skip_plugins() const
 
64
        {
 
65
                QMutexLocker locker(&m);
 
66
                return _skip_plugins;
 
67
        }
 
68
 
 
69
        QStringList plugin_priorities() const
 
70
        {
 
71
                QMutexLocker locker(&m);
 
72
                return _plugin_priorities;
 
73
        }
 
74
 
 
75
        void set(bool use_system, const QString &roots_file, const QStringList &skip_plugins, const QStringList &plugin_priorities)
 
76
        {
 
77
                QMutexLocker locker(&m);
 
78
                _use_system = use_system;
 
79
                _roots_file = roots_file;
 
80
                _skip_plugins = skip_plugins;
 
81
                _plugin_priorities = plugin_priorities;
 
82
        }
 
83
};
 
84
 
 
85
//----------------------------------------------------------------------------
 
86
// DefaultRandomContext
 
87
//----------------------------------------------------------------------------
 
88
class DefaultRandomContext : public RandomContext
 
89
{
 
90
public:
 
91
        DefaultRandomContext(Provider *p) : RandomContext(p) {}
 
92
 
 
93
        virtual Provider::Context *clone() const
 
94
        {
 
95
                return new DefaultRandomContext(provider());
 
96
        }
 
97
 
 
98
        virtual SecureArray nextBytes(int size)
 
99
        {
 
100
                SecureArray buf(size);
 
101
                for(int n = 0; n < (int)buf.size(); ++n)
 
102
                        buf[n] = (char)qrand();
 
103
                return buf;
 
104
        }
 
105
};
 
106
 
 
107
//----------------------------------------------------------------------------
 
108
// DefaultMD5Context
 
109
//----------------------------------------------------------------------------
 
110
 
 
111
/* NOTE: the following code was modified to not need BYTE_ORDER -- Justin */
 
112
 
 
113
/*
 
114
  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
 
115
 
 
116
  This software is provided 'as-is', without any express or implied
 
117
  warranty.  In no event will the authors be held liable for any damages
 
118
  arising from the use of this software.
 
119
 
 
120
  Permission is granted to anyone to use this software for any purpose,
 
121
  including commercial applications, and to alter it and redistribute it
 
122
  freely, subject to the following restrictions:
 
123
 
 
124
  1. The origin of this software must not be misrepresented; you must not
 
125
     claim that you wrote the original software. If you use this software
 
126
     in a product, an acknowledgment in the product documentation would be
 
127
     appreciated but is not required.
 
128
  2. Altered source versions must be plainly marked as such, and must not be
 
129
     misrepresented as being the original software.
 
130
  3. This notice may not be removed or altered from any source distribution.
 
131
 
 
132
  L. Peter Deutsch
 
133
  ghost@aladdin.com
 
134
 
 
135
 */
 
136
/* $Id: qca_default.cpp 697168 2007-08-07 01:46:20Z infiniti $ */
 
137
/*
 
138
  Independent implementation of MD5 (RFC 1321).
 
139
 
 
140
  This code implements the MD5 Algorithm defined in RFC 1321, whose
 
141
  text is available at
 
142
        http://www.ietf.org/rfc/rfc1321.txt
 
143
  The code is derived from the text of the RFC, including the test suite
 
144
  (section A.5) but excluding the rest of Appendix A.  It does not include
 
145
  any code or documentation that is identified in the RFC as being
 
146
  copyrighted.
 
147
 
 
148
  The original and principal author of md5.c is L. Peter Deutsch
 
149
  <ghost@aladdin.com>.  Other authors are noted in the change history
 
150
  that follows (in reverse chronological order):
 
151
 
 
152
  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
 
153
        either statically or dynamically; added missing #include <string.h>
 
154
        in library.
 
155
  2002-03-11 lpd Corrected argument list for main(), and added int return
 
156
        type, in test program and T value program.
 
157
  2002-02-21 lpd Added missing #include <stdio.h> in test program.
 
158
  2000-07-03 lpd Patched to eliminate warnings about "constant is
 
159
        unsigned in ANSI C, signed in traditional"; made test program
 
160
        self-checking.
 
161
  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
 
162
  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
 
163
  1999-05-03 lpd Original version.
 
164
 */
 
165
 
 
166
/*
 
167
 * This package supports both compile-time and run-time determination of CPU
 
168
 * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
 
169
 * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
 
170
 * defined as non-zero, the code will be compiled to run only on big-endian
 
171
 * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
 
172
 * run on either big- or little-endian CPUs, but will run slightly less
 
173
 * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
 
174
 */
 
175
 
 
176
typedef quint8  md5_byte_t; /* 8-bit byte */
 
177
typedef quint32 md5_word_t; /* 32-bit word */
 
178
 
 
179
/* Define the state of the MD5 Algorithm. */
 
180
struct md5_state_t {
 
181
    SecureArray sbuf;
 
182
    md5_word_t *count; // 2   /* message length in bits, lsw first */
 
183
    md5_word_t *abcd;  // 4   /* digest buffer */
 
184
    md5_byte_t *buf;   // 64  /* accumulate block */
 
185
 
 
186
    md5_state_t()
 
187
    {
 
188
        sbuf.resize((6 * sizeof(md5_word_t)) + 64);
 
189
        setup();
 
190
    }
 
191
 
 
192
    md5_state_t(const md5_state_t &from)
 
193
    {
 
194
        *this = from;
 
195
    }
 
196
 
 
197
    md5_state_t & operator=(const md5_state_t &from)
 
198
    {
 
199
        sbuf = from.sbuf;
 
200
        setup();
 
201
        return *this;
 
202
    }
 
203
 
 
204
    inline void setup()
 
205
    {
 
206
        char *p = sbuf.data();
 
207
        count = (md5_word_t *)p;
 
208
        abcd = (md5_word_t *)(p + (2 * sizeof(md5_word_t)));
 
209
        buf = (md5_byte_t *)(p + (6 * sizeof(md5_word_t)));
 
210
    }
 
211
};
 
212
 
 
213
/* Initialize the algorithm. */
 
214
void md5_init(md5_state_t *pms);
 
215
 
 
216
/* Append a string to the message. */
 
217
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
 
218
 
 
219
/* Finish the message and return the digest. */
 
220
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
 
221
 
 
222
#define T_MASK ((md5_word_t)~0)
 
223
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
 
224
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
 
225
#define T3    0x242070db
 
226
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
 
227
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
 
228
#define T6    0x4787c62a
 
229
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
 
230
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
 
231
#define T9    0x698098d8
 
232
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
 
233
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
 
234
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
 
235
#define T13    0x6b901122
 
236
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
 
237
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
 
238
#define T16    0x49b40821
 
239
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
 
240
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
 
241
#define T19    0x265e5a51
 
242
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
 
243
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
 
244
#define T22    0x02441453
 
245
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
 
246
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
 
247
#define T25    0x21e1cde6
 
248
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
 
249
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
 
250
#define T28    0x455a14ed
 
251
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
 
252
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
 
253
#define T31    0x676f02d9
 
254
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
 
255
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
 
256
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
 
257
#define T35    0x6d9d6122
 
258
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
 
259
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
 
260
#define T38    0x4bdecfa9
 
261
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
 
262
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
 
263
#define T41    0x289b7ec6
 
264
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
 
265
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
 
266
#define T44    0x04881d05
 
267
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
 
268
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
 
269
#define T47    0x1fa27cf8
 
270
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
 
271
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
 
272
#define T50    0x432aff97
 
273
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
 
274
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
 
275
#define T53    0x655b59c3
 
276
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
 
277
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
 
278
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
 
279
#define T57    0x6fa87e4f
 
280
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
 
281
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
 
282
#define T60    0x4e0811a1
 
283
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
 
284
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
 
285
#define T63    0x2ad7d2bb
 
286
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
 
287
 
 
288
 
 
289
static void
 
290
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
 
291
{
 
292
        md5_word_t
 
293
        a = pms->abcd[0], b = pms->abcd[1],
 
294
        c = pms->abcd[2], d = pms->abcd[3];
 
295
        md5_word_t t;
 
296
 
 
297
        /* Define storage for little-endian or both types of CPUs. */
 
298
        // possible FIXME: does xbuf really need to be secured?
 
299
        SecureArray sxbuf(16 * sizeof(md5_word_t));
 
300
        md5_word_t *xbuf = (md5_word_t *)sxbuf.data();
 
301
        const md5_word_t *X;
 
302
 
 
303
        {
 
304
                if(QSysInfo::ByteOrder == QSysInfo::BigEndian)
 
305
                {
 
306
                        /*
 
307
                        * On big-endian machines, we must arrange the bytes in the
 
308
                        * right order.
 
309
                        */
 
310
                        const md5_byte_t *xp = data;
 
311
                        int i;
 
312
 
 
313
                        X = xbuf;               /* (dynamic only) */
 
314
 
 
315
                        for (i = 0; i < 16; ++i, xp += 4)
 
316
                                xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
 
317
                }
 
318
                else                    /* dynamic big-endian */
 
319
                {
 
320
                        /*
 
321
                        * On little-endian machines, we can process properly aligned
 
322
                        * data without copying it.
 
323
                        */
 
324
                        if (!((data - (const md5_byte_t *)0) & 3)) {
 
325
                                /* data are properly aligned */
 
326
                                X = (const md5_word_t *)data;
 
327
                        } else {
 
328
                                /* not aligned */
 
329
                                memcpy(xbuf, data, 64);
 
330
                                X = xbuf;
 
331
                        }
 
332
                }
 
333
        }
 
334
 
 
335
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
 
336
 
 
337
    /* Round 1. */
 
338
    /* Let [abcd k s i] denote the operation
 
339
       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
 
340
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
 
341
#define SET(a, b, c, d, k, s, Ti)\
 
342
  t = a + F(b,c,d) + X[k] + Ti;\
 
343
  a = ROTATE_LEFT(t, s) + b
 
344
    /* Do the following 16 operations. */
 
345
    SET(a, b, c, d,  0,  7,  T1);
 
346
    SET(d, a, b, c,  1, 12,  T2);
 
347
    SET(c, d, a, b,  2, 17,  T3);
 
348
    SET(b, c, d, a,  3, 22,  T4);
 
349
    SET(a, b, c, d,  4,  7,  T5);
 
350
    SET(d, a, b, c,  5, 12,  T6);
 
351
    SET(c, d, a, b,  6, 17,  T7);
 
352
    SET(b, c, d, a,  7, 22,  T8);
 
353
    SET(a, b, c, d,  8,  7,  T9);
 
354
    SET(d, a, b, c,  9, 12, T10);
 
355
    SET(c, d, a, b, 10, 17, T11);
 
356
    SET(b, c, d, a, 11, 22, T12);
 
357
    SET(a, b, c, d, 12,  7, T13);
 
358
    SET(d, a, b, c, 13, 12, T14);
 
359
    SET(c, d, a, b, 14, 17, T15);
 
360
    SET(b, c, d, a, 15, 22, T16);
 
361
#undef SET
 
362
 
 
363
     /* Round 2. */
 
364
     /* Let [abcd k s i] denote the operation
 
365
          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
 
366
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
 
367
#define SET(a, b, c, d, k, s, Ti)\
 
368
  t = a + G(b,c,d) + X[k] + Ti;\
 
369
  a = ROTATE_LEFT(t, s) + b
 
370
     /* Do the following 16 operations. */
 
371
    SET(a, b, c, d,  1,  5, T17);
 
372
    SET(d, a, b, c,  6,  9, T18);
 
373
    SET(c, d, a, b, 11, 14, T19);
 
374
    SET(b, c, d, a,  0, 20, T20);
 
375
    SET(a, b, c, d,  5,  5, T21);
 
376
    SET(d, a, b, c, 10,  9, T22);
 
377
    SET(c, d, a, b, 15, 14, T23);
 
378
    SET(b, c, d, a,  4, 20, T24);
 
379
    SET(a, b, c, d,  9,  5, T25);
 
380
    SET(d, a, b, c, 14,  9, T26);
 
381
    SET(c, d, a, b,  3, 14, T27);
 
382
    SET(b, c, d, a,  8, 20, T28);
 
383
    SET(a, b, c, d, 13,  5, T29);
 
384
    SET(d, a, b, c,  2,  9, T30);
 
385
    SET(c, d, a, b,  7, 14, T31);
 
386
    SET(b, c, d, a, 12, 20, T32);
 
387
#undef SET
 
388
 
 
389
     /* Round 3. */
 
390
     /* Let [abcd k s t] denote the operation
 
391
          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
 
392
#define H(x, y, z) ((x) ^ (y) ^ (z))
 
393
#define SET(a, b, c, d, k, s, Ti)\
 
394
  t = a + H(b,c,d) + X[k] + Ti;\
 
395
  a = ROTATE_LEFT(t, s) + b
 
396
     /* Do the following 16 operations. */
 
397
    SET(a, b, c, d,  5,  4, T33);
 
398
    SET(d, a, b, c,  8, 11, T34);
 
399
    SET(c, d, a, b, 11, 16, T35);
 
400
    SET(b, c, d, a, 14, 23, T36);
 
401
    SET(a, b, c, d,  1,  4, T37);
 
402
    SET(d, a, b, c,  4, 11, T38);
 
403
    SET(c, d, a, b,  7, 16, T39);
 
404
    SET(b, c, d, a, 10, 23, T40);
 
405
    SET(a, b, c, d, 13,  4, T41);
 
406
    SET(d, a, b, c,  0, 11, T42);
 
407
    SET(c, d, a, b,  3, 16, T43);
 
408
    SET(b, c, d, a,  6, 23, T44);
 
409
    SET(a, b, c, d,  9,  4, T45);
 
410
    SET(d, a, b, c, 12, 11, T46);
 
411
    SET(c, d, a, b, 15, 16, T47);
 
412
    SET(b, c, d, a,  2, 23, T48);
 
413
#undef SET
 
414
 
 
415
     /* Round 4. */
 
416
     /* Let [abcd k s t] denote the operation
 
417
          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
 
418
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
 
419
#define SET(a, b, c, d, k, s, Ti)\
 
420
  t = a + I(b,c,d) + X[k] + Ti;\
 
421
  a = ROTATE_LEFT(t, s) + b
 
422
     /* Do the following 16 operations. */
 
423
    SET(a, b, c, d,  0,  6, T49);
 
424
    SET(d, a, b, c,  7, 10, T50);
 
425
    SET(c, d, a, b, 14, 15, T51);
 
426
    SET(b, c, d, a,  5, 21, T52);
 
427
    SET(a, b, c, d, 12,  6, T53);
 
428
    SET(d, a, b, c,  3, 10, T54);
 
429
    SET(c, d, a, b, 10, 15, T55);
 
430
    SET(b, c, d, a,  1, 21, T56);
 
431
    SET(a, b, c, d,  8,  6, T57);
 
432
    SET(d, a, b, c, 15, 10, T58);
 
433
    SET(c, d, a, b,  6, 15, T59);
 
434
    SET(b, c, d, a, 13, 21, T60);
 
435
    SET(a, b, c, d,  4,  6, T61);
 
436
    SET(d, a, b, c, 11, 10, T62);
 
437
    SET(c, d, a, b,  2, 15, T63);
 
438
    SET(b, c, d, a,  9, 21, T64);
 
439
#undef SET
 
440
 
 
441
     /* Then perform the following additions. (That is increment each
 
442
        of the four registers by the value it had before this block
 
443
        was started.) */
 
444
    pms->abcd[0] += a;
 
445
    pms->abcd[1] += b;
 
446
    pms->abcd[2] += c;
 
447
    pms->abcd[3] += d;
 
448
}
 
449
 
 
450
void
 
451
md5_init(md5_state_t *pms)
 
452
{
 
453
    pms->count[0] = pms->count[1] = 0;
 
454
    pms->abcd[0] = 0x67452301;
 
455
    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
 
456
    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
 
457
    pms->abcd[3] = 0x10325476;
 
458
}
 
459
 
 
460
void
 
461
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
 
462
{
 
463
    const md5_byte_t *p = data;
 
464
    int left = nbytes;
 
465
    int offset = (pms->count[0] >> 3) & 63;
 
466
    md5_word_t nbits = (md5_word_t)(nbytes << 3);
 
467
 
 
468
    if (nbytes <= 0)
 
469
        return;
 
470
 
 
471
    /* Update the message length. */
 
472
    pms->count[1] += nbytes >> 29;
 
473
    pms->count[0] += nbits;
 
474
    if (pms->count[0] < nbits)
 
475
        pms->count[1]++;
 
476
 
 
477
    /* Process an initial partial block. */
 
478
    if (offset) {
 
479
        int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
 
480
 
 
481
        memcpy(pms->buf + offset, p, copy);
 
482
        if (offset + copy < 64)
 
483
            return;
 
484
        p += copy;
 
485
        left -= copy;
 
486
        md5_process(pms, pms->buf);
 
487
    }
 
488
 
 
489
    /* Process full blocks. */
 
490
    for (; left >= 64; p += 64, left -= 64)
 
491
        md5_process(pms, p);
 
492
 
 
493
    /* Process a final partial block. */
 
494
    if (left)
 
495
        memcpy(pms->buf, p, left);
 
496
}
 
497
 
 
498
void
 
499
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
 
500
{
 
501
    static const md5_byte_t pad[64] = {
 
502
        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
503
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
504
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
505
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 
506
    };
 
507
    md5_byte_t data[8];
 
508
    int i;
 
509
 
 
510
    /* Save the length before padding. */
 
511
    for (i = 0; i < 8; ++i)
 
512
        data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
 
513
    /* Pad to 56 bytes mod 64. */
 
514
    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
 
515
    /* Append the length. */
 
516
    md5_append(pms, data, 8);
 
517
    for (i = 0; i < 16; ++i)
 
518
        digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
 
519
}
 
520
 
 
521
class DefaultMD5Context : public HashContext
 
522
{
 
523
public:
 
524
        DefaultMD5Context(Provider *p) : HashContext(p, "md5")
 
525
        {
 
526
                clear();
 
527
        }
 
528
 
 
529
        virtual Provider::Context *clone() const
 
530
        {
 
531
                return new DefaultMD5Context(*this);
 
532
        }
 
533
 
 
534
        virtual void clear()
 
535
        {
 
536
                secure = true;
 
537
                md5_init(&md5);
 
538
        }
 
539
 
 
540
        virtual void update(const MemoryRegion &in)
 
541
        {
 
542
                if(!in.isSecure())
 
543
                        secure = false;
 
544
                md5_append(&md5, (const md5_byte_t *)in.data(), in.size());
 
545
        }
 
546
 
 
547
        virtual MemoryRegion final()
 
548
        {
 
549
                if(secure)
 
550
                {
 
551
                        SecureArray b(16, 0);
 
552
                        md5_finish(&md5, (md5_byte_t *)b.data());
 
553
                        return b;
 
554
                }
 
555
                else
 
556
                {
 
557
                        QByteArray b(16, 0);
 
558
                        md5_finish(&md5, (md5_byte_t *)b.data());
 
559
                        return b;
 
560
                }
 
561
        }
 
562
 
 
563
        bool secure;
 
564
        md5_state_t md5;
 
565
};
 
566
 
 
567
//----------------------------------------------------------------------------
 
568
// DefaultSHA1Context
 
569
//----------------------------------------------------------------------------
 
570
 
 
571
// SHA1 - from a public domain implementation by Steve Reid (steve@edmweb.com)
 
572
 
 
573
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
 
574
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15]^block->l[(i+2)&15]^block->l[i&15],1))
 
575
 
 
576
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
 
577
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
 
578
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
 
579
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
 
580
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
 
581
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
 
582
 
 
583
struct SHA1_CONTEXT
 
584
{
 
585
        SecureArray sbuf;
 
586
        quint32 *state; // 5
 
587
        quint32 *count; // 2
 
588
        unsigned char *buffer; // 64
 
589
 
 
590
        SHA1_CONTEXT()
 
591
        {
 
592
                sbuf.resize((7 * sizeof(quint32)) + 64);
 
593
                setup();
 
594
        }
 
595
 
 
596
        SHA1_CONTEXT(const SHA1_CONTEXT &from)
 
597
        {
 
598
                *this = from;
 
599
        }
 
600
 
 
601
        SHA1_CONTEXT & operator=(const SHA1_CONTEXT &from)
 
602
        {
 
603
                sbuf = from.sbuf;
 
604
                setup();
 
605
                return *this;
 
606
        }
 
607
 
 
608
        inline void setup()
 
609
        {
 
610
                char *p = sbuf.data();
 
611
                state = (quint32 *)p;
 
612
                count = (quint32 *)(p + (5 * sizeof(quint32)));
 
613
                buffer = (unsigned char *)(p + (7 * sizeof(quint32)));
 
614
        }
 
615
};
 
616
 
 
617
typedef union {
 
618
        unsigned char c[64];
 
619
        quint32 l[16];
 
620
} CHAR64LONG16;
 
621
 
 
622
class DefaultSHA1Context : public HashContext
 
623
{
 
624
public:
 
625
        SHA1_CONTEXT _context;
 
626
        CHAR64LONG16* block;
 
627
        bool secure;
 
628
 
 
629
        DefaultSHA1Context(Provider *p) : HashContext(p, "sha1")
 
630
        {
 
631
                clear();
 
632
        }
 
633
 
 
634
        virtual Provider::Context *clone() const
 
635
        {
 
636
                return new DefaultSHA1Context(*this);
 
637
        }
 
638
 
 
639
        virtual void clear()
 
640
        {
 
641
                secure = true;
 
642
                sha1_init(&_context);
 
643
        }
 
644
 
 
645
        virtual void update(const MemoryRegion &in)
 
646
        {
 
647
                if(!in.isSecure())
 
648
                        secure = false;
 
649
                sha1_update(&_context, (unsigned char *)in.data(), (unsigned int)in.size());
 
650
        }
 
651
 
 
652
        virtual MemoryRegion final()
 
653
        {
 
654
                if(secure)
 
655
                {
 
656
                        SecureArray b(20, 0);
 
657
                        sha1_final((unsigned char *)b.data(), &_context);
 
658
                        return b;
 
659
                }
 
660
                else
 
661
                {
 
662
                        QByteArray b(20, 0);
 
663
                        sha1_final((unsigned char *)b.data(), &_context);
 
664
                        return b;
 
665
                }
 
666
        }
 
667
 
 
668
        inline unsigned long blk0(quint32 i)
 
669
        {
 
670
                if(QSysInfo::ByteOrder == QSysInfo::BigEndian)
 
671
                        return block->l[i];
 
672
                else
 
673
                        return (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) | (rol(block->l[i],8)&0x00FF00FF));
 
674
        }
 
675
 
 
676
        // Hash a single 512-bit block. This is the core of the algorithm.
 
677
        void transform(quint32 state[5], unsigned char buffer[64])
 
678
        {
 
679
                quint32 a, b, c, d, e;
 
680
 
 
681
                block = (CHAR64LONG16*)buffer;
 
682
 
 
683
                // Copy context->state[] to working vars
 
684
                a = state[0];
 
685
                b = state[1];
 
686
                c = state[2];
 
687
                d = state[3];
 
688
                e = state[4];
 
689
 
 
690
                // 4 rounds of 20 operations each. Loop unrolled.
 
691
                R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
 
692
                R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
 
693
                R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
 
694
                R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
 
695
                R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
 
696
                R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
 
697
                R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
 
698
                R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
 
699
                R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
 
700
                R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
 
701
                R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
 
702
                R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
 
703
                R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
 
704
                R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
 
705
                R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
 
706
                R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
 
707
                R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
 
708
                R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
 
709
                R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
 
710
                R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
 
711
 
 
712
                // Add the working vars back into context.state[]
 
713
                state[0] += a;
 
714
                state[1] += b;
 
715
                state[2] += c;
 
716
                state[3] += d;
 
717
                state[4] += e;
 
718
 
 
719
                // Wipe variables
 
720
                a = b = c = d = e = 0;
 
721
        }
 
722
 
 
723
        // SHA1Init - Initialize new context
 
724
        void sha1_init(SHA1_CONTEXT* context)
 
725
        {
 
726
                // SHA1 initialization constants
 
727
                context->state[0] = 0x67452301;
 
728
                context->state[1] = 0xEFCDAB89;
 
729
                context->state[2] = 0x98BADCFE;
 
730
                context->state[3] = 0x10325476;
 
731
                context->state[4] = 0xC3D2E1F0;
 
732
                context->count[0] = context->count[1] = 0;
 
733
        }
 
734
 
 
735
        // Run your data through this
 
736
        void sha1_update(SHA1_CONTEXT* context, unsigned char* data, quint32 len)
 
737
        {
 
738
                quint32 i, j;
 
739
 
 
740
                j = (context->count[0] >> 3) & 63;
 
741
                if((context->count[0] += len << 3) < (len << 3))
 
742
                        context->count[1]++;
 
743
 
 
744
                context->count[1] += (len >> 29);
 
745
 
 
746
                if((j + len) > 63) {
 
747
                        memcpy(&context->buffer[j], data, (i = 64-j));
 
748
                        transform(context->state, context->buffer);
 
749
                        for ( ; i + 63 < len; i += 64) {
 
750
                                transform(context->state, &data[i]);
 
751
                        }
 
752
                        j = 0;
 
753
                }
 
754
                else i = 0;
 
755
                        memcpy(&context->buffer[j], &data[i], len - i);
 
756
        }
 
757
 
 
758
        // Add padding and return the message digest
 
759
        void sha1_final(unsigned char digest[20], SHA1_CONTEXT* context)
 
760
        {
 
761
                quint32 i;
 
762
                unsigned char finalcount[8];
 
763
 
 
764
                for (i = 0; i < 8; i++) {
 
765
                        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
 
766
                        >> ((3-(i & 3)) * 8) ) & 255);  // Endian independent
 
767
                }
 
768
                sha1_update(context, (unsigned char *)"\200", 1);
 
769
                while ((context->count[0] & 504) != 448) {
 
770
                        sha1_update(context, (unsigned char *)"\0", 1);
 
771
                }
 
772
                sha1_update(context, finalcount, 8);  // Should cause a transform()
 
773
                for (i = 0; i < 20; i++) {
 
774
                        digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
 
775
                }
 
776
 
 
777
                // Wipe variables
 
778
                i = 0;
 
779
                memset(context->buffer, 0, 64);
 
780
                memset(context->state, 0, 20);
 
781
                memset(context->count, 0, 8);
 
782
                memset(&finalcount, 0, 8);
 
783
        }
 
784
};
 
785
 
 
786
//----------------------------------------------------------------------------
 
787
// DefaultKeyStoreEntry
 
788
//----------------------------------------------------------------------------
 
789
 
 
790
// this escapes colons, commas, and newlines.  colons and commas so that they
 
791
//   are available as delimiters, and newlines so that our output can be a
 
792
//   single line of text.
 
793
static QString escape_string(const QString &in)
 
794
{
 
795
        QString out;
 
796
        for(int n = 0; n < in.length(); ++n)
 
797
        {
 
798
                if(in[n] == '\\')
 
799
                        out += "\\\\";
 
800
                else if(in[n] == ':')
 
801
                        out += "\\c";
 
802
                else if(in[n] == ',')
 
803
                        out += "\\o";
 
804
                else if(in[n] == '\n')
 
805
                        out += "\\n";
 
806
                else
 
807
                        out += in[n];
 
808
        }
 
809
        return out;
 
810
}
 
811
 
 
812
static bool unescape_string(const QString &in, QString *_out)
 
813
{
 
814
        QString out;
 
815
        for(int n = 0; n < in.length(); ++n)
 
816
        {
 
817
                if(in[n] == '\\')
 
818
                {
 
819
                        if(n + 1 >= in.length())
 
820
                                return false;
 
821
 
 
822
                        if(in[n + 1] == '\\')
 
823
                                out += '\\';
 
824
                        else if(in[n + 1] == 'c')
 
825
                                out += ':';
 
826
                        else if(in[n + 1] == 'o')
 
827
                                out += ',';
 
828
                        else if(in[n + 1] == 'n')
 
829
                                out += '\n';
 
830
                        else
 
831
                                return false;
 
832
                        ++n;
 
833
                }
 
834
                else
 
835
                        out += in[n];
 
836
        }
 
837
        *_out = out;
 
838
        return true;
 
839
}
 
840
 
 
841
static QString escape_stringlist(const QStringList &in)
 
842
{
 
843
        QStringList list;
 
844
        for(int n = 0; n < in.count(); ++n)
 
845
                list += escape_string(in[n]);
 
846
        return list.join(":");
 
847
}
 
848
 
 
849
static bool unescape_stringlist(const QString &in, QStringList *_out)
 
850
{
 
851
        QStringList out;
 
852
        QStringList list = in.split(':');
 
853
        for(int n = 0; n < list.count(); ++n)
 
854
        {
 
855
                QString str;
 
856
                if(!unescape_string(list[n], &str))
 
857
                        return false;
 
858
                out += str;
 
859
        }
 
860
        *_out = out;
 
861
        return true;
 
862
}
 
863
 
 
864
// serialization format is a colon separated list of 7 escaped strings
 
865
//  0 - "qca_def_1" (header)
 
866
//  1 - store id
 
867
//  2 - store name
 
868
//  3 - entry id
 
869
//  4 - entry name
 
870
//  5 - entry type (e.g. "cert")
 
871
//  6 - string encoding of object (e.g. DER encoded in Base64)
 
872
static QString entry_serialize(const QString &storeId, const QString &storeName, const QString &entryId, const QString &entryName, const QString &entryType, const QString &data)
 
873
{
 
874
        QStringList out;
 
875
        out += "qca_def";
 
876
        out += storeId;
 
877
        out += storeName;
 
878
        out += entryId;
 
879
        out += entryName;
 
880
        out += entryType;
 
881
        out += data;
 
882
        return escape_stringlist(out);
 
883
}
 
884
 
 
885
static bool entry_deserialize(const QString &in, QString *storeId, QString *storeName, QString *entryId, QString *entryName, QString *entryType, QString *data)
 
886
{
 
887
        QStringList list;
 
888
        if(!unescape_stringlist(in, &list))
 
889
                return false;
 
890
        if(list.count() != 7)
 
891
                return false;
 
892
        if(list[0] != "qca_def")
 
893
                return false;
 
894
        *storeId   = list[1];
 
895
        *storeName = list[2];
 
896
        *entryId   = list[3];
 
897
        *entryName = list[4];
 
898
        *entryType = list[5];
 
899
        *data      = list[6];
 
900
        return true;
 
901
}
 
902
 
 
903
class DefaultKeyStoreEntry : public KeyStoreEntryContext
 
904
{
 
905
public:
 
906
        KeyStoreEntry::Type _type;
 
907
        QString _id, _name, _storeId, _storeName;
 
908
        Certificate _cert;
 
909
        CRL _crl;
 
910
        mutable QString _serialized;
 
911
 
 
912
        DefaultKeyStoreEntry(const Certificate &cert, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p)
 
913
        {
 
914
                _type = KeyStoreEntry::TypeCertificate;
 
915
                _storeId = storeId;
 
916
                _storeName = storeName;
 
917
                _cert = cert;
 
918
        }
 
919
 
 
920
        DefaultKeyStoreEntry(const CRL &crl, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p)
 
921
        {
 
922
                _type = KeyStoreEntry::TypeCRL;
 
923
                _storeId = storeId;
 
924
                _storeName = storeName;
 
925
                _crl = crl;
 
926
        }
 
927
 
 
928
        virtual Provider::Context *clone() const
 
929
        {
 
930
                return new DefaultKeyStoreEntry(*this);
 
931
        }
 
932
 
 
933
        virtual KeyStoreEntry::Type type() const
 
934
        {
 
935
                return _type;
 
936
        }
 
937
 
 
938
        virtual QString id() const
 
939
        {
 
940
                return _id;
 
941
        }
 
942
 
 
943
        virtual QString name() const
 
944
        {
 
945
                return _name;
 
946
        }
 
947
 
 
948
        virtual QString storeId() const
 
949
        {
 
950
                return _storeId;
 
951
        }
 
952
 
 
953
        virtual QString storeName() const
 
954
        {
 
955
                return _storeName;
 
956
        }
 
957
 
 
958
        virtual Certificate certificate() const
 
959
        {
 
960
                return _cert;
 
961
        }
 
962
 
 
963
        virtual CRL crl() const
 
964
        {
 
965
                return _crl;
 
966
        }
 
967
 
 
968
        virtual QString serialize() const
 
969
        {
 
970
                if(_serialized.isEmpty())
 
971
                {
 
972
                        QString typestr;
 
973
                        QString datastr;
 
974
 
 
975
                        if(_type == KeyStoreEntry::TypeCertificate)
 
976
                        {
 
977
                                typestr = "cert";
 
978
                                datastr = Base64().arrayToString(_cert.toDER());
 
979
                        }
 
980
                        else
 
981
                        {
 
982
                                typestr = "crl";
 
983
                                datastr = Base64().arrayToString(_crl.toDER());
 
984
                        }
 
985
 
 
986
                        _serialized = entry_serialize(_storeId, _storeName, _id, _name, typestr, datastr);
 
987
                }
 
988
 
 
989
                return _serialized;
 
990
        }
 
991
 
 
992
        static DefaultKeyStoreEntry *deserialize(const QString &in, Provider *provider)
 
993
        {
 
994
                QString storeId, storeName, id, name, typestr, datastr;
 
995
 
 
996
                if(entry_deserialize(in, &storeId, &storeName, &id, &name, &typestr, &datastr))
 
997
                {
 
998
                        QByteArray data = Base64().stringToArray(datastr).toByteArray();
 
999
                        DefaultKeyStoreEntry *c;
 
1000
 
 
1001
                        if(typestr == "cert")
 
1002
                        {
 
1003
                                Certificate cert = Certificate::fromDER(data);
 
1004
                                if(cert.isNull())
 
1005
                                        return 0;
 
1006
                                c = new DefaultKeyStoreEntry(cert, storeId, storeName, provider);
 
1007
                        }
 
1008
                        else if(typestr == "crl")
 
1009
                        {
 
1010
                                CRL crl = CRL::fromDER(data);
 
1011
                                if(crl.isNull())
 
1012
                                        return 0;
 
1013
                                c = new DefaultKeyStoreEntry(crl, storeId, storeName, provider);
 
1014
                        }
 
1015
                        else
 
1016
                                return 0;
 
1017
 
 
1018
                        c->_id = id;
 
1019
                        c->_name = name;
 
1020
                        c->_serialized = in;
 
1021
                        return c;
 
1022
                }
 
1023
                return 0;
 
1024
        }
 
1025
 
 
1026
        QString simpleId() const
 
1027
        {
 
1028
                if(_type == KeyStoreEntry::TypeCertificate)
 
1029
                        return QString::number(qHash(_cert.toDER()));
 
1030
                else
 
1031
                        return QString::number(qHash(_crl.toDER()));
 
1032
        }
 
1033
 
 
1034
        QString simpleName() const
 
1035
        {
 
1036
                // use the common name, else orgname
 
1037
                if(_type == KeyStoreEntry::TypeCertificate)
 
1038
                {
 
1039
                        QString str = _cert.commonName();
 
1040
                        if(str.isEmpty())
 
1041
                                str = _cert.subjectInfo().value(Organization);
 
1042
                        return str;
 
1043
                }
 
1044
                else
 
1045
                        return _crl.issuerInfo().value(CommonName);
 
1046
        }
 
1047
};
 
1048
 
 
1049
//----------------------------------------------------------------------------
 
1050
// DefaultKeyStoreList
 
1051
//----------------------------------------------------------------------------
 
1052
class DefaultKeyStoreList : public KeyStoreListContext
 
1053
{
 
1054
        Q_OBJECT
 
1055
public:
 
1056
        bool x509_supported;
 
1057
        DefaultShared *shared;
 
1058
 
 
1059
        DefaultKeyStoreList(Provider *p, DefaultShared *_shared) : KeyStoreListContext(p), shared(_shared)
 
1060
        {
 
1061
        }
 
1062
 
 
1063
        ~DefaultKeyStoreList()
 
1064
        {
 
1065
        }
 
1066
 
 
1067
        virtual Provider::Context *clone() const
 
1068
        {
 
1069
                return 0;
 
1070
        }
 
1071
 
 
1072
        virtual void start()
 
1073
        {
 
1074
                x509_supported = false;
 
1075
 
 
1076
                QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection);
 
1077
        }
 
1078
 
 
1079
        virtual QList<int> keyStores()
 
1080
        {
 
1081
                if(!x509_supported)
 
1082
                {
 
1083
                        if(isSupported("cert") && isSupported("crl"))
 
1084
                                x509_supported = true;
 
1085
                }
 
1086
 
 
1087
                bool have_systemstore = false;
 
1088
#ifndef QCA_NO_SYSTEMSTORE
 
1089
                if(shared->use_system())
 
1090
                        have_systemstore = qca_have_systemstore();
 
1091
#endif
 
1092
 
 
1093
                QList<int> list;
 
1094
 
 
1095
                // system store only shows up if the OS store is available or
 
1096
                //   there is a configured store file
 
1097
                if(x509_supported && (have_systemstore || !shared->roots_file().isEmpty()))
 
1098
                        list += 0;
 
1099
 
 
1100
                return list;
 
1101
        }
 
1102
 
 
1103
        virtual KeyStore::Type type(int) const
 
1104
        {
 
1105
                return KeyStore::System;
 
1106
        }
 
1107
 
 
1108
        virtual QString storeId(int) const
 
1109
        {
 
1110
                return "qca-default-systemstore";
 
1111
        }
 
1112
 
 
1113
        virtual QString name(int) const
 
1114
        {
 
1115
                return "System Trusted Certificates";
 
1116
        }
 
1117
 
 
1118
        virtual QList<KeyStoreEntry::Type> entryTypes(int) const
 
1119
        {
 
1120
                QList<KeyStoreEntry::Type> list;
 
1121
                list += KeyStoreEntry::TypeCertificate;
 
1122
                list += KeyStoreEntry::TypeCRL;
 
1123
                return list;
 
1124
        }
 
1125
 
 
1126
        virtual QList<KeyStoreEntryContext*> entryList(int)
 
1127
        {
 
1128
                QList<KeyStoreEntryContext*> out;
 
1129
 
 
1130
                QList<Certificate> certs;
 
1131
                QList<CRL> crls;
 
1132
 
 
1133
                if(shared->use_system())
 
1134
                {
 
1135
                        CertificateCollection col;
 
1136
#ifndef QCA_NO_SYSTEMSTORE
 
1137
                        col = qca_get_systemstore(QString());
 
1138
#endif
 
1139
                        certs += col.certificates();
 
1140
                        crls += col.crls();
 
1141
                }
 
1142
 
 
1143
                QString roots = shared->roots_file();
 
1144
                if(!roots.isEmpty())
 
1145
                {
 
1146
                        CertificateCollection col = CertificateCollection::fromFlatTextFile(roots);
 
1147
                        certs += col.certificates();
 
1148
                        crls += col.crls();
 
1149
                }
 
1150
 
 
1151
#ifdef FRIENDLY_NAMES
 
1152
                QStringList names = makeFriendlyNames(certs);
 
1153
#endif
 
1154
                for(int n = 0; n < certs.count(); ++n)
 
1155
                {
 
1156
                        DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(certs[n], storeId(0), name(0), provider());
 
1157
                        c->_id = c->simpleId();
 
1158
#ifdef FRIENDLY_NAMES
 
1159
                        c->_name = names[n];
 
1160
#else
 
1161
                        c->_name = c->simpleName();
 
1162
#endif
 
1163
                        out.append(c);
 
1164
                }
 
1165
 
 
1166
                for(int n = 0; n < crls.count(); ++n)
 
1167
                {
 
1168
                        DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(crls[n], storeId(0), name(0), provider());
 
1169
                        c->_id = c->simpleId();
 
1170
                        c->_name = c->simpleName();
 
1171
                        out.append(c);
 
1172
                }
 
1173
 
 
1174
                return out;
 
1175
        }
 
1176
 
 
1177
        virtual KeyStoreEntryContext *entryPassive(const QString &serialized)
 
1178
        {
 
1179
                return DefaultKeyStoreEntry::deserialize(serialized, provider());
 
1180
        }
 
1181
};
 
1182
 
 
1183
//----------------------------------------------------------------------------
 
1184
// DefaultProvider
 
1185
//----------------------------------------------------------------------------
 
1186
static bool unescape_config_stringlist(const QString &in, QStringList *_out)
 
1187
{
 
1188
        QStringList out;
 
1189
        QStringList list = in.split(',');
 
1190
        for(int n = 0; n < list.count(); ++n)
 
1191
        {
 
1192
                QString str;
 
1193
                if(!unescape_string(list[n], &str))
 
1194
                        return false;
 
1195
                out += str.trimmed();
 
1196
        }
 
1197
        *_out = out;
 
1198
        return true;
 
1199
}
 
1200
 
 
1201
class DefaultProvider : public Provider
 
1202
{
 
1203
public:
 
1204
        DefaultShared shared;
 
1205
 
 
1206
        virtual void init()
 
1207
        {
 
1208
                QDateTime now = QDateTime::currentDateTime();
 
1209
 
 
1210
                uint t = now.toTime_t();
 
1211
                if(now.time().msec() > 0)
 
1212
                        t /= now.time().msec();
 
1213
                qsrand(t);
 
1214
        }
 
1215
 
 
1216
        virtual int version() const
 
1217
        {
 
1218
                return QCA_VERSION;
 
1219
        }
 
1220
 
 
1221
        virtual int qcaVersion() const
 
1222
        {
 
1223
                return QCA_VERSION;
 
1224
        }
 
1225
 
 
1226
        virtual QString name() const
 
1227
        {
 
1228
                return "default";
 
1229
        }
 
1230
 
 
1231
        virtual QStringList features() const
 
1232
        {
 
1233
                QStringList list;
 
1234
                list += "random";
 
1235
                list += "md5";
 
1236
                list += "sha1";
 
1237
                list += "keystorelist";
 
1238
                return list;
 
1239
        }
 
1240
 
 
1241
        virtual Provider::Context *createContext(const QString &type)
 
1242
        {
 
1243
                if(type == "random")
 
1244
                        return new DefaultRandomContext(this);
 
1245
                else if(type == "md5")
 
1246
                        return new DefaultMD5Context(this);
 
1247
                else if(type == "sha1")
 
1248
                        return new DefaultSHA1Context(this);
 
1249
                else if(type == "keystorelist")
 
1250
                        return new DefaultKeyStoreList(this, &shared);
 
1251
                else
 
1252
                        return 0;
 
1253
        }
 
1254
 
 
1255
        virtual QVariantMap defaultConfig() const
 
1256
        {
 
1257
                QVariantMap config;
 
1258
                config["formtype"] = "http://affinix.com/qca/forms/default#1.0";
 
1259
                config["use_system"] = true;
 
1260
                config["roots_file"] = QString();
 
1261
                config["skip_plugins"] = QString();
 
1262
                config["plugin_priorities"] = QString();
 
1263
                return config;
 
1264
        }
 
1265
 
 
1266
        virtual void configChanged(const QVariantMap &config)
 
1267
        {
 
1268
                bool use_system = config["use_system"].toBool();
 
1269
                QString roots_file = config["roots_file"].toString();
 
1270
                QString skip_plugins_str = config["skip_plugins"].toString();
 
1271
                QString plugin_priorities_str = config["plugin_priorities"].toString();
 
1272
 
 
1273
                QStringList tmp;
 
1274
 
 
1275
                QStringList skip_plugins;
 
1276
                if(unescape_config_stringlist(skip_plugins_str, &tmp))
 
1277
                        skip_plugins = tmp;
 
1278
 
 
1279
                QStringList plugin_priorities;
 
1280
                if(unescape_config_stringlist(plugin_priorities_str, &tmp))
 
1281
                        plugin_priorities = tmp;
 
1282
 
 
1283
                for(int n = 0; n < plugin_priorities.count(); ++n)
 
1284
                {
 
1285
                        QString &s = plugin_priorities[n];
 
1286
 
 
1287
                        // make sure the entry ends with ":number"
 
1288
                        int x = s.indexOf(':');
 
1289
                        bool ok = false;
 
1290
                        if(x != -1)
 
1291
                                s.mid(x + 1).toInt(&ok);
 
1292
                        if(!ok)
 
1293
                        {
 
1294
                                plugin_priorities.removeAt(n);
 
1295
                                --n;
 
1296
                        }
 
1297
                }
 
1298
 
 
1299
                shared.set(use_system, roots_file, skip_plugins, plugin_priorities);
 
1300
        }
 
1301
};
 
1302
 
 
1303
Provider *create_default_provider()
 
1304
{
 
1305
        return new DefaultProvider;
 
1306
}
 
1307
 
 
1308
QStringList skip_plugins(Provider *defaultProvider)
 
1309
{
 
1310
        DefaultProvider *that = (DefaultProvider *)defaultProvider;
 
1311
        return that->shared.skip_plugins();
 
1312
}
 
1313
 
 
1314
QStringList plugin_priorities(Provider *defaultProvider)
 
1315
{
 
1316
        DefaultProvider *that = (DefaultProvider *)defaultProvider;
 
1317
        return that->shared.plugin_priorities();
 
1318
}
 
1319
 
 
1320
#include "qca_default.moc"
 
1321
 
 
1322
}