--- ./Makefile.am.orig 2009-06-23 11:40:57.000000000 +0000 +++ ./Makefile.am 2009-08-20 13:47:03.000000000 +0000 @@ -88,7 +88,8 @@ DISTCLEANFILES += find-requires rpm_SOURCES = rpmqv.c debug.h system.h rpm_CPPFLAGS = $(AM_CPPFLAGS) -DIAM_RPMDB -DIAM_RPMEIU -DIAM_RPMK -DIAM_RPMQV -rpm_LDADD = build/librpmbuild.la lib/librpm.la rpmio/librpmio.la +rpm_LDADD = lib/librpm.la rpmio/librpmio.la +rpm_LDADD += build/.libs/spec.o build/.libs/misc.o build/.libs/names.o build/.libs/expression.o build/.libs/reqprov.o build/.libs/poptBT.o build/.libs/parse*.o rpm_LDADD += @WITH_LIBELF_LIB@ @WITH_NSS_LIB@ @WITH_POPT_LIB@ @WITH_ZLIB_LIB@ rpmbuild_SOURCES = build.c rpmqv.c build.h debug.h system.h --- ./config.h.in.orig 2009-07-21 08:21:37.000000000 +0000 +++ ./config.h.in 2009-08-20 13:47:03.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 @@ -110,7 +113,7 @@ /* Define as 1 if defines h_errno */ #undef HAVE_HERRNO -/* 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 `inet_aton' function. */ @@ -359,6 +362,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 @@ -456,6 +463,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 2009-07-21 08:20:46.000000000 +0000 +++ ./configure.ac 2009-08-20 13:47:03.000000000 +0000 @@ -300,12 +300,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]) ]) @@ -314,6 +345,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) --- ./lib/signature.c.orig 2009-06-23 11:40:58.000000000 +0000 +++ ./lib/signature.c 2009-08-20 13:47:03.000000000 +0000 @@ -1118,10 +1118,8 @@ verifyRSASignature(rpmKeyring keyring, r DIGEST_CTX md5ctx) { pgpDigParams sigp = dig ? &dig->signature : NULL; - SECOidTag sigalg; rpmRC res = RPMRC_OK; int xx; - SECItem digest; const char *hdr, *signame = _("Unknown");; const char *sig = sigtd->data; int sigver; @@ -1153,27 +1151,21 @@ verifyRSASignature(rpmKeyring keyring, r switch (sigp->hash_algo) { case PGPHASHALGO_MD5: signame = "RSA/MD5"; - sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; break; case PGPHASHALGO_SHA1: signame = "RSA/SHA1"; - sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; break; case PGPHASHALGO_MD2: signame = "RSA/MD2"; - sigalg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; break; case PGPHASHALGO_SHA256: signame = "RSA/SHA256"; - sigalg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; break; case PGPHASHALGO_SHA384: signame = "RSA/SHA384"; - sigalg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; break; case PGPHASHALGO_SHA512: signame = "RSA/SHA512"; - sigalg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; break; /* fallthrough for unsupported / unknown types */ case PGPHASHALGO_TIGER192: @@ -1181,7 +1173,6 @@ verifyRSASignature(rpmKeyring keyring, r case PGPHASHALGO_RIPEMD160: default: res = RPMRC_NOKEY; - sigalg = SEC_OID_UNKNOWN; break; } @@ -1212,9 +1203,6 @@ verifyRSASignature(rpmKeyring keyring, r res = RPMRC_FAIL; goto exit; } - digest.type = siBuffer; - digest.data = dig->md5; - digest.len = dig->md5len; } /* Retrieve the matching public key. */ @@ -1222,29 +1210,8 @@ verifyRSASignature(rpmKeyring keyring, r if (res != RPMRC_OK) goto exit; - { SECItem *sig = dig->rsasig; - size_t siglen = SECKEY_SignatureLen(dig->rsa); - - /* Zero-pad signature data up to expected size if necessary */ - if (siglen > sig->len) { - size_t pad = siglen - sig->len; - if ((sig = SECITEM_AllocItem(NULL, NULL, siglen)) == NULL) { - res = RPMRC_FAIL; - goto exit; - } - memset(sig->data, 0, pad); - memcpy(sig->data+pad, dig->rsasig->data, dig->rsasig->len); - } - - if (VFY_VerifyDigest(&digest, dig->rsa, sig, sigalg, NULL) == SECSuccess) - res = RPMRC_OK; - else - res = RPMRC_FAIL; - - if (sig != dig->rsasig) { - SECITEM_ZfreeItem(sig, 1); - } - } + if (pgpVerifyRSA(dig)) + res = RPMRC_FAIL; exit: if (sigp != NULL) { @@ -1273,7 +1240,6 @@ verifyDSASignature(rpmKeyring keyring, r pgpDigParams sigp = dig ? &dig->signature : NULL; rpmRC res; int xx; - SECItem digest; const char *hdr; int sigver; const char *sig = sigtd->data; @@ -1320,9 +1286,6 @@ verifyDSASignature(rpmKeyring keyring, r res = RPMRC_FAIL; goto exit; } - digest.type = siBuffer; - digest.data = dig->sha1; - digest.len = dig->sha1len; } /* Retrieve the matching public key. */ @@ -1330,10 +1293,7 @@ verifyDSASignature(rpmKeyring keyring, r if (res != RPMRC_OK) goto exit; - if (VFY_VerifyDigest(&digest, dig->dsa, dig->dsasig, - SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST, NULL) == SECSuccess) - res = RPMRC_OK; - else + if (pgpVerifyDSA(dig)) res = RPMRC_FAIL; exit: --- ./rpmio/Makefile.am.orig 2009-06-23 11:40:59.000000000 +0000 +++ ./rpmio/Makefile.am 2009-08-20 13:47:03.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 @@ -19,10 +20,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 0:0:0 librpmio_la_LIBADD = \ ../misc/libmisc.la \ @WITH_NSS_LIB@ \ + @WITH_BEECRYPT_LIB@ \ @WITH_LUA_LIB@ \ @WITH_BZ2_LIB@ \ @WITH_ZLIB_LIB@ \ @@ -31,6 +39,17 @@ 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_builddir)/luaext/ librpmio_la_LIBADD += $(top_builddir)/luaext/libluaext.la --- ./rpmio/base64.c.orig 2009-06-23 11:40:59.000000000 +0000 +++ ./rpmio/base64.c 2009-08-20 13:47:03.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 2009-06-23 11:40:59.000000000 +0000 +++ ./rpmio/digest.c 2009-08-20 13:47:03.000000000 +0000 @@ -4,165 +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. */ -}; - -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(pgpHashAlgo 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(pgpHashAlgo hashalgo) -{ - return HASH_ResultLen(getHashType(hashalgo)); -} - -DIGEST_CTX -rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags) -{ - HASH_HashType type; - DIGEST_CTX ctx; - - if (rpmInitCrypto() < 0) - return NULL; - - ctx = xcalloc(1, sizeof(*ctx)); - ctx->flags = flags; - - type = getHashType(hashalgo); - if (type == HASH_AlgNULL) { - free(ctx); - return NULL; - } - - ctx->hashctx = HASH_Create(type); - if (ctx->hashctx == NULL) { - free(ctx); - return NULL; - } - - 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; -} void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags) { --- ./rpmio/digest.h.orig 2009-06-23 11:40:59.000000000 +0000 +++ ./rpmio/digest.h 2009-08-20 13:47:03.000000000 +0000 @@ -1,11 +1,6 @@ #ifndef _RPMDIGEST_H #define _RPMDIGEST_H -#include -#include -#include -#include - #include #include "rpmio/base64.h" #include "rpmio/rpmio_internal.h" @@ -55,12 +50,22 @@ struct pgpDig_s { size_t md5len; /*!< (rsa) V3 signature hash length. */ /* DSA parameters */ - SECKEYPublicKey *dsa; - SECItem *dsasig; + void *dsa; + void *dsasig; /* RSA parameters */ - SECKEYPublicKey *rsa; - SECItem *rsasig; + void *rsa; + void *rsasig; }; +int pgpSetSigMpiRSA(pgpDig dig, int num, const uint8_t *p); +int pgpSetPubMpiRSA(pgpDig dig, int num, const uint8_t *p); +void pgpCleanRSA(pgpDig dig); +int pgpVerifyRSA(pgpDig dig); + +int pgpSetSigMpiDSA(pgpDig dig, int num, const uint8_t *p); +int pgpSetPubMpiDSA(pgpDig dig, int num, const uint8_t *p); +void pgpCleanDSA(pgpDig dig); +int pgpVerifyDSA(pgpDig dig); + #endif /* _RPMDIGEST_H */ --- ./rpmio/digest_beecrypt.c.orig 2009-08-20 13:47:03.000000000 +0000 +++ ./rpmio/digest_beecrypt.c 2009-08-20 13:47:03.000000000 +0000 @@ -0,0 +1,503 @@ +#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; +} + + +/****************************** 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->rsasig) + dig->rsasig = xcalloc(1, sizeof(*sig)); + sig = dig->rsasig; + 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->rsa) + dig->rsa = xcalloc(1, sizeof(*pub)); + pub = dig->rsa; + 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; + } +} + +void pgpCleanRSA(pgpDig dig) +{ + if (!dig) + return; + if (dig->rsa) { + dig->rsa = _free(dig->rsa); + } + if (dig->rsasig) { + dig->rsasig = _free(dig->rsasig); + } +} + +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) +{ + const char * prefix = NULL; + int res; + mpnumber rsahm; + struct pgpDigSigRSA_s *sig; + struct pgpDigPubRSA_s *pub; + + sig = dig->rsasig; + pub = dig->rsa; + 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 - dig->md5len - 1; + if (bp < buf) + return 1; + *bp++ = 0; + for (; *prefix; prefix += 2) + *bp++ = (nibble(prefix[0]) << 4) | nibble(prefix[1]); + memcpy(bp, dig->md5, dig->md5len); + 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->dsasig) + dig->dsasig = xcalloc(1, sizeof(*sig)); + sig = dig->dsasig; + 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->dsa) + dig->dsa = xcalloc(1, sizeof(*pub)); + pub = dig->dsa; + 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; + } +} + +void pgpCleanDSA(pgpDig dig) +{ + if (!dig) + return; + if (dig->dsa) { + dig->dsa = _free(dig->dsa); + } + if (dig->dsasig) { + dig->dsasig = _free(dig->dsasig); + } +} + +int pgpVerifyDSA(pgpDig dig) +{ + struct pgpDigSigDSA_s *sig; + struct pgpDigPubDSA_s *pub; + mpnumber hm; + int res; + + sig = dig->dsasig; + pub = dig->dsa; + if (!sig || !pub) + return 1; + mpnzero(&hm); + mpnsetbin(&hm, dig->sha1, dig->sha1len); + 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. */ + 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(pgpHashAlgo 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(pgpHashAlgo hashalgo, rpmDigestFlags flags) +{ + DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx)); + int xx; + + ctx->flags = flags; + + 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 2009-08-20 13:47:03.000000000 +0000 +++ ./rpmio/digest_nss.c 2009-08-20 13:49:53.000000000 +0000 @@ -0,0 +1,513 @@ +#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; +} + +/****************************** 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->rsasig; + sig = pgpMpiItem(NULL, sig, p); + dig->rsasig = 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->rsa) + dig->rsa = pgpNewPublicKey(rsaKey); + pub = dig->rsa; + if (!pub) + return 1; + switch(num) { + case 0: + pgpMpiItem(dig->rsa->arena, &pub->u.rsa.modulus, p); + return 0; + case 1: + pgpMpiItem(dig->rsa->arena, &pub->u.rsa.publicExponent, p); + return 0; + default: + return 1; + } +} + +void pgpCleanRSA(pgpDig dig) +{ + if (!dig) + return; + if (dig->rsa) { + SECKEY_DestroyPublicKey(dig->rsa); + dig->rsa = NULL; + } + if (dig->rsasig) { + SECITEM_ZfreeItem(dig->rsasig, PR_TRUE); + dig->rsasig = NULL; + } +} + +int pgpVerifyRSA(pgpDig dig) +{ + SECOidTag sigalg; + SECItem digest; + SECItem *sig; + 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 = dig->md5; + digest.len = dig->md5len; + + sig = dig->rsasig; + siglen = SECKEY_SignatureLen(dig->rsa); + + /* Zero-pad signature data up to expected size if necessary */ + if (siglen > sig->len) { + size_t pad = siglen - sig->len; + if ((sig = SECITEM_AllocItem(NULL, NULL, siglen)) == NULL) { + return 1; + } + memset(sig->data, 0, pad); + memcpy(sig->data+pad, dig->rsasig->data, dig->rsasig->len); + } + + if (VFY_VerifyDigest(&digest, dig->rsa, sig, sigalg, NULL) == SECSuccess) + res = 0; + else + res = 1; + + if (sig != dig->rsasig) { + SECITEM_ZfreeItem(sig, 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->dsasig = sig; + memset(sig->data, 0, 2*DSA_SUBPRIME_LEN); + pgpMpiSet(DSA_SUBPRIME_LEN*8, sig->data, p, pend); + return 0; + case 1: + sig = dig->dsasig; + 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->dsasig = 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->dsa) + dig->dsa = pgpNewPublicKey(dsaKey); + pub = dig->dsa; + 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; + } +} + +void pgpCleanDSA(pgpDig dig) +{ + if (!dig) + return; + if (dig->dsa) { + SECKEY_DestroyPublicKey(dig->dsa); + dig->dsa = NULL; + } + if (dig->dsasig) { + SECITEM_ZfreeItem(dig->dsasig, PR_TRUE); + dig->dsasig = NULL; + } +} + +int pgpVerifyDSA(pgpDig dig) +{ + SECItem digest; + + digest.type = siBuffer; + digest.data = dig->sha1; + digest.len = dig->sha1len; + if (VFY_VerifyDigest(&digest, dig->dsa, dig->dsasig, 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. */ +}; + +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(pgpHashAlgo 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(pgpHashAlgo hashalgo) +{ + return HASH_ResultLen(getHashType(hashalgo)); +} + +DIGEST_CTX +rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags) +{ + HASH_HashType type; + DIGEST_CTX ctx; + + if (rpmInitCrypto() < 0) + return NULL; + + ctx = xcalloc(1, sizeof(*ctx)); + ctx->flags = flags; + + type = getHashType(hashalgo); + if (type == HASH_AlgNULL) { + free(ctx); + return NULL; + } + + ctx->hashctx = HASH_Create(type); + if (ctx->hashctx == NULL) { + free(ctx); + return NULL; + } + + 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 2009-06-23 11:40:59.000000000 +0000 +++ ./rpmio/rpmpgp.c 2009-08-20 13:50:14.000000000 +0000 @@ -20,9 +20,6 @@ static int _debug = 0; static int _print = 0; -static int _crypto_initialized = 0; -static int _new_process = 1; - static struct pgpValTbl_s const pgpSigTypeTbl[] = { { PGPSIGTYPE_BINARY, "Binary document signature" }, { PGPSIGTYPE_TEXT, "Text document signature" }, @@ -291,99 +288,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, - 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 (_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; -} - -static SECKEYPublicKey *pgpNewRSAKey(void) -{ - return pgpNewPublicKey(rsaKey); -} - -static SECKEYPublicKey *pgpNewDSAKey(void) -{ - return pgpNewPublicKey(dsaKey); -} /** \ingroup rpmpgp * Is buffer at beginning of an OpenPGP packet? @@ -579,29 +483,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->rsasig = pgpMpiItem(NULL, _dig->rsasig, p); - if (_dig->rsasig == NULL) - return 1; - break; - default: - break; - } + if (pgpSetSigMpiRSA(_dig, i, p)) + return 1; } pgpPrtStr("", pgpSigRSA[i]); } else if (pubkey_algo == PGPPUBKEYALGO_DSA) { @@ -609,30 +500,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->dsasig != NULL) - SECITEM_FreeItem(_dig->dsasig, PR_FALSE); - else if ((_dig->dsasig=SECITEM_AllocItem(NULL, NULL, 0)) == NULL) { - xx = 1; - break; - } - if (DSAU_EncodeDerSig(_dig->dsasig, &dsaraw) != SECSuccess) - xx = 1; - break; - default: - xx = 1; - break; - } - if (xx) return xx; + if (pgpSetSigMpiDSA(_dig, i, p)) + return 1; } pgpPrtStr("", pgpSigDSA[i]); } else { @@ -824,49 +693,11 @@ static const uint8_t * pgpPrtPubkeyParam char * mpi; if (pubkey_algo == PGPPUBKEYALGO_RSA) { if (i >= 2) break; - if (_dig) { - if (_dig->rsa == NULL) { - _dig->rsa = pgpNewRSAKey(); - if (_dig->rsa == NULL) - break; /* error abort? */ - } - switch (i) { - case 0: /* n */ - pgpMpiItem(_dig->rsa->arena, &_dig->rsa->u.rsa.modulus, p); - break; - case 1: /* e */ - pgpMpiItem(_dig->rsa->arena, &_dig->rsa->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->dsa == NULL) { - _dig->dsa = pgpNewDSAKey(); - if (_dig->dsa == NULL) - break; /* error abort? */ - } - switch (i) { - case 0: /* p */ - pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.params.prime, p); - break; - case 1: /* q */ - pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.params.subPrime, p); - break; - case 2: /* g */ - pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.params.base, p); - break; - case 3: /* y */ - pgpMpiItem(_dig->dsa->arena, &_dig->dsa->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; @@ -1256,25 +1087,8 @@ void pgpCleanDig(pgpDig dig) dig->md5 = _free(dig->md5); dig->sha1 = _free(dig->sha1); - if (dig->dsa != NULL) { - SECKEY_DestroyPublicKey(dig->dsa); - dig->dsa = NULL; - } - - if (dig->dsasig != NULL) { - SECITEM_ZfreeItem(dig->dsasig, PR_TRUE); - dig->dsasig = NULL; - } - - if (dig->rsa != NULL) { - SECKEY_DestroyPublicKey(dig->rsa); - dig->rsa = NULL; - } - - if (dig->rsasig != NULL) { - SECITEM_ZfreeItem(dig->rsasig, PR_TRUE); - dig->rsasig = NULL; - } + pgpCleanRSA(dig); + pgpCleanDSA(dig); } return; @@ -1501,50 +1315,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; -} - -