10 #include <rpm/rpmlog.h>
11 #include "rpmio/digest.h"
15 static int _crypto_initialized = 0;
16 static int _new_process = 1;
18 #if HAVE_NSS_INITCONTEXT
19 static NSSInitContext * _nss_ctx = NULL;
23 * MD5/SHA1 digest private data.
26 rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */
27 HASHContext *hashctx; /*!< Internal NSS hash context. */
28 int algo; /*!< Used hash algorithm */
32 * Only flag for re-initialization here, in the common case the child
33 * exec()'s something else shutting down NSS here would be waste of time.
35 static void at_forkchild(void)
40 int rpmInitCrypto(void)
44 /* Lazy NSS shutdown for re-initialization after fork() */
45 if (_new_process && _crypto_initialized) {
50 * Initialize NSS if not already done.
51 * NSS prior to 3.12.5 only supports a global context which can cause
52 * trouble when an API user wants to use NSS for their own purposes, use
53 * a private context if possible.
55 if (!_crypto_initialized) {
56 /* NSPR sets SIGPIPE to ignore behind our back, save and restore */
57 struct sigaction oact;
58 sigaction(SIGPIPE, NULL, &oact);
59 #if HAVE_NSS_INITCONTEXT
60 PRUint32 flags = (NSS_INIT_READONLY|NSS_INIT_NOCERTDB|
61 NSS_INIT_NOMODDB|NSS_INIT_FORCEOPEN|
62 NSS_INIT_NOROOTINIT|NSS_INIT_OPTIMIZESPACE);
63 _nss_ctx = NSS_InitContext(NULL, NULL, NULL, NULL, NULL, flags);
64 if (_nss_ctx == NULL) {
66 if (NSS_NoDB_Init(NULL) != SECSuccess) {
68 rpmlog(RPMLOG_ERR, _("Failed to initialize NSS library\n"));
71 _crypto_initialized = 1;
73 sigaction(SIGPIPE, &oact, NULL);
76 /* Register one post-fork handler per process */
78 if (pthread_atfork(NULL, NULL, at_forkchild) != 0) {
79 rpmlog(RPMLOG_WARNING, _("Failed to register fork handler: %m\n"));
86 int rpmFreeCrypto(void)
89 if (_crypto_initialized) {
90 #if HAVE_NSS_INITCONTEXT
91 rc = (NSS_ShutdownContext(_nss_ctx) != SECSuccess);
94 rc = (NSS_Shutdown() != SECSuccess);
96 _crypto_initialized = 0;
101 DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
103 DIGEST_CTX nctx = NULL;
105 HASHContext *hctx = HASH_Clone(octx->hashctx);
107 nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
108 nctx->hashctx = hctx;
115 static HASH_HashType getHashType(int hashalgo)
118 case PGPHASHALGO_MD5: return HASH_AlgMD5;
119 case PGPHASHALGO_MD2: return HASH_AlgMD2;
120 case PGPHASHALGO_SHA1: return HASH_AlgSHA1;
122 case PGPHASHALGO_SHA224: return HASH_AlgSHA224;
124 case PGPHASHALGO_SHA256: return HASH_AlgSHA256;
125 case PGPHASHALGO_SHA384: return HASH_AlgSHA384;
126 case PGPHASHALGO_SHA512: return HASH_AlgSHA512;
131 size_t rpmDigestLength(int hashalgo)
133 return HASH_ResultLen(getHashType(hashalgo));
136 DIGEST_CTX rpmDigestInit(int hashalgo, rpmDigestFlags flags)
138 HASH_HashType type = getHashType(hashalgo);
139 HASHContext *hashctx = NULL;
140 DIGEST_CTX ctx = NULL;
142 if (type == HASH_AlgNULL || rpmInitCrypto() < 0)
145 if ((hashctx = HASH_Create(type)) != NULL) {
146 ctx = xcalloc(1, sizeof(*ctx));
148 ctx->algo = hashalgo;
149 ctx->hashctx = hashctx;
150 HASH_Begin(ctx->hashctx);
157 int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
160 const unsigned char *ptr = data;
165 partlen = ~(unsigned int)0xFF;
170 HASH_Update(ctx->hashctx, ptr, partlen);
177 int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
179 unsigned char * digest;
180 unsigned int digestlen;
184 digestlen = HASH_ResultLenContext(ctx->hashctx);
185 digest = xmalloc(digestlen);
188 HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen);
190 /* Return final digest. */
192 if (lenp) *lenp = digestlen;
198 if (lenp) *lenp = (2*digestlen) + 1;
200 const uint8_t * s = (const uint8_t *) digest;
201 *datap = pgpHexStr(s, digestlen);
205 memset(digest, 0, digestlen); /* In case it's sensitive */
208 HASH_Destroy(ctx->hashctx);
209 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
215 static SECOidTag getHashAlg(unsigned int hashalgo)
218 case PGPHASHALGO_MD5: return SEC_OID_MD5;
219 case PGPHASHALGO_MD2: return SEC_OID_MD2;
220 case PGPHASHALGO_SHA1: return SEC_OID_SHA1;
222 case PGPHASHALGO_SHA224: return SEC_OID_SHA224;
224 case PGPHASHALGO_SHA256: return SEC_OID_SHA256;
225 case PGPHASHALGO_SHA384: return SEC_OID_SHA384;
226 case PGPHASHALGO_SHA512: return SEC_OID_SHA512;
228 return SEC_OID_UNKNOWN;
231 static int pgpMpiSet(unsigned int lbits, uint8_t *dest, const uint8_t * p)
233 unsigned int mbits = pgpMpiBits(p);
242 nbits = (lbits > mbits ? lbits : mbits);
243 nbytes = ((nbits + 7) >> 3);
244 ix = (nbits - mbits) >> 3;
248 memcpy(t+ix, p+2, nbytes-ix);
253 static SECItem *pgpMpiItem(PRArenaPool *arena, SECItem *item, const uint8_t *p)
255 size_t nbytes = pgpMpiLen(p)-2;
258 if ((item=SECITEM_AllocItem(arena, item, nbytes)) == NULL)
262 item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes);
264 item->data = PORT_Realloc(item->data, nbytes);
266 if (item->data == NULL) {
268 SECITEM_FreeItem(item, PR_TRUE);
273 memcpy(item->data, p+2, nbytes);
278 static SECKEYPublicKey *pgpNewPublicKey(KeyType type)
281 SECKEYPublicKey *key;
283 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
287 key = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
290 PORT_FreeArena(arena, PR_FALSE);
295 key->pkcs11ID = CK_INVALID_HANDLE;
296 key->pkcs11Slot = NULL;
301 /* compatibility with nss < 3.14 */
302 #ifndef DSA1_SUBPRIME_LEN
303 #define DSA1_SUBPRIME_LEN DSA_SUBPRIME_LEN
305 #ifndef DSA1_SIGNATURE_LEN
306 #define DSA1_SIGNATURE_LEN DSA_SIGNATURE_LEN
309 #define DSA1_Q_BITS DSA_Q_BITS
312 static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
314 SECItem *sig = pgpsig->data;
315 unsigned int qbits = DSA1_Q_BITS;
316 unsigned int subprlen = DSA1_SUBPRIME_LEN;
317 unsigned int siglen = DSA1_SIGNATURE_LEN;
318 int rc = 1; /* assume failure */
322 sig = pgpsig->data = SECITEM_AllocItem(NULL, NULL, siglen);
324 memset(sig->data, 0, siglen);
325 rc = pgpMpiSet(qbits, sig->data, p);
329 if (sig && pgpMpiSet(qbits, sig->data+subprlen, p) == 0) {
330 SECItem *signew = SECITEM_AllocItem(NULL, NULL, 0);
333 if (DSAU_EncodeDerSigWithLen(signew, sig, siglen) == SECSuccess) {
334 SECITEM_FreeItem(sig, PR_TRUE);
335 pgpsig->data = signew;
345 static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
348 SECKEYPublicKey *key = pgpkey->data;
351 key = pgpkey->data = pgpNewPublicKey(dsaKey);
356 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.prime, p);
359 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.subPrime, p);
362 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.base, p);
365 mpi = pgpMpiItem(key->arena, &key->u.dsa.publicValue, p);
370 return (mpi == NULL);
373 static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
374 uint8_t *hash, size_t hashlen, int hash_algo)
376 SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
377 SECOidTag encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
378 SECOidTag hashAlg = getHashAlg(hash_algo);
381 if (hashAlg == SEC_OID_UNKNOWN)
384 rc = VFY_VerifyDigestDirect(&digest, pgpkey->data, pgpsig->data,
385 encAlg, hashAlg, NULL);
387 return (rc != SECSuccess);
390 static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num, const uint8_t *p)
392 SECItem *sigitem = NULL;
395 sigitem = pgpMpiItem(NULL, pgpsig->data, p);
397 pgpsig->data = sigitem;
399 return (sigitem == NULL);
402 static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
404 SECItem *kitem = NULL;
405 SECKEYPublicKey *key = pgpkey->data;
408 key = pgpkey->data = pgpNewPublicKey(rsaKey);
413 kitem = pgpMpiItem(key->arena, &key->u.rsa.modulus, p);
416 kitem = pgpMpiItem(key->arena, &key->u.rsa.publicExponent, p);
421 return (kitem == NULL);
424 static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
425 uint8_t *hash, size_t hashlen, int hash_algo)
427 SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
428 SECItem *sig = pgpsig->data;
429 SECKEYPublicKey *key = pgpkey->data;
430 SECItem *padded = NULL;
431 SECOidTag encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
432 SECOidTag hashAlg = getHashAlg(hash_algo);
433 SECStatus rc = SECFailure;
434 size_t siglen, padlen;
436 if (hashAlg == SEC_OID_UNKNOWN)
439 /* Zero-pad signature to expected size if necessary */
440 siglen = SECKEY_SignatureLen(key);
441 padlen = siglen - sig->len;
443 padded = SECITEM_AllocItem(NULL, NULL, siglen);
446 memset(padded->data, 0, padlen);
447 memcpy(padded->data + padlen, sig->data, sig->len);
451 rc = VFY_VerifyDigestDirect(&digest, key, sig, encAlg, hashAlg, NULL);
454 SECITEM_ZfreeItem(padded, PR_TRUE);
456 return (rc != SECSuccess);
459 static void pgpFreeSigRSADSA(pgpDigAlg sa)
461 SECITEM_ZfreeItem(sa->data, PR_TRUE);
465 static void pgpFreeKeyRSADSA(pgpDigAlg ka)
467 SECKEY_DestroyPublicKey(ka->data);
471 static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num, const uint8_t *p)
476 static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
477 uint8_t *hash, size_t hashlen, int hash_algo)
482 pgpDigAlg pgpPubkeyNew(int algo)
484 pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
487 case PGPPUBKEYALGO_RSA:
488 ka->setmpi = pgpSetKeyMpiRSA;
489 ka->free = pgpFreeKeyRSADSA;
492 case PGPPUBKEYALGO_DSA:
493 ka->setmpi = pgpSetKeyMpiDSA;
494 ka->free = pgpFreeKeyRSADSA;
498 ka->setmpi = pgpSetMpiNULL;
503 ka->verify = pgpVerifyNULL; /* keys can't be verified */
508 pgpDigAlg pgpSignatureNew(int algo)
510 pgpDigAlg sa = xcalloc(1, sizeof(*sa));
513 case PGPPUBKEYALGO_RSA:
514 sa->setmpi = pgpSetSigMpiRSA;
515 sa->free = pgpFreeSigRSADSA;
516 sa->verify = pgpVerifySigRSA;
519 case PGPPUBKEYALGO_DSA:
520 sa->setmpi = pgpSetSigMpiDSA;
521 sa->free = pgpFreeSigRSADSA;
522 sa->verify = pgpVerifySigDSA;
526 sa->setmpi = pgpSetMpiNULL;
527 sa->verify = pgpVerifyNULL;