|
rpm
5.4.4
|
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 #define _ENTRY(_s, _type) { #_s, sizeof(#_s)-1, _type } 00104 static struct _rpmnsProbes_s { 00105 /*@observer@*/ /*@relnull@*/ 00106 const char * NS; 00107 size_t NSlen; 00108 nsType Type; 00109 } rpmnsProbes[] = { 00110 _ENTRY(RWX, RPMNS_TYPE_ACCESS), 00111 _ENTRY(RW_, RPMNS_TYPE_ACCESS), 00112 _ENTRY(RWx, RPMNS_TYPE_ACCESS), 00113 _ENTRY(R_X, RPMNS_TYPE_ACCESS), 00114 _ENTRY(R__, RPMNS_TYPE_ACCESS), 00115 _ENTRY(R_x, RPMNS_TYPE_ACCESS), 00116 _ENTRY(RwX, RPMNS_TYPE_ACCESS), 00117 _ENTRY(Rw_, RPMNS_TYPE_ACCESS), 00118 _ENTRY(Rwx, RPMNS_TYPE_ACCESS), 00119 _ENTRY(_WX, RPMNS_TYPE_ACCESS), 00120 _ENTRY(_W_, RPMNS_TYPE_ACCESS), 00121 _ENTRY(_Wx, RPMNS_TYPE_ACCESS), 00122 _ENTRY(__X, RPMNS_TYPE_ACCESS), 00123 _ENTRY(___, RPMNS_TYPE_ACCESS), 00124 _ENTRY(__x, RPMNS_TYPE_ACCESS), 00125 _ENTRY(_wX, RPMNS_TYPE_ACCESS), 00126 _ENTRY(_w_, RPMNS_TYPE_ACCESS), 00127 _ENTRY(_wx, RPMNS_TYPE_ACCESS), 00128 _ENTRY(config, RPMNS_TYPE_CONFIG), 00129 _ENTRY(cpuinfo, RPMNS_TYPE_CPUINFO), 00130 _ENTRY(digest, RPMNS_TYPE_DIGEST), 00131 _ENTRY(diskspace, RPMNS_TYPE_DISKSPACE), 00132 _ENTRY(envvar, RPMNS_TYPE_ENVVAR), 00133 _ENTRY(executable, RPMNS_TYPE_ACCESS), 00134 _ENTRY(exists, RPMNS_TYPE_ACCESS), 00135 _ENTRY(getconf, RPMNS_TYPE_GETCONF), 00136 _ENTRY(gnupg, RPMNS_TYPE_GNUPG), 00137 _ENTRY(group, RPMNS_TYPE_GROUP), 00138 _ENTRY(macro, RPMNS_TYPE_MACRO), 00139 _ENTRY(mounted, RPMNS_TYPE_MOUNTED), 00140 _ENTRY(rWX, RPMNS_TYPE_ACCESS), 00141 _ENTRY(rW_, RPMNS_TYPE_ACCESS), 00142 _ENTRY(rWx, RPMNS_TYPE_ACCESS), 00143 _ENTRY(r_X, RPMNS_TYPE_ACCESS), 00144 _ENTRY(r__, RPMNS_TYPE_ACCESS), 00145 _ENTRY(r_x, RPMNS_TYPE_ACCESS), 00146 _ENTRY(readable, RPMNS_TYPE_ACCESS), 00147 _ENTRY(rpmlib, RPMNS_TYPE_RPMLIB), 00148 _ENTRY(running, RPMNS_TYPE_RUNNING), 00149 _ENTRY(rwX, RPMNS_TYPE_ACCESS), 00150 _ENTRY(rw_, RPMNS_TYPE_ACCESS), 00151 _ENTRY(rwx, RPMNS_TYPE_ACCESS), 00152 _ENTRY(sanitycheck, RPMNS_TYPE_SANITY), 00153 _ENTRY(signature, RPMNS_TYPE_SIGNATURE), 00154 _ENTRY(soname, RPMNS_TYPE_SONAME), 00155 _ENTRY(uname, RPMNS_TYPE_UNAME), 00156 _ENTRY(user, RPMNS_TYPE_USER), 00157 _ENTRY(vcheck, RPMNS_TYPE_VCHECK), 00158 _ENTRY(verify, RPMNS_TYPE_VERIFY), 00159 _ENTRY(writable, RPMNS_TYPE_ACCESS), 00160 }; 00161 #undef _ENTRY 00162 static size_t rpmnsProbesCount = sizeof(rpmnsProbes)/sizeof(rpmnsProbes[0]); 00163 00164 nsType rpmnsProbe(const char * s, size_t slen) 00165 { 00166 const char * se = strchr(s, ')'); 00167 size_t l, u; 00168 00169 /* XXX Don't bother if string cannot be "NS(N).A" */ 00170 if (se == NULL || (slen = (se - s)) < sizeof("ABC()")-1) 00171 return RPMNS_TYPE_UNKNOWN; 00172 00173 l = 0; 00174 u = rpmnsProbesCount; 00175 while (l < u) { 00176 size_t i = (l + u)/2; 00177 struct _rpmnsProbes_s * av = rpmnsProbes + i; 00178 size_t NSlen = (slen > av->NSlen) ? av->NSlen : slen; 00179 int rc = strncmp(s, av->NS, NSlen); 00180 00181 if (rc == 0) 00182 return (s[NSlen] == '(' ? rpmnsProbes[i].Type : RPMNS_TYPE_UNKNOWN); 00183 else if (rc < 0) 00184 u = i; 00185 else if (rc > 0) 00186 l = i + 1; 00187 } 00188 return RPMNS_TYPE_UNKNOWN; 00189 } 00190 00191 nsType rpmnsClassify(const char * s, size_t slen) 00192 { 00193 const char * se; 00194 nsType Type; 00195 00196 if (slen == 0) slen = strlen(s); 00197 if (*s == '!') { 00198 s++; 00199 slen--; 00200 } 00201 if (*s == '/') 00202 return RPMNS_TYPE_PATH; 00203 se = s + slen; 00204 if (s[0] == '%' && s[1] == '{' && se[-1] == '}') 00205 return RPMNS_TYPE_FUNCTION; 00206 if ((se - s) > 3 && se[-3] == '.' && se[-2] == 's' && se[-1] == 'o') 00207 return RPMNS_TYPE_DSO; 00208 Type = rpmnsProbe(s, slen); 00209 if (Type != RPMNS_TYPE_UNKNOWN) 00210 return Type; 00211 for (se = s; *se != '\0'; se++) { 00212 if (se[0] == '(' || se[--slen] == ')') 00213 return RPMNS_TYPE_NAMESPACE; 00214 if (se[0] == '.' && se[1] == 's' && se[2] == 'o') 00215 return RPMNS_TYPE_DSO; 00216 if (se[0] == '.' && xisdigit((int)se[-1]) && xisdigit((int)se[1])) 00217 return RPMNS_TYPE_VERSION; 00218 if (_rpmns_N_at_A && _rpmns_N_at_A[0]) { 00219 if (se[0] == _rpmns_N_at_A[0] && rpmnsArch(se+1)) 00220 return RPMNS_TYPE_ARCH; 00221 } 00222 /*@-globstate@*/ 00223 if (se[0] == '.') 00224 return RPMNS_TYPE_COMPOUND; 00225 } 00226 return RPMNS_TYPE_STRING; 00227 /*@=globstate@*/ 00228 } 00229 00230 int rpmnsParse(const char * s, rpmns ns) 00231 { 00232 char * t = rpmExpand(s, NULL); 00233 size_t tlen = strlen(t); 00234 00235 ns->Flags = 0; 00236 ns->str = t; 00237 ns->Type = rpmnsClassify(t, tlen); 00238 00239 switch (ns->Type) { 00240 case RPMNS_TYPE_ARCH: 00241 ns->NS = NULL; 00242 ns->N = ns->str; 00243 if (ns->N[0] == '!') 00244 ns->N++; 00245 if ((t = strrchr(t, _rpmns_N_at_A[0])) != NULL) 00246 *t++ = '\0'; 00247 ns->A = t; 00248 break; 00249 case RPMNS_TYPE_RPMLIB: 00250 case RPMNS_TYPE_CPUINFO: 00251 case RPMNS_TYPE_GETCONF: 00252 case RPMNS_TYPE_UNAME: 00253 case RPMNS_TYPE_SONAME: 00254 case RPMNS_TYPE_ACCESS: 00255 case RPMNS_TYPE_USER: 00256 case RPMNS_TYPE_GROUP: 00257 case RPMNS_TYPE_MOUNTED: 00258 case RPMNS_TYPE_DISKSPACE: 00259 case RPMNS_TYPE_DIGEST: 00260 case RPMNS_TYPE_GNUPG: 00261 case RPMNS_TYPE_MACRO: 00262 case RPMNS_TYPE_ENVVAR: 00263 case RPMNS_TYPE_RUNNING: 00264 case RPMNS_TYPE_SANITY: 00265 case RPMNS_TYPE_VCHECK: 00266 case RPMNS_TYPE_SIGNATURE: 00267 case RPMNS_TYPE_VERIFY: 00268 ns->NS = ns->str; 00269 if (ns->NS[0] == '!') 00270 ns->NS++; 00271 if ((t = strchr(t, '(')) != NULL) { 00272 *t++ = '\0'; 00273 ns->N = t; 00274 t[strlen(t)-1] = '\0'; 00275 } else 00276 ns->N = NULL; 00277 ns->A = NULL; 00278 break; 00279 case RPMNS_TYPE_UNKNOWN: 00280 case RPMNS_TYPE_STRING: 00281 case RPMNS_TYPE_PATH: 00282 case RPMNS_TYPE_DSO: 00283 case RPMNS_TYPE_FUNCTION: 00284 case RPMNS_TYPE_VERSION: 00285 case RPMNS_TYPE_COMPOUND: 00286 case RPMNS_TYPE_NAMESPACE: 00287 case RPMNS_TYPE_TAG: 00288 case RPMNS_TYPE_CONFIG: 00289 default: 00290 ns->NS = NULL; 00291 ns->N = ns->str; 00292 if (ns->N[0] == '!') 00293 ns->N++; 00294 ns->A = NULL; 00295 break; 00296 } 00297 return 0; 00298 } 00299 00305 static inline unsigned char nibble(char c) 00306 /*@*/ 00307 { 00308 if (c >= '0' && c <= '9') 00309 return (unsigned char)(c - '0'); 00310 if (c >= 'A' && c <= 'F') 00311 return (unsigned char)((int)(c - 'A') + 10); 00312 if (c >= 'a' && c <= 'f') 00313 return (unsigned char)((int)(c - 'a') + 10); 00314 return '\0'; 00315 } 00316 00317 rpmRC rpmnsProbeSignature(void * _ts, const char * fn, const char * sigfn, 00318 const char * pubfn, const char * pubid, 00319 /*@unused@*/ int flags) 00320 { 00321 rpmts ts = _ts; 00322 pgpDig dig = rpmtsDig(ts); 00323 pgpDigParams sigp = pgpGetSignature(dig); 00324 pgpDigParams pubp = pgpGetPubkey(dig); 00325 rpmuint8_t * sigpkt = NULL; 00326 size_t sigpktlen = 0; 00327 DIGEST_CTX ctx = NULL; 00328 rpmRC rc = RPMRC_FAIL; /* assume failure */ 00329 int xx; 00330 rpmhkp hkp = NULL; 00331 pgpPkt pp = alloca(sizeof(*pp)); 00332 size_t pleft; 00333 int validate = 1; 00334 00335 if (_rpmns_debug) 00336 fprintf(stderr, "==> check(%s, %s, %s, %s)\n", fn, 00337 (sigfn ? sigfn : "(null)"), 00338 (pubfn ? pubfn : "(null)"), 00339 (pubid ? pubid : "(null)")); 00340 00341 /* Load the signature. Use sigfn if specified, otherwise clearsign. */ 00342 if (sigfn && *sigfn) { 00343 const char * _sigfn = rpmExpand(sigfn, NULL); 00344 xx = pgpReadPkts(_sigfn, &sigpkt, &sigpktlen); 00345 if (xx != PGPARMOR_SIGNATURE) { 00346 if (_rpmns_debug) 00347 fprintf(stderr, "==> pgpReadPkts(%s) SIG %p[%u] ret %d\n", _sigfn, sigpkt, (unsigned)sigpktlen, xx); 00348 _sigfn = _free(_sigfn); 00349 goto exit; 00350 } 00351 _sigfn = _free(_sigfn); 00352 } else { 00353 const char * _sigfn = rpmExpand(fn, NULL); 00354 xx = pgpReadPkts(_sigfn, &sigpkt, &sigpktlen); 00355 if (xx != PGPARMOR_SIGNATURE) { 00356 if (_rpmns_debug) 00357 fprintf(stderr, "==> pgpReadPkts(%s) SIG %p[%u] ret %d\n", _sigfn, sigpkt, (unsigned)sigpktlen, xx); 00358 _sigfn = _free(_sigfn); 00359 goto exit; 00360 } 00361 _sigfn = _free(_sigfn); 00362 } 00363 00364 pleft = sigpktlen; 00365 xx = pgpPktLen(sigpkt, pleft, pp); 00366 xx = rpmhkpLoadSignature(NULL, dig, pp); 00367 if (xx) goto exit; 00368 00369 if (sigp->version != (rpmuint8_t)3 && sigp->version != (rpmuint8_t)4) { 00370 if (_rpmns_debug) 00371 fprintf(stderr, "==> unverifiable V%u\n", (unsigned)sigp->version); 00372 goto exit; 00373 } 00374 00375 if (ts->hkp == NULL) 00376 ts->hkp = rpmhkpNew(NULL, 0); 00377 hkp = rpmhkpLink(ts->hkp); 00378 00379 /* Load the pubkey. Use pubfn if specified, otherwise rpmdb keyring. */ 00380 if (pubfn && *pubfn) { 00381 const char * _pubfn = rpmExpand(pubfn, NULL); 00382 /*@-type@*/ 00383 hkp->pkt = _free(hkp->pkt); /* XXX memleaks */ 00384 hkp->pktlen = 0; 00385 xx = pgpReadPkts(_pubfn, &hkp->pkt, &hkp->pktlen); 00386 /*@=type@*/ 00387 if (xx != PGPARMOR_PUBKEY) { 00388 if (_rpmns_debug) 00389 fprintf(stderr, "==> pgpReadPkts(%s) PUB %p[%u] ret %d\n", _pubfn, hkp->pkt, (unsigned)hkp->pktlen, xx); 00390 _pubfn = _free(_pubfn); 00391 goto exit; 00392 } 00393 _pubfn = _free(_pubfn); 00394 00395 /* Split the result into packet array. */ 00396 hkp->pkts = _free(hkp->pkts); /* XXX memleaks */ 00397 hkp->npkts = 0; 00398 xx = pgpGrabPkts(hkp->pkt, hkp->pktlen, &hkp->pkts, &hkp->npkts); 00399 00400 if (!xx) 00401 (void) pgpPubkeyFingerprint(hkp->pkt, hkp->pktlen, hkp->keyid); 00402 memcpy(pubp->signid, hkp->keyid, sizeof(pubp->signid));/* XXX useless */ 00403 00404 /* Validate pubkey self-signatures. */ 00405 if (validate) { 00406 xx = rpmhkpValidate(hkp, NULL); 00407 switch (xx) { 00408 case RPMRC_OK: 00409 break; 00410 case RPMRC_NOTFOUND: 00411 case RPMRC_FAIL: /* XXX remap to NOTFOUND? */ 00412 case RPMRC_NOTTRUSTED: 00413 case RPMRC_NOKEY: 00414 default: 00415 rc = xx; 00416 goto exit; 00417 } 00418 } 00419 00420 /* Retrieve parameters from pubkey/subkey packet(s). */ 00421 xx = rpmhkpFindKey(hkp, dig, sigp->signid, sigp->pubkey_algo); 00422 if (xx) goto exit; 00423 00424 #ifdef DYING 00425 _rpmhkpDumpDig(__FUNCTION__, dig); 00426 #endif 00427 } else { 00428 if ((rc = pgpFindPubkey(dig)) != RPMRC_OK) { 00429 if (_rpmns_debug) 00430 fprintf(stderr, "==> pgpFindPubkey ret %d\n", xx); 00431 goto exit; 00432 } 00433 } 00434 00435 /* Is this the requested pubkey? */ 00436 if (pubid && *pubid) { 00437 size_t ns = strlen(pubid); 00438 const char * s; 00439 char * t; 00440 size_t i; 00441 00442 /* At least 8 hex digits please. */ 00443 for (i = 0, s = pubid; *s && isxdigit(*s); s++, i++) 00444 {}; 00445 if (!(*s == '\0' && i > 8 && (i%2) == 0)) 00446 goto exit; 00447 00448 /* Truncate to key id size. */ 00449 s = pubid; 00450 if (ns > 16) { 00451 s += (ns - 16); 00452 ns = 16; 00453 } 00454 ns >>= 1; 00455 t = memset(alloca(ns), 0, ns); 00456 for (i = 0; i < ns; i++) 00457 t[i] = (char)((nibble(s[2*i]) << 4) | nibble(s[2*i+1])); 00458 00459 /* Compare the pubkey id. */ 00460 s = (const char *)pubp->signid; 00461 xx = memcmp(t, s + (8 - ns), ns); 00462 00463 /* XXX HACK: V4 RSA key id's are wonky atm. */ 00464 if (pubp->pubkey_algo == (rpmuint8_t)PGPPUBKEYALGO_RSA) 00465 xx = 0; 00466 00467 if (xx) { 00468 if (_rpmns_debug) 00469 fprintf(stderr, "==> mismatched: pubkey id (%08x %08x) != %s\n", 00470 pgpGrab(pubp->signid, 4), pgpGrab(pubp->signid+4, 4), pubid); 00471 goto exit; 00472 } 00473 } 00474 00475 /* Do the parameters match the signature? */ 00476 if (!(sigp->pubkey_algo == pubp->pubkey_algo 00477 #ifdef NOTYET 00478 && sigp->hash_algo == pubp->hash_algo 00479 #endif 00480 /* XXX HACK: V4 RSA key id's are wonky atm. */ 00481 && (pubp->pubkey_algo == (rpmuint8_t)PGPPUBKEYALGO_RSA || !memcmp(sigp->signid, pubp->signid, sizeof(sigp->signid))) ) ) { 00482 if (_rpmns_debug) { 00483 fprintf(stderr, "==> mismatch between signature and pubkey\n"); 00484 fprintf(stderr, "\tpubkey_algo: %u %u\n", (unsigned)sigp->pubkey_algo, (unsigned)pubp->pubkey_algo); 00485 fprintf(stderr, "\tsignid: %08X %08X %08X %08X\n", 00486 pgpGrab(sigp->signid, 4), pgpGrab(sigp->signid+4, 4), 00487 pgpGrab(pubp->signid, 4), pgpGrab(pubp->signid+4, 4)); 00488 } 00489 goto exit; 00490 } 00491 00492 /* Compute the message digest. */ 00493 ctx = rpmDigestInit((pgpHashAlgo)sigp->hash_algo, RPMDIGEST_NONE); 00494 00495 { 00496 static const char clrtxt[] = "-----BEGIN PGP SIGNED MESSAGE-----"; 00497 static const char sigtxt[] = "-----BEGIN PGP SIGNATURE-----"; 00498 const char * _fn = rpmExpand(fn, NULL); 00499 rpmiob iob = NULL; 00500 int _rc = rpmiobSlurp(_fn, &iob); 00501 00502 if (!(_rc == 0 && iob != NULL)) { 00503 if (_rpmns_debug) 00504 fprintf(stderr, "==> rpmiobSlurp(%s) MSG ret %d\n", _fn, _rc); 00505 iob = rpmiobFree(iob); 00506 _fn = _free(_fn); 00507 goto exit; 00508 } 00509 _fn = _free(_fn); 00510 00511 /* XXX clearsign sig is PGPSIGTYPE_TEXT not PGPSIGTYPE_BINARY. */ 00512 if (!strncmp((char *)iob->b, clrtxt, strlen(clrtxt))) { 00513 const char * be = (char *) (iob->b + iob->blen); 00514 const char * t; 00515 00516 /* Skip to '\n\n' start-of-plaintext */ 00517 t = (char *) iob->b; 00518 while (t && t < be && *t != '\n') 00519 t = strchr(t, '\n') + 1; 00520 if (!(t && t < be)) 00521 goto exit; 00522 t++; 00523 00524 /* Clearsign digest rtrims " \t\r\n", inserts "\r\n" inter-lines. */ 00525 while (t < be) { 00526 const char * teol; 00527 const char * te; 00528 if (strncmp(t, "- ", 2) == 0) 00529 t += 2; 00530 if ((teol = te = strchr(t, '\n')) == NULL) 00531 break; 00532 while (te > t && strchr(" \t\r\n", te[-1])) 00533 te--; 00534 xx = rpmDigestUpdate(ctx, t, (te - t)); 00535 if (!strncmp((t = teol + 1), sigtxt, strlen(sigtxt))) 00536 break; 00537 xx = rpmDigestUpdate(ctx, "\r\n", sizeof("\r\n")-1); 00538 } 00539 } else 00540 xx = rpmDigestUpdate(ctx, iob->b, iob->blen); 00541 00542 iob = rpmiobFree(iob); 00543 } 00544 00545 if (sigp->hash != NULL) 00546 xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen); 00547 00548 if (sigp->version == (rpmuint8_t)4) { 00549 rpmuint8_t trailer[6]; 00550 trailer[0] = sigp->version; 00551 trailer[1] = (rpmuint8_t)0xff; 00552 trailer[2] = (sigp->hashlen >> 24) & 0xff; 00553 trailer[3] = (sigp->hashlen >> 16) & 0xff; 00554 trailer[4] = (sigp->hashlen >> 8) & 0xff; 00555 trailer[5] = (sigp->hashlen ) & 0xff; 00556 xx = rpmDigestUpdate(ctx, trailer, sizeof(trailer)); 00557 } 00558 00559 /* Load the message digest. */ 00560 switch(sigp->pubkey_algo) { 00561 default: 00562 rc = RPMRC_FAIL; 00563 break; 00564 case PGPPUBKEYALGO_DSA: 00565 rc = (pgpImplSetDSA(ctx, dig, sigp) ? RPMRC_FAIL : RPMRC_OK); 00566 break; 00567 case PGPPUBKEYALGO_RSA: 00568 rc = (pgpImplSetRSA(ctx, dig, sigp) ? RPMRC_FAIL : RPMRC_OK); 00569 break; 00570 } 00571 if (rc != RPMRC_OK) { 00572 if (_rpmns_debug) 00573 fprintf(stderr, "==> can't load pubkey_algo(%u)\n", (unsigned)sigp->pubkey_algo); 00574 goto exit; 00575 } 00576 00577 /* Verify the signature. */ 00578 switch(sigp->pubkey_algo) { 00579 default: 00580 rc = RPMRC_FAIL; 00581 break; 00582 case PGPPUBKEYALGO_RSA: 00583 case PGPPUBKEYALGO_DSA: 00584 rc = (pgpImplVerify(dig) ? RPMRC_OK : RPMRC_FAIL); 00585 break; 00586 } 00587 00588 exit: 00589 sigpkt = _free(sigpkt); 00590 (void) rpmhkpFree(hkp); 00591 hkp = NULL; 00592 /*@-nullstate@*/ 00593 rpmtsCleanDig(ts); 00594 /*@=nullstate@*/ 00595 00596 if (_rpmns_debug) 00597 fprintf(stderr, "============================ verify: %s\n", 00598 (rc == RPMRC_OK ? "OK" : 00599 (rc == RPMRC_NOKEY ? "NOKEY" : 00600 "FAIL"))); 00601 00602 return rc; 00603 }
1.7.5.1