9 #include <rpm/rpmlog.h>
10 #include "rpmio/digest.h"
14 static int _crypto_initialized = 0;
15 static int _new_process = 1;
18 * MD5/SHA1 digest private data.
21 rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */
22 HASHContext *hashctx; /*!< Internal NSS hash context. */
23 int algo; /*!< Used hash algorithm */
27 * Only flag for re-initialization here, in the common case the child
28 * exec()'s something else shutting down NSS here would be waste of time.
30 static void at_forkchild(void)
35 int rpmInitCrypto(void)
39 /* Lazy NSS shutdown for re-initialization after fork() */
40 if (_new_process && _crypto_initialized) {
44 /* Initialize NSS if not already done */
45 if (!_crypto_initialized) {
46 if (NSS_NoDB_Init(NULL) != SECSuccess) {
49 _crypto_initialized = 1;
53 /* Register one post-fork handler per process */
55 if (pthread_atfork(NULL, NULL, at_forkchild) != 0) {
56 rpmlog(RPMLOG_WARNING, _("Failed to register fork handler: %m\n"));
63 int rpmFreeCrypto(void)
66 if (_crypto_initialized) {
67 rc = (NSS_Shutdown() != SECSuccess);
68 _crypto_initialized = 0;
73 DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
75 DIGEST_CTX nctx = NULL;
77 HASHContext *hctx = HASH_Clone(octx->hashctx);
79 nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
87 static HASH_HashType getHashType(int hashalgo)
96 case PGPHASHALGO_SHA1:
99 case PGPHASHALGO_SHA256:
100 return HASH_AlgSHA256;
102 case PGPHASHALGO_SHA384:
103 return HASH_AlgSHA384;
105 case PGPHASHALGO_SHA512:
106 return HASH_AlgSHA512;
108 case PGPHASHALGO_RIPEMD160:
109 case PGPHASHALGO_TIGER192:
110 case PGPHASHALGO_HAVAL_5_160:
117 size_t rpmDigestLength(int hashalgo)
119 return HASH_ResultLen(getHashType(hashalgo));
122 DIGEST_CTX rpmDigestInit(int hashalgo, rpmDigestFlags flags)
124 HASH_HashType type = getHashType(hashalgo);
125 HASHContext *hashctx = NULL;
126 DIGEST_CTX ctx = NULL;
128 if (type == HASH_AlgNULL || rpmInitCrypto() < 0)
131 if ((hashctx = HASH_Create(type)) != NULL) {
132 ctx = xcalloc(1, sizeof(*ctx));
134 ctx->algo = hashalgo;
135 ctx->hashctx = hashctx;
136 HASH_Begin(ctx->hashctx);
143 int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
146 const unsigned char *ptr = data;
151 partlen = ~(unsigned int)0xFF;
156 HASH_Update(ctx->hashctx, ptr, partlen);
163 int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
165 unsigned char * digest;
166 unsigned int digestlen;
170 digestlen = HASH_ResultLenContext(ctx->hashctx);
171 digest = xmalloc(digestlen);
174 HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen);
176 /* Return final digest. */
178 if (lenp) *lenp = digestlen;
184 if (lenp) *lenp = (2*digestlen) + 1;
186 const uint8_t * s = (const uint8_t *) digest;
187 *datap = pgpHexStr(s, digestlen);
191 memset(digest, 0, digestlen); /* In case it's sensitive */
194 HASH_Destroy(ctx->hashctx);
195 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
200 static int pgpMpiSet(unsigned int lbits, uint8_t *dest,
201 const uint8_t * p, const uint8_t * pend)
203 unsigned int mbits = pgpMpiBits(p);
209 if ((p + ((mbits+7) >> 3)) > pend)
215 nbits = (lbits > mbits ? lbits : mbits);
216 nbytes = ((nbits + 7) >> 3);
217 ix = (nbits - mbits) >> 3;
221 memcpy(t+ix, p+2, nbytes-ix);
226 static SECItem *pgpMpiItem(PRArenaPool *arena, SECItem *item,
227 const uint8_t *p, const uint8_t *pend)
229 size_t nbytes = pgpMpiLen(p)-2;
231 if (p + nbytes + 2 > pend)
235 if ((item=SECITEM_AllocItem(arena, item, nbytes)) == NULL)
239 item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes);
241 item->data = PORT_Realloc(item->data, nbytes);
243 if (item->data == NULL) {
245 SECITEM_FreeItem(item, PR_TRUE);
250 memcpy(item->data, p+2, nbytes);
255 static SECKEYPublicKey *pgpNewPublicKey(KeyType type)
258 SECKEYPublicKey *key;
260 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
264 key = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
267 PORT_FreeArena(arena, PR_FALSE);
272 key->pkcs11ID = CK_INVALID_HANDLE;
273 key->pkcs11Slot = NULL;
278 #ifndef DSA_SUBPRIME_LEN
279 #define DSA_SUBPRIME_LEN 20
282 static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num,
283 const uint8_t *p, const uint8_t *pend)
285 SECItem *sig = pgpsig->data;
286 int lbits = DSA_SUBPRIME_LEN * 8;
287 int rc = 1; /* assume failure */
291 sig = pgpsig->data = SECITEM_AllocItem(NULL, NULL, 2*DSA_SUBPRIME_LEN);
292 memset(sig->data, 0, 2 * DSA_SUBPRIME_LEN);
293 rc = pgpMpiSet(lbits, sig->data, p, pend);
296 if (sig && pgpMpiSet(lbits, sig->data+DSA_SUBPRIME_LEN, p, pend) == 0) {
297 SECItem *signew = SECITEM_AllocItem(NULL, NULL, 0);
298 if (signew && DSAU_EncodeDerSig(signew, sig) == SECSuccess) {
299 SECITEM_FreeItem(sig, PR_TRUE);
300 pgpsig->data = signew;
310 static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num,
311 const uint8_t *p, const uint8_t *pend)
314 SECKEYPublicKey *key = pgpkey->data;
317 key = pgpkey->data = pgpNewPublicKey(dsaKey);
322 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.prime, p, pend);
325 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.subPrime, p, pend);
328 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.base, p, pend);
331 mpi = pgpMpiItem(key->arena, &key->u.dsa.publicValue, p, pend);
336 return (mpi == NULL);
339 static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
340 uint8_t *hash, size_t hashlen, int hash_algo)
342 SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
343 SECOidTag sigalg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
346 /* XXX VFY_VerifyDigest() is deprecated in NSS 3.12 */
347 rc = VFY_VerifyDigest(&digest, pgpkey->data, pgpsig->data, sigalg, NULL);
349 return (rc != SECSuccess);
352 static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num,
353 const uint8_t *p, const uint8_t *pend)
355 SECItem *sigitem = NULL;
358 sigitem = pgpMpiItem(NULL, pgpsig->data, p, pend);
360 pgpsig->data = sigitem;
362 return (sigitem == NULL);
365 static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num,
366 const uint8_t *p, const uint8_t *pend)
368 SECItem *kitem = NULL;
369 SECKEYPublicKey *key = pgpkey->data;
372 key = pgpkey->data = pgpNewPublicKey(rsaKey);
377 kitem = pgpMpiItem(key->arena, &key->u.rsa.modulus, p, pend);
380 kitem = pgpMpiItem(key->arena, &key->u.rsa.publicExponent, p, pend);
385 return (kitem == NULL);
388 static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
389 uint8_t *hash, size_t hashlen, int hash_algo)
391 SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
392 SECItem *sig = pgpsig->data;
393 SECKEYPublicKey *key = pgpkey->data;
394 SECItem *padded = NULL;
396 SECStatus rc = SECFailure;
397 size_t siglen, padlen;
400 case PGPHASHALGO_MD5:
401 sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
403 case PGPHASHALGO_MD2:
404 sigalg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
406 case PGPHASHALGO_SHA1:
407 sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
409 case PGPHASHALGO_SHA256:
410 sigalg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
412 case PGPHASHALGO_SHA384:
413 sigalg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
415 case PGPHASHALGO_SHA512:
416 sigalg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
419 return 1; /* dont bother with unknown hash types */
423 /* Zero-pad signature to expected size if necessary */
424 siglen = SECKEY_SignatureLen(key);
425 padlen = siglen - sig->len;
427 padded = SECITEM_AllocItem(NULL, NULL, siglen);
430 memset(padded->data, 0, padlen);
431 memcpy(padded->data + padlen, sig->data, sig->len);
435 /* XXX VFY_VerifyDigest() is deprecated in NSS 3.12 */
436 rc = VFY_VerifyDigest(&digest, key, sig, sigalg, NULL);
439 SECITEM_ZfreeItem(padded, PR_TRUE);
441 return (rc != SECSuccess);
444 static void pgpFreeSigRSADSA(pgpDigAlg sa)
446 SECITEM_ZfreeItem(sa->data, PR_TRUE);
450 static void pgpFreeKeyRSADSA(pgpDigAlg ka)
452 SECKEY_DestroyPublicKey(ka->data);
456 static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num,
457 const uint8_t *p, const uint8_t *pend)
462 static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
463 uint8_t *hash, size_t hashlen, int hash_algo)
468 pgpDigAlg pgpPubkeyNew(int algo)
470 pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
473 case PGPPUBKEYALGO_RSA:
474 ka->setmpi = pgpSetKeyMpiRSA;
475 ka->free = pgpFreeKeyRSADSA;
478 case PGPPUBKEYALGO_DSA:
479 ka->setmpi = pgpSetKeyMpiDSA;
480 ka->free = pgpFreeKeyRSADSA;
484 ka->setmpi = pgpSetMpiNULL;
489 ka->verify = pgpVerifyNULL; /* keys can't be verified */
494 pgpDigAlg pgpSignatureNew(int algo)
496 pgpDigAlg sa = xcalloc(1, sizeof(*sa));
499 case PGPPUBKEYALGO_RSA:
500 sa->setmpi = pgpSetSigMpiRSA;
501 sa->free = pgpFreeSigRSADSA;
502 sa->verify = pgpVerifySigRSA;
505 case PGPPUBKEYALGO_DSA:
506 sa->setmpi = pgpSetSigMpiDSA;
507 sa->free = pgpFreeSigRSADSA;
508 sa->verify = pgpVerifySigDSA;
512 sa->setmpi = pgpSetMpiNULL;
513 sa->verify = pgpVerifyNULL;