--- ./config.h.in.orig	2012-05-22 10:55:46.000000000 +0000
+++ ./config.h.in	2012-05-31 16:41:07.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 to 1 if you have the <bzlib.h> header file. */
 #undef HAVE_BZLIB_H
 
@@ -206,6 +209,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
@@ -290,6 +297,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	2012-05-22 10:55:31.000000000 +0000
+++ ./configure.ac	2012-05-31 16:37:32.000000000 +0000
@@ -239,12 +239,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])
 ])
@@ -253,6 +284,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	2012-03-20 08:07:25.000000000 +0000
+++ ./rpmio/Makefile.am	2012-05-31 16:39:58.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,12 +18,18 @@ 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 3:0:0
 librpmio_la_LIBADD = \
 	../misc/libmisc.la \
 	@WITH_NSS_LIB@ \
+	@WITH_BEECRYPT_LIB@ \
 	@WITH_BZ2_LIB@ \
 	@WITH_ZLIB_LIB@ \
 	@WITH_LIBELF_LIB@ \
@@ -30,6 +37,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/digest_beecrypt.c.orig	2012-05-31 16:42:01.000000000 +0000
+++ ./rpmio/digest_beecrypt.c	2012-05-31 17:33:28.000000000 +0000
@@ -0,0 +1,526 @@
+#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"
+
+/**
+ * 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);	/*!< Digest initialize. */
+    int (*Update) (void * param, const byte * data, size_t size);	/*!< Digest transform. */
+    int (*Digest) (void * param, byte * digest);	/*!< Digest finish. */
+};
+
+
+/****************************  init   ************************************/
+
+int rpmInitCrypto(void) {
+    return 0;
+}
+
+int rpmFreeCrypto(void) {
+    return 0;
+}
+
+/****************************  digest ************************************/
+
+DIGEST_CTX rpmDigestDup(DIGEST_CTX octx)
+{
+    DIGEST_CTX nctx = NULL;
+    if (octx) {
+	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));
+
+    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;
+    }
+
+    (*ctx->Reset)(ctx->param);
+    return ctx;
+}
+
+int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
+{
+    if (ctx == NULL)
+	return -1;
+
+    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);
+
+    /* 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;
+}
+
+/**************************** helpers ************************************/
+
+static inline char * pgpHexCvt(char *t, const byte *s, int nbytes)
+{
+    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, const byte *pend)
+{
+    static char prbuf[2048];
+    char *t = prbuf;
+    int nbytes =  pgpMpiLen(p) - 2;
+    if (nbytes > 1024 || nbytes > pend - (p + 2))
+	return NULL;
+    t = pgpHexCvt(t, p+2, nbytes);
+    return prbuf;
+}
+
+static int pgpHexSet(int lbits, mpnumber * mpn, const byte * p, const byte * pend)
+{
+    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, pend));
+    (void) mpnsethex(mpn, t);
+    t = _free(t);
+    return 0;
+}
+
+static void pgpFreeSigRSADSA(pgpDigAlg sa)
+{
+    if (sa->data)
+	free(sa->data);
+    sa->data = 0;
+}
+
+static void pgpFreeKeyRSADSA(pgpDigAlg sa)
+{
+    if (sa->data)
+	free(sa->data);
+    sa->data = 0;
+}
+
+
+/****************************** RSA **************************************/
+
+struct pgpDigSigRSA_s {
+    mpnumber c;
+};
+
+struct pgpDigKeyRSA_s {
+    rsapk rsa_pk;
+};
+
+static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num,
+                           const uint8_t *p, const uint8_t *pend)
+{
+    struct pgpDigSigRSA_s *sig = pgpsig->data;
+    int rc = 1;
+
+    switch (num) {
+    case 0:
+	sig = pgpsig->data = xcalloc(1, sizeof(*sig));
+	(void) mpnsethex(&sig->c, pgpMpiHex(p, pend));
+	rc = 0;
+	break;
+    }
+    return rc;
+}
+
+static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num,
+                           const uint8_t *p, const uint8_t *pend)
+{
+    struct pgpDigKeyRSA_s *key = pgpkey->data;
+    int rc = 1;
+
+    if (!key)
+	key = pgpkey->data = xcalloc(1, sizeof(*key));
+    switch (num) {
+    case 0:
+	(void) mpbsethex(&key->rsa_pk.n, pgpMpiHex(p, pend));
+	rc = 0;
+	break;
+    case 1:
+	(void) mpnsethex(&key->rsa_pk.e, pgpMpiHex(p, pend));
+	rc = 0;
+	break;
+    }
+    return rc;
+}
+
+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;
+}
+
+static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
+{
+    struct pgpDigKeyRSA_s *key = pgpkey->data;
+    struct pgpDigSigRSA_s *sig = pgpsig->data;
+    const char * prefix = NULL;
+    mpnumber rsahm;
+    int rc = 1;
+
+    if (!sig || !key)
+	return rc;
+
+    switch (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;
+    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
+    rc = rsavrfy(&key->rsa_pk.n, &key->rsa_pk.e, &sig->c, &rsahm) == 1 ? 0 : 1;
+#else
+    rc = rsavrfy(&key->rsa_pk, &rsahm, &sig->c) == 1 ? 0 : 1;
+#endif
+    mpnfree(&rsahm);
+    return rc;
+}
+
+
+/****************************** DSA **************************************/
+
+struct pgpDigSigDSA_s {
+    mpnumber r;
+    mpnumber s;
+};
+
+struct pgpDigKeyDSA_s {
+    mpbarrett p;
+    mpbarrett q;
+    mpnumber g;
+    mpnumber y;
+};
+
+static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num,
+                           const uint8_t *p, const uint8_t *pend)
+{
+    struct pgpDigSigDSA_s *sig = pgpsig->data;
+    int rc = 1;
+
+    switch (num) {
+    case 0:
+	sig = pgpsig->data = xcalloc(1, sizeof(*sig));
+	rc = pgpHexSet(160, &sig->r, p, pend);
+	break;
+    case 1:
+	rc = pgpHexSet(160, &sig->s, p, pend);
+	break;
+    }
+    return rc;
+}
+
+static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num,
+                           const uint8_t *p, const uint8_t *pend)
+{
+    struct pgpDigKeyDSA_s *key = pgpkey->data;
+    int rc = 1;
+
+    if (!key)
+	key = pgpkey->data = xcalloc(1, sizeof(*key));
+
+    switch (num) {
+    case 0:
+	mpbsethex(&key->p, pgpMpiHex(p, pend));
+	rc = 0;
+	break;
+    case 1:
+	mpbsethex(&key->q, pgpMpiHex(p, pend));
+	rc = 0;
+	break;
+    case 2:
+	mpnsethex(&key->g, pgpMpiHex(p, pend));
+	rc = 0;
+	break;
+    case 3:
+	mpnsethex(&key->y, pgpMpiHex(p, pend));
+	rc = 0;
+	break;
+    }
+    return rc;
+}
+
+static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
+{
+    struct pgpDigKeyDSA_s *key = pgpkey->data;
+    struct pgpDigSigDSA_s *sig = pgpsig->data;
+    mpnumber hm;
+    int rc = 1;
+
+    if (sig && key) {
+	mpnzero(&hm);
+	mpnsetbin(&hm, hash, hashlen);
+	rc = dsavrfy(&key->p, &key->q, &key->g, &hm, &key->y, &sig->r, &sig->s) == 1 ? 0 : 1;
+	mpnfree(&hm);
+    }
+    return rc;
+}
+
+static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num,
+                         const uint8_t *p, const uint8_t *pend)
+{
+    return 1;
+}
+
+static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
+                         uint8_t *hash, size_t hashlen, int hash_algo)
+{
+    return 1;
+}
+
+pgpDigAlg pgpPubkeyNew(int algo)
+{
+    pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
+
+    switch (algo) {
+    case PGPPUBKEYALGO_RSA:
+        ka->setmpi = pgpSetKeyMpiRSA;
+        ka->free = pgpFreeKeyRSADSA;
+        ka->mpis = 2;
+        break;
+    case PGPPUBKEYALGO_DSA:
+        ka->setmpi = pgpSetKeyMpiDSA;
+        ka->free = pgpFreeKeyRSADSA;
+        ka->mpis = 4;
+        break;
+    default:
+        ka->setmpi = pgpSetMpiNULL;
+        ka->mpis = -1;
+        break;
+    }
+
+    ka->verify = pgpVerifyNULL; /* keys can't be verified */
+
+    return ka;
+}
+
+pgpDigAlg pgpSignatureNew(int algo)
+{
+    pgpDigAlg sa = xcalloc(1, sizeof(*sa));
+
+    switch (algo) {
+    case PGPPUBKEYALGO_RSA:
+        sa->setmpi = pgpSetSigMpiRSA;
+        sa->free = pgpFreeSigRSADSA;
+        sa->verify = pgpVerifySigRSA;
+        sa->mpis = 1;
+        break;
+    case PGPPUBKEYALGO_DSA:
+        sa->setmpi = pgpSetSigMpiDSA;
+        sa->free = pgpFreeSigRSADSA;
+        sa->verify = pgpVerifySigDSA;
+        sa->mpis = 2;
+        break;
+    default:
+        sa->setmpi = pgpSetMpiNULL;
+        sa->verify = pgpVerifyNULL;
+        sa->mpis = -1;
+        break;
+    }
+    return sa;
+}