2
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
3
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
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.
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.
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
25
#include "qca_textfilter.h"
27
#include "qcaprovider.h"
29
#ifndef QCA_NO_SYSTEMSTORE
30
# include "qca_systemstore.h"
33
#define FRIENDLY_NAMES
43
QStringList _skip_plugins;
44
QStringList _plugin_priorities;
47
DefaultShared() : _use_system(true)
51
bool use_system() const
53
QMutexLocker locker(&m);
57
QString roots_file() const
59
QMutexLocker locker(&m);
63
QStringList skip_plugins() const
65
QMutexLocker locker(&m);
69
QStringList plugin_priorities() const
71
QMutexLocker locker(&m);
72
return _plugin_priorities;
75
void set(bool use_system, const QString &roots_file, const QStringList &skip_plugins, const QStringList &plugin_priorities)
77
QMutexLocker locker(&m);
78
_use_system = use_system;
79
_roots_file = roots_file;
80
_skip_plugins = skip_plugins;
81
_plugin_priorities = plugin_priorities;
85
//----------------------------------------------------------------------------
86
// DefaultRandomContext
87
//----------------------------------------------------------------------------
88
class DefaultRandomContext : public RandomContext
91
DefaultRandomContext(Provider *p) : RandomContext(p) {}
93
virtual Provider::Context *clone() const
95
return new DefaultRandomContext(provider());
98
virtual SecureArray nextBytes(int size)
100
SecureArray buf(size);
101
for(int n = 0; n < (int)buf.size(); ++n)
102
buf[n] = (char)qrand();
107
//----------------------------------------------------------------------------
109
//----------------------------------------------------------------------------
111
/* NOTE: the following code was modified to not need BYTE_ORDER -- Justin */
114
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
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.
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:
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.
136
/* $Id: qca_default.cpp 697168 2007-08-07 01:46:20Z infiniti $ */
138
Independent implementation of MD5 (RFC 1321).
140
This code implements the MD5 Algorithm defined in RFC 1321, whose
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
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):
152
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
153
either statically or dynamically; added missing #include <string.h>
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
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.
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.
176
typedef quint8 md5_byte_t; /* 8-bit byte */
177
typedef quint32 md5_word_t; /* 32-bit word */
179
/* Define the state of the MD5 Algorithm. */
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 */
188
sbuf.resize((6 * sizeof(md5_word_t)) + 64);
192
md5_state_t(const md5_state_t &from)
197
md5_state_t & operator=(const md5_state_t &from)
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)));
213
/* Initialize the algorithm. */
214
void md5_init(md5_state_t *pms);
216
/* Append a string to the message. */
217
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
219
/* Finish the message and return the digest. */
220
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
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)
290
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
293
a = pms->abcd[0], b = pms->abcd[1],
294
c = pms->abcd[2], d = pms->abcd[3];
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();
304
if(QSysInfo::ByteOrder == QSysInfo::BigEndian)
307
* On big-endian machines, we must arrange the bytes in the
310
const md5_byte_t *xp = data;
313
X = xbuf; /* (dynamic only) */
315
for (i = 0; i < 16; ++i, xp += 4)
316
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
318
else /* dynamic big-endian */
321
* On little-endian machines, we can process properly aligned
322
* data without copying it.
324
if (!((data - (const md5_byte_t *)0) & 3)) {
325
/* data are properly aligned */
326
X = (const md5_word_t *)data;
329
memcpy(xbuf, data, 64);
335
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
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);
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);
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);
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);
441
/* Then perform the following additions. (That is increment each
442
of the four registers by the value it had before this block
451
md5_init(md5_state_t *pms)
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;
461
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
463
const md5_byte_t *p = data;
465
int offset = (pms->count[0] >> 3) & 63;
466
md5_word_t nbits = (md5_word_t)(nbytes << 3);
471
/* Update the message length. */
472
pms->count[1] += nbytes >> 29;
473
pms->count[0] += nbits;
474
if (pms->count[0] < nbits)
477
/* Process an initial partial block. */
479
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
481
memcpy(pms->buf + offset, p, copy);
482
if (offset + copy < 64)
486
md5_process(pms, pms->buf);
489
/* Process full blocks. */
490
for (; left >= 64; p += 64, left -= 64)
493
/* Process a final partial block. */
495
memcpy(pms->buf, p, left);
499
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
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
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));
521
class DefaultMD5Context : public HashContext
524
DefaultMD5Context(Provider *p) : HashContext(p, "md5")
529
virtual Provider::Context *clone() const
531
return new DefaultMD5Context(*this);
540
virtual void update(const MemoryRegion &in)
544
md5_append(&md5, (const md5_byte_t *)in.data(), in.size());
547
virtual MemoryRegion final()
551
SecureArray b(16, 0);
552
md5_finish(&md5, (md5_byte_t *)b.data());
558
md5_finish(&md5, (md5_byte_t *)b.data());
567
//----------------------------------------------------------------------------
568
// DefaultSHA1Context
569
//----------------------------------------------------------------------------
571
// SHA1 - from a public domain implementation by Steve Reid (steve@edmweb.com)
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))
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);
588
unsigned char *buffer; // 64
592
sbuf.resize((7 * sizeof(quint32)) + 64);
596
SHA1_CONTEXT(const SHA1_CONTEXT &from)
601
SHA1_CONTEXT & operator=(const SHA1_CONTEXT &from)
610
char *p = sbuf.data();
611
state = (quint32 *)p;
612
count = (quint32 *)(p + (5 * sizeof(quint32)));
613
buffer = (unsigned char *)(p + (7 * sizeof(quint32)));
622
class DefaultSHA1Context : public HashContext
625
SHA1_CONTEXT _context;
629
DefaultSHA1Context(Provider *p) : HashContext(p, "sha1")
634
virtual Provider::Context *clone() const
636
return new DefaultSHA1Context(*this);
642
sha1_init(&_context);
645
virtual void update(const MemoryRegion &in)
649
sha1_update(&_context, (unsigned char *)in.data(), (unsigned int)in.size());
652
virtual MemoryRegion final()
656
SecureArray b(20, 0);
657
sha1_final((unsigned char *)b.data(), &_context);
663
sha1_final((unsigned char *)b.data(), &_context);
668
inline unsigned long blk0(quint32 i)
670
if(QSysInfo::ByteOrder == QSysInfo::BigEndian)
673
return (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) | (rol(block->l[i],8)&0x00FF00FF));
676
// Hash a single 512-bit block. This is the core of the algorithm.
677
void transform(quint32 state[5], unsigned char buffer[64])
679
quint32 a, b, c, d, e;
681
block = (CHAR64LONG16*)buffer;
683
// Copy context->state[] to working vars
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);
712
// Add the working vars back into context.state[]
720
a = b = c = d = e = 0;
723
// SHA1Init - Initialize new context
724
void sha1_init(SHA1_CONTEXT* context)
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;
735
// Run your data through this
736
void sha1_update(SHA1_CONTEXT* context, unsigned char* data, quint32 len)
740
j = (context->count[0] >> 3) & 63;
741
if((context->count[0] += len << 3) < (len << 3))
744
context->count[1] += (len >> 29);
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]);
755
memcpy(&context->buffer[j], &data[i], len - i);
758
// Add padding and return the message digest
759
void sha1_final(unsigned char digest[20], SHA1_CONTEXT* context)
762
unsigned char finalcount[8];
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
768
sha1_update(context, (unsigned char *)"\200", 1);
769
while ((context->count[0] & 504) != 448) {
770
sha1_update(context, (unsigned char *)"\0", 1);
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);
779
memset(context->buffer, 0, 64);
780
memset(context->state, 0, 20);
781
memset(context->count, 0, 8);
782
memset(&finalcount, 0, 8);
786
//----------------------------------------------------------------------------
787
// DefaultKeyStoreEntry
788
//----------------------------------------------------------------------------
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)
796
for(int n = 0; n < in.length(); ++n)
800
else if(in[n] == ':')
802
else if(in[n] == ',')
804
else if(in[n] == '\n')
812
static bool unescape_string(const QString &in, QString *_out)
815
for(int n = 0; n < in.length(); ++n)
819
if(n + 1 >= in.length())
822
if(in[n + 1] == '\\')
824
else if(in[n + 1] == 'c')
826
else if(in[n + 1] == 'o')
828
else if(in[n + 1] == 'n')
841
static QString escape_stringlist(const QStringList &in)
844
for(int n = 0; n < in.count(); ++n)
845
list += escape_string(in[n]);
846
return list.join(":");
849
static bool unescape_stringlist(const QString &in, QStringList *_out)
852
QStringList list = in.split(':');
853
for(int n = 0; n < list.count(); ++n)
856
if(!unescape_string(list[n], &str))
864
// serialization format is a colon separated list of 7 escaped strings
865
// 0 - "qca_def_1" (header)
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)
882
return escape_stringlist(out);
885
static bool entry_deserialize(const QString &in, QString *storeId, QString *storeName, QString *entryId, QString *entryName, QString *entryType, QString *data)
888
if(!unescape_stringlist(in, &list))
890
if(list.count() != 7)
892
if(list[0] != "qca_def")
895
*storeName = list[2];
897
*entryName = list[4];
898
*entryType = list[5];
903
class DefaultKeyStoreEntry : public KeyStoreEntryContext
906
KeyStoreEntry::Type _type;
907
QString _id, _name, _storeId, _storeName;
910
mutable QString _serialized;
912
DefaultKeyStoreEntry(const Certificate &cert, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p)
914
_type = KeyStoreEntry::TypeCertificate;
916
_storeName = storeName;
920
DefaultKeyStoreEntry(const CRL &crl, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p)
922
_type = KeyStoreEntry::TypeCRL;
924
_storeName = storeName;
928
virtual Provider::Context *clone() const
930
return new DefaultKeyStoreEntry(*this);
933
virtual KeyStoreEntry::Type type() const
938
virtual QString id() const
943
virtual QString name() const
948
virtual QString storeId() const
953
virtual QString storeName() const
958
virtual Certificate certificate() const
963
virtual CRL crl() const
968
virtual QString serialize() const
970
if(_serialized.isEmpty())
975
if(_type == KeyStoreEntry::TypeCertificate)
978
datastr = Base64().arrayToString(_cert.toDER());
983
datastr = Base64().arrayToString(_crl.toDER());
986
_serialized = entry_serialize(_storeId, _storeName, _id, _name, typestr, datastr);
992
static DefaultKeyStoreEntry *deserialize(const QString &in, Provider *provider)
994
QString storeId, storeName, id, name, typestr, datastr;
996
if(entry_deserialize(in, &storeId, &storeName, &id, &name, &typestr, &datastr))
998
QByteArray data = Base64().stringToArray(datastr).toByteArray();
999
DefaultKeyStoreEntry *c;
1001
if(typestr == "cert")
1003
Certificate cert = Certificate::fromDER(data);
1006
c = new DefaultKeyStoreEntry(cert, storeId, storeName, provider);
1008
else if(typestr == "crl")
1010
CRL crl = CRL::fromDER(data);
1013
c = new DefaultKeyStoreEntry(crl, storeId, storeName, provider);
1020
c->_serialized = in;
1026
QString simpleId() const
1028
if(_type == KeyStoreEntry::TypeCertificate)
1029
return QString::number(qHash(_cert.toDER()));
1031
return QString::number(qHash(_crl.toDER()));
1034
QString simpleName() const
1036
// use the common name, else orgname
1037
if(_type == KeyStoreEntry::TypeCertificate)
1039
QString str = _cert.commonName();
1041
str = _cert.subjectInfo().value(Organization);
1045
return _crl.issuerInfo().value(CommonName);
1049
//----------------------------------------------------------------------------
1050
// DefaultKeyStoreList
1051
//----------------------------------------------------------------------------
1052
class DefaultKeyStoreList : public KeyStoreListContext
1056
bool x509_supported;
1057
DefaultShared *shared;
1059
DefaultKeyStoreList(Provider *p, DefaultShared *_shared) : KeyStoreListContext(p), shared(_shared)
1063
~DefaultKeyStoreList()
1067
virtual Provider::Context *clone() const
1072
virtual void start()
1074
x509_supported = false;
1076
QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection);
1079
virtual QList<int> keyStores()
1083
if(isSupported("cert") && isSupported("crl"))
1084
x509_supported = true;
1087
bool have_systemstore = false;
1088
#ifndef QCA_NO_SYSTEMSTORE
1089
if(shared->use_system())
1090
have_systemstore = qca_have_systemstore();
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()))
1103
virtual KeyStore::Type type(int) const
1105
return KeyStore::System;
1108
virtual QString storeId(int) const
1110
return "qca-default-systemstore";
1113
virtual QString name(int) const
1115
return "System Trusted Certificates";
1118
virtual QList<KeyStoreEntry::Type> entryTypes(int) const
1120
QList<KeyStoreEntry::Type> list;
1121
list += KeyStoreEntry::TypeCertificate;
1122
list += KeyStoreEntry::TypeCRL;
1126
virtual QList<KeyStoreEntryContext*> entryList(int)
1128
QList<KeyStoreEntryContext*> out;
1130
QList<Certificate> certs;
1133
if(shared->use_system())
1135
CertificateCollection col;
1136
#ifndef QCA_NO_SYSTEMSTORE
1137
col = qca_get_systemstore(QString());
1139
certs += col.certificates();
1143
QString roots = shared->roots_file();
1144
if(!roots.isEmpty())
1146
CertificateCollection col = CertificateCollection::fromFlatTextFile(roots);
1147
certs += col.certificates();
1151
#ifdef FRIENDLY_NAMES
1152
QStringList names = makeFriendlyNames(certs);
1154
for(int n = 0; n < certs.count(); ++n)
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];
1161
c->_name = c->simpleName();
1166
for(int n = 0; n < crls.count(); ++n)
1168
DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(crls[n], storeId(0), name(0), provider());
1169
c->_id = c->simpleId();
1170
c->_name = c->simpleName();
1177
virtual KeyStoreEntryContext *entryPassive(const QString &serialized)
1179
return DefaultKeyStoreEntry::deserialize(serialized, provider());
1183
//----------------------------------------------------------------------------
1185
//----------------------------------------------------------------------------
1186
static bool unescape_config_stringlist(const QString &in, QStringList *_out)
1189
QStringList list = in.split(',');
1190
for(int n = 0; n < list.count(); ++n)
1193
if(!unescape_string(list[n], &str))
1195
out += str.trimmed();
1201
class DefaultProvider : public Provider
1204
DefaultShared shared;
1208
QDateTime now = QDateTime::currentDateTime();
1210
uint t = now.toTime_t();
1211
if(now.time().msec() > 0)
1212
t /= now.time().msec();
1216
virtual int version() const
1221
virtual int qcaVersion() const
1226
virtual QString name() const
1231
virtual QStringList features() const
1237
list += "keystorelist";
1241
virtual Provider::Context *createContext(const QString &type)
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);
1255
virtual QVariantMap defaultConfig() const
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();
1266
virtual void configChanged(const QVariantMap &config)
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();
1275
QStringList skip_plugins;
1276
if(unescape_config_stringlist(skip_plugins_str, &tmp))
1279
QStringList plugin_priorities;
1280
if(unescape_config_stringlist(plugin_priorities_str, &tmp))
1281
plugin_priorities = tmp;
1283
for(int n = 0; n < plugin_priorities.count(); ++n)
1285
QString &s = plugin_priorities[n];
1287
// make sure the entry ends with ":number"
1288
int x = s.indexOf(':');
1291
s.mid(x + 1).toInt(&ok);
1294
plugin_priorities.removeAt(n);
1299
shared.set(use_system, roots_file, skip_plugins, plugin_priorities);
1303
Provider *create_default_provider()
1305
return new DefaultProvider;
1308
QStringList skip_plugins(Provider *defaultProvider)
1310
DefaultProvider *that = (DefaultProvider *)defaultProvider;
1311
return that->shared.skip_plugins();
1314
QStringList plugin_priorities(Provider *defaultProvider)
1316
DefaultProvider *that = (DefaultProvider *)defaultProvider;
1317
return that->shared.plugin_priorities();
1320
#include "qca_default.moc"