1 #include "system.h"
2
3 #include <pthread.h>
4 #include <nss.h>
5 #include <sechash.h>
6 #include <signal.h>
7 #include <keyhi.h>
8 #include <cryptohi.h>
9 #include <blapit.h>
10
11 #include <rpm/rpmlog.h>
12 #include "rpmio/digest.h"
13 #include "debug.h"
14
15
16 static int _crypto_initialized = 0;
17 static int _new_process = 1;
18
19 #if HAVE_NSS_INITCONTEXT
20 static NSSInitContext * _nss_ctx = NULL;
21 #endif
22
23 /**
24 * MD5/SHA1 digest private data.
25 */
26 struct DIGEST_CTX_s {
27 rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */
28 HASHContext *hashctx; /*!< Internal NSS hash context. */
29 int algo; /*!< Used hash algorithm */
30 };
31
32 /*
33 * Only flag for re-initialization here, in the common case the child
34 * exec()'s something else shutting down NSS here would be waste of time.
35 */
at_forkchild(void)36 static void at_forkchild(void)
37 {
38 _new_process = 1;
39 }
40
rpmInitCrypto(void)41 int rpmInitCrypto(void)
42 {
43 int rc = 0;
44
45 /* Lazy NSS shutdown for re-initialization after fork() */
46 if (_new_process && _crypto_initialized) {
47 rpmFreeCrypto();
48 }
49
50 /*
51 * Initialize NSS if not already done.
52 * NSS prior to 3.12.5 only supports a global context which can cause
53 * trouble when an API user wants to use NSS for their own purposes, use
54 * a private context if possible.
55 */
56 if (!_crypto_initialized) {
57 /* NSPR sets SIGPIPE to ignore behind our back, save and restore */
58 struct sigaction oact;
59 sigaction(SIGPIPE, NULL, &oact);
60 #if HAVE_NSS_INITCONTEXT
61 PRUint32 flags = (NSS_INIT_READONLY|NSS_INIT_NOCERTDB|
62 NSS_INIT_NOMODDB|NSS_INIT_FORCEOPEN|
63 NSS_INIT_NOROOTINIT|NSS_INIT_OPTIMIZESPACE);
64 _nss_ctx = NSS_InitContext(NULL, NULL, NULL, NULL, NULL, flags);
65 if (_nss_ctx == NULL) {
66 #else
67 if (NSS_NoDB_Init(NULL) != SECSuccess) {
68 #endif
69 rpmlog(RPMLOG_ERR, _("Failed to initialize NSS library\n"));
70 rc = -1;
71 } else {
72 _crypto_initialized = 1;
73 }
74 sigaction(SIGPIPE, &oact, NULL);
75 }
76
77 /* Register one post-fork handler per process */
78 if (_new_process) {
79 if (pthread_atfork(NULL, NULL, at_forkchild) != 0) {
80 rpmlog(RPMLOG_WARNING, _("Failed to register fork handler: %m\n"));
81 }
82 _new_process = 0;
83 }
84 return rc;
85 }
86
87 int rpmFreeCrypto(void)
88 {
89 int rc = 0;
90 if (_crypto_initialized) {
91 #if HAVE_NSS_INITCONTEXT
92 rc = (NSS_ShutdownContext(_nss_ctx) != SECSuccess);
93 _nss_ctx = NULL;
94 #else
95 rc = (NSS_Shutdown() != SECSuccess);
96 #endif
97 _crypto_initialized = 0;
98 }
99 return rc;
100 }
101
102 DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
103 {
104 DIGEST_CTX nctx = NULL;
105 if (octx) {
106 HASHContext *hctx = HASH_Clone(octx->hashctx);
107 if (hctx) {
108 nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
109 nctx->hashctx = hctx;
110 }
111 }
112 return nctx;
113 }
114
115 RPM_GNUC_PURE
116 static HASH_HashType getHashType(int hashalgo)
117 {
118 switch (hashalgo) {
119 case PGPHASHALGO_MD5: return HASH_AlgMD5;
120 case PGPHASHALGO_SHA1: return HASH_AlgSHA1;
121 #ifdef SHA224_LENGTH
122 case PGPHASHALGO_SHA224: return HASH_AlgSHA224;
123 #endif
124 case PGPHASHALGO_SHA256: return HASH_AlgSHA256;
125 case PGPHASHALGO_SHA384: return HASH_AlgSHA384;
126 case PGPHASHALGO_SHA512: return HASH_AlgSHA512;
127 }
128 return HASH_AlgNULL;
129 }
130
131 size_t rpmDigestLength(int hashalgo)
132 {
133 return HASH_ResultLen(getHashType(hashalgo));
134 }
135
136 DIGEST_CTX rpmDigestInit(int hashalgo, rpmDigestFlags flags)
137 {
138 HASH_HashType type = getHashType(hashalgo);
139 HASHContext *hashctx = NULL;
140 DIGEST_CTX ctx = NULL;
141
142 if (type == HASH_AlgNULL || rpmInitCrypto() < 0)
143 goto exit;
144
145 if ((hashctx = HASH_Create(type)) != NULL) {
146 ctx = xcalloc(1, sizeof(*ctx));
147 ctx->flags = flags;
148 ctx->algo = hashalgo;
149 ctx->hashctx = hashctx;
150 HASH_Begin(ctx->hashctx);
151 }
152
153 exit:
154 return ctx;
155 }
156
157 int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
158 {
159 size_t partlen;
160 const unsigned char *ptr = data;
161
162 if (ctx == NULL)
163 return -1;
164
165 partlen = ~(unsigned int)0xFF;
166 while (len > 0) {
167 if (len < partlen) {
168 partlen = len;
169 }
170 HASH_Update(ctx->hashctx, ptr, partlen);
171 ptr += partlen;
172 len -= partlen;
173 }
174 return 0;
175 }
176
177 int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
178 {
179 unsigned char * digest;
180 unsigned int digestlen;
181
182 if (ctx == NULL)
183 return -1;
184 digestlen = HASH_ResultLenContext(ctx->hashctx);
185 digest = xmalloc(digestlen);
186
187 /* FIX: check rc */
188 HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen);
189
190 /* Return final digest. */
191 if (!asAscii) {
192 if (lenp) *lenp = digestlen;
193 if (datap) {
194 *datap = digest;
195 digest = NULL;
196 }
197 } else {
198 if (lenp) *lenp = (2*digestlen) + 1;
199 if (datap) {
200 const uint8_t * s = (const uint8_t *) digest;
201 *datap = pgpHexStr(s, digestlen);
202 }
203 }
204 if (digest) {
205 memset(digest, 0, digestlen); /* In case it's sensitive */
206 free(digest);
207 }
208 HASH_Destroy(ctx->hashctx);
209 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
210 free(ctx);
211 return 0;
212 }
213
214 RPM_GNUC_PURE
215 static SECOidTag getHashAlg(unsigned int hashalgo)
216 {
217 switch (hashalgo) {
218 case PGPHASHALGO_MD5: return SEC_OID_MD5;
219 case PGPHASHALGO_SHA1: return SEC_OID_SHA1;
220 #ifdef SHA224_LENGTH
221 case PGPHASHALGO_SHA224: return SEC_OID_SHA224;
222 #endif
223 case PGPHASHALGO_SHA256: return SEC_OID_SHA256;
224 case PGPHASHALGO_SHA384: return SEC_OID_SHA384;
225 case PGPHASHALGO_SHA512: return SEC_OID_SHA512;
226 }
227 return SEC_OID_UNKNOWN;
228 }
229
230 static int pgpMpiSet(unsigned int lbits, uint8_t *dest, const uint8_t * p)
231 {
232 unsigned int mbits = pgpMpiBits(p);
233 unsigned int nbits;
234 size_t nbytes;
235 uint8_t *t = dest;
236 unsigned int ix;
237
238 if (mbits > lbits)
239 return 1;
240
241 nbits = (lbits > mbits ? lbits : mbits);
242 nbytes = ((nbits + 7) >> 3);
243 ix = (nbits - mbits) >> 3;
244
245 if (ix > 0)
246 memset(t, '\0', ix);
247 memcpy(t+ix, p+2, nbytes-ix);
248
249 return 0;
250 }
251
252 static SECItem *pgpMpiItem(PRArenaPool *arena, SECItem *item, const uint8_t *p)
253 {
254 size_t nbytes = pgpMpiLen(p)-2;
255
256 if (item == NULL) {
257 if ((item=SECITEM_AllocItem(arena, item, nbytes)) == NULL)
258 return item;
259 } else {
260 if (arena != NULL)
261 item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes);
262 else
263 item->data = PORT_Realloc(item->data, nbytes);
264
265 if (item->data == NULL) {
266 if (arena == NULL)
267 SECITEM_FreeItem(item, PR_TRUE);
268 return NULL;
269 }
270 }
271
272 memcpy(item->data, p+2, nbytes);
273 item->len = nbytes;
274 return item;
275 }
276
277 static SECKEYPublicKey *pgpNewPublicKey(KeyType type)
278 {
279 PRArenaPool *arena;
280 SECKEYPublicKey *key;
281
282 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
283 if (arena == NULL)
284 return NULL;
285
286 key = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
287
288 if (key == NULL) {
289 PORT_FreeArena(arena, PR_FALSE);
290 return NULL;
291 }
292
293 key->keyType = type;
294 key->pkcs11ID = CK_INVALID_HANDLE;
295 key->pkcs11Slot = NULL;
296 key->arena = arena;
297 return key;
298 }
299
300 /* compatibility with nss < 3.14 */
301 #ifndef DSA1_SUBPRIME_LEN
302 #define DSA1_SUBPRIME_LEN DSA_SUBPRIME_LEN
303 #endif
304 #ifndef DSA1_SIGNATURE_LEN
305 #define DSA1_SIGNATURE_LEN DSA_SIGNATURE_LEN
306 #endif
307 #ifndef DSA1_Q_BITS
308 #define DSA1_Q_BITS DSA_Q_BITS
309 #endif
310
311 static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
312 {
313 SECItem *sig = pgpsig->data;
314 unsigned int qbits = DSA1_Q_BITS;
315 unsigned int subprlen = DSA1_SUBPRIME_LEN;
316 unsigned int siglen = DSA1_SIGNATURE_LEN;
317 int rc = 1; /* assume failure */
318
319 switch (num) {
320 case 0:
321 sig = pgpsig->data = SECITEM_AllocItem(NULL, NULL, siglen);
322 if (sig) {
323 memset(sig->data, 0, siglen);
324 rc = pgpMpiSet(qbits, sig->data, p);
325 }
326 break;
327 case 1:
328 if (sig && pgpMpiSet(qbits, sig->data+subprlen, p) == 0) {
329 SECItem *signew = SECITEM_AllocItem(NULL, NULL, 0);
330 if (signew == NULL)
331 break;
332 if (DSAU_EncodeDerSigWithLen(signew, sig, siglen) == SECSuccess) {
333 SECITEM_FreeItem(sig, PR_TRUE);
334 pgpsig->data = signew;
335 rc = 0;
336 }
337 }
338 break;
339 }
340
341 return rc;
342 }
343
344 static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
345 {
346 SECItem *mpi = NULL;
347 SECKEYPublicKey *key = pgpkey->data;
348
349 if (key == NULL)
350 key = pgpkey->data = pgpNewPublicKey(dsaKey);
351
352 if (key) {
353 switch (num) {
354 case 0:
355 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.prime, p);
356 break;
357 case 1:
358 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.subPrime, p);
359 break;
360 case 2:
361 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.base, p);
362 break;
363 case 3:
364 mpi = pgpMpiItem(key->arena, &key->u.dsa.publicValue, p);
365 break;
366 }
367 }
368
369 return (mpi == NULL);
370 }
371
372 static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
373 uint8_t *hash, size_t hashlen, int hash_algo)
374 {
375 SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
376 SECOidTag encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
377 SECOidTag hashAlg = getHashAlg(hash_algo);
378 SECStatus rc;
379
380 if (hashAlg == SEC_OID_UNKNOWN)
381 return 1;
382
383 rc = VFY_VerifyDigestDirect(&digest, pgpkey->data, pgpsig->data,
384 encAlg, hashAlg, NULL);
385
386 return (rc != SECSuccess);
387 }
388
389 static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
390 {
391 SECItem *sigitem = NULL;
392
393 if (num == 0) {
394 sigitem = pgpMpiItem(NULL, pgpsig->data, p);
395 if (sigitem)
396 pgpsig->data = sigitem;
397 }
398 return (sigitem == NULL);
399 }
400
401 static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
402 {
403 SECItem *kitem = NULL;
404 SECKEYPublicKey *key = pgpkey->data;
405
406 if (key == NULL)
407 key = pgpkey->data = pgpNewPublicKey(rsaKey);
408
409 if (key) {
410 switch (num) {
411 case 0:
412 kitem = pgpMpiItem(key->arena, &key->u.rsa.modulus, p);
413 break;
414 case 1:
415 kitem = pgpMpiItem(key->arena, &key->u.rsa.publicExponent, p);
416 break;
417 }
418 }
419
420 return (kitem == NULL);
421 }
422
423 static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
424 uint8_t *hash, size_t hashlen, int hash_algo)
425 {
426 SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
427 SECItem *sig = pgpsig->data;
428 SECKEYPublicKey *key = pgpkey->data;
429 SECItem *padded = NULL;
430 SECOidTag encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
431 SECOidTag hashAlg = getHashAlg(hash_algo);
432 SECStatus rc = SECFailure;
433 size_t siglen, padlen;
434
435 if (hashAlg == SEC_OID_UNKNOWN)
436 return 1;
437
438 /* Zero-pad signature to expected size if necessary */
439 siglen = SECKEY_SignatureLen(key);
440 padlen = siglen - sig->len;
441 if (padlen) {
442 padded = SECITEM_AllocItem(NULL, NULL, siglen);
443 if (padded == NULL)
444 return 1;
445 memset(padded->data, 0, padlen);
446 memcpy(padded->data + padlen, sig->data, sig->len);
447 sig = padded;
448 }
449
450 rc = VFY_VerifyDigestDirect(&digest, key, sig, encAlg, hashAlg, NULL);
451
452 if (padded)
453 SECITEM_ZfreeItem(padded, PR_TRUE);
454
455 return (rc != SECSuccess);
456 }
457
458 static void pgpFreeSigRSADSA(pgpDigAlg sa)
459 {
460 SECITEM_ZfreeItem(sa->data, PR_TRUE);
461 sa->data = NULL;
462 }
463
464 static void pgpFreeKeyRSADSA(pgpDigAlg ka)
465 {
466 SECKEY_DestroyPublicKey(ka->data);
467 ka->data = NULL;
468 }
469
470 static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num, const uint8_t *p)
471 {
472 return 1;
473 }
474
475 static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
476 uint8_t *hash, size_t hashlen, int hash_algo)
477 {
478 return 1;
479 }
480
481 pgpDigAlg pgpPubkeyNew(int algo, int curve)
482 {
483 pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
484
485 switch (algo) {
486 case PGPPUBKEYALGO_RSA:
487 ka->setmpi = pgpSetKeyMpiRSA;
488 ka->free = pgpFreeKeyRSADSA;
489 ka->mpis = 2;
490 break;
491 case PGPPUBKEYALGO_DSA:
492 ka->setmpi = pgpSetKeyMpiDSA;
493 ka->free = pgpFreeKeyRSADSA;
494 ka->mpis = 4;
495 break;
496 default:
497 ka->setmpi = pgpSetMpiNULL;
498 ka->mpis = -1;
499 break;
500 }
501
502 ka->verify = pgpVerifyNULL; /* keys can't be verified */
503
504 return ka;
505 }
506
507 pgpDigAlg pgpSignatureNew(int algo)
508 {
509 pgpDigAlg sa = xcalloc(1, sizeof(*sa));
510
511 switch (algo) {
512 case PGPPUBKEYALGO_RSA:
513 sa->setmpi = pgpSetSigMpiRSA;
514 sa->free = pgpFreeSigRSADSA;
515 sa->verify = pgpVerifySigRSA;
516 sa->mpis = 1;
517 break;
518 case PGPPUBKEYALGO_DSA:
519 sa->setmpi = pgpSetSigMpiDSA;
520 sa->free = pgpFreeSigRSADSA;
521 sa->verify = pgpVerifySigDSA;
522 sa->mpis = 2;
523 break;
524 default:
525 sa->setmpi = pgpSetMpiNULL;
526 sa->verify = pgpVerifyNULL;
527 sa->mpis = -1;
528 break;
529 }
530 return sa;
531 }
532
533