--- ./config.h.in.orig 2011-03-02 06:46:47.000000000 +0000 +++ ./config.h.in 2011-05-10 15:54:41.000000000 +0000 @@ -13,6 +13,9 @@ /* Define to 1 if you have the `basename' function. */ #undef HAVE_BASENAME +/* Define to 1 if you have the header file. */ +#undef HAVE_BEECRYPT_API_H + /* Define as 1 if you bzip2 1.0 */ #undef HAVE_BZ2_1_0 @@ -77,7 +80,7 @@ /* Define as 1 if your zlib has gzseek() */ #undef HAVE_GZSEEK -/* Define if you have the iconv() function. */ +/* Define if you have the iconv() function and it works. */ #undef HAVE_ICONV /* Define to 1 if you have the header file. */ @@ -224,6 +227,10 @@ */ #undef LT_OBJDIR +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + /* Define to 1 if `major', `minor', and `makedev' are declared in . */ #undef MAJOR_IN_MKDEV @@ -308,6 +315,9 @@ /* Build with acl support? */ #undef WITH_ACL +/* Build with beecrypt instead of nss3 support? */ +#undef WITH_BEECRYPT + /* Build with capability support? */ #undef WITH_CAP --- ./configure.ac.orig 2011-03-02 06:46:20.000000000 +0000 +++ ./configure.ac 2011-05-10 15:54:41.000000000 +0000 @@ -246,12 +246,43 @@ AC_CHECK_HEADERS([dwarf.h], [ AM_CONDITIONAL(LIBDWARF,[test "$WITH_LIBDWARF" = yes]) #================= +# Check for beecrypt library if requested. +AC_ARG_WITH(beecrypt, [ --with-beecrypt build with beecrypt support ],,[with_beecrypt=yes]) +AC_ARG_WITH(internal_beecrypt, [ --with-internal-beecrypt build with internal beecrypt library ],,[with_internal_beecrypt=yes]) +AM_CONDITIONAL([WITH_INTERNAL_BEECRYPT],[test "$with_internal_beecrypt" = yes]) +if test "$with_internal_beecrypt" = yes ; then + with_beecrypt=yes +fi +AM_CONDITIONAL([WITH_BEECRYPT],[test "$with_beecrypt" = yes]) + +WITH_BEECRYPT_INCLUDE= +WITH_BEECRYPT_LIB= +if test "$with_beecrypt" = yes ; then + AC_DEFINE(WITH_BEECRYPT, 1, [Build with beecrypt instead of nss3 support?]) + if test "$with_internal_beecrypt" = yes ; then + WITH_BEECRYPT_INCLUDE="-I\$(top_srcdir)/beecrypt" + AC_DEFINE(HAVE_BEECRYPT_API_H, 1, [Define to 1 if you have the header file.]) + else + AC_CHECK_LIB(beecrypt, mpfprintln, [ + WITH_BEECRYPT_LIB="-lbeecrypt" + ],[ + AC_MSG_ERROR([missing required library 'beecrypt']) + ]) + AC_CHECK_HEADER([beecrypt/api.h], [AC_DEFINE(HAVE_BEECRYPT_API_H, 1, [Define to 1 if you have the header file.]) + ]) + fi +fi +AC_SUBST(WITH_BEECRYPT_LIB) +AC_SUBST(WITH_BEECRYPT_INCLUDE) + +#================= # Check for NSS library. # We need nss.h from NSS which needs nspr.h. Unfortunately both glibc and NSS # have a header named nss.h... so make extra check for NSS's sechash.h # which we use too and hopefully is slightly more unique to NSS. WITH_NSS_INCLUDE= WITH_NSS_LIB= +if test "$with_beecrypt" != yes ; then AC_CHECK_HEADERS([nspr.h nss.h sechash.h], [], [ AC_MSG_ERROR([missing required NSPR / NSS header]) ]) @@ -260,6 +291,7 @@ AC_CHECK_LIB(nss3, NSS_NoDB_Init, [ ], [ AC_MSG_ERROR([missing required NSS library 'nss3']) ]) +fi AC_SUBST(WITH_NSS_INCLUDE) AC_SUBST(WITH_NSS_LIB) --- ./rpmio/Makefile.am.orig 2010-12-03 12:11:57.000000000 +0000 +++ ./rpmio/Makefile.am 2011-05-10 15:56:13.000000000 +0000 @@ -2,6 +2,7 @@ AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_builddir)/include/ AM_CPPFLAGS += @WITH_NSS_INCLUDE@ +AM_CPPFLAGS += @WITH_BEECRYPT_INCLUDE@ AM_CPPFLAGS += @WITH_LUA_INCLUDE@ AM_CPPFLAGS += @WITH_POPT_INCLUDE@ AM_CPPFLAGS += -I$(top_srcdir)/misc @@ -18,10 +19,17 @@ librpmio_la_SOURCES = \ rpmstring.c rpmfileutil.c \ rpmkeyring.c +if WITH_BEECRYPT +librpmio_la_SOURCES += digest_beecrypt.c +else +librpmio_la_SOURCES += digest_nss.c +endif + librpmio_la_LDFLAGS = -version-info 2:0:0 librpmio_la_LIBADD = \ ../misc/libmisc.la \ @WITH_NSS_LIB@ \ + @WITH_BEECRYPT_LIB@ \ @WITH_LUA_LIB@ \ @WITH_BZ2_LIB@ \ @WITH_ZLIB_LIB@ \ @@ -30,6 +38,15 @@ librpmio_la_LIBADD = \ @WITH_LZMA_LIB@ \ -lpthread +if WITH_INTERNAL_BEECRYPT +librpmio_la_LIBADD += $(libbeecrypt_la) + +libbeecrypt_la = $(top_builddir)/beecrypt/libbeecrypt_nolibdir.la + +$(top_builddir)/beecrypt/libbeecrypt_nolibdir.la: $(top_builddir)/beecrypt/libbeecrypt.la + sed -e 's/libdir=.*/libdir=/' < $(top_builddir)/beecrypt/libbeecrypt.la > $(top_builddir)/beecrypt/libbeecrypt_nolibdir.la +endif + if WITH_LUAEXT AM_CPPFLAGS += -I$(top_srcdir)/luaext/ librpmio_la_LIBADD += $(top_builddir)/luaext/libluaext.la --- ./rpmio/base64.c.orig 2010-12-03 12:11:57.000000000 +0000 +++ ./rpmio/base64.c 2011-05-10 15:54:41.000000000 +0000 @@ -4,8 +4,11 @@ #include #include +#include "system.h" + #include "rpmio/base64.h" +#ifndef WITH_BEECRYPT static char base64_encode_value(char value_in) { @@ -253,3 +256,4 @@ int main(int argc, char *argv[]) } #endif +#endif /* WITH_BEECRYPT */ --- ./rpmio/digest.c.orig 2010-12-03 12:11:57.000000000 +0000 +++ ./rpmio/digest.c 2011-05-10 16:00:19.000000000 +0000 @@ -4,25 +4,12 @@ #include "system.h" +#include #include "rpmio/digest.h" +#include "rpmio/rpmio_internal.h" #include "debug.h" -#ifdef SHA_DEBUG -#define DPRINTF(_a) fprintf _a -#else -#define DPRINTF(_a) -#endif - - -/** - * MD5/SHA1 digest private data. - */ -struct DIGEST_CTX_s { - rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */ - HASHContext *hashctx; /*!< Internal NSS hash context. */ - int algo; /*!< Used hash algorithm */ -}; #define DIGESTS_MAX 11 struct rpmDigestBundle_s { @@ -109,138 +96,3 @@ DIGEST_CTX rpmDigestBundleDupCtx(rpmDige return dup; } -DIGEST_CTX -rpmDigestDup(DIGEST_CTX octx) -{ - DIGEST_CTX nctx = NULL; - if (octx) { - HASHContext *hctx = HASH_Clone(octx->hashctx); - if (hctx) { - nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx)); - nctx->hashctx = hctx; - } - } - return nctx; -} - -RPM_GNUC_PURE -static HASH_HashType getHashType(int hashalgo) -{ - switch (hashalgo) { - case PGPHASHALGO_MD5: - return HASH_AlgMD5; - break; - case PGPHASHALGO_MD2: - return HASH_AlgMD2; - break; - case PGPHASHALGO_SHA1: - return HASH_AlgSHA1; - break; - case PGPHASHALGO_SHA256: - return HASH_AlgSHA256; - break; - case PGPHASHALGO_SHA384: - return HASH_AlgSHA384; - break; - case PGPHASHALGO_SHA512: - return HASH_AlgSHA512; - break; - case PGPHASHALGO_RIPEMD160: - case PGPHASHALGO_TIGER192: - case PGPHASHALGO_HAVAL_5_160: - default: - return HASH_AlgNULL; - break; - } -} - -size_t -rpmDigestLength(int hashalgo) -{ - return HASH_ResultLen(getHashType(hashalgo)); -} - -DIGEST_CTX -rpmDigestInit(int hashalgo, rpmDigestFlags flags) -{ - HASH_HashType type = getHashType(hashalgo); - HASHContext *hashctx = NULL; - DIGEST_CTX ctx = NULL; - - if (type == HASH_AlgNULL || rpmInitCrypto() < 0) - goto exit; - - if ((hashctx = HASH_Create(type)) != NULL) { - ctx = xcalloc(1, sizeof(*ctx)); - ctx->flags = flags; - ctx->algo = hashalgo; - ctx->hashctx = hashctx; - HASH_Begin(ctx->hashctx); - } - -DPRINTF((stderr, "*** Init(%x) ctx %p hashctx %p\n", flags, ctx, ctx->hashctx)); -exit: - return ctx; -} - -int -rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len) -{ - size_t partlen; - const unsigned char *ptr = data; - - if (ctx == NULL) - return -1; - -DPRINTF((stderr, "*** Update(%p,%p,%zd) hashctx %p \"%s\"\n", ctx, data, len, ctx->hashctx, ((char *)data))); - partlen = ~(unsigned int)0xFF; - while (len > 0) { - if (len < partlen) { - partlen = len; - } - HASH_Update(ctx->hashctx, ptr, partlen); - ptr += partlen; - len -= partlen; - } - return 0; -} - -int -rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii) -{ - unsigned char * digest; - unsigned int digestlen; - - if (ctx == NULL) - return -1; - digestlen = HASH_ResultLenContext(ctx->hashctx); - digest = xmalloc(digestlen); - -DPRINTF((stderr, "*** Final(%p,%p,%p,%zd) hashctx %p digest %p\n", ctx, datap, lenp, asAscii, ctx->hashctx, digest)); -/* FIX: check rc */ - HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen); - - /* Return final digest. */ - if (!asAscii) { - if (lenp) *lenp = digestlen; - if (datap) { - *datap = digest; - digest = NULL; - } - } else { - if (lenp) *lenp = (2*digestlen) + 1; - if (datap) { - const uint8_t * s = (const uint8_t *) digest; - *datap = pgpHexStr(s, digestlen); - } - } - if (digest) { - memset(digest, 0, digestlen); /* In case it's sensitive */ - free(digest); - } - HASH_Destroy(ctx->hashctx); - memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ - free(ctx); - return 0; -} - --- ./rpmio/digest.h.orig 2010-12-03 12:11:57.000000000 +0000 +++ ./rpmio/digest.h 2011-05-10 15:54:41.000000000 +0000 @@ -1,11 +1,6 @@ #ifndef _RPMDIGEST_H #define _RPMDIGEST_H -#include -#include -#include -#include - #include #include "rpmio/base64.h" @@ -42,8 +37,18 @@ struct pgpDig_s { struct pgpDigParams_s pubkey; /* DSA/RSA parameters */ - SECKEYPublicKey *keydata; - SECItem *sigdata; + void *keydata; + void *sigdata; }; +void pgpCleanRSADSA(pgpDig dig); + +int pgpSetSigMpiRSA(pgpDig dig, int num, const uint8_t *p); +int pgpSetPubMpiRSA(pgpDig dig, int num, const uint8_t *p); +int pgpVerifyRSA(pgpDig dig, uint8_t *hash, size_t hashlen); + +int pgpSetSigMpiDSA(pgpDig dig, int num, const uint8_t *p); +int pgpSetPubMpiDSA(pgpDig dig, int num, const uint8_t *p); +int pgpVerifyDSA(pgpDig dig, uint8_t *hash, size_t hashlen); + #endif /* _RPMDIGEST_H */ --- ./rpmio/digest_beecrypt.c.orig 2011-05-10 15:54:41.000000000 +0000 +++ ./rpmio/digest_beecrypt.c 2011-05-10 15:54:41.000000000 +0000 @@ -0,0 +1,493 @@ +#include "system.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#if HAVE_BEECRYPT_API_H +#include +#include +#include +#endif + +#include +#include "rpmio/digest.h" +#include "rpmio/rpmio_internal.h" + +#include "debug.h" + +/* interface to beecrpyt crypto framework */ + +/**************************** init ************************************/ + +int rpmInitCrypto(void) { + return 0; +} + +int rpmFreeCrypto(void) { + return 0; +} + +/**************************** helpers ************************************/ + +static inline unsigned int pgpMpiBits(const uint8_t *p) +{ + return ((p[0] << 8) | p[1]); +} + +static inline size_t pgpMpiLen(const uint8_t *p) +{ + return (2 + ((pgpMpiBits(p)+7)>>3)); +} + +static inline char * pgpHexCvt(char *t, const byte *s, int nbytes) + /*@modifies *t @*/ +{ + static char hex[] = "0123456789abcdef"; + while (nbytes-- > 0) { + unsigned int i; + i = *s++; + *t++ = hex[ (i >> 4) & 0xf ]; + *t++ = hex[ (i ) & 0xf ]; + } + *t = '\0'; + return t; +} + +static const char * pgpMpiHex(const byte *p) +{ + static char prbuf[2048]; + char *t = prbuf; + t = pgpHexCvt(t, p+2, pgpMpiLen(p)-2); + return prbuf; +} + +static int pgpHexSet(int lbits, mpnumber * mpn, const byte * p) +{ + unsigned int mbits = pgpMpiBits(p); + unsigned int nbits; + unsigned int nbytes; + char *t; + unsigned int ix; + + nbits = (lbits > mbits ? lbits : mbits); + nbytes = ((nbits + 7) >> 3); + t = xmalloc(2*nbytes+1); + ix = 2 * ((nbits - mbits) >> 3); + + if (ix > 0) memset(t, (int)'0', ix); + strcpy(t+ix, pgpMpiHex(p)); + (void) mpnsethex(mpn, t); + t = _free(t); + return 0; +} + +void pgpCleanRSADSA(pgpDig dig) +{ + if (!dig) + return; + if (dig->keydata) { + dig->keydata= _free(dig->keydata); + } + if (dig->sigdata) { + dig->sigdata = _free(dig->sigdata); + } +} + + +/****************************** RSA **************************************/ + +struct pgpDigSigRSA_s { + mpnumber c; +}; + +struct pgpDigPubRSA_s { + rsapk rsa_pk; +}; + +int +pgpSetSigMpiRSA(pgpDig dig, int num, const uint8_t *p) +{ + struct pgpDigSigRSA_s *sig; + if (num != 0) + return 1; + if (!dig->sigdata) + dig->sigdata = xcalloc(1, sizeof(*sig)); + sig = dig->sigdata; + if (!sig) + return 1; + (void) mpnsethex(&sig->c, pgpMpiHex(p)); + return 0; +} + +int +pgpSetPubMpiRSA(pgpDig dig, int num, const uint8_t *p) +{ + struct pgpDigPubRSA_s *pub; + + if (!dig->keydata) + dig->keydata = xcalloc(1, sizeof(*pub)); + pub = dig->keydata; + if (!pub) + return 1; + switch(num) { + case 0: + (void) mpbsethex(&pub->rsa_pk.n, pgpMpiHex(p)); + return 0; + case 1: + (void) mpnsethex(&pub->rsa_pk.e, pgpMpiHex(p)); + return 0; + default: + return 1; + } +} + +static inline unsigned char nibble(char c) +{ + if (c >= '0' && c <= '9') + return (c - '0'); + if (c >= 'A' && c <= 'F') + return (c - 'A') + 10; + if (c >= 'a' && c <= 'f') + return (c - 'a') + 10; + return 0; +} + +int pgpVerifyRSA(pgpDig dig, uint8_t *hash, size_t hashlen) +{ + const char * prefix = NULL; + int res; + mpnumber rsahm; + struct pgpDigSigRSA_s *sig; + struct pgpDigPubRSA_s *pub; + + sig = dig->sigdata; + pub = dig->keydata; + if (!sig || !pub) + return 1; + + switch (dig->signature.hash_algo) { + case PGPHASHALGO_MD5: + prefix = "3020300c06082a864886f70d020505000410"; + break; + case PGPHASHALGO_SHA1: + prefix = "3021300906052b0e03021a05000414"; + break; + case PGPHASHALGO_MD2: + prefix = "3020300c06082a864886f70d020205000410"; + break; + case PGPHASHALGO_SHA256: + prefix = "3031300d060960864801650304020105000420"; + break; + case PGPHASHALGO_SHA384: + prefix = "3041300d060960864801650304020205000430"; + break; + case PGPHASHALGO_SHA512: + prefix = "3051300d060960864801650304020305000440"; + break; + /* fallthrough for unsupported / unknown types */ + default: + return 1; + } + + /* Generate RSA modulus parameter. */ + { unsigned int nbits = MP_WORDS_TO_BITS(sig->c.size); + unsigned int nb = (nbits + 7) >> 3; + byte *buf, *bp; + + if (nb < 3) + return 1; + buf = xmalloc(nb); + memset(buf, 0xff, nb); + buf[0] = 0x00; + buf[1] = 0x01; + bp = buf + nb - strlen(prefix)/2 - hashlen - 1; + if (bp < buf) + return 1; + *bp++ = 0; + for (; *prefix; prefix += 2) + *bp++ = (nibble(prefix[0]) << 4) | nibble(prefix[1]); + memcpy(bp, hash, hashlen); + mpnzero(&rsahm); + (void) mpnsetbin(&rsahm, buf, nb); + buf = _free(buf); + } +#if HAVE_BEECRYPT_API_H + res = rsavrfy(&pub->rsa_pk.n, &pub->rsa_pk.e, &sig->c, &rsahm) == 1 ? 0 : 1; +#else + res = rsavrfy(&pub->rsa_pk, &rsahm, &sig->c) == 1 ? 0 : 1; +#endif + mpnfree(&rsahm); + return res; +} + + +/****************************** DSA **************************************/ + +struct pgpDigSigDSA_s { + mpnumber r; + mpnumber s; +}; + +struct pgpDigPubDSA_s { + mpbarrett p; + mpbarrett q; + mpnumber g; + mpnumber y; +}; + +int +pgpSetSigMpiDSA(pgpDig dig, int num, const uint8_t *p) +{ + struct pgpDigSigDSA_s *sig; + + if (!dig->sigdata) + dig->sigdata = xcalloc(1, sizeof(*sig)); + sig = dig->sigdata; + if (!sig) + return 1; + switch(num) { + case 0: + return pgpHexSet(160, &sig->r, p); + case 1: + return pgpHexSet(160, &sig->s, p); + default: + return 1; + } +} + +int +pgpSetPubMpiDSA(pgpDig dig, int num, const uint8_t *p) +{ + struct pgpDigPubDSA_s *pub; + + if (!dig->keydata) + dig->keydata = xcalloc(1, sizeof(*pub)); + pub = dig->keydata; + if (!pub) + return 1; + switch(num) { + case 0: + mpbsethex(&pub->p, pgpMpiHex(p)); + return 0; + case 1: + mpbsethex(&pub->q, pgpMpiHex(p)); + return 0; + case 2: + mpnsethex(&pub->g, pgpMpiHex(p)); + return 0; + case 3: + mpnsethex(&pub->y, pgpMpiHex(p)); + return 0; + default: + return 1; + } +} + +int pgpVerifyDSA(pgpDig dig, uint8_t *hash, size_t hashlen) +{ + struct pgpDigSigDSA_s *sig; + struct pgpDigPubDSA_s *pub; + mpnumber hm; + int res; + + sig = dig->sigdata; + pub = dig->keydata; + if (!sig || !pub) + return 1; + mpnzero(&hm); + mpnsetbin(&hm, hash, hashlen); + res = dsavrfy(&pub->p, &pub->q, &pub->g, &hm, &pub->y, &sig->r, &sig->s) == 1 ? 0 : 1; + mpnfree(&hm); + return res; +} + +/**************************** digest ************************************/ + +#ifdef SHA_DEBUG +#define DPRINTF(_a) fprintf _a +#else +#define DPRINTF(_a) +#endif + +/** + * MD5/SHA1 digest private data. + */ +struct DIGEST_CTX_s { + rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */ + int algo; /*!< Used hash algorithm */ + uint32_t datalen; /*!< No. bytes in block of plaintext data. */ + uint32_t paramlen; /*!< No. bytes of digest parameters. */ + uint32_t digestlen; /*!< No. bytes of digest. */ + void * param; /*!< Digest parameters. */ + int (*Reset) (void * param) + /*@modifies param @*/; /*!< Digest initialize. */ + int (*Update) (void * param, const byte * data, size_t size) + /*@modifies param @*/; /*!< Digest transform. */ + int (*Digest) (void * param, /*@out@*/ byte * digest) + /*@modifies param, digest @*/; /*!< Digest finish. */ +}; + +DIGEST_CTX +rpmDigestDup(DIGEST_CTX octx) +{ + DIGEST_CTX nctx; + nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx)); + nctx->param = memcpy(xcalloc(1, nctx->paramlen), octx->param, nctx->paramlen); + return nctx; +} + +size_t +rpmDigestLength(int hashalgo) +{ + switch (hashalgo) { + case PGPHASHALGO_MD5: + return 16; + case PGPHASHALGO_SHA1: + return 20; +#if HAVE_BEECRYPT_API_H + case PGPHASHALGO_SHA256: + return 32; + case PGPHASHALGO_SHA384: + return 48; + case PGPHASHALGO_SHA512: + return 64; +#endif + default: + return 0; + } +} + +DIGEST_CTX +rpmDigestInit(int hashalgo, rpmDigestFlags flags) +{ + DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx)); + int xx; + + ctx->flags = flags; + ctx->algo = hashalgo; + + switch (hashalgo) { + case PGPHASHALGO_MD5: + ctx->digestlen = 16; + ctx->datalen = 64; + ctx->paramlen = sizeof(md5Param); + ctx->param = xcalloc(1, ctx->paramlen); + ctx->Reset = (void *) md5Reset; + ctx->Update = (void *) md5Update; + ctx->Digest = (void *) md5Digest; + break; + case PGPHASHALGO_SHA1: + ctx->digestlen = 20; + ctx->datalen = 64; + ctx->paramlen = sizeof(sha1Param); + ctx->param = xcalloc(1, ctx->paramlen); + ctx->Reset = (void *) sha1Reset; + ctx->Update = (void *) sha1Update; + ctx->Digest = (void *) sha1Digest; + break; +#if HAVE_BEECRYPT_API_H + case PGPHASHALGO_SHA256: + ctx->digestlen = 32; + ctx->datalen = 64; + ctx->paramlen = sizeof(sha256Param); + ctx->param = xcalloc(1, ctx->paramlen); + ctx->Reset = (void *) sha256Reset; + ctx->Update = (void *) sha256Update; + ctx->Digest = (void *) sha256Digest; + break; + case PGPHASHALGO_SHA384: + ctx->digestlen = 48; + ctx->datalen = 128; + ctx->paramlen = sizeof(sha384Param); + ctx->param = xcalloc(1, ctx->paramlen); + ctx->Reset = (void *) sha384Reset; + ctx->Update = (void *) sha384Update; + ctx->Digest = (void *) sha384Digest; + break; + case PGPHASHALGO_SHA512: + ctx->digestlen = 64; + ctx->datalen = 128; + ctx->paramlen = sizeof(sha512Param); + ctx->param = xcalloc(1, ctx->paramlen); + ctx->Reset = (void *) sha512Reset; + ctx->Update = (void *) sha512Update; + ctx->Digest = (void *) sha512Digest; + break; +#endif + case PGPHASHALGO_RIPEMD160: + case PGPHASHALGO_MD2: + case PGPHASHALGO_TIGER192: + case PGPHASHALGO_HAVAL_5_160: + default: + free(ctx); + return NULL; + } + + xx = (*ctx->Reset) (ctx->param); + +DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param)); + return ctx; +} + +/* LCL: ctx->param may be modified, but ctx is abstract @*/ +int +rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len) +{ + if (ctx == NULL) + return -1; + +DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data))); + return (*ctx->Update) (ctx->param, data, len); +} + +int +rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii) +{ + byte * digest; + char * t; + int i; + + if (ctx == NULL) + return -1; + digest = xmalloc(ctx->digestlen); + +DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest)); + /* FIX: check rc */ + (void) (*ctx->Digest) (ctx->param, digest); + + /* Return final digest. */ + if (!asAscii) { + if (lenp) *lenp = ctx->digestlen; + if (datap) { + *datap = digest; + digest = NULL; + } + } else { + if (lenp) *lenp = (2*ctx->digestlen) + 1; + if (datap) { + const byte * s = (const byte *) digest; + static const char hex[] = "0123456789abcdef"; + + *datap = t = xmalloc((2*ctx->digestlen) + 1); + for (i = 0 ; i < ctx->digestlen; i++) { + *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ]; + *t++ = hex[ (unsigned)((*s++ ) & 0x0f) ]; + } + *t = '\0'; + } + } + if (digest) { + memset(digest, 0, ctx->digestlen); /* In case it's sensitive */ + free(digest); + } + memset(ctx->param, 0, ctx->paramlen); /* In case it's sensitive */ + free(ctx->param); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ + free(ctx); + return 0; +} --- ./rpmio/digest_nss.c.orig 2011-05-10 15:54:41.000000000 +0000 +++ ./rpmio/digest_nss.c 2011-05-10 15:54:41.000000000 +0000 @@ -0,0 +1,500 @@ +#include +#include +#include +#include + +#include "system.h" + +#include +#include "rpmio/rpmio_internal.h" +#include "rpmio/digest.h" + +#include "debug.h" + +/* interface to nss crypto framework */ + +/**************************** init ************************************/ + +static int _crypto_initialized = 0; +static int _new_process = 1; + +/* + * 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 rpmInitCrypto(void) { + int rc = 0; + + if (!_crypto_initialized) { + if (NSS_NoDB_Init(NULL) != SECSuccess) { + rc = -1; + } else { + _crypto_initialized = 1; + } + } + return rc; +} + +int rpmFreeCrypto(void) +{ + int rc = 0; + if (_crypto_initialized) { + rc = (NSS_Shutdown() != SECSuccess); + _crypto_initialized = 0; + } + return rc; +} + +/**************************** helpers ************************************/ + +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; +} + +static SECItem *pgpMpiItem(PRArenaPool *arena, SECItem *item, const uint8_t *p) +{ + size_t nbytes = pgpMpiLen(p)-2; + + 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; +} + +static int pgpMpiSet(unsigned int lbits, + void *dest, const uint8_t * p, const uint8_t * pend) +{ + unsigned int mbits = pgpMpiBits(p); + unsigned int nbits; + size_t nbytes; + char *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; +} + +void pgpCleanRSADSA(pgpDig dig) +{ + if (!dig) + return; + if (dig->keydata) { + SECKEY_DestroyPublicKey(dig->keydata); + dig->keydata = NULL; + } + if (dig->sigdata) { + SECITEM_ZfreeItem(dig->sigdata, PR_TRUE); + dig->sigdata = NULL; + } +} + +/****************************** RSA **************************************/ + +int +pgpSetSigMpiRSA(struct pgpDig_s *dig, int num, const uint8_t *p, const uint8_t *pend) +{ + SECItem *sig; + + if (num != 0) + return 1; + sig = dig->rsasigdata; + sig = pgpMpiItem(NULL, sig, p); + dig->rsasigdata = sig; + if (sig == NULL) + return 1; + return 0; +} + +int +pgpSetPubMpiRSA(struct pgpDig_s *dig, int num, const uint8_t *p, const uint8_t *pend) +{ + SECKEYPublicKey *pub; + + if (!dig->keydata) + dig->keydata = pgpNewPublicKey(rsaKey); + pub = dig->keydata; + if (!pub) + return 1; + switch(num) { + case 0: + pgpMpiItem(pub->arena, &pub->u.rsa.modulus, p); + return 0; + case 1: + pgpMpiItem(pub->arena, &pub->u.rsa.publicExponent, p); + return 0; + default: + return 1; + } +} + +int pgpVerifyRSA(pgpDig dig, uint8_t *hash, size_t hashlen) +{ + SECOidTag sigalg; + SECItem digest; + SECKEYPublicKey *pub; + SECItem *sig; + SECItem *newsig = NULL; + size_t siglen; + int res; + + switch (dig->hash_algo) { + case PGPHASHALGO_MD5: + sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; + break; + case PGPHASHALGO_SHA1: + sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; + break; + case PGPHASHALGO_MD2: + sigalg = SEC_OID_PKCS1_MD2_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; + /* fallthrough for unsupported / unknown types */ + default: + sigalg = SEC_OID_UNKNOWN; + break; + } + digest.type = siBuffer; + digest.data = hash; + digest.len = hashlen; + + pub = dig->keydata; + sig = dig->sigdata; + siglen = SECKEY_SignatureLen(dig->keydata); + + /* Zero-pad signature data up to expected size if necessary */ + if (siglen > sig->len) { + size_t pad = siglen - sig->len; + if ((newsig = SECITEM_AllocItem(NULL, NULL, siglen)) == NULL) { + return 1; + } + memset(newsig->data, 0, pad); + memcpy(newsig->data+pad, sig->data, sig->len); + sig = newsig; + } + + if (VFY_VerifyDigest(&digest, pub, sig, sigalg, NULL) == SECSuccess) + res = 0; + else + res = 1; + + if (newsig) { + SECITEM_ZfreeItem(newsig, 1); + } + return res; +} + + +/****************************** DSA **************************************/ + +int +pgpSetSigMpiDSA(struct pgpDig_s *dig, int num, const uint8_t *p, const uint8_t *pend) +{ + SECItem *sig, *new; + + switch(num) { + case 0: + sig = SECITEM_AllocItem(NULL, NULL, 2*DSA_SUBPRIME_LEN); + dig->sigdata = sig; + memset(sig->data, 0, 2*DSA_SUBPRIME_LEN); + pgpMpiSet(DSA_SUBPRIME_LEN*8, sig->data, p, pend); + return 0; + case 1: + sig = dig->sigdata; + if (!sig) + return 1; + pgpMpiSet(DSA_SUBPRIME_LEN*8, sig->data + DSA_SUBPRIME_LEN, p, pend); + new = SECITEM_AllocItem(NULL, NULL, 0); + if (!new) + return 1; + if (DSAU_EncodeDerSig(new, sig) != SECSuccess) + return 1; + SECITEM_FreeItem(sig, PR_TRUE); + dig->sigdata = new; + return 0; + default: + return 1; + } +} + +int +pgpSetPubMpiDSA(struct pgpDig_s *dig, int num, const uint8_t *p, const uint8_t *pend) +{ + SECKEYPublicKey *pub; + + if (!dig->keydata) + dig->keydata = pgpNewPublicKey(dsaKey); + pub = dig->keydata; + if (!pub) + return 1; + switch(num) { + case 0: + pgpMpiItem(pub->arena, &pub->u.dsa.params.prime, p); + return 0; + case 1: + pgpMpiItem(pub->arena, &pub->u.dsa.params.subPrime, p); + return 0; + case 2: + pgpMpiItem(pub->arena, &pub->u.dsa.params.base, p); + return 0; + case 3: + pgpMpiItem(pub->arena, &pub->u.dsa.publicValue, p); + return 0; + default: + return 1; + } +} + +int pgpVerifyDSA(pgpDig dig, uint8_t *hash, size_t hashlen) +{ + SECItem digest; + SECKEYPublicKey *pub; + SECItem *sig; + + sig = dig->sigdata; + pub = dig->keydata; + digest.type = siBuffer; + digest.data = hash; + digest.len = hashlen; + if (VFY_VerifyDigest(&digest, pub, sig, SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST, NULL) == SECSuccess) + return 0; + else + return 1; +} + + +/**************************** digest ************************************/ + + +#ifdef SHA_DEBUG +#define DPRINTF(_a) fprintf _a +#else +#define DPRINTF(_a) +#endif + + +/** + * MD5/SHA1 digest private data. + */ +struct DIGEST_CTX_s { + rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */ + HASHContext *hashctx; /*!< Internal NSS hash context. */ + int algo; /*!< Used hash algorithm */ +}; + +DIGEST_CTX +rpmDigestDup(DIGEST_CTX octx) +{ + DIGEST_CTX nctx; + nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx)); + nctx->hashctx = HASH_Clone(octx->hashctx); + if (nctx->hashctx == NULL) { + fprintf(stderr, "HASH_Clone failed\n"); + exit(EXIT_FAILURE); /* FIX: callers do not bother checking error return */ + } + return nctx; +} + +RPM_GNUC_PURE +static HASH_HashType getHashType(int hashalgo) +{ + switch (hashalgo) { + case PGPHASHALGO_MD5: + return HASH_AlgMD5; + break; + case PGPHASHALGO_MD2: + return HASH_AlgMD2; + break; + case PGPHASHALGO_SHA1: + return HASH_AlgSHA1; + break; + case PGPHASHALGO_SHA256: + return HASH_AlgSHA256; + break; + case PGPHASHALGO_SHA384: + return HASH_AlgSHA384; + break; + case PGPHASHALGO_SHA512: + return HASH_AlgSHA512; + break; + case PGPHASHALGO_RIPEMD160: + case PGPHASHALGO_TIGER192: + case PGPHASHALGO_HAVAL_5_160: + default: + return HASH_AlgNULL; + break; + } +} + +size_t +rpmDigestLength(int hashalgo) +{ + return HASH_ResultLen(getHashType(hashalgo)); +} + +DIGEST_CTX +rpmDigestInit(int hashalgo, rpmDigestFlags flags) +{ + HASH_HashType type; + HASHContext *hashctx = NULL; + DIGEST_CTX ctx = NULL; + + if (type == HASH_AlgNULL || rpmInitCrypto() < 0) + return NULL; + + if ((hashctx = HASH_Create(type)) == NULL) + return NULL; + ctx = xcalloc(1, sizeof(*ctx)); + ctx->flags = flags; + ctx->algo = hashalgo; + ctx->hashctx = hashctx; + HASH_Begin(ctx->hashctx); + +DPRINTF((stderr, "*** Init(%x) ctx %p hashctx %p\n", flags, ctx, ctx->hashctx)); + return ctx; +} + +int +rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len) +{ + size_t partlen; + const unsigned char *ptr = data; + + if (ctx == NULL) + return -1; + +DPRINTF((stderr, "*** Update(%p,%p,%zd) hashctx %p \"%s\"\n", ctx, data, len, ctx->hashctx, ((char *)data))); + partlen = ~(unsigned int)0xFF; + while (len > 0) { + if (len < partlen) { + partlen = len; + } + HASH_Update(ctx->hashctx, ptr, partlen); + ptr += partlen; + len -= partlen; + } + return 0; +} + +int +rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii) +{ + unsigned char * digest; + unsigned int digestlen; + + if (ctx == NULL) + return -1; + digestlen = HASH_ResultLenContext(ctx->hashctx); + digest = xmalloc(digestlen); + +DPRINTF((stderr, "*** Final(%p,%p,%p,%zd) hashctx %p digest %p\n", ctx, datap, lenp, asAscii, ctx->hashctx, digest)); +/* FIX: check rc */ + HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen); + + /* Return final digest. */ + if (!asAscii) { + if (lenp) *lenp = digestlen; + if (datap) { + *datap = digest; + digest = NULL; + } + } else { + if (lenp) *lenp = (2*digestlen) + 1; + if (datap) { + const uint8_t * s = (const uint8_t *) digest; + *datap = pgpHexStr(s, digestlen); + } + } + if (digest) { + memset(digest, 0, digestlen); /* In case it's sensitive */ + free(digest); + } + HASH_Destroy(ctx->hashctx); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ + free(ctx); + return 0; +} --- ./rpmio/rpmpgp.c.orig 2010-12-03 12:11:57.000000000 +0000 +++ ./rpmio/rpmpgp.c 2011-05-10 16:01:58.000000000 +0000 @@ -20,9 +20,6 @@ static int _debug = 0; 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; @@ -315,89 +312,6 @@ int pgpValTok(pgpValTbl vs, const char * } while ((++vs)->val != -1); return vs->val; } -/** - * @return 0 on success - */ -static int pgpMpiSet(const char * pre, 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 (_debug) -fprintf(stderr, "*** mbits %u nbits %u nbytes %zu ix %u\n", mbits, nbits, nbytes, ix); - if (ix > 0) memset(t, '\0', ix); - memcpy(t+ix, p+2, nbytes-ix); -if (_debug) -fprintf(stderr, "*** %s %s\n", pre, pgpHexStr(dest, nbytes)); - - return 0; -} - -/** - * @return NULL on error - */ -static SECItem *pgpMpiItem(PRArenaPool *arena, SECItem *item, const uint8_t *p) -{ - size_t nbytes = pgpMpiLen(p)-2; - - 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 * Is buffer at beginning of an OpenPGP packet? @@ -593,29 +507,16 @@ static int pgpPrtSigParams(pgpTag tag, u { const uint8_t * pend = h + hlen; size_t i; - SECItem dsaraw; - unsigned char dsabuf[2*DSA_SUBPRIME_LEN]; char *mpi; - dsaraw.type = 0; - dsaraw.data = dsabuf; - dsaraw.len = sizeof(dsabuf); - for (i = 0; p < pend; i++, p += pgpMpiLen(p)) { if (pubkey_algo == PGPPUBKEYALGO_RSA) { if (i >= 1) break; if (_dig && (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT)) { - switch (i) { - case 0: /* m**d */ - _dig->sigdata = pgpMpiItem(NULL, _dig->sigdata, p); - if (_dig->sigdata == NULL) - return 1; - break; - default: - break; - } + if (pgpSetSigMpiRSA(_dig, i, p)) + return 1; } pgpPrtStr("", pgpSigRSA[i]); } else if (pubkey_algo == PGPPUBKEYALGO_DSA) { @@ -623,30 +524,8 @@ static int pgpPrtSigParams(pgpTag tag, u if (_dig && (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT)) { - int xx; - xx = 0; - switch (i) { - case 0: - memset(dsaraw.data, '\0', 2*DSA_SUBPRIME_LEN); - /* r */ - xx = pgpMpiSet(pgpSigDSA[i], DSA_SUBPRIME_LEN*8, dsaraw.data, p, pend); - break; - case 1: /* s */ - xx = pgpMpiSet(pgpSigDSA[i], DSA_SUBPRIME_LEN*8, dsaraw.data + DSA_SUBPRIME_LEN, p, pend); - if (_dig->sigdata != NULL) - SECITEM_FreeItem(_dig->sigdata, PR_FALSE); - else if ((_dig->sigdata=SECITEM_AllocItem(NULL, NULL, 0)) == NULL) { - xx = 1; - break; - } - if (DSAU_EncodeDerSig(_dig->sigdata, &dsaraw) != SECSuccess) - xx = 1; - break; - default: - xx = 1; - break; - } - if (xx) return xx; + if (pgpSetSigMpiDSA(_dig, i, p)) + return 1; } pgpPrtStr("", pgpSigDSA[i]); } else { @@ -838,49 +717,11 @@ static const uint8_t * pgpPrtPubkeyParam char * mpi; if (pubkey_algo == PGPPUBKEYALGO_RSA) { if (i >= 2) break; - if (_dig) { - if (_dig->keydata == NULL) { - _dig->keydata = pgpNewPublicKey(rsaKey); - if (_dig->keydata == NULL) - break; /* error abort? */ - } - switch (i) { - case 0: /* n */ - pgpMpiItem(_dig->keydata->arena, &_dig->keydata->u.rsa.modulus, p); - break; - case 1: /* e */ - pgpMpiItem(_dig->keydata->arena, &_dig->keydata->u.rsa.publicExponent, p); - break; - default: - break; - } - } + pgpSetPubMpiRSA(_dig, i, p); pgpPrtStr("", pgpPublicRSA[i]); } else if (pubkey_algo == PGPPUBKEYALGO_DSA) { if (i >= 4) break; - if (_dig) { - if (_dig->keydata == NULL) { - _dig->keydata = pgpNewPublicKey(dsaKey); - if (_dig->keydata == NULL) - break; /* error abort? */ - } - switch (i) { - case 0: /* p */ - pgpMpiItem(_dig->keydata->arena, &_dig->keydata->u.dsa.params.prime, p); - break; - case 1: /* q */ - pgpMpiItem(_dig->keydata->arena, &_dig->keydata->u.dsa.params.subPrime, p); - break; - case 2: /* g */ - pgpMpiItem(_dig->keydata->arena, &_dig->keydata->u.dsa.params.base, p); - break; - case 3: /* y */ - pgpMpiItem(_dig->keydata->arena, &_dig->keydata->u.dsa.publicValue, p); - break; - default: - break; - } - } + pgpSetPubMpiDSA(_dig, i, p); pgpPrtStr("", pgpPublicDSA[i]); } else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) { if (i >= 3) break; @@ -1265,15 +1106,7 @@ void pgpCleanDig(pgpDig dig) memset(&dig->signature, 0, sizeof(dig->signature)); memset(&dig->pubkey, 0, sizeof(dig->pubkey)); - if (dig->keydata != NULL) { - SECKEY_DestroyPublicKey(dig->keydata); - dig->keydata = NULL; - } - - if (dig->sigdata != NULL) { - SECITEM_ZfreeItem(dig->sigdata, PR_TRUE); - dig->sigdata = NULL; - } + pgpCleanRSADSA(dig); } return; } @@ -1315,39 +1148,6 @@ int pgpPrtPkts(const uint8_t * pkts, siz return 0; } -static SECOidTag getSigAlg(pgpDigParams sigp) -{ - SECOidTag sigalg = SEC_OID_UNKNOWN; - if (sigp->pubkey_algo == PGPPUBKEYALGO_DSA) { - /* assume SHA1 for now, NSS doesn't have SECOID's for other types */ - sigalg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; - } else if (sigp->pubkey_algo == PGPPUBKEYALGO_RSA) { - switch (sigp->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: - break; - } - } - return sigalg; -} - char *pgpIdentItem(pgpDigParams digp) { char *id = NULL; @@ -1396,30 +1196,12 @@ rpmRC pgpVerifySig(pgpDig dig, DIGEST_CT /* Compare leading 16 bits of digest for quick check. */ if (hash && memcmp(hash, sigp->signhash16, 2) == 0) { - SECItem digest = { .type = siBuffer, .data = hash, .len = hashlen }; - SECItem *sig = dig->sigdata; - - /* Zero-pad RSA signature to expected size if necessary */ - if (sigp->pubkey_algo == PGPPUBKEYALGO_RSA) { - size_t siglen = SECKEY_SignatureLen(dig->keydata); - if (siglen > sig->len) { - size_t pad = siglen - sig->len; - if ((sig = SECITEM_AllocItem(NULL, NULL, siglen)) == NULL) { - goto exit; - } - memset(sig->data, 0, pad); - memcpy(sig->data+pad, dig->sigdata->data, dig->sigdata->len); - } - } - - /* XXX VFY_VerifyDigest() is deprecated in NSS 3.12 */ - if (VFY_VerifyDigest(&digest, dig->keydata, sig, - getSigAlg(sigp), NULL) == SECSuccess) { - res = RPMRC_OK; - } - - if (sig != dig->sigdata) { - SECITEM_ZfreeItem(sig, 1); + if (sigp->pubkey_algo == PGPPUBKEYALGO_RSA) { + if (!pgpVerifyRSA(dig, hash, hashlen)) + res = RPMRC_OK; + } else if (sigp->pubkey_algo == PGPPUBKEYALGO_DSA) { + if (!pgpVerifyDSA(dig, hash, hashlen)) + res = RPMRC_OK; } } @@ -1607,50 +1389,3 @@ char * pgpArmorWrap(int atype, const uns 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; -} - -