rpm  5.4.4
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 = 1;         /* assume error */
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         goto exit;
00138 
00139     xx = rpmDigestFinal(ctx, (void **)&gc->digest, &gc->digestlen, 0);
00140     ctx = NULL;         /* XXX avoid double free */
00141 
00142     /* Set RSA hash. */
00143     err = rpmgcErr(gc, "RSA c",
00144             gcry_sexp_build(&gc->hash, NULL,
00145                 "(data (flags pkcs1) (hash %s %b))", hash_algo_name, gc->digestlen, gc->digest) );
00146 if (_pgp_debug < 0) rpmgcDump("gc->hash", gc->hash);
00147 
00148     /* Compare leading 16 bits of digest for quick check. */
00149     {   const rpmuint8_t *s = gc->digest;
00150         const rpmuint8_t *t = sigp->signhash16;
00151         rc = memcmp(s, t, sizeof(sigp->signhash16));
00152     }
00153 
00154 exit:
00155     if (ctx) {          /* XXX Free the context on error returns. */
00156         xx = rpmDigestFinal(ctx, NULL, NULL, 0);
00157         ctx = NULL;
00158     }
00159 SPEW(0, !rc, dig);
00160     return rc;
00161 }
00162 
00163 static
00164 int rpmgcSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00165         /*@modifies dig @*/
00166 {
00167     rpmgc gc = dig->impl;
00168     gcry_error_t err;
00169     int rc;
00170     int xx;
00171 pgpDigParams pubp = pgpGetPubkey(dig);
00172 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00173 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00174 
00175 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00176     xx = rpmDigestFinal(ctx, (void **)&gc->digest, &gc->digestlen, 0);
00177 
00178     /* Set DSA hash. */
00179 /*@-moduncon -noeffectuncon @*/
00180     {   gcry_mpi_t c = NULL;
00181         /* XXX truncate to 160 bits */
00182         err = rpmgcErr(gc, "DSA c",
00183                 gcry_mpi_scan(&c, GCRYMPI_FMT_USG, gc->digest, 160/8, NULL));
00184         err = rpmgcErr(gc, "DSA gc->hash",
00185                 gcry_sexp_build(&gc->hash, NULL,
00186                         "(data (flags raw) (value %m))", c) );
00187         gcry_mpi_release(c);
00188 if (_pgp_debug < 0) rpmgcDump("gc->hash", gc->hash);
00189     }
00190 /*@=moduncon =noeffectuncon @*/
00191 
00192     /* Compare leading 16 bits of digest for quick check. */
00193     rc = memcmp(gc->digest, sigp->signhash16, sizeof(sigp->signhash16));
00194 SPEW(0, !rc, dig);
00195     return rc;
00196 }
00197 
00198 static
00199 int rpmgcSetELG(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00200         /*@*/
00201 {
00202     rpmgc gc = dig->impl;
00203     int rc = 1;         /* XXX always fail. */
00204     int xx;
00205 pgpDigParams pubp = pgpGetPubkey(dig);
00206 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00207 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00208 
00209 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00210     xx = rpmDigestFinal(ctx, (void **)&gc->digest, &gc->digestlen, 0);
00211 
00212     /* Compare leading 16 bits of digest for quick check. */
00213 
00214 SPEW(0, !rc, dig);
00215     return rc;
00216 }
00217 
00218 static
00219 int rpmgcSetECDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00220         /*@*/
00221 {
00222     rpmgc gc = dig->impl;
00223     int rc = 1;         /* assume failure. */
00224     gpg_error_t err;
00225     int xx;
00226 pgpDigParams pubp = pgpGetPubkey(dig);
00227 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00228 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00229 
00230 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00231 gc->digest = _free(gc->digest);
00232 gc->digestlen = 0;
00233     xx = rpmDigestFinal(ctx, (void **)&gc->digest, &gc->digestlen, 0);
00234 
00235     {   gcry_mpi_t c = NULL;
00236         err = rpmgcErr(gc, "ECDSA c",
00237                 gcry_mpi_scan(&c, GCRYMPI_FMT_USG, gc->digest, gc->digestlen, NULL));
00238 if (gc->hash) {
00239     gcry_sexp_release(gc->hash);        gc->hash = NULL;
00240 }
00241         err = rpmgcErr(gc, "ECDSA gc->hash",
00242                 gcry_sexp_build(&gc->hash, NULL,
00243                         "(data (flags raw) (value %m))", c) );
00244         gcry_mpi_release(c);
00245 if (_pgp_debug < 0) rpmgcDump("gc->hash", gc->hash);
00246     }
00247 
00248     /* Compare leading 16 bits of digest for quick check. */
00249     rc = 0;
00250 
00251 SPEW(0, !rc, dig);
00252     return rc;
00253 }
00254 
00255 static int rpmgcErrChk(pgpDig dig, const char * msg, int rc, unsigned expected)
00256 {
00257 rpmgc gc = dig->impl;
00258     /* Was the return code the expected result? */
00259     rc = (gcry_err_code(gc->err) != expected);
00260     if (rc)
00261         fail("%s failed: %s\n", msg, gpg_strerror(gc->err));
00262 /* XXX FIXME: pgpImplStrerror */
00263     return rc;  /* XXX 0 on success */
00264 }
00265 
00266 static int rpmgcAvailable(rpmgc gc, int algo, int rc)
00267 {
00268     /* Permit non-certified algo's if not in FIPS mode. */
00269     if (rc && !gc->in_fips_mode)
00270         rc = 0;
00271 #ifdef  NOTNOW
00272     if (rc)
00273         rpmlog(RPMLOG_INFO,"  algorithm %d not available in fips mode\n", algo);
00274 #else
00275 /* XXX FIXME: refactor back into trsa.c */
00276     if (rc)
00277         fprintf(stderr,"  algorithm %d not available in fips mode\n", algo);
00278 #endif
00279     return rc;  /* XXX 0 on success */
00280 }
00281 
00282 static int rpmgcAvailableCipher(pgpDig dig, int algo)
00283 {
00284     return rpmgcAvailable(dig->impl, algo, gcry_cipher_test_algo(algo));
00285 }
00286 
00287 static int rpmgcAvailableDigest(pgpDig dig, int algo)
00288 {
00289     int rc = 0; /* assume available */
00290     rc = rpmgcAvailable(dig->impl, algo,
00291         (gcry_md_test_algo(algo) || algo == PGPHASHALGO_MD5));
00292     return rc;
00293 }
00294 
00295 static int rpmgcAvailablePubkey(pgpDig dig, int algo)
00296 {
00297     int rc = 0; /* assume available */
00298     rc = rpmgcAvailable(dig->impl, algo, gcry_pk_test_algo(algo));
00299     return rc;
00300 }
00301 
00302 static
00303 int rpmgcVerify(pgpDig dig)
00304 {
00305     rpmgc gc = dig->impl;
00306     int rc;
00307 pgpDigParams pubp = pgpGetPubkey(dig);
00308 pgpDigParams sigp = pgpGetSignature(dig);
00309 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00310 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00311 
00312     if (gc->sig == NULL) {
00313         pgpDigParams pubp = pgpGetPubkey(dig);
00314         switch (pubp->pubkey_algo) {
00315         case PGPPUBKEYALGO_RSA:
00316 assert(gc->c);
00317             gc->err = rpmgcErr(gc, "RSA gc->sig",
00318                 gcry_sexp_build(&gc->sig, NULL,
00319                         "(sig-val (RSA (s %m)))", gc->c) );
00320             break;
00321         case PGPPUBKEYALGO_DSA:
00322         case PGPPUBKEYALGO_ELGAMAL:     /* XXX FIXME: untested. */
00323 assert(gc->r);
00324 assert(gc->s);
00325             gc->err = rpmgcErr(gc, "DSA gc->sig",
00326                 gcry_sexp_build(&gc->sig, NULL,
00327                         "(sig-val (DSA (r %m) (s %m)))", gc->r, gc->s) );
00328             break;
00329         case PGPPUBKEYALGO_ECDSA:       /* XXX FIXME */
00330         default:
00331 assert(0);
00332             break;
00333         }
00334 if (_pgp_debug < 0)
00335 rpmgcDump("gc->sig", gc->sig);
00336     }
00337 
00338     if (gc->pub_key == NULL) {
00339         pgpDigParams pubp = pgpGetPubkey(dig);
00340         switch (pubp->pubkey_algo) {
00341         case PGPPUBKEYALGO_RSA:
00342 assert(gc->n);
00343 assert(gc->e);
00344             gc->err = rpmgcErr(gc, "RSA gc->pub_key",
00345                 gcry_sexp_build(&gc->pub_key, NULL,
00346                         "(public-key (RSA (n %m) (e %m)))", gc->n, gc->e) );
00347             break;
00348         case PGPPUBKEYALGO_DSA:
00349 assert(gc->p);
00350 assert(gc->q);
00351 assert(gc->g);
00352 assert(gc->y);
00353             gc->err = rpmgcErr(gc, "DSA gc->pub_key",
00354                 gcry_sexp_build(&gc->pub_key, NULL,
00355                         "(public-key (DSA (p %m) (q %m) (g %m) (y %m)))",
00356                         gc->p, gc->q, gc->g, gc->y) );
00357             break;
00358         case PGPPUBKEYALGO_ELGAMAL:     /* XXX FIXME: untested. */
00359 assert(gc->p);
00360 assert(gc->g);
00361 assert(gc->y);
00362             gc->err = rpmgcErr(gc, "ELG gc->pub_key",
00363                 gcry_sexp_build(&gc->pub_key, NULL,
00364                         "(public-key (ELG (p %m) (g %m) (y %m)))",
00365                         gc->p, gc->g, gc->y) );
00366             break;
00367         case PGPPUBKEYALGO_ECDSA:
00368         default:
00369 assert(0);
00370             break;
00371         }
00372 if (_pgp_debug < 0)
00373 rpmgcDump("gc->pub_key", gc->pub_key);
00374     }
00375 
00376     /* Verify the signature. */
00377     gc->err = rpmgcErr(gc, "gcry_pk_verify",
00378                 gcry_pk_verify (gc->sig, gc->hash, gc->pub_key));
00379 
00380     rc = (gc->err == 0);
00381 
00382 SPEW(0, rc, dig);
00383     return rc;          /* XXX 1 on success */
00384 }
00385 
00386 static
00387 int rpmgcSign(pgpDig dig)
00388 {
00389     rpmgc gc = dig->impl;
00390     int rc;
00391 pgpDigParams pubp = pgpGetPubkey(dig);
00392 pgpDigParams sigp = pgpGetSignature(dig);
00393 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00394 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
00395 
00396     /* Sign the hash. */
00397     gc->err = rpmgcErr(gc, "gcry_pk_sign",
00398                 gcry_pk_sign (&gc->sig, gc->hash, gc->sec_key));
00399 
00400 if (_pgp_debug < 0 && gc->sig) rpmgcDump("gc->sig", gc->sig);
00401 
00402     rc = (gc->err == 0);
00403 
00404 SPEW(!rc, rc, dig);
00405     return rc;          /* XXX 1 on success */
00406 }
00407 
00408 static
00409 int rpmgcGenerate(pgpDig dig)
00410         /*@*/
00411 {
00412     rpmgc gc = dig->impl;
00413     int rc;
00414 pgpDigParams pubp = pgpGetPubkey(dig);
00415 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
00416 
00417 /* XXX FIXME: gc->{key_spec,key_pair} could be local. */
00418 /* XXX FIXME: gc->qbits w DSA? curve w ECDSA? other params? */
00419     switch (pubp->pubkey_algo) {
00420     case PGPPUBKEYALGO_RSA:
00421 if (gc->nbits == 0) gc->nbits = 1024;   /* XXX FIXME */
00422         gc->err = rpmgcErr(gc, "gc->key_spec",
00423                 gcry_sexp_build(&gc->key_spec, NULL,
00424                         gc->in_fips_mode
00425                             ? "(genkey (RSA (nbits %d)))"
00426                             : "(genkey (RSA (nbits %d)(transient-key)))",
00427                         gc->nbits));
00428         break;
00429     case PGPPUBKEYALGO_DSA:
00430 if (gc->nbits == 0) gc->nbits = 1024;   /* XXX FIXME */
00431         gc->err = rpmgcErr(gc, "gc->key_spec",
00432                 gcry_sexp_build(&gc->key_spec, NULL,
00433                         gc->in_fips_mode
00434                             ? "(genkey (DSA (nbits %d)))"
00435                             : "(genkey (DSA (nbits %d)(transient-key)))",
00436                         gc->nbits));
00437         break;
00438     case PGPPUBKEYALGO_ELGAMAL: /* XXX FIXME: untested. */
00439 if (gc->nbits == 0) gc->nbits = 1024;   /* XXX FIXME */
00440         gc->err = rpmgcErr(gc, "gc->key_spec",
00441                 gcry_sexp_build(&gc->key_spec, NULL,
00442                         gc->in_fips_mode
00443                             ? "(genkey (ELG (nbits %d)))"
00444                             : "(genkey (ELG (nbits %d)(transient-key)))",
00445                         gc->nbits));
00446         break;
00447     case PGPPUBKEYALGO_ECDSA:
00448 if (gc->nbits == 0) gc->nbits = 256;   /* XXX FIXME */
00449 #ifdef  DYING
00450         gc->err = rpmgcErr(gc, "gc->key_spec",
00451                 gcry_sexp_build(&gc->key_spec, NULL,
00452                         gc->in_fips_mode
00453                             ? "(genkey (ECDSA (nbits %d)))"
00454                             : "(genkey (ECDSA (nbits %d)(transient-key)))",
00455                         gc->nbits));
00456 #else
00457         gc->err = rpmgcErr(gc, "gc->key_spec",
00458                 gcry_sexp_build(&gc->key_spec, NULL,
00459                         gc->in_fips_mode
00460                             ? "(genkey (ECDSA (curve prime256v1)))"
00461                             : "(genkey (ECDSA (curve prime256v1)(transient-key)))",
00462                         gc->nbits));
00463 #endif
00464         break;
00465     default:
00466 assert(0);
00467         break;
00468     }
00469     if (gc->err)
00470         goto exit;
00471 if ((_rpmgc_debug || _pgp_debug < 0) && gc->key_spec) rpmgcDump("gc->key_spec", gc->key_spec);
00472 
00473     /* Generate the key pair. */
00474     gc->err = rpmgcErr(gc, "gc->key_pair",
00475                 gcry_pk_genkey(&gc->key_pair, gc->key_spec));
00476     if (gc->err)
00477         goto exit;
00478 if ((_rpmgc_debug || _pgp_debug < 0) && gc->key_pair) rpmgcDump("gc->key_pair", gc->key_pair);
00479 
00480     gc->pub_key = gcry_sexp_find_token(gc->key_pair, "public-key", 0);
00481     if (gc->pub_key == NULL)
00482 /* XXX FIXME: refactor errmsg here. */
00483         goto exit;
00484 if ((_rpmgc_debug || _pgp_debug < 0) && gc->pub_key) rpmgcDump("gc->pub_key", gc->pub_key);
00485 
00486     gc->sec_key = gcry_sexp_find_token(gc->key_pair, "private-key", 0);
00487     if (gc->sec_key == NULL)
00488 /* XXX FIXME: refactor errmsg here. */
00489         goto exit;
00490 if ((_rpmgc_debug || _pgp_debug < 0) && gc->sec_key) rpmgcDump("gc->sec_key", gc->sec_key);
00491 
00492 exit:
00493 
00494     rc = (gc->err == 0 && gc->pub_key && gc->sec_key);
00495 
00496 #ifdef  NOTYET
00497 if (gc->key_spec) {
00498     gcry_sexp_release(gc->key_spec);
00499     gc->key_spec = NULL;
00500 }
00501 if (gc->key_pair) {
00502     gcry_sexp_release(gc->key_pair);
00503     gc->key_pair = NULL;
00504 }
00505 #endif
00506 
00507 SPEW(!rc, rc, dig);
00508     return rc;          /* XXX 1 on success */
00509 }
00510 
00511 /*@-globuse -mustmod @*/
00512 static
00513 int rpmgcMpiItem(/*@unused@*/ const char * pre, pgpDig dig, int itemno,
00514                 const rpmuint8_t * p,
00515                 /*@unused@*/ /*@null@*/ const rpmuint8_t * pend)
00516         /*@globals fileSystem @*/
00517         /*@modifies dig, fileSystem @*/
00518 {
00519     rpmgc gc = dig->impl;
00520     size_t nb = pgpMpiLen(p);
00521     const char * mpiname = "";
00522     gcry_mpi_t * mpip = NULL;
00523     size_t nscan = 0;
00524     int rc = 0;
00525 
00526     switch (itemno) {
00527     default:
00528 assert(0);
00529     case 50:            /* ECDSA r */
00530     case 51:            /* ECDSA s */
00531     case 60:            /* ECDSA curve OID */
00532     case 61:            /* ECDSA Q */
00533         break;
00534     case 10:            /* RSA m**d */
00535         mpiname = "RSA m**d";   mpip = &gc->c;
00536         break;
00537     case 20:            /* DSA r */
00538         mpiname = "DSA r";      mpip = &gc->r;
00539         break;
00540     case 21:            /* DSA s */
00541         mpiname = "DSA s";      mpip = &gc->s;
00542         break;
00543     case 30:            /* RSA n */
00544         mpiname = "RSA n";      mpip = &gc->n;
00545         break;
00546     case 31:            /* RSA e */
00547         mpiname = "RSA e";      mpip = &gc->e;
00548         break;
00549     case 40:            /* DSA p */
00550         mpiname = "DSA p";      mpip = &gc->p;
00551         break;
00552     case 41:            /* DSA q */
00553         mpiname = "DSA q";      mpip = &gc->q;
00554         break;
00555     case 42:            /* DSA g */
00556         mpiname = "DSA g";      mpip = &gc->g;
00557         break;
00558     case 43:            /* DSA y */
00559         mpiname = "DSA y";      mpip = &gc->y;
00560         break;
00561     }
00562 
00563 /*@-moduncon -noeffectuncon @*/
00564     gc->err = rpmgcErr(gc, mpiname,
00565                 gcry_mpi_scan(mpip, GCRYMPI_FMT_PGP, p, nb, &nscan) );
00566 /*@=moduncon =noeffectuncon @*/
00567 assert(nb == nscan);
00568 
00569     if (_pgp_debug < 0)
00570     {   unsigned nbits = gcry_mpi_get_nbits(*mpip);
00571         unsigned char * hex = NULL;
00572         size_t nhex = 0;
00573         gc->err = rpmgcErr(gc, "MPI print",
00574                 gcry_mpi_aprint(GCRYMPI_FMT_HEX, &hex, &nhex, *mpip) );
00575         fprintf(stderr, "*** %s\t%5d:%s\n", mpiname, (int)nbits, hex);
00576         hex = _free(hex);
00577     }
00578 
00579     return rc;
00580 }
00581 /*@=globuse =mustmod @*/
00582 
00583 /*@-mustmod@*/
00584 static
00585 void rpmgcClean(void * impl)
00586         /*@modifies impl @*/
00587 {
00588     rpmgc gc = impl;
00589 /*@-moduncon -noeffectuncon @*/
00590     if (gc != NULL) {
00591         gc->nbits = 0;
00592         gc->err = 0;
00593         gc->badok = 0;
00594         gc->digest = _free(gc->digest);
00595         gc->digestlen = 0;
00596 
00597         if (gc->key_spec) {
00598             gcry_sexp_release(gc->key_spec);
00599             gc->key_spec = NULL;
00600         }
00601         if (gc->key_pair) {
00602             gcry_sexp_release(gc->key_pair);
00603             gc->key_pair = NULL;
00604         }
00605         if (gc->pub_key) {
00606             gcry_sexp_release(gc->pub_key);
00607             gc->pub_key = NULL;
00608         }
00609         if (gc->sec_key) {
00610             gcry_sexp_release(gc->sec_key);
00611             gc->sec_key = NULL;
00612         }
00613         if (gc->hash) {
00614             gcry_sexp_release(gc->hash);
00615             gc->hash = NULL;
00616         }
00617         if (gc->sig) {
00618             gcry_sexp_release(gc->sig);
00619             gc->sig = NULL;
00620         }
00621 
00622         if (gc->c) {
00623             gcry_mpi_release(gc->c);
00624             gc->c = NULL;
00625         }
00626         if (gc->p) {
00627             gcry_mpi_release(gc->p);
00628             gc->p = NULL;
00629         }
00630         if (gc->q) {
00631             gcry_mpi_release(gc->q);
00632             gc->q = NULL;
00633         }
00634         if (gc->g) {
00635             gcry_mpi_release(gc->g);
00636             gc->g = NULL;
00637         }
00638         if (gc->y) {
00639             gcry_mpi_release(gc->y);
00640             gc->y = NULL;
00641         }
00642 
00643         if (gc->r) {
00644             gcry_mpi_release(gc->r);
00645             gc->r = NULL;
00646         }
00647         if (gc->s) {
00648             gcry_mpi_release(gc->s);
00649             gc->s = NULL;
00650         }
00651         if (gc->n) {
00652             gcry_mpi_release(gc->n);
00653             gc->n = NULL;
00654         }
00655         if (gc->e) {
00656             gcry_mpi_release(gc->e);
00657             gc->e = NULL;
00658         }
00659 
00660     }
00661 /*@=moduncon =noeffectuncon @*/
00662 }
00663 /*@=mustmod@*/
00664 
00665 /*@unchecked@*/
00666 static int rpmgc_initialized;
00667 
00668 static /*@null@*/
00669 void * rpmgcFree(/*@only@*/ void * impl)
00670         /*@globals rpmgc_initialized @*/
00671         /*@modifies impl, rpmgc_initialized @*/
00672 {
00673 
00674     rpmgcClean(impl);
00675 
00676     if (--rpmgc_initialized == 0 && _pgp_debug < 0) {
00677         rpmgc gc = impl;
00678         gc->err = rpmgcErr(gc, "CLEAR_DEBUG_FLAGS",
00679                 gcry_control(GCRYCTL_CLEAR_DEBUG_FLAGS, 3));
00680         gc->err = rpmgcErr(gc, "SET_VERBOSITY",
00681                 gcry_control(GCRYCTL_SET_VERBOSITY, 0) );
00682     }
00683 
00684     impl = _free(impl);
00685 
00686     return NULL;
00687 }
00688 
00689 static
00690 void * rpmgcInit(void)
00691         /*@globals rpmgc_initialized @*/
00692         /*@modifies rpmgc_initialized @*/
00693 {
00694     rpmgc gc = xcalloc(1, sizeof(*gc));
00695 
00696     if (rpmgc_initialized++ == 0 && _pgp_debug < 0) {
00697         gc->err = rpmgcErr(gc, "SET_VERBOSITY",
00698                 gcry_control(GCRYCTL_SET_VERBOSITY, 3) );
00699         gc->err = rpmgcErr(gc, "SET_DEBUG_FLAGS",
00700                 gcry_control(GCRYCTL_SET_DEBUG_FLAGS, 3) );
00701     }
00702 
00703     return (void *) gc;
00704 }
00705 
00706 struct pgpImplVecs_s rpmgcImplVecs = {
00707         rpmgcSetRSA,
00708         rpmgcSetDSA,
00709         rpmgcSetELG,
00710         rpmgcSetECDSA,
00711 
00712         rpmgcErrChk,
00713         rpmgcAvailableCipher, rpmgcAvailableDigest, rpmgcAvailablePubkey,
00714         rpmgcVerify, rpmgcSign, rpmgcGenerate,
00715 
00716         rpmgcMpiItem, rpmgcClean,
00717         rpmgcFree, rpmgcInit
00718 };
00719 
00720 #endif
00721