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 #if HAVE_NSS_INITCONTEXT
57 PRUint32 flags = (NSS_INIT_READONLY|NSS_INIT_NOCERTDB|
58 NSS_INIT_NOMODDB|NSS_INIT_FORCEOPEN|
59 NSS_INIT_NOROOTINIT|NSS_INIT_OPTIMIZESPACE);
60 _nss_ctx = NSS_InitContext(NULL, NULL, NULL, NULL, NULL, flags);
61 if (_nss_ctx == NULL) {
63 if (NSS_NoDB_Init(NULL) != SECSuccess) {
67 _crypto_initialized = 1;
71 /* Register one post-fork handler per process */
73 if (pthread_atfork(NULL, NULL, at_forkchild) != 0) {
74 rpmlog(RPMLOG_WARNING, _("Failed to register fork handler: %m\n"));
81 int rpmFreeCrypto(void)
84 if (_crypto_initialized) {
85 #if HAVE_NSS_INITCONTEXT
86 rc = (NSS_ShutdownContext(_nss_ctx) != SECSuccess);
89 rc = (NSS_Shutdown() != SECSuccess);
91 _crypto_initialized = 0;
96 DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
98 DIGEST_CTX nctx = NULL;
100 HASHContext *hctx = HASH_Clone(octx->hashctx);
102 nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
103 nctx->hashctx = hctx;
110 static HASH_HashType getHashType(int hashalgo)
113 case PGPHASHALGO_MD5: return HASH_AlgMD5;
114 case PGPHASHALGO_MD2: return HASH_AlgMD2;
115 case PGPHASHALGO_SHA1: return HASH_AlgSHA1;
117 case PGPHASHALGO_SHA224: return HASH_AlgSHA224;
119 case PGPHASHALGO_SHA256: return HASH_AlgSHA256;
120 case PGPHASHALGO_SHA384: return HASH_AlgSHA384;
121 case PGPHASHALGO_SHA512: return HASH_AlgSHA512;
126 size_t rpmDigestLength(int hashalgo)
128 return HASH_ResultLen(getHashType(hashalgo));
131 DIGEST_CTX rpmDigestInit(int hashalgo, rpmDigestFlags flags)
133 HASH_HashType type = getHashType(hashalgo);
134 HASHContext *hashctx = NULL;
135 DIGEST_CTX ctx = NULL;
137 if (type == HASH_AlgNULL || rpmInitCrypto() < 0)
140 if ((hashctx = HASH_Create(type)) != NULL) {
141 ctx = xcalloc(1, sizeof(*ctx));
143 ctx->algo = hashalgo;
144 ctx->hashctx = hashctx;
145 HASH_Begin(ctx->hashctx);
152 int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
155 const unsigned char *ptr = data;
160 partlen = ~(unsigned int)0xFF;
165 HASH_Update(ctx->hashctx, ptr, partlen);
172 int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
174 unsigned char * digest;
175 unsigned int digestlen;
179 digestlen = HASH_ResultLenContext(ctx->hashctx);
180 digest = xmalloc(digestlen);
183 HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen);
185 /* Return final digest. */
187 if (lenp) *lenp = digestlen;
193 if (lenp) *lenp = (2*digestlen) + 1;
195 const uint8_t * s = (const uint8_t *) digest;
196 *datap = pgpHexStr(s, digestlen);
200 memset(digest, 0, digestlen); /* In case it's sensitive */
203 HASH_Destroy(ctx->hashctx);
204 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
210 static SECOidTag getHashAlg(unsigned int hashalgo)
213 case PGPHASHALGO_MD5: return SEC_OID_MD5;
214 case PGPHASHALGO_MD2: return SEC_OID_MD2;
215 case PGPHASHALGO_SHA1: return SEC_OID_SHA1;
217 case PGPHASHALGO_SHA224: return SEC_OID_SHA224;
219 case PGPHASHALGO_SHA256: return SEC_OID_SHA256;
220 case PGPHASHALGO_SHA384: return SEC_OID_SHA384;
221 case PGPHASHALGO_SHA512: return SEC_OID_SHA512;
223 return SEC_OID_UNKNOWN;
226 static int pgpMpiSet(unsigned int lbits, uint8_t *dest,
227 const uint8_t * p, const uint8_t * pend)
229 unsigned int mbits = pgpMpiBits(p);
235 if ((p + ((mbits+7) >> 3)) > pend)
241 nbits = (lbits > mbits ? lbits : mbits);
242 nbytes = ((nbits + 7) >> 3);
243 ix = (nbits - mbits) >> 3;
247 memcpy(t+ix, p+2, nbytes-ix);
252 static SECItem *pgpMpiItem(PRArenaPool *arena, SECItem *item,
253 const uint8_t *p, const uint8_t *pend)
255 size_t nbytes = pgpMpiLen(p)-2;
257 if (p + nbytes + 2 > pend)
261 if ((item=SECITEM_AllocItem(arena, item, nbytes)) == NULL)
265 item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes);
267 item->data = PORT_Realloc(item->data, nbytes);
269 if (item->data == NULL) {
271 SECITEM_FreeItem(item, PR_TRUE);
276 memcpy(item->data, p+2, nbytes);
281 static SECKEYPublicKey *pgpNewPublicKey(KeyType type)
284 SECKEYPublicKey *key;
286 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
290 key = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
293 PORT_FreeArena(arena, PR_FALSE);
298 key->pkcs11ID = CK_INVALID_HANDLE;
299 key->pkcs11Slot = NULL;
304 /* compatibility with nss < 3.14 */
305 #ifndef DSA1_SUBPRIME_LEN
306 #define DSA1_SUBPRIME_LEN DSA_SUBPRIME_LEN
308 #ifndef DSA1_SIGNATURE_LEN
309 #define DSA1_SIGNATURE_LEN DSA_SIGNATURE_LEN
312 #define DSA1_Q_BITS DSA_Q_BITS
315 static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num,
316 const uint8_t *p, const uint8_t *pend)
318 SECItem *sig = pgpsig->data;
319 int lbits = DSA1_Q_BITS;
320 int rc = 1; /* assume failure */
324 sig = pgpsig->data = SECITEM_AllocItem(NULL, NULL, DSA1_SIGNATURE_LEN);
326 memset(sig->data, 0, DSA1_SIGNATURE_LEN);
327 rc = pgpMpiSet(lbits, sig->data, p, pend);
331 if (sig && pgpMpiSet(lbits, sig->data+DSA1_SUBPRIME_LEN, p, pend) == 0) {
332 SECItem *signew = SECITEM_AllocItem(NULL, NULL, 0);
333 if (signew && DSAU_EncodeDerSig(signew, sig) == SECSuccess) {
334 SECITEM_FreeItem(sig, PR_TRUE);
335 pgpsig->data = signew;
345 static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num,
346 const uint8_t *p, const uint8_t *pend)
349 SECKEYPublicKey *key = pgpkey->data;
352 key = pgpkey->data = pgpNewPublicKey(dsaKey);
357 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.prime, p, pend);
360 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.subPrime, p, pend);
363 mpi = pgpMpiItem(key->arena, &key->u.dsa.params.base, p, pend);
366 mpi = pgpMpiItem(key->arena, &key->u.dsa.publicValue, p, pend);
371 return (mpi == NULL);
374 static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
375 uint8_t *hash, size_t hashlen, int hash_algo)
377 SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
378 SECOidTag encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
379 SECOidTag hashAlg = getHashAlg(hash_algo);
382 if (hashAlg == SEC_OID_UNKNOWN)
385 rc = VFY_VerifyDigestDirect(&digest, pgpkey->data, pgpsig->data,
386 encAlg, hashAlg, NULL);
388 return (rc != SECSuccess);
391 static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num,
392 const uint8_t *p, const uint8_t *pend)
394 SECItem *sigitem = NULL;
397 sigitem = pgpMpiItem(NULL, pgpsig->data, p, pend);
399 pgpsig->data = sigitem;
401 return (sigitem == NULL);
404 static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num,
405 const uint8_t *p, const uint8_t *pend)
407 SECItem *kitem = NULL;
408 SECKEYPublicKey *key = pgpkey->data;
411 key = pgpkey->data = pgpNewPublicKey(rsaKey);
416 kitem = pgpMpiItem(key->arena, &key->u.rsa.modulus, p, pend);
419 kitem = pgpMpiItem(key->arena, &key->u.rsa.publicExponent, p, pend);
424 return (kitem == NULL);
427 static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
428 uint8_t *hash, size_t hashlen, int hash_algo)
430 SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
431 SECItem *sig = pgpsig->data;
432 SECKEYPublicKey *key = pgpkey->data;
433 SECItem *padded = NULL;
434 SECOidTag encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
435 SECOidTag hashAlg = getHashAlg(hash_algo);
436 SECStatus rc = SECFailure;
437 size_t siglen, padlen;
439 if (hashAlg == SEC_OID_UNKNOWN)
442 /* Zero-pad signature to expected size if necessary */
443 siglen = SECKEY_SignatureLen(key);
444 padlen = siglen - sig->len;
446 padded = SECITEM_AllocItem(NULL, NULL, siglen);
449 memset(padded->data, 0, padlen);
450 memcpy(padded->data + padlen, sig->data, sig->len);
454 rc = VFY_VerifyDigestDirect(&digest, key, sig, encAlg, hashAlg, NULL);
457 SECITEM_ZfreeItem(padded, PR_TRUE);
459 return (rc != SECSuccess);
462 static void pgpFreeSigRSADSA(pgpDigAlg sa)
464 SECITEM_ZfreeItem(sa->data, PR_TRUE);
468 static void pgpFreeKeyRSADSA(pgpDigAlg ka)
470 SECKEY_DestroyPublicKey(ka->data);
474 static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num,
475 const uint8_t *p, const uint8_t *pend)
480 static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
481 uint8_t *hash, size_t hashlen, int hash_algo)
486 pgpDigAlg pgpPubkeyNew(int algo)
488 pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
491 case PGPPUBKEYALGO_RSA:
492 ka->setmpi = pgpSetKeyMpiRSA;
493 ka->free = pgpFreeKeyRSADSA;
496 case PGPPUBKEYALGO_DSA:
497 ka->setmpi = pgpSetKeyMpiDSA;
498 ka->free = pgpFreeKeyRSADSA;
502 ka->setmpi = pgpSetMpiNULL;
507 ka->verify = pgpVerifyNULL; /* keys can't be verified */
512 pgpDigAlg pgpSignatureNew(int algo)
514 pgpDigAlg sa = xcalloc(1, sizeof(*sa));
517 case PGPPUBKEYALGO_RSA:
518 sa->setmpi = pgpSetSigMpiRSA;
519 sa->free = pgpFreeSigRSADSA;
520 sa->verify = pgpVerifySigRSA;
523 case PGPPUBKEYALGO_DSA:
524 sa->setmpi = pgpSetSigMpiDSA;
525 sa->free = pgpFreeSigRSADSA;
526 sa->verify = pgpVerifySigDSA;
530 sa->setmpi = pgpSetMpiNULL;
531 sa->verify = pgpVerifyNULL;