rpm 5.3.12
|
00001 00004 #include "system.h" 00005 00006 #define _RPMIOB_INTERNAL /* XXX rpmiobSlurp */ 00007 #include <rpmiotypes.h> 00008 #include <rpmio.h> 00009 #define _RPMHKP_INTERNAL 00010 #include <rpmhkp.h> 00011 #include <rpmmacro.h> 00012 #include <rpmcb.h> 00013 00014 #define _RPMPGP_INTERNAL 00015 #include <rpmpgp.h> 00016 00017 #include <rpmtypes.h> 00018 #include <rpmtag.h> 00019 #define _RPMEVR_INTERNAL 00020 #include <rpmevr.h> 00021 #define _RPMNS_INTERNAL 00022 #include <rpmns.h> 00023 #include <rpmdb.h> 00024 00025 #include <rpmps.h> 00026 #define _RPMTS_INTERNAL /* XXX ts->hkp */ 00027 #include <rpmts.h> 00028 00029 #include "debug.h" 00030 00031 /*@access rpmts @*/ 00032 /*@access pgpDigParams @*/ 00033 /*@access rpmiob @*/ 00034 00035 /*@unchecked@*/ 00036 int _rpmns_debug = 0; 00037 00038 /*@unchecked@*/ /*@observer@*/ /*@relnull@*/ 00039 const char *_rpmns_N_at_A = "."; 00040 00041 /*@-nullassign@*/ 00042 /*@unchecked@*/ /*@observer@*/ 00043 static const char *rpmnsArches[] = { 00044 "i386", "i486", "i586", "i686", "athlon", "pentium3", "pentium4", 00045 "x86_64", "amd64", "ia32e", 00046 "alpha", "alphaev5", "alphaev56", "alphapca56", "alphaev6", "alphaev67", 00047 "sparc", "sun4", "sun4m", "sun4c", "sun4d", "sparcv8", 00048 "sparcv9", "sparcv9b", "sparcv9v", "sparcv9v2", 00049 "sparc64", "sun4u", "sparc64v", 00050 "mips", "mipsel", "IP", 00051 "ppc", "ppciseries", "ppcpseries", 00052 "ppc64", "ppc64iseries", "ppc64pseries", 00053 "m68k", 00054 "rs6000", 00055 "ia64", 00056 "armv3l", "armv4b", "armv4l", 00057 "armv5teb", "armv5tel", "armv5tejl", 00058 "armv6l", 00059 "s390", "i370", "s390x", 00060 "sh", "sh3", "sh4", "sh4a", "xtensa", 00061 "noarch", "fat", 00062 NULL, 00063 }; 00064 /*@=nullassign@*/ 00065 00066 nsType rpmnsArch(const char * str) 00067 { 00068 nsType rc = RPMNS_TYPE_UNKNOWN; 00069 const char ** av; 00070 00071 #if defined(RPM_VENDOR_WINDRIVER) 00072 const char * known_arch = rpmExpand("%{?_known_arch}", NULL); 00073 const char *p, *pe, *t; 00074 for (p = pe = known_arch ; rc == RPMNS_TYPE_UNKNOWN && pe && *pe ; ) { 00075 while (*p && xisspace(*p)) p++; 00076 pe = p ; while (*pe && !xisspace(*pe)) pe++; 00077 if (p == pe) 00078 break; 00079 t = strndup(p, (pe - p)); 00080 p = pe; 00081 if (!strcmp(str, t)) 00082 rc = RPMNS_TYPE_ARCH; 00083 t = _free(t); 00084 } 00085 known_arch = _free(known_arch); 00086 #endif 00087 00088 if (rc == RPMNS_TYPE_UNKNOWN) 00089 for (av = rpmnsArches; *av != NULL; av++) { 00090 if (strcmp(str, *av)) 00091 continue; 00092 rc = RPMNS_TYPE_ARCH; 00093 break; 00094 } 00095 00096 return rc; 00097 } 00098 00102 /*@unchecked@*/ /*@observer@*/ 00103 static struct _rpmnsProbes_s { 00104 /*@observer@*/ /*@relnull@*/ 00105 const char * NS; 00106 nsType Type; 00107 } rpmnsProbes[] = { 00108 { "rpmlib", RPMNS_TYPE_RPMLIB }, 00109 { "config", RPMNS_TYPE_CONFIG }, 00110 { "cpuinfo", RPMNS_TYPE_CPUINFO }, 00111 { "getconf", RPMNS_TYPE_GETCONF }, 00112 { "uname", RPMNS_TYPE_UNAME }, 00113 { "soname", RPMNS_TYPE_SONAME }, 00114 { "user", RPMNS_TYPE_USER }, 00115 { "group", RPMNS_TYPE_GROUP }, 00116 { "mounted", RPMNS_TYPE_MOUNTED }, 00117 { "diskspace", RPMNS_TYPE_DISKSPACE }, 00118 { "digest", RPMNS_TYPE_DIGEST }, 00119 { "gnupg", RPMNS_TYPE_GNUPG }, 00120 { "macro", RPMNS_TYPE_MACRO }, 00121 { "envvar", RPMNS_TYPE_ENVVAR }, 00122 { "running", RPMNS_TYPE_RUNNING }, 00123 { "sanitycheck", RPMNS_TYPE_SANITY }, 00124 { "vcheck", RPMNS_TYPE_VCHECK }, 00125 { "signature", RPMNS_TYPE_SIGNATURE }, 00126 { "verify", RPMNS_TYPE_VERIFY }, 00127 { "exists", RPMNS_TYPE_ACCESS }, 00128 { "executable", RPMNS_TYPE_ACCESS }, 00129 { "readable", RPMNS_TYPE_ACCESS }, 00130 { "writable", RPMNS_TYPE_ACCESS }, 00131 { "RWX", RPMNS_TYPE_ACCESS }, 00132 { "RWx", RPMNS_TYPE_ACCESS }, 00133 { "RW_", RPMNS_TYPE_ACCESS }, 00134 { "RwX", RPMNS_TYPE_ACCESS }, 00135 { "Rwx", RPMNS_TYPE_ACCESS }, 00136 { "Rw_", RPMNS_TYPE_ACCESS }, 00137 { "R_X", RPMNS_TYPE_ACCESS }, 00138 { "R_x", RPMNS_TYPE_ACCESS }, 00139 { "R__", RPMNS_TYPE_ACCESS }, 00140 { "rWX", RPMNS_TYPE_ACCESS }, 00141 { "rWx", RPMNS_TYPE_ACCESS }, 00142 { "rW_", RPMNS_TYPE_ACCESS }, 00143 { "rwX", RPMNS_TYPE_ACCESS }, 00144 { "rwx", RPMNS_TYPE_ACCESS }, 00145 { "rw_", RPMNS_TYPE_ACCESS }, 00146 { "r_X", RPMNS_TYPE_ACCESS }, 00147 { "r_x", RPMNS_TYPE_ACCESS }, 00148 { "r__", RPMNS_TYPE_ACCESS }, 00149 { "_WX", RPMNS_TYPE_ACCESS }, 00150 { "_Wx", RPMNS_TYPE_ACCESS }, 00151 { "_W_", RPMNS_TYPE_ACCESS }, 00152 { "_wX", RPMNS_TYPE_ACCESS }, 00153 { "_wx", RPMNS_TYPE_ACCESS }, 00154 { "_w_", RPMNS_TYPE_ACCESS }, 00155 { "__X", RPMNS_TYPE_ACCESS }, 00156 { "__x", RPMNS_TYPE_ACCESS }, 00157 { "___", RPMNS_TYPE_ACCESS }, 00158 { NULL, 0 } 00159 }; 00160 00161 nsType rpmnsProbe(const char * str) 00162 { 00163 const struct _rpmnsProbes_s * av; 00164 size_t sn = strlen(str); 00165 size_t nb; 00166 00167 if (sn >= 5 && str[sn-1] == ')') 00168 for (av = rpmnsProbes; av->NS != NULL; av++) { 00169 nb = strlen(av->NS); 00170 if (sn > nb && str[nb] == '(' && !strncmp(str, av->NS, nb)) 00171 return av->Type; 00172 } 00173 return RPMNS_TYPE_UNKNOWN; 00174 } 00175 00176 nsType rpmnsClassify(const char * str) 00177 { 00178 const char * s; 00179 nsType Type = RPMNS_TYPE_STRING; 00180 00181 if (*str == '!') 00182 str++; 00183 if (*str == '/') 00184 return RPMNS_TYPE_PATH; 00185 s = str + strlen(str); 00186 if (str[0] == '%' && str[1] == '{' && s[-1] == '}') 00187 return RPMNS_TYPE_FUNCTION; 00188 if ((s - str) > 3 && s[-3] == '.' && s[-2] == 's' && s[-1] == 'o') 00189 return RPMNS_TYPE_DSO; 00190 Type = rpmnsProbe(str); 00191 if (Type != RPMNS_TYPE_UNKNOWN) 00192 return Type; 00193 for (s = str; *s != '\0'; s++) { 00194 if (s[0] == '(' || s[strlen(s)-1] == ')') 00195 return RPMNS_TYPE_NAMESPACE; 00196 if (s[0] == '.' && s[1] == 's' && s[2] == 'o') 00197 return RPMNS_TYPE_DSO; 00198 if (s[0] == '.' && xisdigit((int)s[-1]) && xisdigit((int)s[1])) 00199 return RPMNS_TYPE_VERSION; 00200 if (_rpmns_N_at_A && _rpmns_N_at_A[0]) { 00201 if (s[0] == _rpmns_N_at_A[0] && rpmnsArch(s+1)) 00202 return RPMNS_TYPE_ARCH; 00203 } 00204 /*@-globstate@*/ 00205 if (s[0] == '.') 00206 return RPMNS_TYPE_COMPOUND; 00207 } 00208 return RPMNS_TYPE_STRING; 00209 /*@=globstate@*/ 00210 } 00211 00212 int rpmnsParse(const char * str, rpmns ns) 00213 { 00214 char *t; 00215 ns->str = t = rpmExpand(str, NULL); 00216 ns->Type = rpmnsClassify(ns->str); 00217 switch (ns->Type) { 00218 case RPMNS_TYPE_ARCH: 00219 ns->NS = NULL; 00220 ns->N = ns->str; 00221 if (ns->N[0] == '!') 00222 ns->N++; 00223 if ((t = strrchr(t, _rpmns_N_at_A[0])) != NULL) 00224 *t++ = '\0'; 00225 ns->A = t; 00226 break; 00227 case RPMNS_TYPE_RPMLIB: 00228 case RPMNS_TYPE_CPUINFO: 00229 case RPMNS_TYPE_GETCONF: 00230 case RPMNS_TYPE_UNAME: 00231 case RPMNS_TYPE_SONAME: 00232 case RPMNS_TYPE_ACCESS: 00233 case RPMNS_TYPE_USER: 00234 case RPMNS_TYPE_GROUP: 00235 case RPMNS_TYPE_MOUNTED: 00236 case RPMNS_TYPE_DISKSPACE: 00237 case RPMNS_TYPE_DIGEST: 00238 case RPMNS_TYPE_GNUPG: 00239 case RPMNS_TYPE_MACRO: 00240 case RPMNS_TYPE_ENVVAR: 00241 case RPMNS_TYPE_RUNNING: 00242 case RPMNS_TYPE_SANITY: 00243 case RPMNS_TYPE_VCHECK: 00244 case RPMNS_TYPE_SIGNATURE: 00245 case RPMNS_TYPE_VERIFY: 00246 ns->NS = ns->str; 00247 if (ns->NS[0] == '!') 00248 ns->NS++; 00249 if ((t = strchr(t, '(')) != NULL) { 00250 *t++ = '\0'; 00251 ns->N = t; 00252 t[strlen(t)-1] = '\0'; 00253 } else 00254 ns->N = NULL; 00255 ns->A = NULL; 00256 break; 00257 case RPMNS_TYPE_UNKNOWN: 00258 case RPMNS_TYPE_STRING: 00259 case RPMNS_TYPE_PATH: 00260 case RPMNS_TYPE_DSO: 00261 case RPMNS_TYPE_FUNCTION: 00262 case RPMNS_TYPE_VERSION: 00263 case RPMNS_TYPE_COMPOUND: 00264 case RPMNS_TYPE_NAMESPACE: 00265 case RPMNS_TYPE_TAG: 00266 case RPMNS_TYPE_CONFIG: 00267 default: 00268 ns->NS = NULL; 00269 ns->N = ns->str; 00270 if (ns->N[0] == '!') 00271 ns->N++; 00272 ns->A = NULL; 00273 break; 00274 } 00275 return 0; 00276 } 00277 00283 static inline unsigned char nibble(char c) 00284 /*@*/ 00285 { 00286 if (c >= '0' && c <= '9') 00287 return (unsigned char)(c - '0'); 00288 if (c >= 'A' && c <= 'F') 00289 return (unsigned char)((int)(c - 'A') + 10); 00290 if (c >= 'a' && c <= 'f') 00291 return (unsigned char)((int)(c - 'a') + 10); 00292 return '\0'; 00293 } 00294 00295 rpmRC rpmnsProbeSignature(void * _ts, const char * fn, const char * sigfn, 00296 const char * pubfn, const char * pubid, 00297 /*@unused@*/ int flags) 00298 { 00299 rpmts ts = _ts; 00300 pgpDig dig = rpmtsDig(ts); 00301 pgpDigParams sigp = pgpGetSignature(dig); 00302 pgpDigParams pubp = pgpGetPubkey(dig); 00303 rpmuint8_t * sigpkt = NULL; 00304 size_t sigpktlen = 0; 00305 DIGEST_CTX ctx = NULL; 00306 rpmRC rc = RPMRC_FAIL; /* assume failure */ 00307 int xx; 00308 rpmhkp hkp = NULL; 00309 pgpPkt pp = alloca(sizeof(*pp)); 00310 size_t pleft; 00311 int validate = 1; 00312 00313 if (_rpmns_debug) 00314 fprintf(stderr, "==> check(%s, %s, %s, %s)\n", fn, 00315 (sigfn ? sigfn : "(null)"), 00316 (pubfn ? pubfn : "(null)"), 00317 (pubid ? pubid : "(null)")); 00318 00319 /* Load the signature. Use sigfn if specified, otherwise clearsign. */ 00320 if (sigfn && *sigfn) { 00321 const char * _sigfn = rpmExpand(sigfn, NULL); 00322 xx = pgpReadPkts(_sigfn, &sigpkt, &sigpktlen); 00323 if (xx != PGPARMOR_SIGNATURE) { 00324 if (_rpmns_debug) 00325 fprintf(stderr, "==> pgpReadPkts(%s) SIG %p[%u] ret %d\n", _sigfn, sigpkt, (unsigned)sigpktlen, xx); 00326 _sigfn = _free(_sigfn); 00327 goto exit; 00328 } 00329 _sigfn = _free(_sigfn); 00330 } else { 00331 const char * _sigfn = rpmExpand(fn, NULL); 00332 xx = pgpReadPkts(_sigfn, &sigpkt, &sigpktlen); 00333 if (xx != PGPARMOR_SIGNATURE) { 00334 if (_rpmns_debug) 00335 fprintf(stderr, "==> pgpReadPkts(%s) SIG %p[%u] ret %d\n", _sigfn, sigpkt, (unsigned)sigpktlen, xx); 00336 _sigfn = _free(_sigfn); 00337 goto exit; 00338 } 00339 _sigfn = _free(_sigfn); 00340 } 00341 00342 pleft = sigpktlen; 00343 xx = pgpPktLen(sigpkt, pleft, pp); 00344 xx = rpmhkpLoadSignature(NULL, dig, pp); 00345 if (xx) goto exit; 00346 00347 if (sigp->version != (rpmuint8_t)3 && sigp->version != (rpmuint8_t)4) { 00348 if (_rpmns_debug) 00349 fprintf(stderr, "==> unverifiable V%u\n", (unsigned)sigp->version); 00350 goto exit; 00351 } 00352 00353 if (ts->hkp == NULL) 00354 ts->hkp = rpmhkpNew(NULL, 0); 00355 hkp = rpmhkpLink(ts->hkp); 00356 00357 /* Load the pubkey. Use pubfn if specified, otherwise rpmdb keyring. */ 00358 if (pubfn && *pubfn) { 00359 const char * _pubfn = rpmExpand(pubfn, NULL); 00360 /*@-type@*/ 00361 hkp->pkt = _free(hkp->pkt); /* XXX memleaks */ 00362 hkp->pktlen = 0; 00363 xx = pgpReadPkts(_pubfn, &hkp->pkt, &hkp->pktlen); 00364 /*@=type@*/ 00365 if (xx != PGPARMOR_PUBKEY) { 00366 if (_rpmns_debug) 00367 fprintf(stderr, "==> pgpReadPkts(%s) PUB %p[%u] ret %d\n", _pubfn, hkp->pkt, (unsigned)hkp->pktlen, xx); 00368 _pubfn = _free(_pubfn); 00369 goto exit; 00370 } 00371 _pubfn = _free(_pubfn); 00372 00373 /* Split the result into packet array. */ 00374 hkp->pkts = _free(hkp->pkts); /* XXX memleaks */ 00375 hkp->npkts = 0; 00376 xx = pgpGrabPkts(hkp->pkt, hkp->pktlen, &hkp->pkts, &hkp->npkts); 00377 00378 if (!xx) 00379 (void) pgpPubkeyFingerprint(hkp->pkt, hkp->pktlen, hkp->keyid); 00380 memcpy(pubp->signid, hkp->keyid, sizeof(pubp->signid));/* XXX useless */ 00381 00382 /* Validate pubkey self-signatures. */ 00383 if (validate) { 00384 xx = rpmhkpValidate(hkp, NULL); 00385 switch (xx) { 00386 case RPMRC_OK: 00387 break; 00388 case RPMRC_NOTFOUND: 00389 case RPMRC_FAIL: /* XXX remap to NOTFOUND? */ 00390 case RPMRC_NOTTRUSTED: 00391 case RPMRC_NOKEY: 00392 default: 00393 rc = xx; 00394 goto exit; 00395 } 00396 } 00397 00398 /* Retrieve parameters from pubkey/subkey packet(s). */ 00399 xx = rpmhkpFindKey(hkp, dig, sigp->signid, sigp->pubkey_algo); 00400 if (xx) goto exit; 00401 00402 #ifdef DYING 00403 _rpmhkpDumpDig(__FUNCTION__, dig); 00404 #endif 00405 } else { 00406 if ((rc = pgpFindPubkey(dig)) != RPMRC_OK) { 00407 if (_rpmns_debug) 00408 fprintf(stderr, "==> pgpFindPubkey ret %d\n", xx); 00409 goto exit; 00410 } 00411 } 00412 00413 /* Is this the requested pubkey? */ 00414 if (pubid && *pubid) { 00415 size_t ns = strlen(pubid); 00416 const char * s; 00417 char * t; 00418 size_t i; 00419 00420 /* At least 8 hex digits please. */ 00421 for (i = 0, s = pubid; *s && isxdigit(*s); s++, i++) 00422 {}; 00423 if (!(*s == '\0' && i > 8 && (i%2) == 0)) 00424 goto exit; 00425 00426 /* Truncate to key id size. */ 00427 s = pubid; 00428 if (ns > 16) { 00429 s += (ns - 16); 00430 ns = 16; 00431 } 00432 ns >>= 1; 00433 t = memset(alloca(ns), 0, ns); 00434 for (i = 0; i < ns; i++) 00435 t[i] = (char)((nibble(s[2*i]) << 4) | nibble(s[2*i+1])); 00436 00437 /* Compare the pubkey id. */ 00438 s = (const char *)pubp->signid; 00439 xx = memcmp(t, s + (8 - ns), ns); 00440 00441 /* XXX HACK: V4 RSA key id's are wonky atm. */ 00442 if (pubp->pubkey_algo == (rpmuint8_t)PGPPUBKEYALGO_RSA) 00443 xx = 0; 00444 00445 if (xx) { 00446 if (_rpmns_debug) 00447 fprintf(stderr, "==> mismatched: pubkey id (%08x %08x) != %s\n", 00448 pgpGrab(pubp->signid, 4), pgpGrab(pubp->signid+4, 4), pubid); 00449 goto exit; 00450 } 00451 } 00452 00453 /* Do the parameters match the signature? */ 00454 if (!(sigp->pubkey_algo == pubp->pubkey_algo 00455 #ifdef NOTYET 00456 && sigp->hash_algo == pubp->hash_algo 00457 #endif 00458 /* XXX HACK: V4 RSA key id's are wonky atm. */ 00459 && (pubp->pubkey_algo == (rpmuint8_t)PGPPUBKEYALGO_RSA || !memcmp(sigp->signid, pubp->signid, sizeof(sigp->signid))) ) ) { 00460 if (_rpmns_debug) { 00461 fprintf(stderr, "==> mismatch between signature and pubkey\n"); 00462 fprintf(stderr, "\tpubkey_algo: %u %u\n", (unsigned)sigp->pubkey_algo, (unsigned)pubp->pubkey_algo); 00463 fprintf(stderr, "\tsignid: %08X %08X %08X %08X\n", 00464 pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4), 00465 pgpGrab(pubp->signid, 4), pgpGrab(pubp->signid+4, 4)); 00466 } 00467 goto exit; 00468 } 00469 00470 /* Compute the message digest. */ 00471 ctx = rpmDigestInit((pgpHashAlgo)sigp->hash_algo, RPMDIGEST_NONE); 00472 00473 { 00474 static const char clrtxt[] = "-----BEGIN PGP SIGNED MESSAGE-----"; 00475 static const char sigtxt[] = "-----BEGIN PGP SIGNATURE-----"; 00476 const char * _fn = rpmExpand(fn, NULL); 00477 rpmiob iob = NULL; 00478 int _rc = rpmiobSlurp(_fn, &iob); 00479 00480 if (!(_rc == 0 && iob != NULL)) { 00481 if (_rpmns_debug) 00482 fprintf(stderr, "==> rpmiobSlurp(%s) MSG ret %d\n", _fn, _rc); 00483 iob = rpmiobFree(iob); 00484 _fn = _free(_fn); 00485 goto exit; 00486 } 00487 _fn = _free(_fn); 00488 00489 /* XXX clearsign sig is PGPSIGTYPE_TEXT not PGPSIGTYPE_BINARY. */ 00490 if (!strncmp((char *)iob->b, clrtxt, strlen(clrtxt))) { 00491 const char * be = (char *) (iob->b + iob->blen); 00492 const char * t; 00493 00494 /* Skip to '\n\n' start-of-plaintext */ 00495 t = (char *) iob->b; 00496 while (t && t < be && *t != '\n') 00497 t = strchr(t, '\n') + 1; 00498 if (!(t && t < be)) 00499 goto exit; 00500 t++; 00501 00502 /* Clearsign digest rtrims " \t\r\n", inserts "\r\n" inter-lines. */ 00503 while (t < be) { 00504 const char * teol; 00505 const char * te; 00506 if (strncmp(t, "- ", 2) == 0) 00507 t += 2; 00508 if ((teol = te = strchr(t, '\n')) == NULL) 00509 break; 00510 while (te > t && strchr(" \t\r\n", te[-1])) 00511 te--; 00512 xx = rpmDigestUpdate(ctx, t, (te - t)); 00513 if (!strncmp((t = teol + 1), sigtxt, strlen(sigtxt))) 00514 break; 00515 xx = rpmDigestUpdate(ctx, "\r\n", sizeof("\r\n")-1); 00516 } 00517 } else 00518 xx = rpmDigestUpdate(ctx, iob->b, iob->blen); 00519 00520 iob = rpmiobFree(iob); 00521 } 00522 00523 if (sigp->hash != NULL) 00524 xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen); 00525 00526 if (sigp->version == (rpmuint8_t)4) { 00527 rpmuint8_t trailer[6]; 00528 trailer[0] = sigp->version; 00529 trailer[1] = (rpmuint8_t)0xff; 00530 trailer[2] = (sigp->hashlen >> 24) & 0xff; 00531 trailer[3] = (sigp->hashlen >> 16) & 0xff; 00532 trailer[4] = (sigp->hashlen >> 8) & 0xff; 00533 trailer[5] = (sigp->hashlen ) & 0xff; 00534 xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer)); 00535 } 00536 00537 /* Load the message digest. */ 00538 switch(sigp->pubkey_algo) { 00539 default: 00540 rc = RPMRC_FAIL; 00541 break; 00542 case PGPPUBKEYALGO_DSA: 00543 rc = (pgpImplSetDSA(ctx, dig, sigp) ? RPMRC_FAIL : RPMRC_OK); 00544 break; 00545 case PGPPUBKEYALGO_RSA: 00546 rc = (pgpImplSetRSA(ctx, dig, sigp) ? RPMRC_FAIL : RPMRC_OK); 00547 break; 00548 } 00549 if (rc != RPMRC_OK) { 00550 if (_rpmns_debug) 00551 fprintf(stderr, "==> can't load pubkey_algo(%u)\n", (unsigned)sigp->pubkey_algo); 00552 goto exit; 00553 } 00554 00555 /* Verify the signature. */ 00556 switch(sigp->pubkey_algo) { 00557 default: 00558 rc = RPMRC_FAIL; 00559 break; 00560 case PGPPUBKEYALGO_RSA: 00561 case PGPPUBKEYALGO_DSA: 00562 rc = (pgpImplVerify(dig) ? RPMRC_OK : RPMRC_FAIL); 00563 break; 00564 } 00565 00566 exit: 00567 sigpkt = _free(sigpkt); 00568 (void) rpmhkpFree(hkp); 00569 hkp = NULL; 00570 /*@-nullstate@*/ 00571 rpmtsCleanDig(ts); 00572 /*@=nullstate@*/ 00573 00574 if (_rpmns_debug) 00575 fprintf(stderr, "============================ verify: %s\n", 00576 (rc == RPMRC_OK ? "OK" : 00577 (rc == RPMRC_NOKEY ? "NOKEY" : 00578 "FAIL"))); 00579 00580 return rc; 00581 }