rpm 5.3.7
|
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