diff options
Diffstat (limited to 'packaging/rpm-beecrypt.diff')
-rw-r--r-- | packaging/rpm-beecrypt.diff | 1725 |
1 files changed, 1725 insertions, 0 deletions
diff --git a/packaging/rpm-beecrypt.diff b/packaging/rpm-beecrypt.diff new file mode 100644 index 0000000..55036f7 --- /dev/null +++ b/packaging/rpm-beecrypt.diff @@ -0,0 +1,1725 @@ +--- ./config.h.in.orig 2011-07-15 09:37:41.000000000 +0000 ++++ ./config.h.in 2011-07-18 16:34:29.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 <beecrypt/api.h> 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 <inttypes.h> header file. */ +@@ -227,6 +230,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 <mkdev.h>. + */ + #undef MAJOR_IN_MKDEV +@@ -311,6 +318,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-07-15 09:37:20.000000000 +0000 ++++ ./configure.ac 2011-07-18 16:34:29.000000000 +0000 +@@ -252,12 +252,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 <beecrypt/api.h> 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 <beecrypt/api.h> 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]) + ]) +@@ -266,6 +297,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 2011-07-15 09:36:33.000000000 +0000 ++++ ./rpmio/Makefile.am 2011-07-18 16:36:35.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_POPT_INCLUDE@ + AM_CPPFLAGS += -I$(top_srcdir)/misc + AM_CPPFLAGS += -DRPMCONFIGDIR="\"@RPMCONFIGDIR@\"" +@@ -17,10 +18,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:1:0 + librpmio_la_LIBADD = \ + ../misc/libmisc.la \ + @WITH_NSS_LIB@ \ ++ @WITH_BEECRYPT_LIB@ \ + @WITH_BZ2_LIB@ \ + @WITH_ZLIB_LIB@ \ + @WITH_LIBELF_LIB@ \ +@@ -28,6 +36,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_LUA + AM_CPPFLAGS += -I$(top_srcdir)/luaext/ + AM_CPPFLAGS += @LUA_CFLAGS@ +--- ./rpmio/base64.c.orig 2011-07-12 11:28:13.000000000 +0000 ++++ ./rpmio/base64.c 2011-07-18 16:34:29.000000000 +0000 +@@ -4,8 +4,11 @@ + #include <arpa/inet.h> + #include <stdlib.h> + ++#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 2011-07-12 11:28:13.000000000 +0000 ++++ ./rpmio/digest.c 2011-07-18 16:34:29.000000000 +0000 +@@ -4,25 +4,12 @@ + + #include "system.h" + ++#include <rpm/rpmpgp.h> + #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 2011-07-12 11:28:13.000000000 +0000 ++++ ./rpmio/digest.h 2011-07-18 16:34:29.000000000 +0000 +@@ -1,11 +1,6 @@ + #ifndef _RPMDIGEST_H + #define _RPMDIGEST_H + +-#include <nss.h> +-#include <sechash.h> +-#include <keyhi.h> +-#include <cryptohi.h> +- + #include <rpm/rpmpgp.h> + #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-07-18 16:34:29.000000000 +0000 ++++ ./rpmio/digest_beecrypt.c 2011-07-18 16:34:29.000000000 +0000 +@@ -0,0 +1,493 @@ ++#include "system.h" ++ ++#include <beecrypt.h> ++#include <dsa.h> ++#include <endianness.h> ++#include <md5.h> ++#include <mp.h> ++#include <rsa.h> ++#include <rsapk.h> ++#include <sha1.h> ++#if HAVE_BEECRYPT_API_H ++#include <sha256.h> ++#include <sha384.h> ++#include <sha512.h> ++#endif ++ ++#include <rpm/rpmpgp.h> ++#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-07-18 16:34:29.000000000 +0000 ++++ ./rpmio/digest_nss.c 2011-07-18 16:34:29.000000000 +0000 +@@ -0,0 +1,500 @@ ++#include <nss.h> ++#include <sechash.h> ++#include <keyhi.h> ++#include <cryptohi.h> ++ ++#include "system.h" ++ ++#include <rpm/rpmpgp.h> ++#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 2011-07-15 09:32:41.000000000 +0000 ++++ ./rpmio/rpmpgp.c 2011-07-18 16:42:25.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 { +@@ -842,49 +721,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) +- return NULL; +- } +- 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) +- return NULL; +- } +- 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; +@@ -1269,15 +1110,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; + } +@@ -1319,39 +1152,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; +@@ -1409,30 +1209,12 @@ rpmRC pgpVerifySig(pgpDig dig, DIGEST_CT + if (dig->keydata == NULL) { + res = RPMRC_NOKEY; + } else { +- 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 (!pgpVerifyRSA(dig, hash, hashlen)) ++ res = RPMRC_OK; ++ } else if (sigp->pubkey_algo == PGPPUBKEYALGO_DSA) { ++ if (!pgpVerifyDSA(dig, hash, hashlen)) ++ res = RPMRC_OK; + } + } + +@@ -1620,50 +1402,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; +-} +- +- |