rpm 5.3.7

rpmio/rpmgc.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <rpmiotypes.h>
00008 #define _RPMGC_INTERNAL
00009 #if defined(WITH_GCRYPT)
00010 #define _RPMPGP_INTERNAL
00011 #include <rpmgc.h>
00012 #endif
00013 
00014 #include "debug.h"
00015 
00016 #if defined(WITH_GCRYPT)
00017 
00018 /*@access pgpDig @*/
00019 /*@access pgpDigParams @*/
00020 
00021 /*@-redecl@*/
00022 /*@unchecked@*/
00023 extern int _pgp_debug;
00024 
00025 /*@unchecked@*/
00026 extern int _pgp_print;
00027 /*@=redecl@*/
00028 
00029 
00030 /*@unchecked@*/
00031 static int _rpmgc_debug;
00032 
00033 #define SPEW(_t, _rc, _dig)     \
00034   { if ((_t) || _rpmgc_debug || _pgp_debug < 0) \
00035         fprintf(stderr, "<-- %s(%p) %s\t%s\n", __FUNCTION__, (_dig), \
00036                 ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN); \
00037   }
00038 
00039 static const char * rpmgcHashAlgo2Name(uint32_t algo)
00040 {
00041     return pgpValStr(pgpHashTbl, (rpmuint8_t)algo);
00042 }
00043 
00044 static const char * rpmgcPubkeyAlgo2Name(uint32_t algo)
00045 {
00046     return pgpValStr(pgpPubkeyTbl, (rpmuint8_t)algo);
00047 }
00048 
00049 static void fail(const char *format, ...)
00050 {
00051     va_list arg_ptr;
00052 
00053     va_start(arg_ptr, format);
00054     vfprintf(stderr, format, arg_ptr);
00055     va_end(arg_ptr);
00056     _pgp_error_count++;
00057 }
00058 
00059 static
00060 void rpmgcDump(const char * msg, gcry_sexp_t sexp)
00061         /*@*/
00062 {
00063     if (_rpmgc_debug || _pgp_debug) {
00064         size_t nb = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
00065         char * buf = alloca(nb+1);
00066 
00067         nb = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, buf, nb);
00068         buf[nb] = '\0';
00069         fprintf(stderr, "========== %s:\n%s", msg, buf);
00070     }
00071     return;
00072 }
00073 
00074 static
00075 gcry_error_t rpmgcErr(rpmgc gc, const char * msg, gcry_error_t err)
00076         /*@*/
00077 {
00078     /* XXX Don't spew on expected failures ... */
00079     if (err && gcry_err_code(err) != gc->badok)
00080         fprintf (stderr, "rpmgc: %s(0x%0x): %s/%s\n",
00081                 msg, (unsigned)err, gcry_strsource(err), gcry_strerror(err));
00082     return err;
00083 }
00084 
00085 static
00086 int rpmgcSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00087         /*@modifies dig @*/
00088 {
00089     rpmgc gc = dig->impl;
00090     gcry_error_t err;
00091     const char * hash_algo_name = NULL;
00092     int rc;
00093     int xx;
00094 pgpDigParams pubp = pgpGetPubkey(dig);
00095 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00096 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00097 
00098     switch (sigp->hash_algo) {
00099     case PGPHASHALGO_MD5:
00100         hash_algo_name = "md5";
00101         break;
00102     case PGPHASHALGO_SHA1:
00103         hash_algo_name = "sha1";
00104         break;
00105     case PGPHASHALGO_RIPEMD160:
00106         hash_algo_name = "ripemd160";   /* XXX FIXME: RPM != GCRYPT name */
00107         break;
00108     case PGPHASHALGO_MD2:
00109         hash_algo_name = "md2";
00110         break;
00111     case PGPHASHALGO_TIGER192:
00112         hash_algo_name = "tiger";
00113         break;
00114     case PGPHASHALGO_HAVAL_5_160:
00115 #ifdef  NOTYET
00116         hash_algo_name = "haval";
00117 #endif
00118         break;
00119     case PGPHASHALGO_SHA256:
00120         hash_algo_name = "sha256";
00121         break;
00122     case PGPHASHALGO_SHA384:
00123         hash_algo_name = "sha384";
00124         break;
00125     case PGPHASHALGO_SHA512:
00126         hash_algo_name = "sha512";
00127         break;
00128     case PGPHASHALGO_SHA224:
00129 #ifdef  NOTYET
00130         hash_algo_name = "sha224";
00131 #endif
00132         break;
00133     default:
00134         break;
00135     }
00136     if (hash_algo_name == NULL)
00137         return 1;
00138 
00139     xx = rpmDigestFinal(ctx, (void **)&gc->digest, &gc->digestlen, 0);
00140 
00141     /* Set RSA hash. */
00142     err = rpmgcErr(gc, "RSA c",
00143             gcry_sexp_build(&gc->hash, NULL,
00144                 "(data (flags pkcs1) (hash %s %b))", hash_algo_name, gc->digestlen, gc->digest) );
00145 if (_pgp_debug < 0) rpmgcDump("gc->hash", gc->hash);
00146 
00147     /* Compare leading 16 bits of digest for quick check. */
00148     {   const rpmuint8_t *s = gc->digest;
00149         const rpmuint8_t *t = sigp->signhash16;
00150         rc = memcmp(s, t, sizeof(sigp->signhash16));
00151     }
00152 
00153 SPEW(0, !rc, dig);
00154     return rc;
00155 }
00156 
00157 static
00158 int rpmgcSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00159         /*@modifies dig @*/
00160 {
00161     rpmgc gc = dig->impl;
00162     gcry_error_t err;
00163     int rc;
00164     int xx;
00165 pgpDigParams pubp = pgpGetPubkey(dig);
00166 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00167 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00168 
00169 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00170     xx = rpmDigestFinal(ctx, (void **)&gc->digest, &gc->digestlen, 0);
00171 
00172     /* Set DSA hash. */
00173 /*@-moduncon -noeffectuncon @*/
00174     {   gcry_mpi_t c = NULL;
00175         /* XXX truncate to 160 bits */
00176         err = rpmgcErr(gc, "DSA c",
00177                 gcry_mpi_scan(&c, GCRYMPI_FMT_USG, gc->digest, 160/8, NULL));
00178         err = rpmgcErr(gc, "DSA gc->hash",
00179                 gcry_sexp_build(&gc->hash, NULL,
00180                         "(data (flags raw) (value %m))", c) );
00181         gcry_mpi_release(c);
00182 if (_pgp_debug < 0) rpmgcDump("gc->hash", gc->hash);
00183     }
00184 /*@=moduncon =noeffectuncon @*/
00185 
00186     /* Compare leading 16 bits of digest for quick check. */
00187     rc = memcmp(gc->digest, sigp->signhash16, sizeof(sigp->signhash16));
00188 SPEW(0, !rc, dig);
00189     return rc;
00190 }
00191 
00192 static
00193 int rpmgcSetELG(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00194         /*@*/
00195 {
00196     rpmgc gc = dig->impl;
00197     int rc = 1;         /* XXX always fail. */
00198     int xx;
00199 pgpDigParams pubp = pgpGetPubkey(dig);
00200 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00201 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00202 
00203 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00204     xx = rpmDigestFinal(ctx, (void **)&gc->digest, &gc->digestlen, 0);
00205 
00206     /* Compare leading 16 bits of digest for quick check. */
00207 
00208 SPEW(0, !rc, dig);
00209     return rc;
00210 }
00211 
00212 static
00213 int rpmgcSetECDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00214         /*@*/
00215 {
00216     rpmgc gc = dig->impl;
00217     int rc = 1;         /* assume failure. */
00218     gpg_error_t err;
00219     int xx;
00220 pgpDigParams pubp = pgpGetPubkey(dig);
00221 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00222 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00223 
00224 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00225 gc->digest = _free(gc->digest);
00226 gc->digestlen = 0;
00227     xx = rpmDigestFinal(ctx, (void **)&gc->digest, &gc->digestlen, 0);
00228 
00229     {   gcry_mpi_t c = NULL;
00230         err = rpmgcErr(gc, "ECDSA c",
00231                 gcry_mpi_scan(&c, GCRYMPI_FMT_USG, gc->digest, gc->digestlen, NULL));
00232 if (gc->hash) {
00233     gcry_sexp_release(gc->hash);        gc->hash = NULL;
00234 }
00235         err = rpmgcErr(gc, "ECDSA gc->hash",
00236                 gcry_sexp_build(&gc->hash, NULL,
00237                         "(data (flags raw) (value %m))", c) );
00238         gcry_mpi_release(c);
00239 if (_pgp_debug < 0) rpmgcDump("gc->hash", gc->hash);
00240     }
00241 
00242     /* Compare leading 16 bits of digest for quick check. */
00243     rc = 0;
00244 
00245 SPEW(0, !rc, dig);
00246     return rc;
00247 }
00248 
00249 static int rpmgcErrChk(pgpDig dig, const char * msg, int rc, unsigned expected)
00250 {
00251 rpmgc gc = dig->impl;
00252     /* Was the return code the expected result? */
00253     rc = (gcry_err_code(gc->err) != expected);
00254     if (rc)
00255         fail("%s failed: %s\n", msg, gpg_strerror(gc->err));
00256 /* XXX FIXME: pgpImplStrerror */
00257     return rc;  /* XXX 0 on success */
00258 }
00259 
00260 static int rpmgcAvailable(rpmgc gc, int algo, int rc)
00261 {
00262     /* Permit non-certified algo's if not in FIPS mode. */
00263     if (rc && !gc->in_fips_mode)
00264         rc = 0;
00265 #ifdef  NOTNOW
00266     if (rc)
00267         rpmlog(RPMLOG_INFO,"  algorithm %d not available in fips mode\n", algo);
00268 #else
00269 /* XXX FIXME: refactor back into trsa.c */
00270     if (rc)
00271         fprintf(stderr,"  algorithm %d not available in fips mode\n", algo);
00272 #endif
00273     return rc;  /* XXX 0 on success */
00274 }
00275 
00276 static int rpmgcAvailableCipher(pgpDig dig, int algo)
00277 {
00278     return rpmgcAvailable(dig->impl, algo, gcry_cipher_test_algo(algo));
00279 }
00280 
00281 static int rpmgcAvailableDigest(pgpDig dig, int algo)
00282 {
00283     int rc = 0; /* assume available */
00284     rc = rpmgcAvailable(dig->impl, algo,
00285         (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
00286     return rc;
00287 }
00288 
00289 static int rpmgcAvailablePubkey(pgpDig dig, int algo)
00290 {
00291     int rc = 0; /* assume available */
00292     rc = rpmgcAvailable(dig->impl, algo, gcry_pk_test_algo(algo));
00293     return rc;
00294 }
00295 
00296 static
00297 int rpmgcVerify(pgpDig dig)
00298 {
00299     rpmgc gc = dig->impl;
00300     int rc;
00301 pgpDigParams pubp = pgpGetPubkey(dig);
00302 pgpDigParams sigp = pgpGetSignature(dig);
00303 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00304 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00305 
00306     if (gc->sig == NULL) {
00307         pgpDigParams pubp = pgpGetPubkey(dig);
00308         switch (pubp->pubkey_algo) {
00309         case PGPPUBKEYALGO_RSA:
00310 assert(gc->c);
00311             gc->err = rpmgcErr(gc, "RSA gc->sig",
00312                 gcry_sexp_build(&gc->sig, NULL,
00313                         "(sig-val (RSA (s %m)))", gc->c) );
00314             break;
00315         case PGPPUBKEYALGO_DSA:
00316         case PGPPUBKEYALGO_ELGAMAL:     /* XXX FIXME: untested. */
00317 assert(gc->r);
00318 assert(gc->s);
00319             gc->err = rpmgcErr(gc, "DSA gc->sig",
00320                 gcry_sexp_build(&gc->sig, NULL,
00321                         "(sig-val (DSA (r %m) (s %m)))", gc->r, gc->s) );
00322             break;
00323         case PGPPUBKEYALGO_ECDSA:       /* XXX FIXME */
00324         default:
00325 assert(0);
00326             break;
00327         }
00328 if (_pgp_debug < 0)
00329 rpmgcDump("gc->sig", gc->sig);
00330     }
00331 
00332     if (gc->pub_key == NULL) {
00333         pgpDigParams pubp = pgpGetPubkey(dig);
00334         switch (pubp->pubkey_algo) {
00335         case PGPPUBKEYALGO_RSA:
00336 assert(gc->n);
00337 assert(gc->e);
00338             gc->err = rpmgcErr(gc, "RSA gc->pub_key",
00339                 gcry_sexp_build(&gc->pub_key, NULL,
00340                         "(public-key (RSA (n %m) (e %m)))", gc->n, gc->e) );
00341             break;
00342         case PGPPUBKEYALGO_DSA:
00343 assert(gc->p);
00344 assert(gc->q);
00345 assert(gc->g);
00346 assert(gc->y);
00347             gc->err = rpmgcErr(gc, "DSA gc->pub_key",
00348                 gcry_sexp_build(&gc->pub_key, NULL,
00349                         "(public-key (DSA (p %m) (q %m) (g %m) (y %m)))",
00350                         gc->p, gc->q, gc->g, gc->y) );
00351             break;
00352         case PGPPUBKEYALGO_ELGAMAL:     /* XXX FIXME: untested. */
00353 assert(gc->p);
00354 assert(gc->g);
00355 assert(gc->y);
00356             gc->err = rpmgcErr(gc, "ELG gc->pub_key",
00357                 gcry_sexp_build(&gc->pub_key, NULL,
00358                         "(public-key (ELG (p %m) (g %m) (y %m)))",
00359                         gc->p, gc->g, gc->y) );
00360             break;
00361         case PGPPUBKEYALGO_ECDSA:
00362         default:
00363 assert(0);
00364             break;
00365         }
00366 if (_pgp_debug < 0)
00367 rpmgcDump("gc->pub_key", gc->pub_key);
00368     }
00369 
00370     /* Verify the signature. */
00371     gc->err = rpmgcErr(gc, "gcry_pk_verify",
00372                 gcry_pk_verify (gc->sig, gc->hash, gc->pub_key));
00373 
00374     rc = (gc->err == 0);
00375 
00376 SPEW(0, rc, dig);
00377     return rc;          /* XXX 1 on success */
00378 }
00379 
00380 static
00381 int rpmgcSign(pgpDig dig)
00382 {
00383     rpmgc gc = dig->impl;
00384     int rc;
00385 pgpDigParams pubp = pgpGetPubkey(dig);
00386 pgpDigParams sigp = pgpGetSignature(dig);
00387 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00388 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00389 
00390     /* Sign the hash. */
00391     gc->err = rpmgcErr(gc, "gcry_pk_sign",
00392                 gcry_pk_sign (&gc->sig, gc->hash, gc->sec_key));
00393 
00394 if (_pgp_debug < 0 && gc->sig) rpmgcDump("gc->sig", gc->sig);
00395 
00396     rc = (gc->err == 0);
00397 
00398 SPEW(!rc, rc, dig);
00399     return rc;          /* XXX 1 on success */
00400 }
00401 
00402 static
00403 int rpmgcGenerate(pgpDig dig)
00404         /*@*/
00405 {
00406     rpmgc gc = dig->impl;
00407     int rc;
00408 pgpDigParams pubp = pgpGetPubkey(dig);
00409 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00410 
00411 /* XXX FIXME: gc->{key_spec,key_pair} could be local. */
00412 /* XXX FIXME: gc->qbits w DSA? curve w ECDSA? other params? */
00413     switch (pubp->pubkey_algo) {
00414     case PGPPUBKEYALGO_RSA:
00415 if (gc->nbits == 0) gc->nbits = 1024;   /* XXX FIXME */
00416         gc->err = rpmgcErr(gc, "gc->key_spec",
00417                 gcry_sexp_build(&gc->key_spec, NULL,
00418                         gc->in_fips_mode
00419                             ? "(genkey (RSA (nbits %d)))"
00420                             : "(genkey (RSA (nbits %d)(transient-key)))",
00421                         gc->nbits));
00422         break;
00423     case PGPPUBKEYALGO_DSA:
00424 if (gc->nbits == 0) gc->nbits = 1024;   /* XXX FIXME */
00425         gc->err = rpmgcErr(gc, "gc->key_spec",
00426                 gcry_sexp_build(&gc->key_spec, NULL,
00427                         gc->in_fips_mode
00428                             ? "(genkey (DSA (nbits %d)))"
00429                             : "(genkey (DSA (nbits %d)(transient-key)))",
00430                         gc->nbits));
00431         break;
00432     case PGPPUBKEYALGO_ELGAMAL: /* XXX FIXME: untested. */
00433 if (gc->nbits == 0) gc->nbits = 1024;   /* XXX FIXME */
00434         gc->err = rpmgcErr(gc, "gc->key_spec",
00435                 gcry_sexp_build(&gc->key_spec, NULL,
00436                         gc->in_fips_mode
00437                             ? "(genkey (ELG (nbits %d)))"
00438                             : "(genkey (ELG (nbits %d)(transient-key)))",
00439                         gc->nbits));
00440         break;
00441     case PGPPUBKEYALGO_ECDSA:
00442 if (gc->nbits == 0) gc->nbits = 256;   /* XXX FIXME */
00443 #ifdef  DYING
00444         gc->err = rpmgcErr(gc, "gc->key_spec",
00445                 gcry_sexp_build(&gc->key_spec, NULL,
00446                         gc->in_fips_mode
00447                             ? "(genkey (ECDSA (nbits %d)))"
00448                             : "(genkey (ECDSA (nbits %d)(transient-key)))",
00449                         gc->nbits));
00450 #else
00451         gc->err = rpmgcErr(gc, "gc->key_spec",
00452                 gcry_sexp_build(&gc->key_spec, NULL,
00453                         gc->in_fips_mode
00454                             ? "(genkey (ECDSA (curve prime256v1)))"
00455                             : "(genkey (ECDSA (curve prime256v1)(transient-key)))",
00456                         gc->nbits));
00457 #endif
00458         break;
00459     default:
00460 assert(0);
00461         break;
00462     }
00463     if (gc->err)
00464         goto exit;
00465 if ((_rpmgc_debug || _pgp_debug < 0) && gc->key_spec) rpmgcDump("gc->key_spec", gc->key_spec);
00466 
00467     /* Generate the key pair. */
00468     gc->err = rpmgcErr(gc, "gc->key_pair",
00469                 gcry_pk_genkey(&gc->key_pair, gc->key_spec));
00470     if (gc->err)
00471         goto exit;
00472 if ((_rpmgc_debug || _pgp_debug < 0) && gc->key_pair) rpmgcDump("gc->key_pair", gc->key_pair);
00473 
00474     gc->pub_key = gcry_sexp_find_token(gc->key_pair, "public-key", 0);
00475     if (gc->pub_key == NULL)
00476 /* XXX FIXME: refactor errmsg here. */
00477         goto exit;
00478 if ((_rpmgc_debug || _pgp_debug < 0) && gc->pub_key) rpmgcDump("gc->pub_key", gc->pub_key);
00479 
00480     gc->sec_key = gcry_sexp_find_token(gc->key_pair, "private-key", 0);
00481     if (gc->sec_key == NULL)
00482 /* XXX FIXME: refactor errmsg here. */
00483         goto exit;
00484 if ((_rpmgc_debug || _pgp_debug < 0) && gc->sec_key) rpmgcDump("gc->sec_key", gc->sec_key);
00485 
00486 exit:
00487 
00488     rc = (gc->err == 0 && gc->pub_key && gc->sec_key);
00489 
00490 #ifdef  NOTYET
00491 if (gc->key_spec) {
00492     gcry_sexp_release(gc->key_spec);
00493     gc->key_spec = NULL;
00494 }
00495 if (gc->key_pair) {
00496     gcry_sexp_release(gc->key_pair);
00497     gc->key_pair = NULL;
00498 }
00499 #endif
00500 
00501 SPEW(!rc, rc, dig);
00502     return rc;          /* XXX 1 on success */
00503 }
00504 
00505 /*@-globuse -mustmod @*/
00506 static
00507 int rpmgcMpiItem(/*@unused@*/ const char * pre, pgpDig dig, int itemno,
00508                 const rpmuint8_t * p,
00509                 /*@unused@*/ /*@null@*/ const rpmuint8_t * pend)
00510         /*@globals fileSystem @*/
00511         /*@modifies dig, fileSystem @*/
00512 {
00513     rpmgc gc = dig->impl;
00514     size_t nb = pgpMpiLen(p);
00515     const char * mpiname = "";
00516     gcry_mpi_t * mpip = NULL;
00517     size_t nscan = 0;
00518     int rc = 0;
00519 
00520     switch (itemno) {
00521     default:
00522 assert(0);
00523     case 50:            /* ECDSA r */
00524     case 51:            /* ECDSA s */
00525     case 60:            /* ECDSA curve OID */
00526     case 61:            /* ECDSA Q */
00527         break;
00528     case 10:            /* RSA m**d */
00529         mpiname = "RSA m**d";   mpip = &gc->c;
00530         break;
00531     case 20:            /* DSA r */
00532         mpiname = "DSA r";      mpip = &gc->r;
00533         break;
00534     case 21:            /* DSA s */
00535         mpiname = "DSA s";      mpip = &gc->s;
00536         break;
00537     case 30:            /* RSA n */
00538         mpiname = "RSA n";      mpip = &gc->n;
00539         break;
00540     case 31:            /* RSA e */
00541         mpiname = "RSA e";      mpip = &gc->e;
00542         break;
00543     case 40:            /* DSA p */
00544         mpiname = "DSA p";      mpip = &gc->p;
00545         break;
00546     case 41:            /* DSA q */
00547         mpiname = "DSA q";      mpip = &gc->q;
00548         break;
00549     case 42:            /* DSA g */
00550         mpiname = "DSA g";      mpip = &gc->g;
00551         break;
00552     case 43:            /* DSA y */
00553         mpiname = "DSA y";      mpip = &gc->y;
00554         break;
00555     }
00556 
00557 /*@-moduncon -noeffectuncon @*/
00558     gc->err = rpmgcErr(gc, mpiname,
00559                 gcry_mpi_scan(mpip, GCRYMPI_FMT_PGP, p, nb, &nscan) );
00560 /*@=moduncon =noeffectuncon @*/
00561 assert(nb == nscan);
00562 
00563     if (_pgp_debug < 0)
00564     {   unsigned nbits = gcry_mpi_get_nbits(*mpip);
00565         unsigned char * hex = NULL;
00566         size_t nhex = 0;
00567         gc->err = rpmgcErr(gc, "MPI print",
00568                 gcry_mpi_aprint(GCRYMPI_FMT_HEX, &hex, &nhex, *mpip) );
00569         fprintf(stderr, "*** %s\t%5d:%s\n", mpiname, (int)nbits, hex);
00570         hex = _free(hex);
00571     }
00572 
00573     return rc;
00574 }
00575 /*@=globuse =mustmod @*/
00576 
00577 /*@-mustmod@*/
00578 static
00579 void rpmgcClean(void * impl)
00580         /*@modifies impl @*/
00581 {
00582     rpmgc gc = impl;
00583 /*@-moduncon -noeffectuncon @*/
00584     if (gc != NULL) {
00585         gc->nbits = 0;
00586         gc->err = 0;
00587         gc->badok = 0;
00588         gc->digest = _free(gc->digest);
00589         gc->digestlen = 0;
00590 
00591         if (gc->key_spec) {
00592             gcry_sexp_release(gc->key_spec);
00593             gc->key_spec = NULL;
00594         }
00595         if (gc->key_pair) {
00596             gcry_sexp_release(gc->key_pair);
00597             gc->key_pair = NULL;
00598         }
00599         if (gc->pub_key) {
00600             gcry_sexp_release(gc->pub_key);
00601             gc->pub_key = NULL;
00602         }
00603         if (gc->sec_key) {
00604             gcry_sexp_release(gc->sec_key);
00605             gc->sec_key = NULL;
00606         }
00607         if (gc->hash) {
00608             gcry_sexp_release(gc->hash);
00609             gc->hash = NULL;
00610         }
00611         if (gc->sig) {
00612             gcry_sexp_release(gc->sig);
00613             gc->sig = NULL;
00614         }
00615 
00616         if (gc->c) {
00617             gcry_mpi_release(gc->c);
00618             gc->c = NULL;
00619         }
00620         if (gc->p) {
00621             gcry_mpi_release(gc->p);
00622             gc->p = NULL;
00623         }
00624         if (gc->q) {
00625             gcry_mpi_release(gc->q);
00626             gc->q = NULL;
00627         }
00628         if (gc->g) {
00629             gcry_mpi_release(gc->g);
00630             gc->g = NULL;
00631         }
00632         if (gc->y) {
00633             gcry_mpi_release(gc->y);
00634             gc->y = NULL;
00635         }
00636 
00637         if (gc->r) {
00638             gcry_mpi_release(gc->r);
00639             gc->r = NULL;
00640         }
00641         if (gc->s) {
00642             gcry_mpi_release(gc->s);
00643             gc->s = NULL;
00644         }
00645         if (gc->n) {
00646             gcry_mpi_release(gc->n);
00647             gc->n = NULL;
00648         }
00649         if (gc->e) {
00650             gcry_mpi_release(gc->e);
00651             gc->e = NULL;
00652         }
00653 
00654     }
00655 /*@=moduncon =noeffectuncon @*/
00656 }
00657 /*@=mustmod@*/
00658 
00659 /*@unchecked@*/
00660 static int rpmgc_initialized;
00661 
00662 static /*@null@*/
00663 void * rpmgcFree(/*@only@*/ void * impl)
00664         /*@globals rpmgc_initialized @*/
00665         /*@modifies impl, rpmgc_initialized @*/
00666 {
00667 
00668     rpmgcClean(impl);
00669 
00670     if (--rpmgc_initialized == 0 && _pgp_debug < 0) {
00671         rpmgc gc = impl;
00672         gc->err = rpmgcErr(gc, "CLEAR_DEBUG_FLAGS",
00673                 gcry_control(GCRYCTL_CLEAR_DEBUG_FLAGS, 3));
00674         gc->err = rpmgcErr(gc, "SET_VERBOSITY",
00675                 gcry_control(GCRYCTL_SET_VERBOSITY, 0) );
00676     }
00677 
00678     impl = _free(impl);
00679 
00680     return NULL;
00681 }
00682 
00683 static
00684 void * rpmgcInit(void)
00685         /*@globals rpmgc_initialized @*/
00686         /*@modifies rpmgc_initialized @*/
00687 {
00688     rpmgc gc = xcalloc(1, sizeof(*gc));
00689 
00690     if (rpmgc_initialized++ == 0 && _pgp_debug < 0) {
00691         gc->err = rpmgcErr(gc, "SET_VERBOSITY",
00692                 gcry_control(GCRYCTL_SET_VERBOSITY, 3) );
00693         gc->err = rpmgcErr(gc, "SET_DEBUG_FLAGS",
00694                 gcry_control(GCRYCTL_SET_DEBUG_FLAGS, 3) );
00695     }
00696 
00697     return (void *) gc;
00698 }
00699 
00700 struct pgpImplVecs_s rpmgcImplVecs = {
00701         rpmgcSetRSA,
00702         rpmgcSetDSA,
00703         rpmgcSetELG,
00704         rpmgcSetECDSA,
00705 
00706         rpmgcErrChk,
00707         rpmgcAvailableCipher, rpmgcAvailableDigest, rpmgcAvailablePubkey,
00708         rpmgcVerify, rpmgcSign, rpmgcGenerate,
00709 
00710         rpmgcMpiItem, rpmgcClean,
00711         rpmgcFree, rpmgcInit
00712 };
00713 
00714 #endif
00715