rpm 5.3.12
rpmdb/rpmns.c
Go to the documentation of this file.
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 }