RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: [email protected] Module: rpm Date: 08-Jun-2010 22:44:21 Branch: HEAD Handle: 2010060820441802 Modified files: rpm CHANGES rpm/rpmio rpmssl.c rpmssl.h rpm/tests tecdsa.c trsa.c Log: - ssl: resurrect RSA verification. RSA breaks my brain every time. - ssl: add RSA/DSA sign/generate methods. Summary: Revision Changes Path 1.3381 +2 -0 rpm/CHANGES 2.38 +175 -84 rpm/rpmio/rpmssl.c 2.12 +0 -2 rpm/rpmio/rpmssl.h 1.20 +17 -12 rpm/tests/tecdsa.c 1.29 +165 -17 rpm/tests/trsa.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/CHANGES ============================================================================ $ cvs diff -u -r1.3380 -r1.3381 CHANGES --- rpm/CHANGES 7 Jun 2010 20:24:14 -0000 1.3380 +++ rpm/CHANGES 8 Jun 2010 20:44:18 -0000 1.3381 @@ -1,4 +1,6 @@ 5.3.0 -> 5.4a1: + - jbj: ssl: resurrect RSA verification. RSA breaks my brain every time. + - jbj: ssl: add RSA/DSA sign/generate methods. - jbj: tests: stub-in generate/sign/verify test cases for RSA/DSA. - jbj: bc: use rpmpricrt() for signing, 3x-4x faster. - jbj: bc: resurrect RSA verification. RSA breaks my brain every time. @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmssl.c ============================================================================ $ cvs diff -u -r2.37 -r2.38 rpmssl.c --- rpm/rpmio/rpmssl.c 6 Jun 2010 21:49:41 -0000 2.37 +++ rpm/rpmio/rpmssl.c 8 Jun 2010 20:44:19 -0000 2.38 @@ -34,6 +34,16 @@ extern int _pgp_print; /*...@=redecl@*/ + +/*...@unchecked@*/ +static int _rpmssl_debug; + +#define SPEW(_t, _rc, _dig) \ + { if ((_t) || _rpmssl_debug || _pgp_debug < 0) \ + fprintf(stderr, "<-- %s(%p) %s\t%s\n", __FUNCTION__, (_dig), \ + ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN); \ + } + static const char * _pgpHashAlgo2Name(uint32_t algo) { return pgpValStr(pgpHashTbl, (rpmuint8_t)algo); @@ -62,54 +72,41 @@ return (unsigned char) '\0'; } -/*...@-modfilesys@*/ -static -void hexdump(const char * msg, unsigned char * b, size_t blen) - /*...@*/ -{ - static const char hex[] = "0123456789abcdef"; - - fprintf(stderr, "*** %s:", msg); - if (b != NULL) - while (blen > 0) { - fprintf(stderr, "%c%c", - hex[ (unsigned)((*b >> 4) & 0x0f) ], - hex[ (unsigned)((*b ) & 0x0f) ]); - blen--; - b++; - } - fprintf(stderr, "\n"); - return; -} -/*...@=modfilesys@*/ - static int rpmsslSetRSA(/*...@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) /*...@modifies dig @*/ { rpmssl ssl = dig->impl; - unsigned int nbits = BN_num_bits(ssl->c); - unsigned int nb = (nbits + 7) >> 3; + unsigned int nb = RSA_size(ssl->rsa); const char * prefix = rpmDigestASN1(ctx); const char * hexstr; const char * s; rpmuint8_t signhash16[2]; char * tt; + int rc; int xx; +pgpDigParams pubp = pgpGetPubkey(dig); +dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); +dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); assert(sigp->hash_algo == rpmDigestAlgo(ctx)); if (prefix == NULL) return 1; - xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 1); +/* XXX FIXME: do PKCS1 padding in binary not hex */ +/* XXX FIXME: should this lazy free be done elsewhere? */ +ssl->digest = _free(ssl->digest); +ssl->digestlen = 0; + xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 1); + hexstr = tt = xmalloc(2 * nb + 1); memset(tt, (int) 'f', (2 * nb)); tt[0] = '0'; tt[1] = '0'; tt[2] = '0'; tt[3] = '1'; - tt += (2 * nb) - strlen(prefix) - strlen(dig->md5) - 2; + tt += (2 * nb) - strlen(prefix) - strlen(ssl->digest) - 2; *tt++ = '0'; *tt++ = '0'; tt = stpcpy(tt, prefix); - tt = stpcpy(tt, dig->md5); + tt = stpcpy(tt, ssl->digest); /* Set RSA hash. */ /*...@-moduncon -noeffectuncon @*/ @@ -122,12 +119,14 @@ /*...@=modfilesys@*/ /* Compare leading 16 bits of digest for quick check. */ - s = dig->md5; + s = ssl->digest; /*...@-type@*/ signhash16[0] = (rpmuint8_t) (nibble(s[0]) << 4) | nibble(s[1]); signhash16[1] = (rpmuint8_t) (nibble(s[2]) << 4) | nibble(s[3]); /*...@=type@*/ - return memcmp(signhash16, sigp->signhash16, sizeof(sigp->signhash16)); + rc = memcmp(signhash16, sigp->signhash16, sizeof(sigp->signhash16)); +SPEW(rc, !rc, dig); + return rc; } static unsigned char * rpmsslBN2bin(const char * msg, const BIGNUM * s, size_t maxn) @@ -139,18 +138,9 @@ if (nt < maxn) { size_t pad = (maxn - nt); -/*...@-modfilesys@*/ -if (_pgp_debug < 0) fprintf(stderr, "\tmemmove(%p, %p, %u)\n", t+pad, t, (unsigned)nt); -/*...@=modfilesys@*/ memmove(t+pad, t, nt); -/*...@-modfilesys@*/ -if (_pgp_debug < 0) fprintf(stderr, "\tmemset(%p, 0, %u)\n", t, (unsigned)pad); -/*...@=modfilesys@*/ memset(t, 0, pad); } -/*...@-modfilesys@*/ -if (_pgp_debug < 0) hexdump(msg, t, maxn); -/*...@=modfilesys@*/ return t; } @@ -199,22 +189,79 @@ if (hm[i] == 0xff) continue; i++; -/*...@-modfilesys@*/ -if (_pgp_debug < 0) hexdump("HM", hm + i, (maxn - i)); -/*...@=modfilesys@*/ break; } -/*...@-modfilesys@*/ -if (_pgp_debug < 0) hexdump("HM", hm + (maxn - nb), nb); -if (_pgp_debug < 0) hexdump(" C", c, nb); -/*...@=modfilesys@*/ - rc = ((maxn - i) == nb && (xx = memcmp(hm+i, c, nb)) == 0); c = _free(c); hm = _free(hm); +SPEW(!rc, rc, dig); + return rc; +} + +static +int rpmsslSignRSA(/*...@unused@*/pgpDig dig) + /*...@*/ +{ + rpmssl ssl = dig->impl; + int rc = 0; /* assume failure. */ + unsigned char * c = NULL; + unsigned char * hm = NULL; + size_t maxn; + size_t nb; +int xx; + +#ifdef DYING +assert(ssl->rsa); /* XXX ensure lazy malloc with parameter set. */ +#else +if (ssl->rsa == NULL) return rc; +#endif + + maxn = RSA_size(ssl->rsa); +assert(ssl->hm); + hm = rpmsslBN2bin("hm", ssl->hm, maxn); + + c = xmalloc(maxn); + xx = RSA_private_encrypt((int)maxn, hm, c, ssl->rsa, RSA_NO_PADDING); + ssl->c = BN_bin2bn(c, maxn, NULL); + + c = _free(c); + hm = _free(hm); + + rc = (ssl->c != NULL); + +SPEW(!rc, rc, dig); + + return rc; +} + +static +int rpmsslGenerateRSA(/*...@unused@*/pgpDig dig) + /*...@*/ +{ + rpmssl ssl = dig->impl; + int rc = 0; /* assume failure. */ +static unsigned long _e = 0x10001; +BIGNUM * bn = BN_new(); + +if (ssl->nbits == 0) ssl->nbits = 1024; /* XXX FIXME */ +assert(bn); +assert(ssl->nbits); + + if ((ssl->rsa = RSA_new()) != NULL + && BN_set_word(bn, _e) + && RSA_generate_key_ex(ssl->rsa, ssl->nbits, bn, NULL)) + rc = 1; + if (!rc && ssl->rsa) { + RSA_free(ssl->rsa); + ssl->rsa = NULL; + } +if (bn) BN_free(bn); + +SPEW(!rc, rc, dig); + return rc; } @@ -222,14 +269,24 @@ int rpmsslSetDSA(/*...@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) /*...@modifies dig @*/ { + rpmssl ssl = dig->impl; + int rc; int xx; +pgpDigParams pubp = pgpGetPubkey(dig); +dig->pubkey_algoN = _pgpPubkeyAlgo2Name(pubp->pubkey_algo); +dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); assert(sigp->hash_algo == rpmDigestAlgo(ctx)); /* Set DSA hash. */ - xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 0); +/* XXX FIXME: should this lazy free be done elsewhere? */ +ssl->digest = _free(ssl->digest); +ssl->digestlen = 0; + xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 0); /* Compare leading 16 bits of digest for quick check. */ - return memcmp(dig->sha1, sigp->signhash16, sizeof(sigp->signhash16)); + rc = memcmp(ssl->digest, sigp->signhash16, sizeof(sigp->signhash16)); +SPEW(rc, !rc, dig); + return rc; } static @@ -241,9 +298,55 @@ assert(ssl->dsa); /* XXX ensure lazy malloc with parameter set. */ /* Verify DSA signature. */ -/*...@-moduncon@*/ - rc = (DSA_do_verify(dig->sha1, (int)dig->sha1len, ssl->dsasig, ssl->dsa) == 1); -/*...@=moduncon@*/ + rc = DSA_do_verify(ssl->digest, (int)ssl->digestlen, ssl->dsasig, ssl->dsa); + rc = (rc == 1); + +SPEW(!rc, rc, dig); + return rc; +} + +static +int rpmsslSignDSA(/*...@unused@*/pgpDig dig) + /*...@*/ +{ + rpmssl ssl = dig->impl; + int rc = 0; /* assume failure */ + +#ifdef DYING +assert(ssl->dsa); /* XXX ensure lazy malloc with parameter set. */ +#else +if (ssl->dsa == NULL) return rc; +#endif + + ssl->dsasig = DSA_do_sign(ssl->digest, ssl->digestlen, ssl->dsa); + rc = (ssl->dsasig != NULL); + +SPEW(!rc, rc, dig); + + return rc; +} + +static +int rpmsslGenerateDSA(/*...@unused@*/pgpDig dig) + /*...@*/ +{ + rpmssl ssl = dig->impl; + int rc = 0; /* assume failure. */ + +if (ssl->nbits == 0) ssl->nbits = 1024; /* XXX FIXME */ +assert(ssl->nbits); + + if ((ssl->dsa = DSA_new()) != NULL + && DSA_generate_parameters_ex(ssl->dsa, ssl->nbits, + NULL, 0, NULL, NULL, NULL) + && DSA_generate_key(ssl->dsa)) + rc = 1; + if (!rc && ssl->dsa) { + DSA_free(ssl->dsa); + ssl->dsa = NULL; + } + +SPEW(!rc, rc, dig); return rc; } @@ -252,14 +355,21 @@ int rpmsslSetELG(/*...@only@*/ DIGEST_CTX ctx, /*...@unused@*/pgpDig dig, pgpDigParams sigp) /*...@*/ { + rpmssl ssl = dig->impl; int rc = 1; /* XXX always fail. */ int xx; assert(sigp->hash_algo == rpmDigestAlgo(ctx)); - xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0); + +/* XXX FIXME: should this lazy free be done elsewhere? */ +ssl->digest = _free(ssl->digest); +ssl->digestlen = 0; + xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 0); /* Compare leading 16 bits of digest for quick check. */ +rc = 0; +SPEW(rc, !rc, dig); return rc; } @@ -267,24 +377,21 @@ int rpmsslSetECDSA(/*...@only@*/ DIGEST_CTX ctx, /*...@unused@*/pgpDig dig, pgpDigParams sigp) /*...@*/ { + rpmssl ssl = dig->impl; int rc = 1; /* assume failure. */ int xx; assert(sigp->hash_algo == rpmDigestAlgo(ctx)); -#if !defined(OPENSSL_NO_ECDSA) - { rpmssl ssl = dig->impl; +/* XXX FIXME: should this lazy free be done elsewhere? */ ssl->digest = _free(ssl->digest); ssl->digestlen = 0; - xx = rpmDigestFinal(ctx, &ssl->digest, &ssl->digestlen, 0); - } + xx = rpmDigestFinal(ctx, &ssl->digest, &ssl->digestlen, 0); /* Compare leading 16 bits of digest for quick check. */ - rc = 0; -#else - xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0); -#endif +rc = 0; +SPEW(rc, !rc, dig); return rc; } @@ -296,10 +403,11 @@ #if !defined(OPENSSL_NO_ECDSA) rpmssl ssl = dig->impl; - - rc = (ECDSA_do_verify(ssl->digest, ssl->digestlen, ssl->ecdsasig, ssl->ecdsakey) == 1); + rc = ECDSA_do_verify(ssl->digest, ssl->digestlen, ssl->ecdsasig, ssl->ecdsakey); #endif + rc = (rc == 1); +SPEW(!rc, rc, dig); return rc; } @@ -312,10 +420,10 @@ #if !defined(OPENSSL_NO_ECDSA) rpmssl ssl = dig->impl; ssl->ecdsasig = ECDSA_do_sign(ssl->digest, ssl->digestlen, ssl->ecdsakey); - if (ssl->ecdsasig) - rc = 1; + rc = (ssl->ecdsasig != NULL); #endif +SPEW(!rc, rc, dig); return rc; } @@ -333,6 +441,7 @@ rc = 1; #endif +SPEW(!rc, rc, dig); return rc; } @@ -406,8 +515,7 @@ rc = rpmsslVerifyECDSA(dig); break; } -if (_pgp_debug < 0) -fprintf(stderr, "<-- %s(%p) rc %d\t%s\n", __FUNCTION__, dig, rc, dig->pubkey_algoN); +SPEW(!rc, rc, dig); return rc; } @@ -421,14 +529,10 @@ default: break; case PGPPUBKEYALGO_RSA: -#ifdef NOTYET rc = rpmsslSignRSA(dig); -#endif break; case PGPPUBKEYALGO_DSA: -#ifdef NOTYET rc = rpmsslSignDSA(dig); -#endif break; case PGPPUBKEYALGO_ELGAMAL: #ifdef NOTYET @@ -439,8 +543,7 @@ rc = rpmsslSignECDSA(dig); break; } -if (_pgp_debug < 0) -fprintf(stderr, "<-- %s(%p) rc %d\t%s\n", __FUNCTION__, dig, rc, dig->pubkey_algoN); +SPEW(!rc, rc, dig); return rc; } @@ -454,14 +557,10 @@ default: break; case PGPPUBKEYALGO_RSA: -#ifdef NOTYET rc = rpmsslGenerateRSA(dig); -#endif break; case PGPPUBKEYALGO_DSA: -#ifdef NOTYET rc = rpmsslGenerateDSA(dig); -#endif break; case PGPPUBKEYALGO_ELGAMAL: #ifdef NOTYET @@ -472,8 +571,7 @@ rc = rpmsslGenerateECDSA(dig); break; } -if (_pgp_debug < 0) -fprintf(stderr, "<-- %s(%p) rc %d\t%s\n", __FUNCTION__, dig, rc, dig->pubkey_algoN); +SPEW(!rc, rc, dig); return rc; } @@ -574,13 +672,6 @@ ECDSA_SIG_free(ssl->ecdsasig); ssl->ecdsasig = NULL; - if (ssl->r) - BN_free(ssl->r); - ssl->r = NULL; - if (ssl->s) - BN_free(ssl->s); - ssl->s = NULL; - if (ssl->ecdsakey_bad) EC_KEY_free(ssl->ecdsakey_bad); ssl->ecdsakey_bad = NULL; @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmssl.h ============================================================================ $ cvs diff -u -r2.11 -r2.12 rpmssl.h --- rpm/rpmio/rpmssl.h 6 Jun 2010 21:49:41 -0000 2.11 +++ rpm/rpmio/rpmssl.h 8 Jun 2010 20:44:19 -0000 2.12 @@ -56,8 +56,6 @@ EC_KEY * ecdsakey; ECDSA_SIG * ecdsasig; - BIGNUM * r; /* XXX tecdsa */ - BIGNUM * s; /* XXX tecdsa */ }; #endif @@ . patch -p0 <<'@@ .' Index: rpm/tests/tecdsa.c ============================================================================ $ cvs diff -u -r1.19 -r1.20 tecdsa.c --- rpm/tests/tecdsa.c 6 Jun 2010 15:39:14 -0000 1.19 +++ rpm/tests/tecdsa.c 8 Jun 2010 20:44:20 -0000 1.20 @@ -77,16 +77,17 @@ #define _RPMPGP_INTERNAL #include <poptIO.h> -#define _RPMNSS_INTERNAL -#include <rpmnss.h> -#include <pk11pub.h> -#include <secerr.h> #ifdef NOTNOW #define _RPMBC_INTERNAL #include <rpmbc.h> #define _RPMGC_INTERNAL #include <rpmgc.h> +#define _RPMNSS_INTERNAL +#include <rpmnss.h> +#include <pk11pub.h> +#include <secerr.h> +#endif /* NOTNOW */ #define _RPMSSL_INTERNAL #include <rpmssl.h> @@ -97,7 +98,6 @@ #include <openssl/ecdsa.h> #include <openssl/err.h> #include <openssl/rand.h> -#endif /* NOTNOW */ #include "debug.h" @@ -904,7 +904,7 @@ /*==============================================================*/ #if defined(_RPMSSL_INTERNAL) -static KEY rpmsslNIDS[] = { +static keyNV_t rpmsslNIDS[] = { { "c2pnb163v1", 684 }, /* X9.62 curve over a 163 bit binary field */ { "c2pnb163v2", 685 }, /* X9.62 curve over a 163 bit binary field */ { "c2pnb163v3", 686 }, /* X9.62 curve over a 163 bit binary field */ @@ -1437,12 +1437,17 @@ /* check the {r,s} parameters */ if (pgpImplVecs == &rpmsslImplVecs) { rpmssl ssl = dig->impl; - if (!rpmsslLoadBN(&ssl->r, r_in, _rpmssl_spew) - || BN_cmp(ssl->ecdsasig->r, ssl->r)) - goto exit; - if (!rpmsslLoadBN(&ssl->s, s_in, _rpmssl_spew) - || BN_cmp(ssl->ecdsasig->s, ssl->s)) - goto exit; + ECDSA_SIG ecdsasig = { .r = NULL, .s = NULL }; + int xx = 0; + if (!rpmsslLoadBN(&ecdsasig.r, r_in, _rpmssl_spew) + || BN_cmp(ssl->ecdsasig->r, ecdsasig.r)) + xx++; + if (!rpmsslLoadBN(&ecdsasig.s, s_in, _rpmssl_spew) + || BN_cmp(ssl->ecdsasig->s, ecdsasig.s)) + xx++; + if (ecdsasig.r) BN_free(ecdsasig.r); + if (ecdsasig.s) BN_free(ecdsasig.s); + if (xx) goto exit; } #endif /* _RPMSSL_INTERNAL */ bingo++; @@ . patch -p0 <<'@@ .' Index: rpm/tests/trsa.c ============================================================================ $ cvs diff -u -r1.28 -r1.29 trsa.c --- rpm/tests/trsa.c 8 Jun 2010 14:05:29 -0000 1.28 +++ rpm/tests/trsa.c 8 Jun 2010 20:44:20 -0000 1.29 @@ -78,16 +78,17 @@ #define _RPMPGP_INTERNAL #include <poptIO.h> -#define _RPMBC_INTERNAL -#include <rpmbc.h> #ifdef NOTYET +#define _RPMBC_INTERNAL +#include <rpmbc.h> #define _RPMGC_INTERNAL #include <rpmgc.h> #define _RPMNSS_INTERNAL #include <rpmnss.h> #include <pk11pub.h> #include <secerr.h> +#endif /* NOTYET */ #define _RPMSSL_INTERNAL #include <rpmssl.h> @@ -100,7 +101,6 @@ #include <openssl/err.h> #include <openssl/rand.h> #include <openssl/x509v3.h> /* XXX X509V3_EXT_cleanup() */ -#endif /* NOTYET */ #include "debug.h" @@ -3066,22 +3066,19 @@ #if !defined(_RPMGC_INTERNAL) { DIGEST_CTX ctx = NULL; + uint8_t * digest = NULL; + size_t digestlen = 0; int xx; pgpDigParams pubp = pgpGetPubkey(dig); dalgo = (pubp->pubkey_algo == PGPPUBKEYALGO_ECDSA ? PGPHASHALGO_SHA256 : PGPHASHALGO_SHA1); -#if defined(_RPMNSS_INTERNAL) +#if defined(_RPMNSS_INTERNAL) /* XXX Grrr only SHA1 "supported" */ dalgo = PGPHASHALGO_SHA1; #endif sigp->hash_algo = dalgo; dig->hash_algoN = _pgpHashAlgo2Name(sigp->hash_algo); msg = rpmExpand(dig->pubkey_algoN, "-", dig->hash_algoN, " sign", NULL); -{ - DIGEST_CTX ctx = NULL; - uint8_t * digest = NULL; - size_t digestlen = 0; - ctx = rpmDigestInit(sigp->hash_algo, 0); xx = rpmDigestUpdate(ctx, "abc", sizeof("abc")-1); xx = rpmDigestFinal(rpmDigestDup(ctx), &digest, &digestlen, 0); @@ -3108,7 +3105,6 @@ } digest = _free(digest); if (xx && !rc) rc = 1; -} xx = pgpImplSign(dig); if (!xx && !rc) rc = 1; /* XXX 1 on success */ @@ -5279,13 +5275,129 @@ return rc; /* XXX 1 on success */ } +#define _spewBN(_N, _BN) \ + { BIGNUM * bn = _BN; \ + char * t = bn ? BN_bn2hex(bn) : ""; \ + fprintf(stderr, "\t " _N ": %s\n", t); \ + if (bn) OPENSSL_free(t); \ + } + +static void rpmsslDumpRSA(const char * msg, rpmssl ssl) +{ + if (msg) fprintf(stderr, "========== %s\n", msg); + + if (ssl->rsa) { + _spewBN(" n", ssl->rsa->n); + _spewBN(" e", ssl->rsa->e); + _spewBN(" d", ssl->rsa->d); + _spewBN(" p", ssl->rsa->p); + _spewBN(" q", ssl->rsa->q); + _spewBN("dp", ssl->rsa->dmp1); + _spewBN("dq", ssl->rsa->dmq1); + _spewBN("qi", ssl->rsa->iqmp); + } + + _spewBN("hm", ssl->hm); + _spewBN(" c", ssl->c); +} + +static void rpmsslDumpDSA(const char * msg, rpmssl ssl) +{ + if (msg) fprintf(stderr, "========== %s\n", msg); + + if (ssl->dsa) { + _spewBN(" p", ssl->dsa->p); + _spewBN(" q", ssl->dsa->q); + _spewBN(" g", ssl->dsa->g); + _spewBN(" x", ssl->dsa->priv_key); + _spewBN(" y", ssl->dsa->pub_key); + } + + if (ssl->dsasig) { + _spewBN(" r", ssl->dsasig->r); + _spewBN(" s", ssl->dsasig->s); + } + + _spewBN("hm", ssl->hm); +} + +static void rpmsslDumpECDSA(const char * msg, rpmssl ssl) +{ + if (msg) fprintf(stderr, "========== %s\n", msg); + + if (ssl->ecdsakey) { + const EC_GROUP * group = EC_KEY_get0_group(ssl->ecdsakey); + const EC_METHOD * method = EC_GROUP_method_of(group); + BIGNUM * n = BN_new(); + BIGNUM * h = BN_new(); + BIGNUM * p = BN_new(); + BIGNUM * a = BN_new(); + BIGNUM * b = BN_new(); + const EC_POINT * G = EC_GROUP_get0_generator(group); + BIGNUM * Gx = BN_new(); + BIGNUM * Gy = BN_new(); + const BIGNUM * d = EC_KEY_get0_private_key(ssl->ecdsakey); + const EC_POINT * Q = EC_KEY_get0_public_key(ssl->ecdsakey); + BIGNUM * Qx = BN_new(); + BIGNUM * Qy = BN_new(); + unsigned char * seed = EC_GROUP_get0_seed(group); + size_t seed_len = EC_GROUP_get_seed_len(group); + int xx; + + fprintf(stderr, "\tfield_type: %d\n", EC_METHOD_get_field_type(method)); + fprintf(stderr, "\tcurve_name: %d\n", EC_GROUP_get_curve_name(group)); + fprintf(stderr, "\t asn1_flag: %d\n", EC_GROUP_get_asn1_flag(group)); + fprintf(stderr, "\t degree: %d\n", EC_GROUP_get_degree(group)); + if (seed) + fprintf(stderr, "\t seed: %s\n", pgpHexStr(seed, seed_len)); + + xx = EC_GROUP_get_curve_GFp(group, p, a, b, NULL); + if (xx) { + _spewBN(" p", p); + xx = EC_GROUP_get_order(group, n, NULL); + if (xx) _spewBN(" n", n); + _spewBN(" b", b); + _spewBN(" a", a); + xx = EC_GROUP_get_cofactor(group, h, NULL); + if (xx) _spewBN(" h", h); + } + + xx = EC_POINT_get_affine_coordinates_GFp(group, G, Gx, Gy, NULL); + if (xx) { + _spewBN("Gx", Gx); + _spewBN("Gy", Gy); + } + + _spewBN(" d", (BIGNUM *)d); + xx = EC_POINT_get_affine_coordinates_GFp(group, Q, Qx, Qy, NULL); + if (xx) { + _spewBN("Qx", Qx); + _spewBN("Qy", Qy); + } + + if (Qy) BN_free(Qy); + if (Qx) BN_free(Qx); + if (Gy) BN_free(Gy); + if (Gx) BN_free(Gx); + if (b) BN_free(b); + if (a) BN_free(a); + if (p) BN_free(p); + if (h) BN_free(h); + if (n) BN_free(n); + } + + if (ssl->ecdsasig->r) _spewBN(" r", ssl->ecdsasig->r); + if (ssl->ecdsasig->s) _spewBN(" s", ssl->ecdsasig->s); +} + +#undef _spewBN + static int rpmsslSetRSA(/*...@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) /*...@modifies dig @*/ { rpmssl ssl = dig->impl; - unsigned int nbits = BN_num_bits(ssl->c); - unsigned int nb = (nbits + 7) >> 3; + unsigned int nb = 0; const char * prefix = rpmDigestASN1(ctx); const char * hexstr; const char * s; @@ -5297,6 +5409,27 @@ if (prefix == NULL) return 1; + /* + * The no. of bytes for hash + PKCS1 padding is needed. + * Either n or c can be used as the size, but different code paths + * populate n or c indeterminately. So try c, then n, + * and error if the no. of bytes isn't sane. + */ +#ifdef DYING + if (ssl->c) + nb = BN_num_bytes(ssl->c); + else if (ssl->rsa->n) + nb = BN_num_bytes(ssl->rsa->n); +#else + nb = RSA_size(ssl->rsa); +#endif + if (nb < 64/8 || nb > 65536/8) /* XXX generous "sanity" check */ + return 1; + +/* XXX FIXME: do PKCS1 padding in binary not hex */ +/* XXX FIXME: should this lazy free be done elsewhere? */ +ssl->digest = _free(ssl->digest); +ssl->digestlen = 0; xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 1); hexstr = tt = xmalloc(2 * nb + 1); memset(tt, (int) 'f', (2 * nb)); @@ -5309,6 +5442,10 @@ /* Set RSA hash. */ /*...@-moduncon -noeffectuncon @*/ +if (ssl->hm) { +BN_free(ssl->hm); +ssl->hm = NULL; +} xx = BN_hex2bn(&ssl->hm, hexstr); /*...@=moduncon =noeffectuncon @*/ @@ -5433,13 +5570,16 @@ { rpmssl ssl = dig->impl; int rc = 0; /* assume failure. */ + unsigned char * c = NULL; + unsigned char * hm = NULL; + size_t maxn; +#ifdef DYING static const char _asn1[] = { 0x30,0x21,0x30,0x09,0x06,0x05,0x2b, 0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14 }; - size_t maxn; - unsigned char * hm = NULL; - unsigned char * c = NULL; size_t nb; +#endif +int xx; #ifdef DYING assert(ssl->rsa); /* XXX ensure lazy malloc with parameter set. */ @@ -5448,6 +5588,7 @@ #endif maxn = RSA_size(ssl->rsa); +#ifdef DYING nb = maxn - ssl->digestlen; @@ -5460,9 +5601,14 @@ memcpy(hm + nb, ssl->digest, ssl->digestlen); ssl->hm = BN_bin2bn(hm, maxn, NULL); +#else +assert(ssl->hm); +hm = xmalloc(BN_num_bytes(ssl->hm)); +hm = rpmsslBN2bin("hm", ssl->hm, maxn); +#endif - c = xmalloc(maxn); - nb = RSA_private_encrypt((int)maxn, hm, c, ssl->rsa, RSA_NO_PADDING); + c = xmalloc(RSA_size(ssl->rsa)); + xx = RSA_private_encrypt((int)maxn, hm, c, ssl->rsa, RSA_NO_PADDING); ssl->c = BN_bin2bn(c, maxn, NULL); c = _free(c); @@ -5511,6 +5657,8 @@ assert(sigp->hash_algo == rpmDigestAlgo(ctx)); /* Set DSA hash. */ +ssl->digest = _free(ssl->digest); +ssl->digestlen = 0; xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 0); /* Compare leading 16 bits of digest for quick check. */ @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository [email protected]
