rpm/rpm-beecrypt.diff

1727 lines
42 KiB
Diff
Raw Normal View History

--- ./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 <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. */
@@ -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 <mkdev.h>.
*/
#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 <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])
])
@@ -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 <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 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 <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 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 <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-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 <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-05-10 15:54:41.000000000 +0000
+++ ./rpmio/digest_nss.c 2011-05-10 15:54:41.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 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;
-}
-
-