rpm 5.3.12
rpmio/rpmssl.c
Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #include <rpmlog.h>
00007 
00008 #include <rpmiotypes.h>
00009 #define _RPMPGP_INTERNAL
00010 #if defined(WITH_SSL)
00011 
00012 #if defined(__LCLINT__) && !defined(__i386__)
00013 #define __i386__
00014 #endif
00015 
00016 #define _RPMSSL_INTERNAL
00017 #include <rpmssl.h>
00018 #endif
00019 
00020 #include "debug.h"
00021 
00022 #if defined(WITH_SSL)
00023 
00024 /*@access pgpDig @*/
00025 /*@access pgpDigParams @*/
00026 
00027 /*@-redecl@*/
00028 /*@unchecked@*/
00029 extern int _pgp_debug;
00030 
00031 /*@unchecked@*/
00032 extern int _pgp_print;
00033 /*@=redecl@*/
00034 
00035 /*@unchecked@*/
00036 static int _rpmssl_debug;
00037 
00038 #define SPEW(_t, _rc, _dig)     \
00039   { if ((_t) || _rpmssl_debug || _pgp_debug < 0) \
00040         fprintf(stderr, "<-- %s(%p) %s\t%s\n", __FUNCTION__, (_dig), \
00041                 ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN); \
00042   }
00043 
00044 static const char * rpmsslHashAlgo2Name(uint32_t algo)
00045 {
00046     return pgpValStr(pgpHashTbl, (rpmuint8_t)algo);
00047 }
00048 
00049 static const char * rpmsslPubkeyAlgo2Name(uint32_t algo)
00050 {
00051     return pgpValStr(pgpPubkeyTbl, (rpmuint8_t)algo);
00052 }
00053 
00059 static
00060 unsigned char nibble(char c)
00061         /*@*/
00062 {
00063     if (c >= '0' && c <= '9')
00064         return (unsigned char) (c - '0');
00065     if (c >= 'A' && c <= 'F')
00066         return (unsigned char)((int)(c - 'A') + 10);
00067     if (c >= 'a' && c <= 'f')
00068         return (unsigned char)((int)(c - 'a') + 10);
00069     return (unsigned char) '\0';
00070 }
00071 
00072 static unsigned char * rpmsslBN2bin(const char * msg, const BIGNUM * s, size_t maxn)
00073 {
00074     unsigned char * t = xcalloc(1, maxn);
00075 /*@-modunconnomods@*/
00076     size_t nt = BN_bn2bin(s, t);
00077 /*@=modunconnomods@*/
00078 
00079     if (nt < maxn) {
00080         size_t pad = (maxn - nt);
00081         memmove(t+pad, t, nt);
00082         memset(t, 0, pad);
00083     }
00084     return t;
00085 }
00086 
00087 static
00088 int rpmsslSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00089         /*@modifies dig @*/
00090 {
00091     rpmssl ssl = dig->impl;
00092     unsigned int nb = RSA_size(ssl->rsa);
00093     const char * prefix = rpmDigestASN1(ctx);
00094     const char * hexstr;
00095     const char * s;
00096     rpmuint8_t signhash16[2];
00097     char * tt;
00098     int rc;
00099     int xx;
00100 pgpDigParams pubp = pgpGetPubkey(dig);
00101 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
00102 dig->hash_algoN = rpmsslHashAlgo2Name(sigp->hash_algo);
00103 
00104 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00105     if (prefix == NULL)
00106         return 1;
00107 
00108 /* XXX FIXME: do PKCS1 padding in binary not hex */
00109 /* XXX FIXME: should this lazy free be done elsewhere? */
00110 ssl->digest = _free(ssl->digest);
00111 ssl->digestlen = 0;
00112     xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 1);
00113 
00114     hexstr = tt = xmalloc(2 * nb + 1);
00115     memset(tt, (int) 'f', (2 * nb));
00116     tt[0] = '0'; tt[1] = '0';
00117     tt[2] = '0'; tt[3] = '1';
00118     tt += (2 * nb) - strlen(prefix) - strlen(ssl->digest) - 2;
00119     *tt++ = '0'; *tt++ = '0';
00120     tt = stpcpy(tt, prefix);
00121     tt = stpcpy(tt, ssl->digest);
00122 
00123     /* Set RSA hash. */
00124 /*@-moduncon -noeffectuncon @*/
00125     xx = BN_hex2bn(&ssl->hm, hexstr);
00126 /*@=moduncon =noeffectuncon @*/
00127 
00128 /*@-modfilesys@*/
00129 if (_pgp_debug < 0) fprintf(stderr, "*** hm: %s\n", hexstr);
00130     hexstr = _free(hexstr);
00131 /*@=modfilesys@*/
00132 
00133     /* Compare leading 16 bits of digest for quick check. */
00134     s = ssl->digest;
00135 /*@-type@*/
00136     signhash16[0] = (rpmuint8_t) (nibble(s[0]) << 4) | nibble(s[1]);
00137     signhash16[1] = (rpmuint8_t) (nibble(s[2]) << 4) | nibble(s[3]);
00138 /*@=type@*/
00139     rc = memcmp(signhash16, sigp->signhash16, sizeof(sigp->signhash16));
00140 SPEW(0, !rc, dig);
00141     return rc;
00142 }
00143 
00144 static
00145 int rpmsslVerifyRSA(pgpDig dig)
00146         /*@*/
00147 {
00148     rpmssl ssl = dig->impl;
00149 /*@-moduncon@*/
00150     size_t maxn;
00151     unsigned char * hm;
00152     unsigned char *  c;
00153     size_t nb;
00154 /*@=moduncon@*/
00155     size_t i;
00156     int rc = 0;
00157     int xx;
00158 
00159 assert(ssl->rsa);       /* XXX ensure lazy malloc with parameter set. */
00160     maxn = BN_num_bytes(ssl->rsa->n);
00161     hm = rpmsslBN2bin("hm", ssl->hm, maxn);
00162     c = rpmsslBN2bin(" c", ssl->c, maxn);
00163     nb = RSA_public_decrypt((int)maxn, c, c, ssl->rsa, RSA_PKCS1_PADDING);
00164 
00165 /*@=moduncon@*/
00166     /* Verify RSA signature. */
00167     /* XXX This is _NOT_ the correct openssl function to use:
00168      *  rc = RSA_verify(type, m, m_len, sigbuf, siglen, ssl->rsa)
00169      *
00170      * Here's what needs doing (from OpenPGP reference sources in 1999):
00171      *  static u32_t checkrsa(BIGNUM * a, RSA * key, u8_t * hash, int hlen)
00172      *  {
00173      *    u8_t dbuf[MAXSIGM];
00174      *    int j, ll;
00175      *
00176      *    j = BN_bn2bin(a, dbuf);
00177      *    ll = BN_num_bytes(key->n);
00178      *    while (j < ll)
00179      *      memmove(&dbuf[1], dbuf, j++), dbuf[0] = 0;
00180      *    j = RSA_public_decrypt(ll, dbuf, dbuf, key, RSA_PKCS1_PADDING);
00181      *    RSA_free(key);
00182      *    return (j != hlen || memcmp(dbuf, hash, j));
00183      *  }
00184      */
00185     for (i = 2; i < maxn; i++) {
00186         if (hm[i] == 0xff)
00187             continue;
00188         i++;
00189         break;
00190     }
00191 
00192     rc = ((maxn - i) == nb && (xx = memcmp(hm+i, c, nb)) == 0);
00193 
00194     c = _free(c);
00195     hm = _free(hm);
00196 
00197 SPEW(!rc, rc, dig);
00198     return rc;
00199 }
00200 
00201 static
00202 int rpmsslSignRSA(pgpDig dig)
00203         /*@*/
00204 {
00205     rpmssl ssl = dig->impl;
00206     int rc = 0;         /* assume failure. */
00207     unsigned char *  c = NULL;
00208     unsigned char * hm = NULL;
00209     size_t maxn;
00210 int xx;
00211 
00212 #ifdef  DYING
00213 assert(ssl->rsa);       /* XXX ensure lazy malloc with parameter set. */
00214 #else
00215 if (ssl->rsa == NULL) return rc;
00216 #endif
00217 
00218     maxn = RSA_size(ssl->rsa);
00219 assert(ssl->hm);
00220     hm = rpmsslBN2bin("hm", ssl->hm, maxn);
00221 
00222     c = xmalloc(maxn);
00223     xx = RSA_private_encrypt((int)maxn, hm, c, ssl->rsa, RSA_NO_PADDING);
00224     ssl->c = BN_bin2bn(c, maxn, NULL);
00225 
00226     c = _free(c);
00227     hm = _free(hm);
00228 
00229     rc = (ssl->c != NULL);
00230 
00231 SPEW(!rc, rc, dig);
00232 
00233     return rc;
00234 }
00235 
00236 static
00237 int rpmsslGenerateRSA(pgpDig dig)
00238         /*@*/
00239 {
00240     rpmssl ssl = dig->impl;
00241     int rc = 0;         /* assume failure. */
00242 static unsigned long _e = 0x10001;
00243 
00244 if (ssl->nbits == 0) ssl->nbits = 1024; /* XXX FIXME */
00245 assert(ssl->nbits);
00246 
00247 #if defined(HAVE_RSA_GENERATE_KEY_EX)
00248     {   BIGNUM * bn = BN_new();
00249 assert(bn);
00250         if ((ssl->rsa = RSA_new()) != NULL
00251          && BN_set_word(bn, _e)
00252          && RSA_generate_key_ex(ssl->rsa, ssl->nbits, bn, NULL))
00253             rc = 1;
00254         if (bn) BN_free(bn);
00255     }
00256 #else
00257     /* XXX older & deprecated API in openssl-0.97a (Centos4/s390x) */
00258     if ((ssl->rsa = RSA_generate_key(ssl->nbits, _e, NULL, NULL)) != NULL)
00259         rc = 1;
00260 #endif
00261 
00262     if (!rc && ssl->rsa) {
00263         RSA_free(ssl->rsa);
00264         ssl->rsa = NULL;
00265     }
00266 
00267 SPEW(!rc, rc, dig);
00268 
00269     return rc;
00270 }
00271 
00272 static
00273 int rpmsslSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00274         /*@modifies dig @*/
00275 {
00276     rpmssl ssl = dig->impl;
00277     int rc;
00278     int xx;
00279 pgpDigParams pubp = pgpGetPubkey(dig);
00280 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
00281 dig->hash_algoN = rpmsslHashAlgo2Name(sigp->hash_algo);
00282 
00283 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00284     /* Set DSA hash. */
00285 /* XXX FIXME: should this lazy free be done elsewhere? */
00286 ssl->digest = _free(ssl->digest);
00287 ssl->digestlen = 0;
00288     xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 0);
00289 
00290     /* Compare leading 16 bits of digest for quick check. */
00291     rc = memcmp(ssl->digest, sigp->signhash16, sizeof(sigp->signhash16));
00292 SPEW(0, !rc, dig);
00293     return rc;
00294 }
00295 
00296 static
00297 int rpmsslVerifyDSA(pgpDig dig)
00298         /*@*/
00299 {
00300     rpmssl ssl = dig->impl;
00301     int rc;
00302 
00303 assert(ssl->dsa);       /* XXX ensure lazy malloc with parameter set. */
00304     /* Verify DSA signature. */
00305     rc = DSA_do_verify(ssl->digest, (int)ssl->digestlen, ssl->dsasig, ssl->dsa);
00306     rc = (rc == 1);
00307 
00308 SPEW(!rc, rc, dig);
00309     return rc;
00310 }
00311 
00312 static
00313 int rpmsslSignDSA(pgpDig dig)
00314         /*@*/
00315 {
00316     rpmssl ssl = dig->impl;
00317     int rc = 0;         /* assume failure */
00318 
00319 #ifdef  DYING
00320 assert(ssl->dsa);       /* XXX ensure lazy malloc with parameter set. */
00321 #else
00322 if (ssl->dsa == NULL) return rc;
00323 #endif
00324 
00325     ssl->dsasig = DSA_do_sign(ssl->digest, ssl->digestlen, ssl->dsa);
00326     rc = (ssl->dsasig != NULL);
00327 
00328 SPEW(!rc, rc, dig);
00329 
00330     return rc;
00331 }
00332 
00333 static
00334 int rpmsslGenerateDSA(pgpDig dig)
00335         /*@*/
00336 {
00337     rpmssl ssl = dig->impl;
00338     int rc = 0;         /* assume failure. */
00339 
00340 if (ssl->nbits == 0) ssl->nbits = 1024; /* XXX FIXME */
00341 assert(ssl->nbits);
00342 
00343 #if defined(HAVE_DSA_GENERATE_PARAMETERS_EX)
00344     if ((ssl->dsa = DSA_new()) != NULL
00345      && DSA_generate_parameters_ex(ssl->dsa, ssl->nbits,
00346                 NULL, 0, NULL, NULL, NULL)
00347      && DSA_generate_key(ssl->dsa))
00348         rc = 1;
00349 #else
00350     /* XXX older & deprecated API in openssl-0.97a (Centos4/s390x) */
00351     if ((ssl->dsa = DSA_generate_parameters(ssl->nbits,
00352                 NULL, 0, NULL, NULL, NULL, NULL)) != NULL
00353      && DSA_generate_key(ssl->dsa))
00354         rc = 1;
00355 #endif
00356 
00357     if (!rc && ssl->dsa) {
00358         DSA_free(ssl->dsa);
00359         ssl->dsa = NULL;
00360     }
00361 
00362 SPEW(!rc, rc, dig);
00363 
00364     return rc;
00365 }
00366 
00367 static
00368 int rpmsslSetELG(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
00369         /*@*/
00370 {
00371     rpmssl ssl = dig->impl;
00372     int rc = 1;         /* XXX always fail. */
00373     int xx;
00374 
00375 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00376 
00377 /* XXX FIXME: should this lazy free be done elsewhere? */
00378 ssl->digest = _free(ssl->digest);
00379 ssl->digestlen = 0;
00380     xx = rpmDigestFinal(ctx, (void **)&ssl->digest, &ssl->digestlen, 0);
00381 
00382     /* Compare leading 16 bits of digest for quick check. */
00383 rc = 0;
00384 
00385 SPEW(rc, !rc, dig);
00386     return rc;
00387 }
00388 
00389 static
00390 int rpmsslSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
00391         /*@*/
00392 {
00393     rpmssl ssl = dig->impl;
00394     int rc = 1;         /* assume failure. */
00395     int xx;
00396 
00397 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00398 
00399 /* XXX FIXME: should this lazy free be done elsewhere? */
00400 ssl->digest = _free(ssl->digest);
00401 ssl->digestlen = 0;
00402     xx = rpmDigestFinal(ctx, &ssl->digest, &ssl->digestlen, 0);
00403 
00404     /* Compare leading 16 bits of digest for quick check. */
00405 rc = 0;
00406 
00407 SPEW(rc, !rc, dig);
00408     return rc;
00409 }
00410 
00411 static
00412 int rpmsslVerifyECDSA(pgpDig dig)
00413         /*@*/
00414 {
00415     int rc = 0;         /* assume failure. */
00416 
00417 #if !defined(OPENSSL_NO_ECDSA)
00418     rpmssl ssl = dig->impl;
00419     rc = ECDSA_do_verify(ssl->digest, ssl->digestlen, ssl->ecdsasig, ssl->ecdsakey);
00420 #endif
00421     rc = (rc == 1);
00422 
00423 SPEW(!rc, rc, dig);
00424     return rc;
00425 }
00426 
00427 static
00428 int rpmsslSignECDSA(pgpDig dig)
00429         /*@*/
00430 {
00431     int rc = 0;         /* assume failure. */
00432 
00433 #if !defined(OPENSSL_NO_ECDSA)
00434     rpmssl ssl = dig->impl;
00435     ssl->ecdsasig = ECDSA_do_sign(ssl->digest, ssl->digestlen, ssl->ecdsakey);
00436     rc = (ssl->ecdsasig != NULL);
00437 #endif
00438 
00439 SPEW(!rc, rc, dig);
00440     return rc;
00441 }
00442 
00443 static
00444 int rpmsslGenerateECDSA(pgpDig dig)
00445         /*@*/
00446 {
00447     int rc = 0;         /* assume failure. */
00448 
00449 #if !defined(OPENSSL_NO_ECDSA)
00450     rpmssl ssl = dig->impl;
00451 
00452 if (ssl->nid == 0) {            /* XXX FIXME */
00453 ssl->nid = NID_X9_62_prime256v1;
00454 ssl->nbits = 256;
00455 }
00456 
00457     if ((ssl->ecdsakey = EC_KEY_new_by_curve_name(ssl->nid)) != NULL
00458      && EC_KEY_generate_key(ssl->ecdsakey))
00459         rc = 1;
00460 #endif
00461 
00462 SPEW(!rc, rc, dig);
00463     return rc;
00464 }
00465 
00466 static int rpmsslErrChk(pgpDig dig, const char * msg, int rc, unsigned expected)
00467 {
00468 #ifdef  NOTYET
00469 rpmgc gc = dig->impl;
00470     /* Was the return code the expected result? */
00471     rc = (gcry_err_code(gc->err) != expected);
00472     if (rc)
00473         fail("%s failed: %s\n", msg, gpg_strerror(gc->err));
00474 /* XXX FIXME: rpmsslStrerror */
00475 #else
00476     rc = (rc == 0);     /* XXX impedance match 1 -> 0 on success */
00477 #endif
00478     return rc;  /* XXX 0 on success */
00479 }
00480 
00481 static int rpmsslAvailableCipher(pgpDig dig, int algo)
00482 {
00483     int rc = 0; /* assume available */
00484 #ifdef  NOTYET
00485     rc = rpmgsslvailable(dig->impl, algo,
00486         (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
00487 #endif  /* _RPMGC_INTERNAL */
00488     return rc;
00489 }
00490 
00491 static int rpmsslAvailableDigest(pgpDig dig, int algo)
00492 {
00493     int rc = 0; /* assume available */
00494 #ifdef  NOTYET
00495     rc = rpmgsslvailable(dig->impl, algo,
00496         (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
00497 #endif  /* _RPMGC_INTERNAL */
00498     return rc;
00499 }
00500 
00501 static int rpmsslAvailablePubkey(pgpDig dig, int algo)
00502 {
00503     int rc = 0; /* assume available */
00504 #ifdef  NOTYET
00505     rc = rpmsslAvailable(dig->impl, algo, gcry_pk_test_algo(algo));
00506 #endif  /* _RPMGC_INTERNAL */
00507     return rc;
00508 }
00509 
00510 static int rpmsslVerify(pgpDig dig)
00511 {
00512     int rc = 0;         /* assume failure */
00513 pgpDigParams pubp = pgpGetPubkey(dig);
00514 pgpDigParams sigp = pgpGetSignature(dig);
00515 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
00516 dig->hash_algoN = rpmsslHashAlgo2Name(sigp->hash_algo);
00517 
00518     switch (pubp->pubkey_algo) {
00519     default:
00520         break;
00521     case PGPPUBKEYALGO_RSA:
00522         rc = rpmsslVerifyRSA(dig);
00523         break;
00524     case PGPPUBKEYALGO_DSA:
00525         rc = rpmsslVerifyDSA(dig);
00526         break;
00527     case PGPPUBKEYALGO_ELGAMAL:
00528 #ifdef  NOTYET
00529         rc = rpmsslVerifyELG(dig);
00530 #endif
00531         break;
00532     case PGPPUBKEYALGO_ECDSA:
00533         rc = rpmsslVerifyECDSA(dig);
00534         break;
00535     }
00536 SPEW(!rc, rc, dig);
00537     return rc;
00538 }
00539 
00540 static int rpmsslSign(pgpDig dig)
00541 {
00542     int rc = 0;         /* assume failure */
00543 pgpDigParams pubp = pgpGetPubkey(dig);
00544 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
00545 
00546     switch (pubp->pubkey_algo) {
00547     default:
00548         break;
00549     case PGPPUBKEYALGO_RSA:
00550         rc = rpmsslSignRSA(dig);
00551         break;
00552     case PGPPUBKEYALGO_DSA:
00553         rc = rpmsslSignDSA(dig);
00554         break;
00555     case PGPPUBKEYALGO_ELGAMAL:
00556 #ifdef  NOTYET
00557         rc = rpmsslSignELG(dig);
00558 #endif
00559         break;
00560     case PGPPUBKEYALGO_ECDSA:
00561         rc = rpmsslSignECDSA(dig);
00562         break;
00563     }
00564 SPEW(!rc, rc, dig);
00565     return rc;
00566 }
00567 
00568 static int rpmsslGenerate(pgpDig dig)
00569 {
00570     int rc = 0;         /* assume failure */
00571 pgpDigParams pubp = pgpGetPubkey(dig);
00572 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
00573 
00574     switch (pubp->pubkey_algo) {
00575     default:
00576         break;
00577     case PGPPUBKEYALGO_RSA:
00578         rc = rpmsslGenerateRSA(dig);
00579         break;
00580     case PGPPUBKEYALGO_DSA:
00581         rc = rpmsslGenerateDSA(dig);
00582         break;
00583     case PGPPUBKEYALGO_ELGAMAL:
00584 #ifdef  NOTYET
00585         rc = rpmsslGenerateELG(dig);
00586 #endif
00587         break;
00588     case PGPPUBKEYALGO_ECDSA:
00589         rc = rpmsslGenerateECDSA(dig);
00590         break;
00591     }
00592 SPEW(!rc, rc, dig);
00593     return rc;
00594 }
00595 
00596 static
00597 int rpmsslMpiItem(/*@unused@*/ const char * pre, pgpDig dig, int itemno,
00598                 const rpmuint8_t * p,
00599                 /*@unused@*/ /*@null@*/ const rpmuint8_t * pend)
00600         /*@*/
00601 {
00602     rpmssl ssl = dig->impl;
00603     unsigned int nb = ((pgpMpiBits(p) + 7) >> 3);
00604     int rc = 0;
00605 
00606 /*@-moduncon@*/
00607     switch (itemno) {
00608     default:
00609 assert(0);
00610     case 50:            /* ECDSA r */
00611     case 51:            /* ECDSA s */
00612     case 60:            /* ECDSA curve OID */
00613     case 61:            /* ECDSA Q */
00614         break;
00615     case 10:            /* RSA m**d */
00616         ssl->c = BN_bin2bn(p+2, nb, ssl->c);
00617         break;
00618     case 20:            /* DSA r */
00619         if (ssl->dsasig == NULL) ssl->dsasig = DSA_SIG_new();
00620         ssl->dsasig->r = BN_bin2bn(p+2, nb, ssl->dsasig->r);
00621         break;
00622     case 21:            /* DSA s */
00623         if (ssl->dsasig == NULL) ssl->dsasig = DSA_SIG_new();
00624         ssl->dsasig->s = BN_bin2bn(p+2, nb, ssl->dsasig->s);
00625         break;
00626     case 30:            /* RSA n */
00627         if (ssl->rsa == NULL) ssl->rsa = RSA_new();
00628         ssl->rsa->n = BN_bin2bn(p+2, nb, ssl->rsa->n);
00629         break;
00630     case 31:            /* RSA e */
00631         if (ssl->rsa == NULL) ssl->rsa = RSA_new();
00632         ssl->rsa->e = BN_bin2bn(p+2, nb, ssl->rsa->e);
00633         break;
00634     case 40:            /* DSA p */
00635         if (ssl->dsa == NULL) ssl->dsa = DSA_new();
00636         ssl->dsa->p = BN_bin2bn(p+2, nb, ssl->dsa->p);
00637         break;
00638     case 41:            /* DSA q */
00639         if (ssl->dsa == NULL) ssl->dsa = DSA_new();
00640         ssl->dsa->q = BN_bin2bn(p+2, nb, ssl->dsa->q);
00641         break;
00642     case 42:            /* DSA g */
00643         if (ssl->dsa == NULL) ssl->dsa = DSA_new();
00644         ssl->dsa->g = BN_bin2bn(p+2, nb, ssl->dsa->g);
00645         break;
00646     case 43:            /* DSA y */
00647         if (ssl->dsa == NULL) ssl->dsa = DSA_new();
00648         ssl->dsa->pub_key = BN_bin2bn(p+2, nb, ssl->dsa->pub_key);
00649         break;
00650     }
00651 /*@=moduncon@*/
00652     return rc;
00653 }
00654 
00655 /*@-mustmod@*/
00656 static
00657 void rpmsslClean(void * impl)
00658         /*@modifies impl @*/
00659 {
00660     rpmssl ssl = impl;
00661 /*@-moduncon@*/
00662     if (ssl != NULL) {
00663         ssl->nbits = 0;
00664         ssl->err = 0;
00665         ssl->badok = 0;
00666         ssl->digest = _free(ssl->digest);
00667         ssl->digestlen = 0;
00668 
00669         if (ssl->dsa)
00670             DSA_free(ssl->dsa);
00671         ssl->dsa = NULL;
00672         if (ssl->dsasig)
00673             DSA_SIG_free(ssl->dsasig);
00674         ssl->dsasig = NULL;
00675 
00676         if (ssl->rsa)
00677             RSA_free(ssl->rsa);
00678         ssl->rsa = NULL;
00679         if (ssl->hm)
00680             BN_free(ssl->hm);
00681         ssl->hm = NULL;
00682         if (ssl->c)
00683             BN_free(ssl->c);
00684         ssl->c = NULL;
00685 
00686 #if !defined(OPENSSL_NO_ECDSA)
00687         if (ssl->ecdsakey)
00688             EC_KEY_free(ssl->ecdsakey);
00689         ssl->ecdsakey = NULL;
00690         if (ssl->ecdsasig)
00691             ECDSA_SIG_free(ssl->ecdsasig);
00692         ssl->ecdsasig = NULL;
00693 
00694         if (ssl->ecdsakey_bad)
00695             EC_KEY_free(ssl->ecdsakey_bad);
00696         ssl->ecdsakey_bad = NULL;
00697 #endif
00698 
00699     }
00700 /*@=moduncon@*/
00701 }
00702 /*@=mustmod@*/
00703 
00704 static /*@null@*/
00705 void * rpmsslFree(/*@only@*/ void * impl)
00706         /*@modifies impl @*/
00707 {
00708     rpmsslClean(impl);
00709     impl = _free(impl);
00710     return NULL;
00711 }
00712 
00713 static
00714 void * rpmsslInit(void)
00715         /*@*/
00716 {
00717     rpmssl ssl = xcalloc(1, sizeof(*ssl));
00718 /*@-moduncon@*/
00719     ERR_load_crypto_strings();
00720 /*@=moduncon@*/
00721     return (void *) ssl;
00722 }
00723 
00724 struct pgpImplVecs_s rpmsslImplVecs = {
00725         rpmsslSetRSA,
00726         rpmsslSetDSA,
00727         rpmsslSetELG,
00728         rpmsslSetECDSA,
00729 
00730         rpmsslErrChk,
00731         rpmsslAvailableCipher, rpmsslAvailableDigest, rpmsslAvailablePubkey,
00732         rpmsslVerify, rpmsslSign, rpmsslGenerate,
00733 
00734         rpmsslMpiItem, rpmsslClean,
00735         rpmsslFree, rpmsslInit
00736 };
00737 
00738 #endif
00739