1836 lines
44 KiB
Diff
1836 lines
44 KiB
Diff
|
--- ./Makefile.am.orig 2009-06-23 11:40:57.000000000 +0000
|
||
|
+++ ./Makefile.am 2009-08-20 13:47:03.000000000 +0000
|
||
|
@@ -88,7 +88,8 @@ DISTCLEANFILES += find-requires
|
||
|
|
||
|
rpm_SOURCES = rpmqv.c debug.h system.h
|
||
|
rpm_CPPFLAGS = $(AM_CPPFLAGS) -DIAM_RPMDB -DIAM_RPMEIU -DIAM_RPMK -DIAM_RPMQV
|
||
|
-rpm_LDADD = build/librpmbuild.la lib/librpm.la rpmio/librpmio.la
|
||
|
+rpm_LDADD = lib/librpm.la rpmio/librpmio.la
|
||
|
+rpm_LDADD += build/.libs/spec.o build/.libs/misc.o build/.libs/names.o build/.libs/expression.o build/.libs/reqprov.o build/.libs/poptBT.o build/.libs/parse*.o
|
||
|
rpm_LDADD += @WITH_LIBELF_LIB@ @WITH_NSS_LIB@ @WITH_POPT_LIB@ @WITH_ZLIB_LIB@
|
||
|
|
||
|
rpmbuild_SOURCES = build.c rpmqv.c build.h debug.h system.h
|
||
|
--- ./config.h.in.orig 2009-07-21 08:21:37.000000000 +0000
|
||
|
+++ ./config.h.in 2009-08-20 13:47:03.000000000 +0000
|
||
|
@@ -13,6 +13,9 @@
|
||
|
/* Define to 1 if you have the `basename' function. */
|
||
|
#undef HAVE_BASENAME
|
||
|
|
||
|
+/* Define to 1 if you have the <beecrypt/api.h> header file. */
|
||
|
+#undef HAVE_BEECRYPT_API_H
|
||
|
+
|
||
|
/* Define as 1 if you bzip2 1.0 */
|
||
|
#undef HAVE_BZ2_1_0
|
||
|
|
||
|
@@ -110,7 +113,7 @@
|
||
|
/* Define as 1 if <netdb.h> defines h_errno */
|
||
|
#undef HAVE_HERRNO
|
||
|
|
||
|
-/* Define if you have the iconv() function. */
|
||
|
+/* Define if you have the iconv() function and it works. */
|
||
|
#undef HAVE_ICONV
|
||
|
|
||
|
/* Define to 1 if you have the `inet_aton' function. */
|
||
|
@@ -359,6 +362,10 @@
|
||
|
*/
|
||
|
#undef LT_OBJDIR
|
||
|
|
||
|
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||
|
+ */
|
||
|
+#undef LT_OBJDIR
|
||
|
+
|
||
|
/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
|
||
|
*/
|
||
|
#undef MAJOR_IN_MKDEV
|
||
|
@@ -456,6 +463,9 @@
|
||
|
/* Build with acl support? */
|
||
|
#undef WITH_ACL
|
||
|
|
||
|
+/* Build with beecrypt instead of nss3 support? */
|
||
|
+#undef WITH_BEECRYPT
|
||
|
+
|
||
|
/* Build with capability support? */
|
||
|
#undef WITH_CAP
|
||
|
|
||
|
--- ./configure.ac.orig 2009-07-21 08:20:46.000000000 +0000
|
||
|
+++ ./configure.ac 2009-08-20 13:47:03.000000000 +0000
|
||
|
@@ -300,12 +300,43 @@ AC_CHECK_HEADERS([dwarf.h], [
|
||
|
AM_CONDITIONAL(LIBDWARF,[test "$WITH_LIBDWARF" = yes])
|
||
|
|
||
|
#=================
|
||
|
+# Check for beecrypt library if requested.
|
||
|
+AC_ARG_WITH(beecrypt, [ --with-beecrypt build with beecrypt support ],,[with_beecrypt=yes])
|
||
|
+AC_ARG_WITH(internal_beecrypt, [ --with-internal-beecrypt build with internal beecrypt library ],,[with_internal_beecrypt=yes])
|
||
|
+AM_CONDITIONAL([WITH_INTERNAL_BEECRYPT],[test "$with_internal_beecrypt" = yes])
|
||
|
+if test "$with_internal_beecrypt" = yes ; then
|
||
|
+ with_beecrypt=yes
|
||
|
+fi
|
||
|
+AM_CONDITIONAL([WITH_BEECRYPT],[test "$with_beecrypt" = yes])
|
||
|
+
|
||
|
+WITH_BEECRYPT_INCLUDE=
|
||
|
+WITH_BEECRYPT_LIB=
|
||
|
+if test "$with_beecrypt" = yes ; then
|
||
|
+ AC_DEFINE(WITH_BEECRYPT, 1, [Build with beecrypt instead of nss3 support?])
|
||
|
+ if test "$with_internal_beecrypt" = yes ; then
|
||
|
+ WITH_BEECRYPT_INCLUDE="-I\$(top_srcdir)/beecrypt"
|
||
|
+ AC_DEFINE(HAVE_BEECRYPT_API_H, 1, [Define to 1 if you have the <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])
|
||
|
])
|
||
|
@@ -314,6 +345,7 @@ AC_CHECK_LIB(nss3, NSS_NoDB_Init, [
|
||
|
], [
|
||
|
AC_MSG_ERROR([missing required NSS library 'nss3'])
|
||
|
])
|
||
|
+fi
|
||
|
AC_SUBST(WITH_NSS_INCLUDE)
|
||
|
AC_SUBST(WITH_NSS_LIB)
|
||
|
|
||
|
--- ./lib/signature.c.orig 2009-06-23 11:40:58.000000000 +0000
|
||
|
+++ ./lib/signature.c 2009-08-20 13:47:03.000000000 +0000
|
||
|
@@ -1118,10 +1118,8 @@ verifyRSASignature(rpmKeyring keyring, r
|
||
|
DIGEST_CTX md5ctx)
|
||
|
{
|
||
|
pgpDigParams sigp = dig ? &dig->signature : NULL;
|
||
|
- SECOidTag sigalg;
|
||
|
rpmRC res = RPMRC_OK;
|
||
|
int xx;
|
||
|
- SECItem digest;
|
||
|
const char *hdr, *signame = _("Unknown");;
|
||
|
const char *sig = sigtd->data;
|
||
|
int sigver;
|
||
|
@@ -1153,27 +1151,21 @@ verifyRSASignature(rpmKeyring keyring, r
|
||
|
switch (sigp->hash_algo) {
|
||
|
case PGPHASHALGO_MD5:
|
||
|
signame = "RSA/MD5";
|
||
|
- sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
|
||
|
break;
|
||
|
case PGPHASHALGO_SHA1:
|
||
|
signame = "RSA/SHA1";
|
||
|
- sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
|
||
|
break;
|
||
|
case PGPHASHALGO_MD2:
|
||
|
signame = "RSA/MD2";
|
||
|
- sigalg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
|
||
|
break;
|
||
|
case PGPHASHALGO_SHA256:
|
||
|
signame = "RSA/SHA256";
|
||
|
- sigalg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
|
||
|
break;
|
||
|
case PGPHASHALGO_SHA384:
|
||
|
signame = "RSA/SHA384";
|
||
|
- sigalg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
|
||
|
break;
|
||
|
case PGPHASHALGO_SHA512:
|
||
|
signame = "RSA/SHA512";
|
||
|
- sigalg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
|
||
|
break;
|
||
|
/* fallthrough for unsupported / unknown types */
|
||
|
case PGPHASHALGO_TIGER192:
|
||
|
@@ -1181,7 +1173,6 @@ verifyRSASignature(rpmKeyring keyring, r
|
||
|
case PGPHASHALGO_RIPEMD160:
|
||
|
default:
|
||
|
res = RPMRC_NOKEY;
|
||
|
- sigalg = SEC_OID_UNKNOWN;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
@@ -1212,9 +1203,6 @@ verifyRSASignature(rpmKeyring keyring, r
|
||
|
res = RPMRC_FAIL;
|
||
|
goto exit;
|
||
|
}
|
||
|
- digest.type = siBuffer;
|
||
|
- digest.data = dig->md5;
|
||
|
- digest.len = dig->md5len;
|
||
|
}
|
||
|
|
||
|
/* Retrieve the matching public key. */
|
||
|
@@ -1222,29 +1210,8 @@ verifyRSASignature(rpmKeyring keyring, r
|
||
|
if (res != RPMRC_OK)
|
||
|
goto exit;
|
||
|
|
||
|
- { SECItem *sig = dig->rsasig;
|
||
|
- size_t siglen = SECKEY_SignatureLen(dig->rsa);
|
||
|
-
|
||
|
- /* Zero-pad signature data up to expected size if necessary */
|
||
|
- if (siglen > sig->len) {
|
||
|
- size_t pad = siglen - sig->len;
|
||
|
- if ((sig = SECITEM_AllocItem(NULL, NULL, siglen)) == NULL) {
|
||
|
- res = RPMRC_FAIL;
|
||
|
- goto exit;
|
||
|
- }
|
||
|
- memset(sig->data, 0, pad);
|
||
|
- memcpy(sig->data+pad, dig->rsasig->data, dig->rsasig->len);
|
||
|
- }
|
||
|
-
|
||
|
- if (VFY_VerifyDigest(&digest, dig->rsa, sig, sigalg, NULL) == SECSuccess)
|
||
|
- res = RPMRC_OK;
|
||
|
- else
|
||
|
- res = RPMRC_FAIL;
|
||
|
-
|
||
|
- if (sig != dig->rsasig) {
|
||
|
- SECITEM_ZfreeItem(sig, 1);
|
||
|
- }
|
||
|
- }
|
||
|
+ if (pgpVerifyRSA(dig))
|
||
|
+ res = RPMRC_FAIL;
|
||
|
|
||
|
exit:
|
||
|
if (sigp != NULL) {
|
||
|
@@ -1273,7 +1240,6 @@ verifyDSASignature(rpmKeyring keyring, r
|
||
|
pgpDigParams sigp = dig ? &dig->signature : NULL;
|
||
|
rpmRC res;
|
||
|
int xx;
|
||
|
- SECItem digest;
|
||
|
const char *hdr;
|
||
|
int sigver;
|
||
|
const char *sig = sigtd->data;
|
||
|
@@ -1320,9 +1286,6 @@ verifyDSASignature(rpmKeyring keyring, r
|
||
|
res = RPMRC_FAIL;
|
||
|
goto exit;
|
||
|
}
|
||
|
- digest.type = siBuffer;
|
||
|
- digest.data = dig->sha1;
|
||
|
- digest.len = dig->sha1len;
|
||
|
}
|
||
|
|
||
|
/* Retrieve the matching public key. */
|
||
|
@@ -1330,10 +1293,7 @@ verifyDSASignature(rpmKeyring keyring, r
|
||
|
if (res != RPMRC_OK)
|
||
|
goto exit;
|
||
|
|
||
|
- if (VFY_VerifyDigest(&digest, dig->dsa, dig->dsasig,
|
||
|
- SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST, NULL) == SECSuccess)
|
||
|
- res = RPMRC_OK;
|
||
|
- else
|
||
|
+ if (pgpVerifyDSA(dig))
|
||
|
res = RPMRC_FAIL;
|
||
|
|
||
|
exit:
|
||
|
--- ./rpmio/Makefile.am.orig 2009-06-23 11:40:59.000000000 +0000
|
||
|
+++ ./rpmio/Makefile.am 2009-08-20 13:47:03.000000000 +0000
|
||
|
@@ -2,6 +2,7 @@
|
||
|
|
||
|
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_builddir)/include/
|
||
|
AM_CPPFLAGS += @WITH_NSS_INCLUDE@
|
||
|
+AM_CPPFLAGS += @WITH_BEECRYPT_INCLUDE@
|
||
|
AM_CPPFLAGS += @WITH_LUA_INCLUDE@
|
||
|
AM_CPPFLAGS += @WITH_POPT_INCLUDE@
|
||
|
AM_CPPFLAGS += -I$(top_srcdir)/misc
|
||
|
@@ -19,10 +20,17 @@ librpmio_la_SOURCES = \
|
||
|
rpmstring.c rpmfileutil.c \
|
||
|
rpmkeyring.c
|
||
|
|
||
|
+if WITH_BEECRYPT
|
||
|
+librpmio_la_SOURCES += digest_beecrypt.c
|
||
|
+else
|
||
|
+librpmio_la_SOURCES += digest_nss.c
|
||
|
+endif
|
||
|
+
|
||
|
librpmio_la_LDFLAGS = -version-info 0:0:0
|
||
|
librpmio_la_LIBADD = \
|
||
|
../misc/libmisc.la \
|
||
|
@WITH_NSS_LIB@ \
|
||
|
+ @WITH_BEECRYPT_LIB@ \
|
||
|
@WITH_LUA_LIB@ \
|
||
|
@WITH_BZ2_LIB@ \
|
||
|
@WITH_ZLIB_LIB@ \
|
||
|
@@ -31,6 +39,17 @@ librpmio_la_LIBADD = \
|
||
|
@WITH_LZMA_LIB@ \
|
||
|
-lpthread
|
||
|
|
||
|
+if WITH_INTERNAL_BEECRYPT
|
||
|
+librpmio_la_LIBADD += $(libbeecrypt_la)
|
||
|
+
|
||
|
+libbeecrypt_la = $(top_builddir)/beecrypt/libbeecrypt_nolibdir.la
|
||
|
+
|
||
|
+$(top_builddir)/beecrypt/libbeecrypt_nolibdir.la: $(top_builddir)/beecrypt/libbeecrypt.la
|
||
|
+ sed -e 's/libdir=.*/libdir=/' < $(top_builddir)/beecrypt/libbeecrypt.la > $(top_builddir)/beecrypt/libbeecrypt_nolibdir.la
|
||
|
+endif
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
if WITH_LUAEXT
|
||
|
AM_CPPFLAGS += -I$(top_builddir)/luaext/
|
||
|
librpmio_la_LIBADD += $(top_builddir)/luaext/libluaext.la
|
||
|
--- ./rpmio/base64.c.orig 2009-06-23 11:40:59.000000000 +0000
|
||
|
+++ ./rpmio/base64.c 2009-08-20 13:47:03.000000000 +0000
|
||
|
@@ -4,8 +4,11 @@
|
||
|
#include <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 2009-06-23 11:40:59.000000000 +0000
|
||
|
+++ ./rpmio/digest.c 2009-08-20 13:47:03.000000000 +0000
|
||
|
@@ -4,165 +4,12 @@
|
||
|
|
||
|
#include "system.h"
|
||
|
|
||
|
+#include <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. */
|
||
|
-};
|
||
|
-
|
||
|
-DIGEST_CTX
|
||
|
-rpmDigestDup(DIGEST_CTX octx)
|
||
|
-{
|
||
|
- DIGEST_CTX nctx;
|
||
|
- nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
|
||
|
- nctx->hashctx = HASH_Clone(octx->hashctx);
|
||
|
- if (nctx->hashctx == NULL) {
|
||
|
- fprintf(stderr, "HASH_Clone failed\n");
|
||
|
- exit(EXIT_FAILURE); /* FIX: callers do not bother checking error return */
|
||
|
- }
|
||
|
- return nctx;
|
||
|
-}
|
||
|
-
|
||
|
-RPM_GNUC_PURE
|
||
|
-static HASH_HashType getHashType(pgpHashAlgo hashalgo)
|
||
|
-{
|
||
|
- switch (hashalgo) {
|
||
|
- case PGPHASHALGO_MD5:
|
||
|
- return HASH_AlgMD5;
|
||
|
- break;
|
||
|
- case PGPHASHALGO_MD2:
|
||
|
- return HASH_AlgMD2;
|
||
|
- break;
|
||
|
- case PGPHASHALGO_SHA1:
|
||
|
- return HASH_AlgSHA1;
|
||
|
- break;
|
||
|
- case PGPHASHALGO_SHA256:
|
||
|
- return HASH_AlgSHA256;
|
||
|
- break;
|
||
|
- case PGPHASHALGO_SHA384:
|
||
|
- return HASH_AlgSHA384;
|
||
|
- break;
|
||
|
- case PGPHASHALGO_SHA512:
|
||
|
- return HASH_AlgSHA512;
|
||
|
- break;
|
||
|
- case PGPHASHALGO_RIPEMD160:
|
||
|
- case PGPHASHALGO_TIGER192:
|
||
|
- case PGPHASHALGO_HAVAL_5_160:
|
||
|
- default:
|
||
|
- return HASH_AlgNULL;
|
||
|
- break;
|
||
|
- }
|
||
|
-}
|
||
|
-
|
||
|
-size_t
|
||
|
-rpmDigestLength(pgpHashAlgo hashalgo)
|
||
|
-{
|
||
|
- return HASH_ResultLen(getHashType(hashalgo));
|
||
|
-}
|
||
|
-
|
||
|
-DIGEST_CTX
|
||
|
-rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
|
||
|
-{
|
||
|
- HASH_HashType type;
|
||
|
- DIGEST_CTX ctx;
|
||
|
-
|
||
|
- if (rpmInitCrypto() < 0)
|
||
|
- return NULL;
|
||
|
-
|
||
|
- ctx = xcalloc(1, sizeof(*ctx));
|
||
|
- ctx->flags = flags;
|
||
|
-
|
||
|
- type = getHashType(hashalgo);
|
||
|
- if (type == HASH_AlgNULL) {
|
||
|
- free(ctx);
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- ctx->hashctx = HASH_Create(type);
|
||
|
- if (ctx->hashctx == NULL) {
|
||
|
- free(ctx);
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- HASH_Begin(ctx->hashctx);
|
||
|
-
|
||
|
-DPRINTF((stderr, "*** Init(%x) ctx %p hashctx %p\n", flags, ctx, ctx->hashctx));
|
||
|
- return ctx;
|
||
|
-}
|
||
|
-
|
||
|
-int
|
||
|
-rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
|
||
|
-{
|
||
|
- size_t partlen;
|
||
|
- const unsigned char *ptr = data;
|
||
|
-
|
||
|
- if (ctx == NULL)
|
||
|
- return -1;
|
||
|
-
|
||
|
-DPRINTF((stderr, "*** Update(%p,%p,%zd) hashctx %p \"%s\"\n", ctx, data, len, ctx->hashctx, ((char *)data)));
|
||
|
- partlen = ~(unsigned int)0xFF;
|
||
|
- while (len > 0) {
|
||
|
- if (len < partlen) {
|
||
|
- partlen = len;
|
||
|
- }
|
||
|
- HASH_Update(ctx->hashctx, ptr, partlen);
|
||
|
- ptr += partlen;
|
||
|
- len -= partlen;
|
||
|
- }
|
||
|
- return 0;
|
||
|
-}
|
||
|
-
|
||
|
-int
|
||
|
-rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
|
||
|
-{
|
||
|
- unsigned char * digest;
|
||
|
- unsigned int digestlen;
|
||
|
-
|
||
|
- if (ctx == NULL)
|
||
|
- return -1;
|
||
|
- digestlen = HASH_ResultLenContext(ctx->hashctx);
|
||
|
- digest = xmalloc(digestlen);
|
||
|
-
|
||
|
-DPRINTF((stderr, "*** Final(%p,%p,%p,%zd) hashctx %p digest %p\n", ctx, datap, lenp, asAscii, ctx->hashctx, digest));
|
||
|
-/* FIX: check rc */
|
||
|
- HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen);
|
||
|
-
|
||
|
- /* Return final digest. */
|
||
|
- if (!asAscii) {
|
||
|
- if (lenp) *lenp = digestlen;
|
||
|
- if (datap) {
|
||
|
- *datap = digest;
|
||
|
- digest = NULL;
|
||
|
- }
|
||
|
- } else {
|
||
|
- if (lenp) *lenp = (2*digestlen) + 1;
|
||
|
- if (datap) {
|
||
|
- const uint8_t * s = (const uint8_t *) digest;
|
||
|
- *datap = pgpHexStr(s, digestlen);
|
||
|
- }
|
||
|
- }
|
||
|
- if (digest) {
|
||
|
- memset(digest, 0, digestlen); /* In case it's sensitive */
|
||
|
- free(digest);
|
||
|
- }
|
||
|
- HASH_Destroy(ctx->hashctx);
|
||
|
- memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||
|
- free(ctx);
|
||
|
- return 0;
|
||
|
-}
|
||
|
|
||
|
void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
|
||
|
{
|
||
|
--- ./rpmio/digest.h.orig 2009-06-23 11:40:59.000000000 +0000
|
||
|
+++ ./rpmio/digest.h 2009-08-20 13:47:03.000000000 +0000
|
||
|
@@ -1,11 +1,6 @@
|
||
|
#ifndef _RPMDIGEST_H
|
||
|
#define _RPMDIGEST_H
|
||
|
|
||
|
-#include <nss.h>
|
||
|
-#include <sechash.h>
|
||
|
-#include <keyhi.h>
|
||
|
-#include <cryptohi.h>
|
||
|
-
|
||
|
#include <rpm/rpmpgp.h>
|
||
|
#include "rpmio/base64.h"
|
||
|
#include "rpmio/rpmio_internal.h"
|
||
|
@@ -55,12 +50,22 @@ struct pgpDig_s {
|
||
|
size_t md5len; /*!< (rsa) V3 signature hash length. */
|
||
|
|
||
|
/* DSA parameters */
|
||
|
- SECKEYPublicKey *dsa;
|
||
|
- SECItem *dsasig;
|
||
|
+ void *dsa;
|
||
|
+ void *dsasig;
|
||
|
|
||
|
/* RSA parameters */
|
||
|
- SECKEYPublicKey *rsa;
|
||
|
- SECItem *rsasig;
|
||
|
+ void *rsa;
|
||
|
+ void *rsasig;
|
||
|
};
|
||
|
|
||
|
+int pgpSetSigMpiRSA(pgpDig dig, int num, const uint8_t *p);
|
||
|
+int pgpSetPubMpiRSA(pgpDig dig, int num, const uint8_t *p);
|
||
|
+void pgpCleanRSA(pgpDig dig);
|
||
|
+int pgpVerifyRSA(pgpDig dig);
|
||
|
+
|
||
|
+int pgpSetSigMpiDSA(pgpDig dig, int num, const uint8_t *p);
|
||
|
+int pgpSetPubMpiDSA(pgpDig dig, int num, const uint8_t *p);
|
||
|
+void pgpCleanDSA(pgpDig dig);
|
||
|
+int pgpVerifyDSA(pgpDig dig);
|
||
|
+
|
||
|
#endif /* _RPMDIGEST_H */
|
||
|
--- ./rpmio/digest_beecrypt.c.orig 2009-08-20 13:47:03.000000000 +0000
|
||
|
+++ ./rpmio/digest_beecrypt.c 2009-08-20 13:47:03.000000000 +0000
|
||
|
@@ -0,0 +1,503 @@
|
||
|
+#include "system.h"
|
||
|
+
|
||
|
+#include <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;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+/****************************** RSA **************************************/
|
||
|
+
|
||
|
+struct pgpDigSigRSA_s {
|
||
|
+ mpnumber c;
|
||
|
+};
|
||
|
+
|
||
|
+struct pgpDigPubRSA_s {
|
||
|
+ rsapk rsa_pk;
|
||
|
+};
|
||
|
+
|
||
|
+int
|
||
|
+pgpSetSigMpiRSA(pgpDig dig, int num, const uint8_t *p)
|
||
|
+{
|
||
|
+ struct pgpDigSigRSA_s *sig;
|
||
|
+ if (num != 0)
|
||
|
+ return 1;
|
||
|
+ if (!dig->rsasig)
|
||
|
+ dig->rsasig = xcalloc(1, sizeof(*sig));
|
||
|
+ sig = dig->rsasig;
|
||
|
+ if (!sig)
|
||
|
+ return 1;
|
||
|
+ (void) mpnsethex(&sig->c, pgpMpiHex(p));
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+pgpSetPubMpiRSA(pgpDig dig, int num, const uint8_t *p)
|
||
|
+{
|
||
|
+ struct pgpDigPubRSA_s *pub;
|
||
|
+
|
||
|
+ if (!dig->rsa)
|
||
|
+ dig->rsa = xcalloc(1, sizeof(*pub));
|
||
|
+ pub = dig->rsa;
|
||
|
+ if (!pub)
|
||
|
+ return 1;
|
||
|
+ switch(num) {
|
||
|
+ case 0:
|
||
|
+ (void) mpbsethex(&pub->rsa_pk.n, pgpMpiHex(p));
|
||
|
+ return 0;
|
||
|
+ case 1:
|
||
|
+ (void) mpnsethex(&pub->rsa_pk.e, pgpMpiHex(p));
|
||
|
+ return 0;
|
||
|
+ default:
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void pgpCleanRSA(pgpDig dig)
|
||
|
+{
|
||
|
+ if (!dig)
|
||
|
+ return;
|
||
|
+ if (dig->rsa) {
|
||
|
+ dig->rsa = _free(dig->rsa);
|
||
|
+ }
|
||
|
+ if (dig->rsasig) {
|
||
|
+ dig->rsasig = _free(dig->rsasig);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static inline unsigned char nibble(char c)
|
||
|
+{
|
||
|
+ if (c >= '0' && c <= '9')
|
||
|
+ return (c - '0');
|
||
|
+ if (c >= 'A' && c <= 'F')
|
||
|
+ return (c - 'A') + 10;
|
||
|
+ if (c >= 'a' && c <= 'f')
|
||
|
+ return (c - 'a') + 10;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int pgpVerifyRSA(pgpDig dig)
|
||
|
+{
|
||
|
+ const char * prefix = NULL;
|
||
|
+ int res;
|
||
|
+ mpnumber rsahm;
|
||
|
+ struct pgpDigSigRSA_s *sig;
|
||
|
+ struct pgpDigPubRSA_s *pub;
|
||
|
+
|
||
|
+ sig = dig->rsasig;
|
||
|
+ pub = dig->rsa;
|
||
|
+ if (!sig || !pub)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ switch (dig->signature.hash_algo) {
|
||
|
+ case PGPHASHALGO_MD5:
|
||
|
+ prefix = "3020300c06082a864886f70d020505000410";
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA1:
|
||
|
+ prefix = "3021300906052b0e03021a05000414";
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_MD2:
|
||
|
+ prefix = "3020300c06082a864886f70d020205000410";
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA256:
|
||
|
+ prefix = "3031300d060960864801650304020105000420";
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA384:
|
||
|
+ prefix = "3041300d060960864801650304020205000430";
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA512:
|
||
|
+ prefix = "3051300d060960864801650304020305000440";
|
||
|
+ break;
|
||
|
+ /* fallthrough for unsupported / unknown types */
|
||
|
+ default:
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Generate RSA modulus parameter. */
|
||
|
+ { unsigned int nbits = MP_WORDS_TO_BITS(sig->c.size);
|
||
|
+ unsigned int nb = (nbits + 7) >> 3;
|
||
|
+ byte *buf, *bp;
|
||
|
+
|
||
|
+ if (nb < 3)
|
||
|
+ return 1;
|
||
|
+ buf = xmalloc(nb);
|
||
|
+ memset(buf, 0xff, nb);
|
||
|
+ buf[0] = 0x00;
|
||
|
+ buf[1] = 0x01;
|
||
|
+ bp = buf + nb - strlen(prefix)/2 - dig->md5len - 1;
|
||
|
+ if (bp < buf)
|
||
|
+ return 1;
|
||
|
+ *bp++ = 0;
|
||
|
+ for (; *prefix; prefix += 2)
|
||
|
+ *bp++ = (nibble(prefix[0]) << 4) | nibble(prefix[1]);
|
||
|
+ memcpy(bp, dig->md5, dig->md5len);
|
||
|
+ mpnzero(&rsahm);
|
||
|
+ (void) mpnsetbin(&rsahm, buf, nb);
|
||
|
+ buf = _free(buf);
|
||
|
+ }
|
||
|
+#if HAVE_BEECRYPT_API_H
|
||
|
+ res = rsavrfy(&pub->rsa_pk.n, &pub->rsa_pk.e, &sig->c, &rsahm) == 1 ? 0 : 1;
|
||
|
+#else
|
||
|
+ res = rsavrfy(&pub->rsa_pk, &rsahm, &sig->c) == 1 ? 0 : 1;
|
||
|
+#endif
|
||
|
+ mpnfree(&rsahm);
|
||
|
+ return res;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+/****************************** DSA **************************************/
|
||
|
+
|
||
|
+struct pgpDigSigDSA_s {
|
||
|
+ mpnumber r;
|
||
|
+ mpnumber s;
|
||
|
+};
|
||
|
+
|
||
|
+struct pgpDigPubDSA_s {
|
||
|
+ mpbarrett p;
|
||
|
+ mpbarrett q;
|
||
|
+ mpnumber g;
|
||
|
+ mpnumber y;
|
||
|
+};
|
||
|
+
|
||
|
+int
|
||
|
+pgpSetSigMpiDSA(pgpDig dig, int num, const uint8_t *p)
|
||
|
+{
|
||
|
+ struct pgpDigSigDSA_s *sig;
|
||
|
+
|
||
|
+ if (!dig->dsasig)
|
||
|
+ dig->dsasig = xcalloc(1, sizeof(*sig));
|
||
|
+ sig = dig->dsasig;
|
||
|
+ if (!sig)
|
||
|
+ return 1;
|
||
|
+ switch(num) {
|
||
|
+ case 0:
|
||
|
+ return pgpHexSet(160, &sig->r, p);
|
||
|
+ case 1:
|
||
|
+ return pgpHexSet(160, &sig->s, p);
|
||
|
+ default:
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+pgpSetPubMpiDSA(pgpDig dig, int num, const uint8_t *p)
|
||
|
+{
|
||
|
+ struct pgpDigPubDSA_s *pub;
|
||
|
+
|
||
|
+ if (!dig->dsa)
|
||
|
+ dig->dsa = xcalloc(1, sizeof(*pub));
|
||
|
+ pub = dig->dsa;
|
||
|
+ if (!pub)
|
||
|
+ return 1;
|
||
|
+ switch(num) {
|
||
|
+ case 0:
|
||
|
+ mpbsethex(&pub->p, pgpMpiHex(p));
|
||
|
+ return 0;
|
||
|
+ case 1:
|
||
|
+ mpbsethex(&pub->q, pgpMpiHex(p));
|
||
|
+ return 0;
|
||
|
+ case 2:
|
||
|
+ mpnsethex(&pub->g, pgpMpiHex(p));
|
||
|
+ return 0;
|
||
|
+ case 3:
|
||
|
+ mpnsethex(&pub->y, pgpMpiHex(p));
|
||
|
+ return 0;
|
||
|
+ default:
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void pgpCleanDSA(pgpDig dig)
|
||
|
+{
|
||
|
+ if (!dig)
|
||
|
+ return;
|
||
|
+ if (dig->dsa) {
|
||
|
+ dig->dsa = _free(dig->dsa);
|
||
|
+ }
|
||
|
+ if (dig->dsasig) {
|
||
|
+ dig->dsasig = _free(dig->dsasig);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+int pgpVerifyDSA(pgpDig dig)
|
||
|
+{
|
||
|
+ struct pgpDigSigDSA_s *sig;
|
||
|
+ struct pgpDigPubDSA_s *pub;
|
||
|
+ mpnumber hm;
|
||
|
+ int res;
|
||
|
+
|
||
|
+ sig = dig->dsasig;
|
||
|
+ pub = dig->dsa;
|
||
|
+ if (!sig || !pub)
|
||
|
+ return 1;
|
||
|
+ mpnzero(&hm);
|
||
|
+ mpnsetbin(&hm, dig->sha1, dig->sha1len);
|
||
|
+ res = dsavrfy(&pub->p, &pub->q, &pub->g, &hm, &pub->y, &sig->r, &sig->s) == 1 ? 0 : 1;
|
||
|
+ mpnfree(&hm);
|
||
|
+ return res;
|
||
|
+}
|
||
|
+
|
||
|
+/**************************** digest ************************************/
|
||
|
+
|
||
|
+#ifdef SHA_DEBUG
|
||
|
+#define DPRINTF(_a) fprintf _a
|
||
|
+#else
|
||
|
+#define DPRINTF(_a)
|
||
|
+#endif
|
||
|
+
|
||
|
+/**
|
||
|
+ * MD5/SHA1 digest private data.
|
||
|
+ */
|
||
|
+struct DIGEST_CTX_s {
|
||
|
+ rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */
|
||
|
+ uint32_t datalen; /*!< No. bytes in block of plaintext data. */
|
||
|
+ uint32_t paramlen; /*!< No. bytes of digest parameters. */
|
||
|
+ uint32_t digestlen; /*!< No. bytes of digest. */
|
||
|
+ void * param; /*!< Digest parameters. */
|
||
|
+ int (*Reset) (void * param)
|
||
|
+ /*@modifies param @*/; /*!< Digest initialize. */
|
||
|
+ int (*Update) (void * param, const byte * data, size_t size)
|
||
|
+ /*@modifies param @*/; /*!< Digest transform. */
|
||
|
+ int (*Digest) (void * param, /*@out@*/ byte * digest)
|
||
|
+ /*@modifies param, digest @*/; /*!< Digest finish. */
|
||
|
+};
|
||
|
+
|
||
|
+DIGEST_CTX
|
||
|
+rpmDigestDup(DIGEST_CTX octx)
|
||
|
+{
|
||
|
+ DIGEST_CTX nctx;
|
||
|
+ nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
|
||
|
+ nctx->param = memcpy(xcalloc(1, nctx->paramlen), octx->param, nctx->paramlen);
|
||
|
+ return nctx;
|
||
|
+}
|
||
|
+
|
||
|
+size_t
|
||
|
+rpmDigestLength(pgpHashAlgo hashalgo)
|
||
|
+{
|
||
|
+ switch (hashalgo) {
|
||
|
+ case PGPHASHALGO_MD5:
|
||
|
+ return 16;
|
||
|
+ case PGPHASHALGO_SHA1:
|
||
|
+ return 20;
|
||
|
+#if HAVE_BEECRYPT_API_H
|
||
|
+ case PGPHASHALGO_SHA256:
|
||
|
+ return 32;
|
||
|
+ case PGPHASHALGO_SHA384:
|
||
|
+ return 48;
|
||
|
+ case PGPHASHALGO_SHA512:
|
||
|
+ return 64;
|
||
|
+#endif
|
||
|
+ default:
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+DIGEST_CTX
|
||
|
+rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
|
||
|
+{
|
||
|
+ DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
|
||
|
+ int xx;
|
||
|
+
|
||
|
+ ctx->flags = flags;
|
||
|
+
|
||
|
+ switch (hashalgo) {
|
||
|
+ case PGPHASHALGO_MD5:
|
||
|
+ ctx->digestlen = 16;
|
||
|
+ ctx->datalen = 64;
|
||
|
+ ctx->paramlen = sizeof(md5Param);
|
||
|
+ ctx->param = xcalloc(1, ctx->paramlen);
|
||
|
+ ctx->Reset = (void *) md5Reset;
|
||
|
+ ctx->Update = (void *) md5Update;
|
||
|
+ ctx->Digest = (void *) md5Digest;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA1:
|
||
|
+ ctx->digestlen = 20;
|
||
|
+ ctx->datalen = 64;
|
||
|
+ ctx->paramlen = sizeof(sha1Param);
|
||
|
+ ctx->param = xcalloc(1, ctx->paramlen);
|
||
|
+ ctx->Reset = (void *) sha1Reset;
|
||
|
+ ctx->Update = (void *) sha1Update;
|
||
|
+ ctx->Digest = (void *) sha1Digest;
|
||
|
+ break;
|
||
|
+#if HAVE_BEECRYPT_API_H
|
||
|
+ case PGPHASHALGO_SHA256:
|
||
|
+ ctx->digestlen = 32;
|
||
|
+ ctx->datalen = 64;
|
||
|
+ ctx->paramlen = sizeof(sha256Param);
|
||
|
+ ctx->param = xcalloc(1, ctx->paramlen);
|
||
|
+ ctx->Reset = (void *) sha256Reset;
|
||
|
+ ctx->Update = (void *) sha256Update;
|
||
|
+ ctx->Digest = (void *) sha256Digest;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA384:
|
||
|
+ ctx->digestlen = 48;
|
||
|
+ ctx->datalen = 128;
|
||
|
+ ctx->paramlen = sizeof(sha384Param);
|
||
|
+ ctx->param = xcalloc(1, ctx->paramlen);
|
||
|
+ ctx->Reset = (void *) sha384Reset;
|
||
|
+ ctx->Update = (void *) sha384Update;
|
||
|
+ ctx->Digest = (void *) sha384Digest;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA512:
|
||
|
+ ctx->digestlen = 64;
|
||
|
+ ctx->datalen = 128;
|
||
|
+ ctx->paramlen = sizeof(sha512Param);
|
||
|
+ ctx->param = xcalloc(1, ctx->paramlen);
|
||
|
+ ctx->Reset = (void *) sha512Reset;
|
||
|
+ ctx->Update = (void *) sha512Update;
|
||
|
+ ctx->Digest = (void *) sha512Digest;
|
||
|
+ break;
|
||
|
+#endif
|
||
|
+ case PGPHASHALGO_RIPEMD160:
|
||
|
+ case PGPHASHALGO_MD2:
|
||
|
+ case PGPHASHALGO_TIGER192:
|
||
|
+ case PGPHASHALGO_HAVAL_5_160:
|
||
|
+ default:
|
||
|
+ free(ctx);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ xx = (*ctx->Reset) (ctx->param);
|
||
|
+
|
||
|
+DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
|
||
|
+ return ctx;
|
||
|
+}
|
||
|
+
|
||
|
+/* LCL: ctx->param may be modified, but ctx is abstract @*/
|
||
|
+int
|
||
|
+rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
|
||
|
+{
|
||
|
+ if (ctx == NULL)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data)));
|
||
|
+ return (*ctx->Update) (ctx->param, data, len);
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
|
||
|
+{
|
||
|
+ byte * digest;
|
||
|
+ char * t;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ if (ctx == NULL)
|
||
|
+ return -1;
|
||
|
+ digest = xmalloc(ctx->digestlen);
|
||
|
+
|
||
|
+DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest));
|
||
|
+ /* FIX: check rc */
|
||
|
+ (void) (*ctx->Digest) (ctx->param, digest);
|
||
|
+
|
||
|
+ /* Return final digest. */
|
||
|
+ if (!asAscii) {
|
||
|
+ if (lenp) *lenp = ctx->digestlen;
|
||
|
+ if (datap) {
|
||
|
+ *datap = digest;
|
||
|
+ digest = NULL;
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ if (lenp) *lenp = (2*ctx->digestlen) + 1;
|
||
|
+ if (datap) {
|
||
|
+ const byte * s = (const byte *) digest;
|
||
|
+ static const char hex[] = "0123456789abcdef";
|
||
|
+
|
||
|
+ *datap = t = xmalloc((2*ctx->digestlen) + 1);
|
||
|
+ for (i = 0 ; i < ctx->digestlen; i++) {
|
||
|
+ *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
|
||
|
+ *t++ = hex[ (unsigned)((*s++ ) & 0x0f) ];
|
||
|
+ }
|
||
|
+ *t = '\0';
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if (digest) {
|
||
|
+ memset(digest, 0, ctx->digestlen); /* In case it's sensitive */
|
||
|
+ free(digest);
|
||
|
+ }
|
||
|
+ memset(ctx->param, 0, ctx->paramlen); /* In case it's sensitive */
|
||
|
+ free(ctx->param);
|
||
|
+ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||
|
+ free(ctx);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
--- ./rpmio/digest_nss.c.orig 2009-08-20 13:47:03.000000000 +0000
|
||
|
+++ ./rpmio/digest_nss.c 2009-08-20 13:49:53.000000000 +0000
|
||
|
@@ -0,0 +1,513 @@
|
||
|
+#include <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;
|
||
|
+}
|
||
|
+
|
||
|
+/****************************** RSA **************************************/
|
||
|
+
|
||
|
+int
|
||
|
+pgpSetSigMpiRSA(struct pgpDig_s *dig, int num, const uint8_t *p, const uint8_t *pend)
|
||
|
+{
|
||
|
+ SECItem *sig;
|
||
|
+
|
||
|
+ if (num != 0)
|
||
|
+ return 1;
|
||
|
+ sig = dig->rsasig;
|
||
|
+ sig = pgpMpiItem(NULL, sig, p);
|
||
|
+ dig->rsasig = sig;
|
||
|
+ if (sig == NULL)
|
||
|
+ return 1;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+pgpSetPubMpiRSA(struct pgpDig_s *dig, int num, const uint8_t *p, const uint8_t *pend)
|
||
|
+{
|
||
|
+ SECKEYPublicKey *pub;
|
||
|
+
|
||
|
+ if (!dig->rsa)
|
||
|
+ dig->rsa = pgpNewPublicKey(rsaKey);
|
||
|
+ pub = dig->rsa;
|
||
|
+ if (!pub)
|
||
|
+ return 1;
|
||
|
+ switch(num) {
|
||
|
+ case 0:
|
||
|
+ pgpMpiItem(dig->rsa->arena, &pub->u.rsa.modulus, p);
|
||
|
+ return 0;
|
||
|
+ case 1:
|
||
|
+ pgpMpiItem(dig->rsa->arena, &pub->u.rsa.publicExponent, p);
|
||
|
+ return 0;
|
||
|
+ default:
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void pgpCleanRSA(pgpDig dig)
|
||
|
+{
|
||
|
+ if (!dig)
|
||
|
+ return;
|
||
|
+ if (dig->rsa) {
|
||
|
+ SECKEY_DestroyPublicKey(dig->rsa);
|
||
|
+ dig->rsa = NULL;
|
||
|
+ }
|
||
|
+ if (dig->rsasig) {
|
||
|
+ SECITEM_ZfreeItem(dig->rsasig, PR_TRUE);
|
||
|
+ dig->rsasig = NULL;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+int pgpVerifyRSA(pgpDig dig)
|
||
|
+{
|
||
|
+ SECOidTag sigalg;
|
||
|
+ SECItem digest;
|
||
|
+ SECItem *sig;
|
||
|
+ size_t siglen;
|
||
|
+ int res;
|
||
|
+
|
||
|
+ switch (dig->hash_algo) {
|
||
|
+ case PGPHASHALGO_MD5:
|
||
|
+ sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA1:
|
||
|
+ sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_MD2:
|
||
|
+ sigalg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA256:
|
||
|
+ sigalg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA384:
|
||
|
+ sigalg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA512:
|
||
|
+ sigalg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
|
||
|
+ break;
|
||
|
+ /* fallthrough for unsupported / unknown types */
|
||
|
+ default:
|
||
|
+ sigalg = SEC_OID_UNKNOWN;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ digest.type = siBuffer;
|
||
|
+ digest.data = dig->md5;
|
||
|
+ digest.len = dig->md5len;
|
||
|
+
|
||
|
+ sig = dig->rsasig;
|
||
|
+ siglen = SECKEY_SignatureLen(dig->rsa);
|
||
|
+
|
||
|
+ /* Zero-pad signature data up to expected size if necessary */
|
||
|
+ if (siglen > sig->len) {
|
||
|
+ size_t pad = siglen - sig->len;
|
||
|
+ if ((sig = SECITEM_AllocItem(NULL, NULL, siglen)) == NULL) {
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ memset(sig->data, 0, pad);
|
||
|
+ memcpy(sig->data+pad, dig->rsasig->data, dig->rsasig->len);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (VFY_VerifyDigest(&digest, dig->rsa, sig, sigalg, NULL) == SECSuccess)
|
||
|
+ res = 0;
|
||
|
+ else
|
||
|
+ res = 1;
|
||
|
+
|
||
|
+ if (sig != dig->rsasig) {
|
||
|
+ SECITEM_ZfreeItem(sig, 1);
|
||
|
+ }
|
||
|
+ return res;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+/****************************** DSA **************************************/
|
||
|
+
|
||
|
+int
|
||
|
+pgpSetSigMpiDSA(struct pgpDig_s *dig, int num, const uint8_t *p, const uint8_t *pend)
|
||
|
+{
|
||
|
+ SECItem *sig, *new;
|
||
|
+
|
||
|
+ switch(num) {
|
||
|
+ case 0:
|
||
|
+ sig = SECITEM_AllocItem(NULL, NULL, 2*DSA_SUBPRIME_LEN);
|
||
|
+ dig->dsasig = sig;
|
||
|
+ memset(sig->data, 0, 2*DSA_SUBPRIME_LEN);
|
||
|
+ pgpMpiSet(DSA_SUBPRIME_LEN*8, sig->data, p, pend);
|
||
|
+ return 0;
|
||
|
+ case 1:
|
||
|
+ sig = dig->dsasig;
|
||
|
+ if (!sig)
|
||
|
+ return 1;
|
||
|
+ pgpMpiSet(DSA_SUBPRIME_LEN*8, sig->data + DSA_SUBPRIME_LEN, p, pend);
|
||
|
+ new = SECITEM_AllocItem(NULL, NULL, 0);
|
||
|
+ if (!new)
|
||
|
+ return 1;
|
||
|
+ if (DSAU_EncodeDerSig(new, sig) != SECSuccess)
|
||
|
+ return 1;
|
||
|
+ SECITEM_FreeItem(sig, PR_TRUE);
|
||
|
+ dig->dsasig = new;
|
||
|
+ return 0;
|
||
|
+ default:
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+pgpSetPubMpiDSA(struct pgpDig_s *dig, int num, const uint8_t *p, const uint8_t *pend)
|
||
|
+{
|
||
|
+ SECKEYPublicKey *pub;
|
||
|
+
|
||
|
+ if (!dig->dsa)
|
||
|
+ dig->dsa = pgpNewPublicKey(dsaKey);
|
||
|
+ pub = dig->dsa;
|
||
|
+ if (!pub)
|
||
|
+ return 1;
|
||
|
+ switch(num) {
|
||
|
+ case 0:
|
||
|
+ pgpMpiItem(pub->arena, &pub->u.dsa.params.prime, p);
|
||
|
+ return 0;
|
||
|
+ case 1:
|
||
|
+ pgpMpiItem(pub->arena, &pub->u.dsa.params.subPrime, p);
|
||
|
+ return 0;
|
||
|
+ case 2:
|
||
|
+ pgpMpiItem(pub->arena, &pub->u.dsa.params.base, p);
|
||
|
+ return 0;
|
||
|
+ case 3:
|
||
|
+ pgpMpiItem(pub->arena, &pub->u.dsa.publicValue, p);
|
||
|
+ return 0;
|
||
|
+ default:
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void pgpCleanDSA(pgpDig dig)
|
||
|
+{
|
||
|
+ if (!dig)
|
||
|
+ return;
|
||
|
+ if (dig->dsa) {
|
||
|
+ SECKEY_DestroyPublicKey(dig->dsa);
|
||
|
+ dig->dsa = NULL;
|
||
|
+ }
|
||
|
+ if (dig->dsasig) {
|
||
|
+ SECITEM_ZfreeItem(dig->dsasig, PR_TRUE);
|
||
|
+ dig->dsasig = NULL;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+int pgpVerifyDSA(pgpDig dig)
|
||
|
+{
|
||
|
+ SECItem digest;
|
||
|
+
|
||
|
+ digest.type = siBuffer;
|
||
|
+ digest.data = dig->sha1;
|
||
|
+ digest.len = dig->sha1len;
|
||
|
+ if (VFY_VerifyDigest(&digest, dig->dsa, dig->dsasig, SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST, NULL) == SECSuccess)
|
||
|
+ return 0;
|
||
|
+ else
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+/**************************** digest ************************************/
|
||
|
+
|
||
|
+
|
||
|
+#ifdef SHA_DEBUG
|
||
|
+#define DPRINTF(_a) fprintf _a
|
||
|
+#else
|
||
|
+#define DPRINTF(_a)
|
||
|
+#endif
|
||
|
+
|
||
|
+
|
||
|
+/**
|
||
|
+ * MD5/SHA1 digest private data.
|
||
|
+ */
|
||
|
+struct DIGEST_CTX_s {
|
||
|
+ rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */
|
||
|
+ HASHContext *hashctx; /*!< Internal NSS hash context. */
|
||
|
+};
|
||
|
+
|
||
|
+DIGEST_CTX
|
||
|
+rpmDigestDup(DIGEST_CTX octx)
|
||
|
+{
|
||
|
+ DIGEST_CTX nctx;
|
||
|
+ nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
|
||
|
+ nctx->hashctx = HASH_Clone(octx->hashctx);
|
||
|
+ if (nctx->hashctx == NULL) {
|
||
|
+ fprintf(stderr, "HASH_Clone failed\n");
|
||
|
+ exit(EXIT_FAILURE); /* FIX: callers do not bother checking error return */
|
||
|
+ }
|
||
|
+ return nctx;
|
||
|
+}
|
||
|
+
|
||
|
+RPM_GNUC_PURE
|
||
|
+static HASH_HashType getHashType(pgpHashAlgo hashalgo)
|
||
|
+{
|
||
|
+ switch (hashalgo) {
|
||
|
+ case PGPHASHALGO_MD5:
|
||
|
+ return HASH_AlgMD5;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_MD2:
|
||
|
+ return HASH_AlgMD2;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA1:
|
||
|
+ return HASH_AlgSHA1;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA256:
|
||
|
+ return HASH_AlgSHA256;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA384:
|
||
|
+ return HASH_AlgSHA384;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_SHA512:
|
||
|
+ return HASH_AlgSHA512;
|
||
|
+ break;
|
||
|
+ case PGPHASHALGO_RIPEMD160:
|
||
|
+ case PGPHASHALGO_TIGER192:
|
||
|
+ case PGPHASHALGO_HAVAL_5_160:
|
||
|
+ default:
|
||
|
+ return HASH_AlgNULL;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+size_t
|
||
|
+rpmDigestLength(pgpHashAlgo hashalgo)
|
||
|
+{
|
||
|
+ return HASH_ResultLen(getHashType(hashalgo));
|
||
|
+}
|
||
|
+
|
||
|
+DIGEST_CTX
|
||
|
+rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
|
||
|
+{
|
||
|
+ HASH_HashType type;
|
||
|
+ DIGEST_CTX ctx;
|
||
|
+
|
||
|
+ if (rpmInitCrypto() < 0)
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ ctx = xcalloc(1, sizeof(*ctx));
|
||
|
+ ctx->flags = flags;
|
||
|
+
|
||
|
+ type = getHashType(hashalgo);
|
||
|
+ if (type == HASH_AlgNULL) {
|
||
|
+ free(ctx);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ ctx->hashctx = HASH_Create(type);
|
||
|
+ if (ctx->hashctx == NULL) {
|
||
|
+ free(ctx);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ HASH_Begin(ctx->hashctx);
|
||
|
+
|
||
|
+DPRINTF((stderr, "*** Init(%x) ctx %p hashctx %p\n", flags, ctx, ctx->hashctx));
|
||
|
+ return ctx;
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
|
||
|
+{
|
||
|
+ size_t partlen;
|
||
|
+ const unsigned char *ptr = data;
|
||
|
+
|
||
|
+ if (ctx == NULL)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+DPRINTF((stderr, "*** Update(%p,%p,%zd) hashctx %p \"%s\"\n", ctx, data, len, ctx->hashctx, ((char *)data)));
|
||
|
+ partlen = ~(unsigned int)0xFF;
|
||
|
+ while (len > 0) {
|
||
|
+ if (len < partlen) {
|
||
|
+ partlen = len;
|
||
|
+ }
|
||
|
+ HASH_Update(ctx->hashctx, ptr, partlen);
|
||
|
+ ptr += partlen;
|
||
|
+ len -= partlen;
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
|
||
|
+{
|
||
|
+ unsigned char * digest;
|
||
|
+ unsigned int digestlen;
|
||
|
+
|
||
|
+ if (ctx == NULL)
|
||
|
+ return -1;
|
||
|
+ digestlen = HASH_ResultLenContext(ctx->hashctx);
|
||
|
+ digest = xmalloc(digestlen);
|
||
|
+
|
||
|
+DPRINTF((stderr, "*** Final(%p,%p,%p,%zd) hashctx %p digest %p\n", ctx, datap, lenp, asAscii, ctx->hashctx, digest));
|
||
|
+/* FIX: check rc */
|
||
|
+ HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen);
|
||
|
+
|
||
|
+ /* Return final digest. */
|
||
|
+ if (!asAscii) {
|
||
|
+ if (lenp) *lenp = digestlen;
|
||
|
+ if (datap) {
|
||
|
+ *datap = digest;
|
||
|
+ digest = NULL;
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ if (lenp) *lenp = (2*digestlen) + 1;
|
||
|
+ if (datap) {
|
||
|
+ const uint8_t * s = (const uint8_t *) digest;
|
||
|
+ *datap = pgpHexStr(s, digestlen);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if (digest) {
|
||
|
+ memset(digest, 0, digestlen); /* In case it's sensitive */
|
||
|
+ free(digest);
|
||
|
+ }
|
||
|
+ HASH_Destroy(ctx->hashctx);
|
||
|
+ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||
|
+ free(ctx);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
--- ./rpmio/rpmpgp.c.orig 2009-06-23 11:40:59.000000000 +0000
|
||
|
+++ ./rpmio/rpmpgp.c 2009-08-20 13:50:14.000000000 +0000
|
||
|
@@ -20,9 +20,6 @@ static int _debug = 0;
|
||
|
|
||
|
static int _print = 0;
|
||
|
|
||
|
-static int _crypto_initialized = 0;
|
||
|
-static int _new_process = 1;
|
||
|
-
|
||
|
static struct pgpValTbl_s const pgpSigTypeTbl[] = {
|
||
|
{ PGPSIGTYPE_BINARY, "Binary document signature" },
|
||
|
{ PGPSIGTYPE_TEXT, "Text document signature" },
|
||
|
@@ -291,99 +288,6 @@ int pgpValTok(pgpValTbl vs, const char *
|
||
|
} while ((++vs)->val != -1);
|
||
|
return vs->val;
|
||
|
}
|
||
|
-/**
|
||
|
- * @return 0 on success
|
||
|
- */
|
||
|
-static int pgpMpiSet(const char * pre, unsigned int lbits,
|
||
|
- void *dest, const uint8_t * p, const uint8_t * pend)
|
||
|
-{
|
||
|
- unsigned int mbits = pgpMpiBits(p);
|
||
|
- unsigned int nbits;
|
||
|
- size_t nbytes;
|
||
|
- char *t = dest;
|
||
|
- unsigned int ix;
|
||
|
-
|
||
|
- if ((p + ((mbits+7) >> 3)) > pend)
|
||
|
- return 1;
|
||
|
-
|
||
|
- if (mbits > lbits)
|
||
|
- return 1;
|
||
|
-
|
||
|
- nbits = (lbits > mbits ? lbits : mbits);
|
||
|
- nbytes = ((nbits + 7) >> 3);
|
||
|
- ix = (nbits - mbits) >> 3;
|
||
|
-
|
||
|
-if (_debug)
|
||
|
-fprintf(stderr, "*** mbits %u nbits %u nbytes %zu ix %u\n", mbits, nbits, nbytes, ix);
|
||
|
- if (ix > 0) memset(t, '\0', ix);
|
||
|
- memcpy(t+ix, p+2, nbytes-ix);
|
||
|
-if (_debug)
|
||
|
-fprintf(stderr, "*** %s %s\n", pre, pgpHexStr(dest, nbytes));
|
||
|
-
|
||
|
- return 0;
|
||
|
-}
|
||
|
-
|
||
|
-/**
|
||
|
- * @return NULL on error
|
||
|
- */
|
||
|
-static SECItem *pgpMpiItem(PRArenaPool *arena, SECItem *item, const uint8_t *p)
|
||
|
-{
|
||
|
- size_t nbytes = pgpMpiLen(p)-2;
|
||
|
-
|
||
|
- if (item == NULL) {
|
||
|
- if ((item=SECITEM_AllocItem(arena, item, nbytes)) == NULL)
|
||
|
- return item;
|
||
|
- } else {
|
||
|
- if (arena != NULL)
|
||
|
- item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes);
|
||
|
- else
|
||
|
- item->data = PORT_Realloc(item->data, nbytes);
|
||
|
-
|
||
|
- if (item->data == NULL) {
|
||
|
- if (arena == NULL)
|
||
|
- SECITEM_FreeItem(item, PR_TRUE);
|
||
|
- return NULL;
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
- memcpy(item->data, p+2, nbytes);
|
||
|
- item->len = nbytes;
|
||
|
- return item;
|
||
|
-}
|
||
|
-/*@=boundswrite@*/
|
||
|
-
|
||
|
-static SECKEYPublicKey *pgpNewPublicKey(KeyType type)
|
||
|
-{
|
||
|
- PRArenaPool *arena;
|
||
|
- SECKEYPublicKey *key;
|
||
|
-
|
||
|
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||
|
- if (arena == NULL)
|
||
|
- return NULL;
|
||
|
-
|
||
|
- key = PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
|
||
|
-
|
||
|
- if (key == NULL) {
|
||
|
- PORT_FreeArena(arena, PR_FALSE);
|
||
|
- return NULL;
|
||
|
- }
|
||
|
-
|
||
|
- key->keyType = type;
|
||
|
- key->pkcs11ID = CK_INVALID_HANDLE;
|
||
|
- key->pkcs11Slot = NULL;
|
||
|
- key->arena = arena;
|
||
|
- return key;
|
||
|
-}
|
||
|
-
|
||
|
-static SECKEYPublicKey *pgpNewRSAKey(void)
|
||
|
-{
|
||
|
- return pgpNewPublicKey(rsaKey);
|
||
|
-}
|
||
|
-
|
||
|
-static SECKEYPublicKey *pgpNewDSAKey(void)
|
||
|
-{
|
||
|
- return pgpNewPublicKey(dsaKey);
|
||
|
-}
|
||
|
|
||
|
/** \ingroup rpmpgp
|
||
|
* Is buffer at beginning of an OpenPGP packet?
|
||
|
@@ -579,29 +483,16 @@ static int pgpPrtSigParams(pgpTag tag, u
|
||
|
{
|
||
|
const uint8_t * pend = h + hlen;
|
||
|
size_t i;
|
||
|
- SECItem dsaraw;
|
||
|
- unsigned char dsabuf[2*DSA_SUBPRIME_LEN];
|
||
|
char *mpi;
|
||
|
|
||
|
- dsaraw.type = 0;
|
||
|
- dsaraw.data = dsabuf;
|
||
|
- dsaraw.len = sizeof(dsabuf);
|
||
|
-
|
||
|
for (i = 0; p < pend; i++, p += pgpMpiLen(p)) {
|
||
|
if (pubkey_algo == PGPPUBKEYALGO_RSA) {
|
||
|
if (i >= 1) break;
|
||
|
if (_dig &&
|
||
|
(sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
|
||
|
{
|
||
|
- switch (i) {
|
||
|
- case 0: /* m**d */
|
||
|
- _dig->rsasig = pgpMpiItem(NULL, _dig->rsasig, p);
|
||
|
- if (_dig->rsasig == NULL)
|
||
|
- return 1;
|
||
|
- break;
|
||
|
- default:
|
||
|
- break;
|
||
|
- }
|
||
|
+ if (pgpSetSigMpiRSA(_dig, i, p))
|
||
|
+ return 1;
|
||
|
}
|
||
|
pgpPrtStr("", pgpSigRSA[i]);
|
||
|
} else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
|
||
|
@@ -609,30 +500,8 @@ static int pgpPrtSigParams(pgpTag tag, u
|
||
|
if (_dig &&
|
||
|
(sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT))
|
||
|
{
|
||
|
- int xx;
|
||
|
- xx = 0;
|
||
|
- switch (i) {
|
||
|
- case 0:
|
||
|
- memset(dsaraw.data, '\0', 2*DSA_SUBPRIME_LEN);
|
||
|
- /* r */
|
||
|
- xx = pgpMpiSet(pgpSigDSA[i], DSA_SUBPRIME_LEN*8, dsaraw.data, p, pend);
|
||
|
- break;
|
||
|
- case 1: /* s */
|
||
|
- xx = pgpMpiSet(pgpSigDSA[i], DSA_SUBPRIME_LEN*8, dsaraw.data + DSA_SUBPRIME_LEN, p, pend);
|
||
|
- if (_dig->dsasig != NULL)
|
||
|
- SECITEM_FreeItem(_dig->dsasig, PR_FALSE);
|
||
|
- else if ((_dig->dsasig=SECITEM_AllocItem(NULL, NULL, 0)) == NULL) {
|
||
|
- xx = 1;
|
||
|
- break;
|
||
|
- }
|
||
|
- if (DSAU_EncodeDerSig(_dig->dsasig, &dsaraw) != SECSuccess)
|
||
|
- xx = 1;
|
||
|
- break;
|
||
|
- default:
|
||
|
- xx = 1;
|
||
|
- break;
|
||
|
- }
|
||
|
- if (xx) return xx;
|
||
|
+ if (pgpSetSigMpiDSA(_dig, i, p))
|
||
|
+ return 1;
|
||
|
}
|
||
|
pgpPrtStr("", pgpSigDSA[i]);
|
||
|
} else {
|
||
|
@@ -824,49 +693,11 @@ static const uint8_t * pgpPrtPubkeyParam
|
||
|
char * mpi;
|
||
|
if (pubkey_algo == PGPPUBKEYALGO_RSA) {
|
||
|
if (i >= 2) break;
|
||
|
- if (_dig) {
|
||
|
- if (_dig->rsa == NULL) {
|
||
|
- _dig->rsa = pgpNewRSAKey();
|
||
|
- if (_dig->rsa == NULL)
|
||
|
- break; /* error abort? */
|
||
|
- }
|
||
|
- switch (i) {
|
||
|
- case 0: /* n */
|
||
|
- pgpMpiItem(_dig->rsa->arena, &_dig->rsa->u.rsa.modulus, p);
|
||
|
- break;
|
||
|
- case 1: /* e */
|
||
|
- pgpMpiItem(_dig->rsa->arena, &_dig->rsa->u.rsa.publicExponent, p);
|
||
|
- break;
|
||
|
- default:
|
||
|
- break;
|
||
|
- }
|
||
|
- }
|
||
|
+ pgpSetPubMpiRSA(_dig, i, p);
|
||
|
pgpPrtStr("", pgpPublicRSA[i]);
|
||
|
} else if (pubkey_algo == PGPPUBKEYALGO_DSA) {
|
||
|
if (i >= 4) break;
|
||
|
- if (_dig) {
|
||
|
- if (_dig->dsa == NULL) {
|
||
|
- _dig->dsa = pgpNewDSAKey();
|
||
|
- if (_dig->dsa == NULL)
|
||
|
- break; /* error abort? */
|
||
|
- }
|
||
|
- switch (i) {
|
||
|
- case 0: /* p */
|
||
|
- pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.params.prime, p);
|
||
|
- break;
|
||
|
- case 1: /* q */
|
||
|
- pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.params.subPrime, p);
|
||
|
- break;
|
||
|
- case 2: /* g */
|
||
|
- pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.params.base, p);
|
||
|
- break;
|
||
|
- case 3: /* y */
|
||
|
- pgpMpiItem(_dig->dsa->arena, &_dig->dsa->u.dsa.publicValue, p);
|
||
|
- break;
|
||
|
- default:
|
||
|
- break;
|
||
|
- }
|
||
|
- }
|
||
|
+ pgpSetPubMpiDSA(_dig, i, p);
|
||
|
pgpPrtStr("", pgpPublicDSA[i]);
|
||
|
} else if (pubkey_algo == PGPPUBKEYALGO_ELGAMAL_ENCRYPT) {
|
||
|
if (i >= 3) break;
|
||
|
@@ -1256,25 +1087,8 @@ void pgpCleanDig(pgpDig dig)
|
||
|
dig->md5 = _free(dig->md5);
|
||
|
dig->sha1 = _free(dig->sha1);
|
||
|
|
||
|
- if (dig->dsa != NULL) {
|
||
|
- SECKEY_DestroyPublicKey(dig->dsa);
|
||
|
- dig->dsa = NULL;
|
||
|
- }
|
||
|
-
|
||
|
- if (dig->dsasig != NULL) {
|
||
|
- SECITEM_ZfreeItem(dig->dsasig, PR_TRUE);
|
||
|
- dig->dsasig = NULL;
|
||
|
- }
|
||
|
-
|
||
|
- if (dig->rsa != NULL) {
|
||
|
- SECKEY_DestroyPublicKey(dig->rsa);
|
||
|
- dig->rsa = NULL;
|
||
|
- }
|
||
|
-
|
||
|
- if (dig->rsasig != NULL) {
|
||
|
- SECITEM_ZfreeItem(dig->rsasig, PR_TRUE);
|
||
|
- dig->rsasig = NULL;
|
||
|
- }
|
||
|
+ pgpCleanRSA(dig);
|
||
|
+ pgpCleanDSA(dig);
|
||
|
|
||
|
}
|
||
|
return;
|
||
|
@@ -1501,50 +1315,3 @@ char * pgpArmorWrap(int atype, const uns
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
-/*
|
||
|
- * Only flag for re-initialization here, in the common case the child
|
||
|
- * exec()'s something else shutting down NSS here would be waste of time.
|
||
|
- */
|
||
|
-static void at_forkchild(void)
|
||
|
-{
|
||
|
- _new_process = 1;
|
||
|
-}
|
||
|
-
|
||
|
-int rpmInitCrypto(void) {
|
||
|
- int rc = 0;
|
||
|
-
|
||
|
- /* Lazy NSS shutdown for re-initialization after fork() */
|
||
|
- if (_new_process && _crypto_initialized) {
|
||
|
- rpmFreeCrypto();
|
||
|
- }
|
||
|
-
|
||
|
- /* Initialize NSS if not already done */
|
||
|
- if (!_crypto_initialized) {
|
||
|
- if (NSS_NoDB_Init(NULL) != SECSuccess) {
|
||
|
- rc = -1;
|
||
|
- } else {
|
||
|
- _crypto_initialized = 1;
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
- /* Register one post-fork handler per process */
|
||
|
- if (_new_process) {
|
||
|
- if (pthread_atfork(NULL, NULL, at_forkchild) != 0) {
|
||
|
- rpmlog(RPMLOG_WARNING, _("Failed to register fork handler: %m\n"));
|
||
|
- }
|
||
|
- _new_process = 0;
|
||
|
- }
|
||
|
- return rc;
|
||
|
-}
|
||
|
-
|
||
|
-int rpmFreeCrypto(void)
|
||
|
-{
|
||
|
- int rc = 0;
|
||
|
- if (_crypto_initialized) {
|
||
|
- rc = (NSS_Shutdown() != SECSuccess);
|
||
|
- _crypto_initialized = 0;
|
||
|
- }
|
||
|
- return rc;
|
||
|
-}
|
||
|
-
|
||
|
-
|