summaryrefslogtreecommitdiff
path: root/rpmio/rpmpgp.c
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2011-11-04 16:28:50 +0200
committerPanu Matilainen <pmatilai@redhat.com>2011-11-04 16:49:01 +0200
commit3db9a10577f1868bcf6cc15fe76a03851af39355 (patch)
tree3d4373987891c50b0a6a30a02e6a2cd9e56c6470 /rpmio/rpmpgp.c
parent85b90e4176cd32eee912cbefdc4438c801b7edbf (diff)
downloadlibrpm-tizen-3db9a10577f1868bcf6cc15fe76a03851af39355.tar.gz
librpm-tizen-3db9a10577f1868bcf6cc15fe76a03851af39355.tar.bz2
librpm-tizen-3db9a10577f1868bcf6cc15fe76a03851af39355.zip
Bury all NSS specifics into a separate source
- Not everybody needs/wants the certified monster that NSS is (along with all its quirks), this leaves room for alternative compile-time selectable crypto backends. Besides that, we get a clean functionality separation for the PGP parser and the cryptography parts. - The whole crypto abstraction works inspired + somewhat based on Michael Schroeder's similar patch in Suse, kudos. - TODO: port beecrypt support from Suse to the new interface.
Diffstat (limited to 'rpmio/rpmpgp.c')
-rw-r--r--rpmio/rpmpgp.c403
1 files changed, 2 insertions, 401 deletions
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
index 200e15c0f..274f6854e 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -5,8 +5,8 @@
#include "system.h"
-#include <pthread.h>
-
+#include <time.h>
+#include <netinet/in.h>
#include <rpm/rpmstring.h>
#include <rpm/rpmlog.h>
@@ -17,9 +17,6 @@
static int _print = 0;
-static int _crypto_initialized = 0;
-static int _new_process = 1;
-
typedef const struct pgpValTbl_s {
int val;
char const * const str;
@@ -243,28 +240,6 @@ static void pgpPrtVal(const char * pre, pgpValTbl vs, uint8_t val)
}
/** \ingroup rpmpgp
- * Return no. of bits in a multiprecision integer.
- * @param p pointer to multiprecision integer
- * @return no. of bits
- */
-static
-unsigned int pgpMpiBits(const uint8_t *p)
-{
- return ((p[0] << 8) | p[1]);
-}
-
-/** \ingroup rpmpgp
- * Return no. of bytes in a multiprecision integer.
- * @param p pointer to multiprecision integer
- * @return no. of bytes
- */
-static
-size_t pgpMpiLen(const uint8_t *p)
-{
- return (2 + ((pgpMpiBits(p)+7)>>3));
-}
-
-/** \ingroup rpmpgp
* Return hex formatted representation of a multiprecision integer.
* @param p bytes
* @return hex formatted string (malloc'ed)
@@ -296,90 +271,6 @@ int pgpValTok(pgpValTbl vs, const char * s, const char * se)
} while ((++vs)->val != -1);
return vs->val;
}
-/**
- * @return 0 on success
- */
-static int pgpMpiSet(unsigned int lbits, uint8_t *dest,
- const uint8_t * p, const uint8_t * pend)
-{
- unsigned int mbits = pgpMpiBits(p);
- unsigned int nbits;
- size_t nbytes;
- uint8_t *t = dest;
- unsigned int ix;
-
- if ((p + ((mbits+7) >> 3)) > pend)
- return 1;
-
- if (mbits > lbits)
- return 1;
-
- nbits = (lbits > mbits ? lbits : mbits);
- nbytes = ((nbits + 7) >> 3);
- ix = (nbits - mbits) >> 3;
-
- if (ix > 0)
- memset(t, '\0', ix);
- memcpy(t+ix, p+2, nbytes-ix);
-
- return 0;
-}
-
-/**
- * @return NULL on error
- */
-static SECItem *pgpMpiItem(PRArenaPool *arena, SECItem *item,
- const uint8_t *p, const uint8_t *pend)
-{
- size_t nbytes = pgpMpiLen(p)-2;
-
- if (p + nbytes + 2 > pend)
- return NULL;
-
- if (item == NULL) {
- if ((item=SECITEM_AllocItem(arena, item, nbytes)) == NULL)
- return item;
- } else {
- if (arena != NULL)
- item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes);
- else
- item->data = PORT_Realloc(item->data, nbytes);
-
- if (item->data == NULL) {
- if (arena == NULL)
- SECITEM_FreeItem(item, PR_TRUE);
- return NULL;
- }
- }
-
- memcpy(item->data, p+2, nbytes);
- item->len = nbytes;
- return item;
-}
-/*@=boundswrite@*/
-
-static SECKEYPublicKey *pgpNewPublicKey(KeyType type)
-{
- PRArenaPool *arena;
- SECKEYPublicKey *key;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- return NULL;
-
- key = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
-
- if (key == NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
-
- key->keyType = type;
- key->pkcs11ID = CK_INVALID_HANDLE;
- key->pkcs11Slot = NULL;
- key->arena = arena;
- return key;
-}
/** \ingroup rpmpgp
* Decode length from 1, 2, or 5 octet body length encoding, used in
@@ -580,248 +471,6 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype,
return (hlen != 0); /* non-zero hlen is an error */
}
-#ifndef DSA_SUBPRIME_LEN
-#define DSA_SUBPRIME_LEN 20
-#endif
-
-static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num,
- const uint8_t *p, const uint8_t *pend)
-{
- SECItem *sig = pgpsig->data;
- int lbits = DSA_SUBPRIME_LEN * 8;
- int rc = 1; /* assume failure */
-
- switch (num) {
- case 0:
- sig = pgpsig->data = SECITEM_AllocItem(NULL, NULL, 2*DSA_SUBPRIME_LEN);
- memset(sig->data, 0, 2 * DSA_SUBPRIME_LEN);
- rc = pgpMpiSet(lbits, sig->data, p, pend);
- break;
- case 1:
- if (sig && pgpMpiSet(lbits, sig->data+DSA_SUBPRIME_LEN, p, pend) == 0) {
- SECItem *signew = SECITEM_AllocItem(NULL, NULL, 0);
- if (signew && DSAU_EncodeDerSig(signew, sig) == SECSuccess) {
- SECITEM_FreeItem(sig, PR_TRUE);
- pgpsig->data = signew;
- rc = 0;
- }
- }
- break;
- }
-
- return rc;
-}
-
-static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num,
- const uint8_t *p, const uint8_t *pend)
-{
- SECItem *mpi = NULL;
- SECKEYPublicKey *key = pgpkey->data;
-
- if (key == NULL)
- key = pgpkey->data = pgpNewPublicKey(dsaKey);
-
- if (key) {
- switch (num) {
- case 0:
- mpi = pgpMpiItem(key->arena, &key->u.dsa.params.prime, p, pend);
- break;
- case 1:
- mpi = pgpMpiItem(key->arena, &key->u.dsa.params.subPrime, p, pend);
- break;
- case 2:
- mpi = pgpMpiItem(key->arena, &key->u.dsa.params.base, p, pend);
- break;
- case 3:
- mpi = pgpMpiItem(key->arena, &key->u.dsa.publicValue, p, pend);
- break;
- }
- }
-
- return (mpi == NULL);
-}
-
-static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
- uint8_t *hash, size_t hashlen, int hash_algo)
-{
- SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
- SECOidTag sigalg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
- SECStatus rc;
-
- /* XXX VFY_VerifyDigest() is deprecated in NSS 3.12 */
- rc = VFY_VerifyDigest(&digest, pgpkey->data, pgpsig->data, sigalg, NULL);
-
- return (rc != SECSuccess);
-}
-
-static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num,
- const uint8_t *p, const uint8_t *pend)
-{
- SECItem *sigitem = NULL;
-
- if (num == 0) {
- sigitem = pgpMpiItem(NULL, pgpsig->data, p, pend);
- if (sigitem)
- pgpsig->data = sigitem;
- }
- return (sigitem == NULL);
-}
-
-static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num,
- const uint8_t *p, const uint8_t *pend)
-{
- SECItem *kitem = NULL;
- SECKEYPublicKey *key = pgpkey->data;
-
- if (key == NULL)
- key = pgpkey->data = pgpNewPublicKey(rsaKey);
-
- if (key) {
- switch (num) {
- case 0:
- kitem = pgpMpiItem(key->arena, &key->u.rsa.modulus, p, pend);
- break;
- case 1:
- kitem = pgpMpiItem(key->arena, &key->u.rsa.publicExponent, p, pend);
- break;
- }
- }
-
- return (kitem == NULL);
-}
-
-static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
- uint8_t *hash, size_t hashlen, int hash_algo)
-{
- SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen };
- SECItem *sig = pgpsig->data;
- SECKEYPublicKey *key = pgpkey->data;
- SECItem *padded = NULL;
- SECOidTag sigalg;
- SECStatus rc = SECFailure;
- size_t siglen, padlen;
-
- switch (hash_algo) {
- case PGPHASHALGO_MD5:
- sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
- break;
- case PGPHASHALGO_MD2:
- sigalg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
- break;
- case PGPHASHALGO_SHA1:
- sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
- break;
- case PGPHASHALGO_SHA256:
- sigalg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
- break;
- case PGPHASHALGO_SHA384:
- sigalg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
- break;
- case PGPHASHALGO_SHA512:
- sigalg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
- break;
- default:
- return 1; /* dont bother with unknown hash types */
- break;
- }
-
- /* Zero-pad signature to expected size if necessary */
- siglen = SECKEY_SignatureLen(key);
- padlen = siglen - sig->len;
- if (padlen) {
- padded = SECITEM_AllocItem(NULL, NULL, siglen);
- if (padded == NULL)
- return 1;
- memset(padded->data, 0, padlen);
- memcpy(padded->data + padlen, sig->data, sig->len);
- sig = padded;
- }
-
- /* XXX VFY_VerifyDigest() is deprecated in NSS 3.12 */
- rc = VFY_VerifyDigest(&digest, key, sig, sigalg, NULL);
-
- if (padded)
- SECITEM_ZfreeItem(padded, PR_TRUE);
-
- return (rc != SECSuccess);
-}
-
-static void pgpFreeSigRSADSA(pgpDigAlg sa)
-{
- SECITEM_ZfreeItem(sa->data, PR_TRUE);
- sa->data = NULL;
-}
-
-static void pgpFreeKeyRSADSA(pgpDigAlg ka)
-{
- SECKEY_DestroyPublicKey(ka->data);
- ka->data = NULL;
-}
-
-static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num,
- const uint8_t *p, const uint8_t *pend)
-{
- return 1;
-}
-
-static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
- uint8_t *hash, size_t hashlen, int hash_algo)
-{
- return 1;
-}
-
-pgpDigAlg pgpPubkeyNew(int algo)
-{
- pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
-
- switch (algo) {
- case PGPPUBKEYALGO_RSA:
- ka->setmpi = pgpSetKeyMpiRSA;
- ka->free = pgpFreeKeyRSADSA;
- ka->mpis = 2;
- break;
- case PGPPUBKEYALGO_DSA:
- ka->setmpi = pgpSetKeyMpiDSA;
- ka->free = pgpFreeKeyRSADSA;
- ka->mpis = 4;
- break;
- default:
- ka->setmpi = pgpSetMpiNULL;
- ka->mpis = -1;
- break;
- }
-
- ka->verify = pgpVerifyNULL; /* keys can't be verified */
-
- return ka;
-}
-
-pgpDigAlg pgpSignatureNew(int algo)
-{
- pgpDigAlg sa = xcalloc(1, sizeof(*sa));
-
- switch (algo) {
- case PGPPUBKEYALGO_RSA:
- sa->setmpi = pgpSetSigMpiRSA;
- sa->free = pgpFreeSigRSADSA;
- sa->verify = pgpVerifySigRSA;
- sa->mpis = 1;
- break;
- case PGPPUBKEYALGO_DSA:
- sa->setmpi = pgpSetSigMpiDSA;
- sa->free = pgpFreeSigRSADSA;
- sa->verify = pgpVerifySigDSA;
- sa->mpis = 2;
- break;
- default:
- sa->setmpi = pgpSetMpiNULL;
- sa->verify = pgpVerifyNULL;
- sa->mpis = -1;
- break;
- }
- return sa;
-}
-
pgpDigAlg pgpDigAlgFree(pgpDigAlg alg)
{
if (alg) {
@@ -1514,51 +1163,3 @@ char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
return val;
}
-/*
- * Only flag for re-initialization here, in the common case the child
- * exec()'s something else shutting down NSS here would be waste of time.
- */
-static void at_forkchild(void)
-{
- _new_process = 1;
-}
-
-int rpmInitCrypto(void)
-{
- int rc = 0;
-
- /* Lazy NSS shutdown for re-initialization after fork() */
- if (_new_process && _crypto_initialized) {
- rpmFreeCrypto();
- }
-
- /* Initialize NSS if not already done */
- if (!_crypto_initialized) {
- if (NSS_NoDB_Init(NULL) != SECSuccess) {
- rc = -1;
- } else {
- _crypto_initialized = 1;
- }
- }
-
- /* Register one post-fork handler per process */
- if (_new_process) {
- if (pthread_atfork(NULL, NULL, at_forkchild) != 0) {
- rpmlog(RPMLOG_WARNING, _("Failed to register fork handler: %m\n"));
- }
- _new_process = 0;
- }
- return rc;
-}
-
-int rpmFreeCrypto(void)
-{
- int rc = 0;
- if (_crypto_initialized) {
- rc = (NSS_Shutdown() != SECSuccess);
- _crypto_initialized = 0;
- }
- return rc;
-}
-
-