pgpDig rpmPubkeyDig(rpmPubkey key) { pgpDig dig = NULL; static unsigned char zeros[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int rc; if (key == NULL) return NULL; dig = pgpNewDig(); rc = pgpPrtPkts(key->pkt, key->pktlen, dig, 0); if (rc == 0) { pgpDigParams pubp = pgpDigGetParams(dig, PGPTAG_PUBLIC_KEY); if (!pubp || !memcmp(pubp->signid, zeros, sizeof(pubp->signid)) || !memcmp(pubp->time, zeros, sizeof(pubp->time)) || pubp->userid == NULL) { rc = -1; } } if (rc) dig = pgpFreeDig(dig); return dig; }
rpmRC rpmKeyringLookup(rpmKeyring keyring, pgpDig sig) { rpmRC res = RPMRC_NOKEY; pgpDigParams sigp = pgpDigGetParams(sig, PGPTAG_SIGNATURE); rpmPubkey key = findbySig(keyring, sigp); if (key) { /* * Callers expect sig to have the key data parsed into pgpDig * on (successful) return, sigh. No need to check for return * here as this is validated at rpmPubkeyNew() already. */ pgpPrtPkts(key->pkt, key->pktlen, sig, 0); res = RPMRC_OK; } return res; }
/* Build pubkey header. */ static int makePubkeyHeader(rpmts ts, rpmPubkey key, Header * hdrp) { Header h = headerNew(); const char * afmt = "%{pubkeys:armor}"; const char * group = "Public Keys"; const char * license = "pubkey"; const char * buildhost = "localhost"; const char * userid; rpmsenseFlags pflags = (RPMSENSE_KEYRING|RPMSENSE_EQUAL); uint32_t zero = 0; uint32_t keytime = 0; pgpDig dig = NULL; pgpDigParams pubp = NULL; char * d = NULL; char * enc = NULL; char * n = NULL; char * u = NULL; char * v = NULL; char * r = NULL; char * evr = NULL; int rc = -1; if ((enc = rpmPubkeyBase64(key)) == NULL) goto exit; if ((dig = rpmPubkeyDig(key)) == NULL) goto exit; if ((pubp = pgpDigGetParams(dig, PGPTAG_PUBLIC_KEY)) == NULL) goto exit; /* Build header elements. */ v = pgpHexStr(pubp->signid, sizeof(pubp->signid)); r = pgpHexStr(pubp->time, sizeof(pubp->time)); userid = pubp->userid ? pubp->userid : "none"; keytime = pgpGrab(pubp->time, sizeof(pubp->time)); rasprintf(&n, "gpg(%s)", v+8); rasprintf(&u, "gpg(%s)", userid); rasprintf(&evr, "%d:%s-%s", pubp->version, v, r); headerPutString(h, RPMTAG_PUBKEYS, enc); if ((d = headerFormat(h, afmt, NULL)) == NULL) goto exit; headerPutString(h, RPMTAG_NAME, "gpg-pubkey"); headerPutString(h, RPMTAG_VERSION, v+8); headerPutString(h, RPMTAG_RELEASE, r); headerPutString(h, RPMTAG_DESCRIPTION, d); headerPutString(h, RPMTAG_GROUP, group); headerPutString(h, RPMTAG_LICENSE, license); headerPutString(h, RPMTAG_SUMMARY, u); headerPutString(h, RPMTAG_PACKAGER, userid); headerPutUint32(h, RPMTAG_SIZE, &zero, 1); headerPutString(h, RPMTAG_PROVIDENAME, u); headerPutString(h, RPMTAG_PROVIDEVERSION, evr); headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1); headerPutString(h, RPMTAG_PROVIDENAME, n); headerPutString(h, RPMTAG_PROVIDEVERSION, evr); headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pflags, 1); headerPutString(h, RPMTAG_RPMVERSION, RPMVERSION); headerPutString(h, RPMTAG_BUILDHOST, buildhost); headerPutUint32(h, RPMTAG_BUILDTIME, &keytime, 1); headerPutString(h, RPMTAG_SOURCERPM, "(none)"); /* Reload the lot to immutable region and stomp sha1 digest on it */ h = headerReload(h, RPMTAG_HEADERIMMUTABLE); if (h != NULL) { char *sha1 = NULL; unsigned int blen = 0; const void *blob = headerExport(h, &blen); /* XXX FIXME: bah, this code is repeated in way too many places */ DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); rpmDigestUpdate(ctx, rpm_header_magic, sizeof(rpm_header_magic)); rpmDigestUpdate(ctx, blob, blen); rpmDigestFinal(ctx, (void **)&sha1, NULL, 1); if (sha1) { headerPutString(h, RPMTAG_SHA1HEADER, sha1); *hdrp = headerLink(h); rc = 0; } free(sha1); } exit: headerFree(h); pgpFreeDig(dig); free(n); free(u); free(v); free(r); free(evr); free(enc); free(d); return rc; }