2012-08-28 15:31:44 +02:00
|
|
|
--- ./config.h.in.orig 2012-05-22 10:55:46.000000000 +0000
|
|
|
|
+++ ./config.h.in 2012-05-31 16:41:07.000000000 +0000
|
2009-08-28 15:54:03 +02:00
|
|
|
@@ -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
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
/* Define to 1 if you have the <bzlib.h> header file. */
|
|
|
|
#undef HAVE_BZLIB_H
|
2009-08-28 15:54:03 +02:00
|
|
|
|
2012-08-28 15:31:44 +02:00
|
|
|
@@ -206,6 +209,10 @@
|
2009-08-28 15:54:03 +02:00
|
|
|
*/
|
|
|
|
#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
|
2012-08-28 15:31:44 +02:00
|
|
|
@@ -290,6 +297,9 @@
|
2009-08-28 15:54:03 +02:00
|
|
|
/* Build with acl support? */
|
|
|
|
#undef WITH_ACL
|
|
|
|
|
|
|
|
+/* Build with beecrypt instead of nss3 support? */
|
|
|
|
+#undef WITH_BEECRYPT
|
|
|
|
+
|
|
|
|
/* Build with capability support? */
|
|
|
|
#undef WITH_CAP
|
|
|
|
|
2012-08-28 15:31:44 +02:00
|
|
|
--- ./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], [
|
2009-08-28 15:54:03 +02:00
|
|
|
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])
|
|
|
|
])
|
2012-08-28 15:31:44 +02:00
|
|
|
@@ -253,6 +284,7 @@ AC_CHECK_LIB(nss3, NSS_NoDB_Init, [
|
2009-08-28 15:54:03 +02:00
|
|
|
], [
|
|
|
|
AC_MSG_ERROR([missing required NSS library 'nss3'])
|
|
|
|
])
|
|
|
|
+fi
|
|
|
|
AC_SUBST(WITH_NSS_INCLUDE)
|
|
|
|
AC_SUBST(WITH_NSS_LIB)
|
|
|
|
|
2012-08-28 15:31:44 +02:00
|
|
|
--- ./rpmio/Makefile.am.orig 2012-03-20 08:07:25.000000000 +0000
|
|
|
|
+++ ./rpmio/Makefile.am 2012-05-31 16:39:58.000000000 +0000
|
2009-08-28 15:54:03 +02:00
|
|
|
@@ -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
|
2011-07-19 15:04:21 +02:00
|
|
|
AM_CPPFLAGS += -DRPMCONFIGDIR="\"@RPMCONFIGDIR@\""
|
2012-08-28 15:31:44 +02:00
|
|
|
@@ -17,12 +18,18 @@ librpmio_la_SOURCES = \
|
2009-08-28 15:54:03 +02:00
|
|
|
rpmstring.c rpmfileutil.c \
|
|
|
|
rpmkeyring.c
|
|
|
|
|
|
|
|
+if WITH_BEECRYPT
|
|
|
|
+librpmio_la_SOURCES += digest_beecrypt.c
|
|
|
|
+else
|
2012-08-28 15:31:44 +02:00
|
|
|
librpmio_la_SOURCES += digest_nss.c
|
2009-08-28 15:54:03 +02:00
|
|
|
+endif
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
|
|
|
|
librpmio_la_LDFLAGS = -version-info 3:0:0
|
2009-08-28 15:54:03 +02:00
|
|
|
librpmio_la_LIBADD = \
|
|
|
|
../misc/libmisc.la \
|
|
|
|
@WITH_NSS_LIB@ \
|
|
|
|
+ @WITH_BEECRYPT_LIB@ \
|
|
|
|
@WITH_BZ2_LIB@ \
|
|
|
|
@WITH_ZLIB_LIB@ \
|
2011-07-19 15:04:21 +02:00
|
|
|
@WITH_LIBELF_LIB@ \
|
2012-08-28 15:31:44 +02:00
|
|
|
@@ -30,6 +37,15 @@ librpmio_la_LIBADD = \
|
2009-08-28 15:54:03 +02:00
|
|
|
@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
|
|
|
|
+
|
2011-07-19 15:04:21 +02:00
|
|
|
if WITH_LUA
|
2010-03-26 11:56:28 +01:00
|
|
|
AM_CPPFLAGS += -I$(top_srcdir)/luaext/
|
2011-07-19 15:04:21 +02:00
|
|
|
AM_CPPFLAGS += @LUA_CFLAGS@
|
2012-08-28 15:31:44 +02:00
|
|
|
--- ./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 @@
|
2009-08-28 15:54:03 +02:00
|
|
|
+#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"
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+/**
|
|
|
|
+ * 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. */
|
|
|
|
+};
|
|
|
|
+
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
|
|
|
+/**************************** init ************************************/
|
|
|
|
+
|
|
|
|
+int rpmInitCrypto(void) {
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int rpmFreeCrypto(void) {
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+/**************************** 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;
|
|
|
|
+}
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+int rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ if (ctx == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ return (*ctx->Update) (ctx->param, data, len);
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ 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;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+/**************************** helpers ************************************/
|
|
|
|
+
|
2009-08-28 15:54:03 +02:00
|
|
|
+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;
|
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static const char * pgpMpiHex(const byte *p, const byte *pend)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
|
|
|
+ static char prbuf[2048];
|
|
|
|
+ char *t = prbuf;
|
2012-08-28 15:31:44 +02:00
|
|
|
+ int nbytes = pgpMpiLen(p) - 2;
|
|
|
|
+ if (nbytes > 1024 || nbytes > pend - (p + 2))
|
|
|
|
+ return NULL;
|
|
|
|
+ t = pgpHexCvt(t, p+2, nbytes);
|
2009-08-28 15:54:03 +02:00
|
|
|
+ return prbuf;
|
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static int pgpHexSet(int lbits, mpnumber * mpn, const byte * p, const byte * pend)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
|
|
|
+ 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);
|
2012-08-28 15:31:44 +02:00
|
|
|
+ strcpy(t+ix, pgpMpiHex(p, pend));
|
2009-08-28 15:54:03 +02:00
|
|
|
+ (void) mpnsethex(mpn, t);
|
|
|
|
+ t = _free(t);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static void pgpFreeSigRSADSA(pgpDigAlg sa)
|
2010-03-26 11:56:28 +01:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ if (sa->data)
|
|
|
|
+ free(sa->data);
|
|
|
|
+ sa->data = 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void pgpFreeKeyRSADSA(pgpDigAlg sa)
|
|
|
|
+{
|
|
|
|
+ if (sa->data)
|
|
|
|
+ free(sa->data);
|
|
|
|
+ sa->data = 0;
|
2010-03-26 11:56:28 +01:00
|
|
|
+}
|
|
|
|
+
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
|
|
|
+/****************************** RSA **************************************/
|
|
|
|
+
|
|
|
|
+struct pgpDigSigRSA_s {
|
|
|
|
+ mpnumber c;
|
|
|
|
+};
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+struct pgpDigKeyRSA_s {
|
2009-08-28 15:54:03 +02:00
|
|
|
+ rsapk rsa_pk;
|
|
|
|
+};
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num,
|
|
|
|
+ const uint8_t *p, const uint8_t *pend)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ 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;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num,
|
|
|
|
+ const uint8_t *p, const uint8_t *pend)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ struct pgpDigKeyRSA_s *key = pgpkey->data;
|
|
|
|
+ int rc = 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ if (!key)
|
|
|
|
+ key = pgpkey->data = xcalloc(1, sizeof(*key));
|
|
|
|
+ switch (num) {
|
2009-08-28 15:54:03 +02:00
|
|
|
+ case 0:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ (void) mpbsethex(&key->rsa_pk.n, pgpMpiHex(p, pend));
|
|
|
|
+ rc = 0;
|
|
|
|
+ break;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ case 1:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ (void) mpnsethex(&key->rsa_pk.e, pgpMpiHex(p, pend));
|
|
|
|
+ rc = 0;
|
|
|
|
+ break;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ }
|
2012-08-28 15:31:44 +02:00
|
|
|
+ return rc;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
|
|
|
+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;
|
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ struct pgpDigKeyRSA_s *key = pgpkey->data;
|
|
|
|
+ struct pgpDigSigRSA_s *sig = pgpsig->data;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ const char * prefix = NULL;
|
|
|
|
+ mpnumber rsahm;
|
2012-08-28 15:31:44 +02:00
|
|
|
+ int rc = 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ if (!sig || !key)
|
|
|
|
+ return rc;
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ switch (hash_algo) {
|
2009-08-28 15:54:03 +02:00
|
|
|
+ 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;
|
2010-03-26 11:56:28 +01:00
|
|
|
+ bp = buf + nb - strlen(prefix)/2 - hashlen - 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ if (bp < buf)
|
|
|
|
+ return 1;
|
|
|
|
+ *bp++ = 0;
|
|
|
|
+ for (; *prefix; prefix += 2)
|
|
|
|
+ *bp++ = (nibble(prefix[0]) << 4) | nibble(prefix[1]);
|
2010-03-26 11:56:28 +01:00
|
|
|
+ memcpy(bp, hash, hashlen);
|
2009-08-28 15:54:03 +02:00
|
|
|
+ mpnzero(&rsahm);
|
|
|
|
+ (void) mpnsetbin(&rsahm, buf, nb);
|
|
|
|
+ buf = _free(buf);
|
|
|
|
+ }
|
|
|
|
+#if HAVE_BEECRYPT_API_H
|
2012-08-28 15:31:44 +02:00
|
|
|
+ rc = rsavrfy(&key->rsa_pk.n, &key->rsa_pk.e, &sig->c, &rsahm) == 1 ? 0 : 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+#else
|
2012-08-28 15:31:44 +02:00
|
|
|
+ rc = rsavrfy(&key->rsa_pk, &rsahm, &sig->c) == 1 ? 0 : 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+#endif
|
|
|
|
+ mpnfree(&rsahm);
|
2012-08-28 15:31:44 +02:00
|
|
|
+ return rc;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/****************************** DSA **************************************/
|
|
|
|
+
|
|
|
|
+struct pgpDigSigDSA_s {
|
|
|
|
+ mpnumber r;
|
|
|
|
+ mpnumber s;
|
|
|
|
+};
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+struct pgpDigKeyDSA_s {
|
2009-08-28 15:54:03 +02:00
|
|
|
+ mpbarrett p;
|
|
|
|
+ mpbarrett q;
|
|
|
|
+ mpnumber g;
|
|
|
|
+ mpnumber y;
|
|
|
|
+};
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num,
|
|
|
|
+ const uint8_t *p, const uint8_t *pend)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ struct pgpDigSigDSA_s *sig = pgpsig->data;
|
|
|
|
+ int rc = 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ switch (num) {
|
2009-08-28 15:54:03 +02:00
|
|
|
+ case 0:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ sig = pgpsig->data = xcalloc(1, sizeof(*sig));
|
|
|
|
+ rc = pgpHexSet(160, &sig->r, p, pend);
|
|
|
|
+ break;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ case 1:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ rc = pgpHexSet(160, &sig->s, p, pend);
|
|
|
|
+ break;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ }
|
2012-08-28 15:31:44 +02:00
|
|
|
+ return rc;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num,
|
|
|
|
+ const uint8_t *p, const uint8_t *pend)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ struct pgpDigKeyDSA_s *key = pgpkey->data;
|
|
|
|
+ int rc = 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ if (!key)
|
|
|
|
+ key = pgpkey->data = xcalloc(1, sizeof(*key));
|
|
|
|
+
|
|
|
|
+ switch (num) {
|
2009-08-28 15:54:03 +02:00
|
|
|
+ case 0:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ mpbsethex(&key->p, pgpMpiHex(p, pend));
|
|
|
|
+ rc = 0;
|
|
|
|
+ break;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ case 1:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ mpbsethex(&key->q, pgpMpiHex(p, pend));
|
|
|
|
+ rc = 0;
|
|
|
|
+ break;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ case 2:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ mpnsethex(&key->g, pgpMpiHex(p, pend));
|
|
|
|
+ rc = 0;
|
|
|
|
+ break;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ case 3:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ mpnsethex(&key->y, pgpMpiHex(p, pend));
|
|
|
|
+ rc = 0;
|
|
|
|
+ break;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ }
|
2012-08-28 15:31:44 +02:00
|
|
|
+ return rc;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ struct pgpDigKeyDSA_s *key = pgpkey->data;
|
|
|
|
+ struct pgpDigSigDSA_s *sig = pgpsig->data;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ mpnumber hm;
|
2012-08-28 15:31:44 +02:00
|
|
|
+ int rc = 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ 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;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num,
|
|
|
|
+ const uint8_t *p, const uint8_t *pend)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ return 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
|
|
|
|
+ uint8_t *hash, size_t hashlen, int hash_algo)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ return 1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+pgpDigAlg pgpPubkeyNew(int algo)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ pgpDigAlg ka = xcalloc(1, sizeof(*ka));;
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ switch (algo) {
|
|
|
|
+ case PGPPUBKEYALGO_RSA:
|
|
|
|
+ ka->setmpi = pgpSetKeyMpiRSA;
|
|
|
|
+ ka->free = pgpFreeKeyRSADSA;
|
|
|
|
+ ka->mpis = 2;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ break;
|
2012-08-28 15:31:44 +02:00
|
|
|
+ case PGPPUBKEYALGO_DSA:
|
|
|
|
+ ka->setmpi = pgpSetKeyMpiDSA;
|
|
|
|
+ ka->free = pgpFreeKeyRSADSA;
|
|
|
|
+ ka->mpis = 4;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ break;
|
|
|
|
+ default:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ ka->setmpi = pgpSetMpiNULL;
|
|
|
|
+ ka->mpis = -1;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ ka->verify = pgpVerifyNULL; /* keys can't be verified */
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ return ka;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+pgpDigAlg pgpSignatureNew(int algo)
|
2009-08-28 15:54:03 +02:00
|
|
|
+{
|
2012-08-28 15:31:44 +02:00
|
|
|
+ pgpDigAlg sa = xcalloc(1, sizeof(*sa));
|
2009-08-28 15:54:03 +02:00
|
|
|
+
|
2012-08-28 15:31:44 +02:00
|
|
|
+ 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;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ default:
|
2012-08-28 15:31:44 +02:00
|
|
|
+ sa->setmpi = pgpSetMpiNULL;
|
|
|
|
+ sa->verify = pgpVerifyNULL;
|
|
|
|
+ sa->mpis = -1;
|
|
|
|
+ break;
|
2009-08-28 15:54:03 +02:00
|
|
|
+ }
|
2012-08-28 15:31:44 +02:00
|
|
|
+ return sa;
|
2009-08-28 15:54:03 +02:00
|
|
|
+}
|