7 #include <netinet/in.h>
9 #include <rpm/rpmlib.h> /* XXX RPMSIGTAG, other sig stuff */
10 #include <rpm/rpmts.h>
11 #include <rpm/rpmlog.h>
12 #include <rpm/rpmstring.h>
13 #include <rpm/rpmkeyring.h>
15 #include "lib/rpmlead.h"
16 #include "lib/signature.h"
17 #include "rpmio/digest.h"
18 #include "rpmio/rpmio_internal.h" /* fd*Digest(), fd stats */
19 #include "lib/header_internal.h" /* XXX headerCheck */
23 static int _print_pkts = 0;
25 static const unsigned int nkeyids_max = 256;
26 static unsigned int nkeyids = 0;
27 static unsigned int nextkeyid = 0;
28 static unsigned int * keyids;
30 void headerMergeLegacySigs(Header h, const Header sigh)
35 hi = headerInitIterator(sigh);
36 for (; headerNext(hi, &td); rpmtdFreeData(&td))
39 /* XXX Translate legacy signature tag values. */
41 td.tag = RPMTAG_SIGSIZE;
44 td.tag = RPMTAG_SIGPGP;
47 td.tag = RPMTAG_SIGMD5;
50 td.tag = RPMTAG_SIGGPG;
53 td.tag = RPMTAG_SIGPGP5;
55 case RPMSIGTAG_PAYLOADSIZE:
56 td.tag = RPMTAG_ARCHIVESIZE;
62 if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE))
66 if (td.data == NULL) continue; /* XXX can't happen */
67 if (!headerIsEntry(h, td.tag)) {
68 if (hdrchkType(td.type))
70 if (td.count < 0 || hdrchkData(td.count))
86 if (td.count >= 16*1024)
89 case RPM_STRING_ARRAY_TYPE:
90 case RPM_I18NSTRING_TYPE:
94 (void) headerPut(h, &td, HEADERPUT_DEFAULT);
97 hi = headerFreeIterator(hi);
100 Header headerRegenSigHeader(const Header h, int noArchiveSize)
102 Header sigh = rpmNewSignature();
106 for (hi = headerInitIterator(h); headerNext(hi, &td); rpmtdFreeData(&td)) {
108 /* XXX Translate legacy signature tag values. */
110 td.tag = RPMSIGTAG_SIZE;
113 td.tag = RPMSIGTAG_PGP;
116 td.tag = RPMSIGTAG_MD5;
119 td.tag = RPMSIGTAG_GPG;
122 td.tag = RPMSIGTAG_PGP5;
124 case RPMTAG_ARCHIVESIZE:
125 /* XXX rpm-4.1 and later has archive size in signature header. */
128 td.tag = RPMSIGTAG_PAYLOADSIZE;
130 case RPMTAG_SHA1HEADER:
131 case RPMTAG_DSAHEADER:
132 case RPMTAG_RSAHEADER:
134 if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE))
138 if (td.data == NULL) continue; /* XXX can't happen */
139 if (!headerIsEntry(sigh, td.tag))
140 (void) headerPut(sigh, &td, HEADERPUT_DEFAULT);
142 hi = headerFreeIterator(hi);
147 * Remember current key id.
148 * @param dig OpenPGP packet containter
149 * @return 0 if new keyid, otherwise 1
151 static int stashKeyid(pgpDig dig)
153 pgpDigParams sigp = dig ? &dig->signature : NULL;
157 if (dig == NULL || sigp == NULL)
160 keyid = pgpGrab(sigp->signid+4, 4);
165 for (i = 0; i < nkeyids; i++) {
166 if (keyid == keyids[i])
170 if (nkeyids < nkeyids_max) {
172 keyids = xrealloc(keyids, nkeyids * sizeof(*keyids));
174 if (keyids) /* XXX can't happen */
175 keyids[nextkeyid] = keyid;
177 nextkeyid %= nkeyids_max;
182 /* Parse the parameters from the OpenPGP packets that will be needed. */
183 static rpmRC parsePGP(rpmtd sigtd, const char *type, pgpDig dig)
185 rpmRC rc = RPMRC_FAIL;
186 int debug = (_print_pkts & rpmIsDebug());
187 if ((pgpPrtPkts(sigtd->data, sigtd->count, dig, debug) == 0) &&
188 (dig->signature.version == 3 || dig->signature.version == 4)) {
192 _("skipping %s with unverifiable V%u signature\n"), type,
193 dig->signature.version);
198 static rpmRC headerVerify(rpmKeyring keyring, rpmVSFlags vsflags,
199 const void * uh, size_t uc, char ** msg)
203 int32_t * ei = (int32_t *) uh;
204 int32_t il = ntohl(ei[0]);
205 int32_t dl = ntohl(ei[1]);
206 entryInfo pe = (entryInfo) &ei[2];
208 int32_t pvlen = sizeof(ildl) + (il * sizeof(*pe)) + dl;
209 unsigned char * dataStart = (unsigned char *) (pe + il);
210 struct indexEntry_s entry;
211 struct entryInfo_s info;
212 unsigned const char * b;
217 unsigned char * regionEnd = NULL;
218 rpmRC rc = RPMRC_FAIL; /* assume failure */
221 struct rpmtd_s sigtd;
222 DIGEST_CTX ctx = NULL;
224 /* Is the blob the right size? */
225 if (uc > 0 && pvlen != uc) {
226 rasprintf(&buf, _("blob size(%d): BAD, 8 + 16 * il(%d) + dl(%d)\n"),
227 (int)uc, (int)il, (int)dl);
231 memset(&entry, 0, sizeof(entry));
232 memset(&info, 0, sizeof(info));
234 /* Check (and convert) the 1st tag element. */
235 xx = headerVerifyInfo(1, dl, pe, &entry.info, 0);
237 rasprintf(&buf, _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
238 0, entry.info.tag, entry.info.type,
239 entry.info.offset, entry.info.count);
243 /* Is there an immutable header region tag? */
244 if (!(entry.info.tag == RPMTAG_HEADERIMMUTABLE
245 && entry.info.type == RPM_BIN_TYPE
246 && entry.info.count == REGION_TAG_COUNT))
252 /* Is the offset within the data area? */
253 if (entry.info.offset >= dl) {
255 _("region offset: BAD, tag %d type %d offset %d count %d\n"),
256 entry.info.tag, entry.info.type,
257 entry.info.offset, entry.info.count);
261 /* Is there an immutable header region tag trailer? */
262 regionEnd = dataStart + entry.info.offset;
263 (void) memcpy(&info, regionEnd, REGION_TAG_COUNT);
264 regionEnd += REGION_TAG_COUNT;
266 xx = headerVerifyInfo(1, dl, &info, &entry.info, 1);
268 !(entry.info.tag == RPMTAG_HEADERIMMUTABLE
269 && entry.info.type == RPM_BIN_TYPE
270 && entry.info.count == REGION_TAG_COUNT))
273 _("region trailer: BAD, tag %d type %d offset %d count %d\n"),
274 entry.info.tag, entry.info.type,
275 entry.info.offset, entry.info.count);
278 memset(&info, 0, sizeof(info));
280 /* Is the no. of tags in the region less than the total no. of tags? */
281 ril = entry.info.offset/sizeof(*pe);
282 if ((entry.info.offset % sizeof(*pe)) || ril > il) {
283 rasprintf(&buf, _("region size: BAD, ril(%d) > il(%d)\n"), ril, il);
287 /* Find a header-only digest/signature tag. */
288 for (i = ril; i < il; i++) {
289 xx = headerVerifyInfo(1, dl, pe+i, &entry.info, 0);
292 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
293 i, entry.info.tag, entry.info.type,
294 entry.info.offset, entry.info.count);
298 switch (entry.info.tag) {
299 case RPMTAG_SHA1HEADER:
300 if (vsflags & RPMVSF_NOSHA1HEADER)
303 for (b = dataStart + entry.info.offset; *b != '\0'; b++) {
304 if (strchr("0123456789abcdefABCDEF", *b) == NULL)
308 if (entry.info.type != RPM_STRING_TYPE || *b != '\0' || blen != 40)
310 rasprintf(&buf, _("hdr SHA1: BAD, not hex\n"));
314 info = entry.info; /* structure assignment */
318 case RPMTAG_RSAHEADER:
319 if (vsflags & RPMVSF_NORSAHEADER)
321 if (entry.info.type != RPM_BIN_TYPE) {
322 rasprintf(&buf, _("hdr RSA: BAD, not binary\n"));
325 info = entry.info; /* structure assignment */
328 case RPMTAG_DSAHEADER:
329 if (vsflags & RPMVSF_NODSAHEADER)
331 if (entry.info.type != RPM_BIN_TYPE) {
332 rasprintf(&buf, _("hdr DSA: BAD, not binary\n"));
335 info = entry.info; /* structure assignment */
345 /* Return determined RPMRC_OK/RPMRC_FAIL conditions. */
346 if (rc != RPMRC_NOTFOUND) {
354 /* If no header-only digest/signature, then do simple sanity check. */
357 xx = headerVerifyInfo(ril-1, dl, pe+1, &entry.info, 0);
360 _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
361 xx+1, entry.info.tag, entry.info.type,
362 entry.info.offset, entry.info.count);
365 rasprintf(&buf, "Header sanity check: OK\n");
375 /* Verify header-only digest/signature. */
378 goto verifyinfo_exit;
380 sigtd.tag = info.tag;
381 sigtd.type = info.type;
382 sigtd.count = info.count;
383 sigtd.data = memcpy(xmalloc(siglen), dataStart + info.offset, siglen);
384 sigtd.flags = RPMTD_ALLOCED;
387 case RPMTAG_RSAHEADER:
388 case RPMTAG_DSAHEADER:
389 if ((rc = parsePGP(&sigtd, "header", dig)) != RPMRC_OK) {
394 case RPMTAG_SHA1HEADER: {
395 pgpHashAlgo hashalgo = (info.tag == RPMTAG_SHA1HEADER) ?
396 PGPHASHALGO_SHA1 : dig->signature.hash_algo;
397 ildl[0] = htonl(ril);
398 ildl[1] = (regionEnd - dataStart);
399 ildl[1] = htonl(ildl[1]);
401 ctx = rpmDigestInit(hashalgo, RPMDIGEST_NONE);
403 b = (unsigned char *) rpm_header_magic;
404 nb = sizeof(rpm_header_magic);
405 (void) rpmDigestUpdate(ctx, b, nb);
407 b = (unsigned char *) ildl;
409 (void) rpmDigestUpdate(ctx, b, nb);
411 b = (unsigned char *) pe;
412 nb = (htonl(ildl[0]) * sizeof(*pe));
413 (void) rpmDigestUpdate(ctx, b, nb);
415 b = (unsigned char *) dataStart;
417 (void) rpmDigestUpdate(ctx, b, nb);
420 sigtd.data = _free(sigtd.data); /* Hmm...? */
424 rc = rpmVerifySignature(keyring, &sigtd, dig, ctx, &buf);
431 rpmtdFreeData(&sigtd);
433 rpmDigestFinal(ctx, NULL, NULL, 0);
437 rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, char ** msg)
440 rpmVSFlags vsflags = rpmtsVSFlags(ts);
441 rpmKeyring keyring = rpmtsGetKeyring(ts, 1);
443 rpmswEnter(rpmtsOp(ts, RPMTS_OP_DIGEST), 0);
444 rc = headerVerify(keyring, vsflags, uh, uc, msg);
445 rpmswExit(rpmtsOp(ts, RPMTS_OP_DIGEST), uc);
446 rpmKeyringFree(keyring);
451 static rpmRC rpmpkgReadHeader(rpmKeyring keyring, rpmVSFlags vsflags,
452 FD_t fd, Header *hdrp, char ** msg)
462 rpmRC rc = RPMRC_FAIL; /* assume failure */
470 memset(block, 0, sizeof(block));
471 if ((xx = timedRead(fd, (char *)block, sizeof(block))) != sizeof(block)) {
473 _("hdr size(%d): BAD, read returned %d\n"), (int)sizeof(block), xx);
476 if (memcmp(block, rpm_header_magic, sizeof(rpm_header_magic))) {
477 rasprintf(&buf, _("hdr magic: BAD\n"));
480 il = ntohl(block[2]);
481 if (hdrchkTags(il)) {
482 rasprintf(&buf, _("hdr tags: BAD, no. of tags(%d) out of range\n"), il);
485 dl = ntohl(block[3]);
486 if (hdrchkData(dl)) {
488 _("hdr data: BAD, no. of bytes(%d) out of range\n"), dl);
492 nb = (il * sizeof(struct entryInfo_s)) + dl;
493 uc = sizeof(il) + sizeof(dl) + nb;
497 if ((xx = timedRead(fd, (char *)&ei[2], nb)) != nb) {
498 rasprintf(&buf, _("hdr blob(%zd): BAD, read returned %d\n"), nb, xx);
502 /* Sanity check header tags */
503 rc = headerVerify(keyring, vsflags, ei, uc, msg);
507 /* OK, blob looks sane, load the header. */
510 rasprintf(&buf, _("hdr load: BAD\n"));
514 ei = NULL; /* XXX will be freed with header */
517 if (hdrp && h && rc == RPMRC_OK)
518 *hdrp = headerLink(h);
522 if (msg != NULL && *msg == NULL && buf != NULL) {
531 rpmRC rpmReadHeader(rpmts ts, FD_t fd, Header *hdrp, char ** msg)
534 rpmKeyring keyring = rpmtsGetKeyring(ts, 1);
535 rpmVSFlags vsflags = rpmtsVSFlags(ts);
537 rc = rpmpkgReadHeader(keyring, vsflags, fd, hdrp, msg);
539 rpmKeyringFree(keyring);
543 static rpmRC rpmpkgRead(rpmKeyring keyring, rpmVSFlags vsflags,
544 FD_t fd, const char * fn, Header * hdrp)
552 struct rpmtd_s sigtd;
555 rpmRC rc = RPMRC_FAIL; /* assume failure */
557 headerGetFlags hgeflags = HEADERGET_DEFAULT;
558 DIGEST_CTX ctx = NULL;
560 if (hdrp) *hdrp = NULL;
565 if ((rc = rpmLeadRead(fd, l)) == RPMRC_OK) {
566 const char * err = NULL;
567 if ((rc = rpmLeadCheck(l, &err)) == RPMRC_FAIL) {
568 rpmlog(RPMLOG_ERR, "%s: %s\n", fn, err);
570 leadtype = rpmLeadType(l);
577 /* Read the signature header. */
579 rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg);
582 rpmlog(RPMLOG_ERR, _("%s: rpmReadSignature failed: %s"), fn,
583 (msg && *msg ? msg : "\n"));
589 rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn);
597 #define _chk(_mask, _tag) \
598 (sigtag == 0 && !(vsflags & (_mask)) && headerIsEntry(sigh, (_tag)))
601 * Figger the most effective available signature.
602 * Prefer signatures over digests, then header-only over header+payload.
603 * DSA will be preferred over RSA if both exist because tested first.
604 * Note that NEEDPAYLOAD prevents header+payload signatures and digests.
607 if (_chk(RPMVSF_NODSAHEADER, RPMSIGTAG_DSA)) {
608 sigtag = RPMSIGTAG_DSA;
609 } else if (_chk(RPMVSF_NORSAHEADER, RPMSIGTAG_RSA)) {
610 sigtag = RPMSIGTAG_RSA;
611 } else if (_chk(RPMVSF_NODSA|RPMVSF_NEEDPAYLOAD, RPMSIGTAG_GPG)) {
612 sigtag = RPMSIGTAG_GPG;
613 fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
614 } else if (_chk(RPMVSF_NORSA|RPMVSF_NEEDPAYLOAD, RPMSIGTAG_PGP)) {
615 sigtag = RPMSIGTAG_PGP;
616 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
617 } else if (_chk(RPMVSF_NOSHA1HEADER, RPMSIGTAG_SHA1)) {
618 sigtag = RPMSIGTAG_SHA1;
619 } else if (_chk(RPMVSF_NOMD5|RPMVSF_NEEDPAYLOAD, RPMSIGTAG_MD5)) {
620 sigtag = RPMSIGTAG_MD5;
621 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
624 /* Read the metadata, computing digest(s) on the fly. */
628 rc = rpmpkgReadHeader(keyring, vsflags, fd, &h, &msg);
630 if (rc != RPMRC_OK || h == NULL) {
631 rpmlog(RPMLOG_ERR, _("%s: headerRead failed: %s"), fn,
632 (msg && *msg ? msg : "\n"));
638 /* Any digests or signatures to check? */
650 /* Retrieve the tag parameters from the signature header. */
651 if (!headerGet(sigh, sigtag, &sigtd, hgeflags)) {
659 if ((rc = parsePGP(&sigtd, "package", dig)) != RPMRC_OK) {
664 { struct rpmtd_s utd;
665 pgpHashAlgo hashalgo = (sigtag == RPMSIGTAG_SHA1) ?
666 PGPHASHALGO_SHA1 : dig->signature.hash_algo;
668 if (!headerGet(h, RPMTAG_HEADERIMMUTABLE, &utd, hgeflags))
670 ctx = rpmDigestInit(hashalgo, RPMDIGEST_NONE);
671 (void) rpmDigestUpdate(ctx, rpm_header_magic, sizeof(rpm_header_magic));
672 (void) rpmDigestUpdate(ctx, utd.data, utd.count);
676 case RPMSIGTAG_PGP5: /* XXX legacy */
678 if ((rc = parsePGP(&sigtd, "package", dig)) != RPMRC_OK) {
683 /* Legacy signatures need the compressed payload in the digest too. */
684 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0) {}
686 rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"),
692 ctx = rpmDigestBundleDupCtx(fd->digests, (sigtag == RPMSIGTAG_MD5) ?
693 PGPHASHALGO_MD5 : dig->signature.hash_algo);
699 /** @todo Implement disable/enable/warn/error/anal policy. */
700 rc = rpmVerifySignature(keyring, &sigtd, dig, ctx, &msg);
703 case RPMRC_OK: /* Signature is OK. */
704 rpmlog(RPMLOG_DEBUG, "%s: %s", fn, msg);
706 case RPMRC_NOTTRUSTED: /* Signature is OK, but key is not trusted. */
707 case RPMRC_NOKEY: /* Public key is unavailable. */
708 /* XXX Print NOKEY/NOTTRUSTED warning only once. */
709 { int lvl = (stashKeyid(dig) ? RPMLOG_DEBUG : RPMLOG_WARNING);
710 rpmlog(lvl, "%s: %s", fn, msg);
712 case RPMRC_NOTFOUND: /* Signature is unknown type. */
713 rpmlog(RPMLOG_WARNING, "%s: %s", fn, msg);
716 case RPMRC_FAIL: /* Signature does not verify. */
717 rpmlog(RPMLOG_ERR, "%s: %s", fn, msg);
723 if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) {
724 /* Retrofit RPMTAG_SOURCEPACKAGE to srpms for compatibility */
725 if (leadtype == RPMLEAD_SOURCE && headerIsSource(h)) {
726 if (!headerIsEntry(h, RPMTAG_SOURCEPACKAGE)) {
728 headerPutUint32(h, RPMTAG_SOURCEPACKAGE, &one, 1);
732 * Try to make sure binary rpms have RPMTAG_SOURCERPM set as that's
733 * what we use for differentiating binary vs source elsewhere.
735 if (!headerIsEntry(h, RPMTAG_SOURCEPACKAGE) && headerIsSource(h)) {
736 headerPutString(h, RPMTAG_SOURCERPM, "(none)");
739 * Convert legacy headers on the fly. Not having "new" style compressed
740 * filenames is close enough estimate for legacy indication...
742 if (!headerIsEntry(h, RPMTAG_DIRNAMES)) {
743 headerConvert(h, HEADERCONV_RETROFIT_V3);
746 /* Append (and remap) signature tags to the metadata. */
747 headerMergeLegacySigs(h, sigh);
749 /* Bump reference count for return. */
750 *hdrp = headerLink(h);
752 rpmtdFreeData(&sigtd);
753 rpmDigestFinal(ctx, NULL, NULL, 0);
756 sigh = rpmFreeSignature(sigh);
760 rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
763 rpmKeyring keyring = rpmtsGetKeyring(ts, 1);
764 rpmVSFlags vsflags = rpmtsVSFlags(ts);
766 rc = rpmpkgRead(keyring, vsflags, fd, fn, hdrp);
768 rpmKeyringFree(keyring);
773 * Check for supported payload format in header.
774 * @param h header to check
775 * @return RPMRC_OK if supported, RPMRC_FAIL otherwise
777 rpmRC headerCheckPayloadFormat(Header h) {
779 const char *payloadfmt = headerGetString(h, RPMTAG_PAYLOADFORMAT);
781 * XXX Ugh, rpm 3.x packages don't have payload format tag. Instead
782 * of blinly allowing, should check somehow (HDRID existence or... ?)
784 if (!payloadfmt) return rc;
786 if (!rstreq(payloadfmt, "cpio")) {
787 char *nevra = headerGetAsString(h, RPMTAG_NEVRA);
788 if (payloadfmt && rstreq(payloadfmt, "drpm")) {
790 _("%s is a Delta RPM and cannot be directly installed\n"),
794 _("Unsupported payload (%s) in package %s\n"),
795 payloadfmt ? payloadfmt : "none", nevra);
797 nevra = _free(nevra);