2 * \file lib/rpmchecksig.c
3 * Verify the signature of a package.
8 #include "rpmio_internal.h"
16 #include "signature.h"
17 #include "misc.h" /* XXX for makeTempFile() */
20 /*@access FD_t @*/ /* XXX stealing digests */
22 /*@access pgpDigParams @*/
25 static int _print_pkts = 0;
30 static int manageFile(/*@out@*/ FD_t *fdp,
31 /*@null@*/ /*@out@*/ const char **fnp,
32 int flags, /*@unused@*/ int rc)
33 /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
34 /*@modifies *fdp, *fnp, rpmGlobalMacroContext,
35 fileSystem, internalState @*/
40 if (fdp == NULL) /* programmer error */
44 /* close and reset *fdp to NULL */
45 if (*fdp && (fnp == NULL || *fnp == NULL)) {
51 /* open a file and set *fdp */
52 if (*fdp == NULL && fnp != NULL && *fnp != NULL) {
53 fd = Fopen(*fnp, ((flags & O_WRONLY) ? "w.ufdio" : "r.ufdio"));
54 if (fd == NULL || Ferror(fd)) {
55 rpmError(RPMERR_OPEN, _("%s: open failed: %s\n"), *fnp,
63 /* open a temp file */
64 if (*fdp == NULL && (fnp == NULL || *fnp == NULL)) {
66 if (makeTempFile(NULL, (fnp ? &fn : NULL), &fd)) {
67 rpmError(RPMERR_MAKETEMP, _("makeTempFile failed\n"));
72 *fdp = fdLink(fd, "manageFile return");
73 fd = fdFree(fd, "manageFile return");
79 if (*fdp != NULL && fnp != NULL && *fnp != NULL)
82 /* XXX never reached */
88 * Copy header+payload, calculating digest(s) on the fly.
91 static int copyFile(FD_t *sfdp, const char **sfnp,
92 FD_t *tfdp, const char **tfnp)
93 /*@globals rpmGlobalMacroContext,
94 fileSystem, internalState @*/
95 /*@modifies *sfdp, *sfnp, *tfdp, *tfnp, rpmGlobalMacroContext,
96 fileSystem, internalState @*/
98 unsigned char buf[BUFSIZ];
102 if (manageFile(sfdp, sfnp, O_RDONLY, 0))
104 if (manageFile(tfdp, tfnp, O_WRONLY|O_CREAT|O_TRUNC, 0))
107 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), *sfdp)) > 0)
109 if (Fwrite(buf, sizeof(buf[0]), count, *tfdp) != count) {
110 rpmError(RPMERR_FWRITE, _("%s: Fwrite failed: %s\n"), *tfnp,
116 rpmError(RPMERR_FREAD, _("%s: Fread failed: %s\n"), *sfnp, Fstrerror(*sfdp));
123 if (*sfdp) (void) manageFile(sfdp, NULL, 0, rc);
124 if (*tfdp) (void) manageFile(tfdp, NULL, 0, rc);
130 * Retrieve signer fingerprint from an OpenPGP signature tag.
131 * @param sig signature header
132 * @param sigtag signature tag
133 * @retval signid signer fingerprint
134 * @return 0 on success
136 static int getSignid(Header sig, int sigtag, unsigned char * signid)
137 /*@globals fileSystem @*/
138 /*@modifies *signid, fileSystem @*/
145 if (headerGetEntry(sig, sigtag, &pkttyp, &pkt, &pktlen) && pkt != NULL) {
146 pgpDig dig = pgpNewDig();
148 if (!pgpPrtPkts(pkt, pktlen, dig, 0)) {
150 memcpy(signid, dig->signature.signid, sizeof(dig->signature.signid));
155 dig = pgpFreeDig(dig);
157 pkt = headerFreeData(pkt, pkttyp);
162 * Create/modify elements in signature header.
163 * @param ts transaction set
164 * @param qva mode flags and parameters
165 * @param argv array of package file names (NULL terminated)
166 * @return 0 on success
168 static int rpmReSign(/*@unused@*/ rpmts ts,
169 QVA_t qva, const char ** argv)
170 /*@globals rpmGlobalMacroContext,
171 fileSystem, internalState @*/
172 /*@modifies rpmGlobalMacroContext,
173 fileSystem, internalState @*/
177 struct rpmlead lead, *l = &lead;
179 const char *rpm, *trpm;
180 const char *sigtarget = NULL;
186 int res = EXIT_FAILURE;
194 while ((rpm = *argv++) != NULL)
198 fprintf(stdout, "%s:\n", rpm);
200 if (manageFile(&fd, &rpm, O_RDONLY, 0))
204 memset(l, 0, sizeof(*l));
206 rc = readLead(fd, l);
207 if (rc != RPMRC_OK) {
208 rpmError(RPMERR_READLEAD, _("%s: not an rpm package\n"), rpm);
213 rpmError(RPMERR_BADSIGTYPE, _("%s: Can't sign v1 packaging\n"), rpm);
215 /*@notreached@*/ /*@switchbreak@*/ break;
217 rpmError(RPMERR_BADSIGTYPE, _("%s: Can't re-sign v2 packaging\n"), rpm);
219 /*@notreached@*/ /*@switchbreak@*/ break;
221 /*@switchbreak@*/ break;
225 rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
228 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed: %s"), rpm,
229 (msg && *msg ? msg : "\n"));
232 /*@notreached@*/ /*@switchbreak@*/ break;
235 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), rpm);
238 /*@switchbreak@*/ break;
242 /* Write the header and archive to a temp file */
243 /* ASSERT: ofd == NULL && sigtarget == NULL */
244 if (copyFile(&fd, &rpm, &ofd, &sigtarget))
246 /* Both fd and ofd are now closed. sigtarget contains tempfile name. */
247 /* ASSERT: fd == NULL && ofd == NULL */
249 /* Dump the immutable region (if present). */
250 if (headerGetEntry(sigh, RPMTAG_HEADERSIGNATURES, &uht, &uh, &uhc)) {
252 int_32 tag, type, count;
259 uh = headerFreeData(uh, uht);
263 oh = headerCopyLoad(uh);
264 for (hi = headerInitIterator(oh);
265 headerNextIterator(hi, &tag, &type, &ptr, &count);
266 ptr = headerFreeData(ptr, type))
269 xx = headerAddEntry(nh, tag, type, ptr, count);
271 hi = headerFreeIterator(hi);
274 sigh = headerFree(sigh);
275 sigh = headerLink(nh);
279 /* Eliminate broken digest values. */
280 xx = headerRemoveEntry(sigh, RPMSIGTAG_LEMD5_1);
281 xx = headerRemoveEntry(sigh, RPMSIGTAG_LEMD5_2);
282 xx = headerRemoveEntry(sigh, RPMSIGTAG_BADSHA1_1);
283 xx = headerRemoveEntry(sigh, RPMSIGTAG_BADSHA1_2);
285 /* Toss and recalculate header+payload size and digests. */
286 xx = headerRemoveEntry(sigh, RPMSIGTAG_SIZE);
287 xx = rpmAddSignature(sigh, sigtarget, RPMSIGTAG_SIZE, qva->passPhrase);
288 xx = headerRemoveEntry(sigh, RPMSIGTAG_MD5);
289 xx = rpmAddSignature(sigh, sigtarget, RPMSIGTAG_MD5, qva->passPhrase);
290 xx = headerRemoveEntry(sigh, RPMSIGTAG_SHA1);
291 xx = rpmAddSignature(sigh, sigtarget, RPMSIGTAG_SHA1, qva->passPhrase);
293 /* If gpg/pgp is configured, replace the signature. */
294 if ((sigtag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
295 unsigned char oldsignid[8], newsignid[8];
297 /* Grab the old signature fingerprint (if any) */
298 memset(oldsignid, 0, sizeof(oldsignid));
299 xx = getSignid(sigh, sigtag, oldsignid);
303 xx = headerRemoveEntry(sigh, RPMSIGTAG_DSA);
307 xx = headerRemoveEntry(sigh, RPMSIGTAG_RSA);
308 /*@switchbreak@*/ break;
311 xx = headerRemoveEntry(sigh, sigtag);
312 xx = rpmAddSignature(sigh, sigtarget, sigtag, qva->passPhrase);
314 /* If package was previously signed, check for same signer. */
315 memset(newsignid, 0, sizeof(newsignid));
316 if (memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
318 /* Grab the new signature fingerprint */
319 xx = getSignid(sigh, sigtag, newsignid);
321 /* If same signer, skip resigning the package. */
322 if (!memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
324 rpmMessage(RPMMESS_WARNING,
325 _("%s: was already signed by key ID %s, skipping\n"),
326 rpm, pgpHexStr(newsignid+4, sizeof(newsignid)-4));
328 /* Clean up intermediate target */
329 xx = unlink(sigtarget);
330 sigtarget = _free(sigtarget);
337 /* Reallocate the signature into one contiguous region. */
338 sigh = headerReload(sigh, RPMTAG_HEADERSIGNATURES);
339 if (sigh == NULL) /* XXX can't happen */
342 /* Write the lead/signature of the output rpm */
345 strcat(tmprpm, ".XXXXXX");
347 (void) mktemp(tmprpm);
350 if (manageFile(&ofd, &trpm, O_WRONLY|O_CREAT|O_TRUNC, 0))
353 l->signature_type = RPMSIGTYPE_HEADERSIG;
354 rc = writeLead(ofd, l);
355 if (rc != RPMRC_OK) {
356 rpmError(RPMERR_WRITELEAD, _("%s: writeLead failed: %s\n"), trpm,
361 if (rpmWriteSignature(ofd, sigh)) {
362 rpmError(RPMERR_SIGGEN, _("%s: rpmWriteSignature failed: %s\n"), trpm,
367 /* Append the header and archive from the temp file */
368 /* ASSERT: fd == NULL && ofd != NULL */
369 if (copyFile(&fd, &sigtarget, &ofd, &trpm))
371 /* Both fd and ofd are now closed. */
372 /* ASSERT: fd == NULL && ofd == NULL */
374 /* Move final target into place. */
376 xx = rename(trpm, rpm);
379 /* Clean up intermediate target */
380 xx = unlink(sigtarget);
381 sigtarget = _free(sigtarget);
388 if (fd) (void) manageFile(&fd, NULL, 0, res);
389 if (ofd) (void) manageFile(&ofd, NULL, 0, res);
391 sigh = rpmFreeSignature(sigh);
394 xx = unlink(sigtarget);
395 sigtarget = _free(sigtarget);
397 if (tmprpm[0] != '\0') {
405 int rpmcliImportPubkey(const rpmts ts, const unsigned char * pkt, ssize_t pktlen)
407 const char * afmt = "%{pubkeys:armor}";
408 const char * group = "Public Keys";
409 const char * license = "pubkey";
410 const char * buildhost = "localhost";
411 int_32 pflags = (RPMSENSE_KEYRING|RPMSENSE_EQUAL);
414 pgpDigParams pubp = NULL;
415 const char * d = NULL;
416 const char * enc = NULL;
417 const char * n = NULL;
418 const char * u = NULL;
419 const char * v = NULL;
420 const char * r = NULL;
421 const char * evr = NULL;
423 int rc = 1; /* assume failure */
427 if (pkt == NULL || pktlen <= 0)
429 if (rpmtsOpenDB(ts, (O_RDWR|O_CREAT)))
432 if ((enc = b64encode(pkt, pktlen)) == NULL)
437 /* Build header elements. */
438 (void) pgpPrtPkts(pkt, pktlen, dig, 0);
442 v = t = xmalloc(16+1);
443 t = stpcpy(t, pgpHexStr(pubp->signid, sizeof(pubp->signid)));
445 r = t = xmalloc(8+1);
446 t = stpcpy(t, pgpHexStr(pubp->time, sizeof(pubp->time)));
448 n = t = xmalloc(sizeof("gpg()")+8);
449 t = stpcpy( stpcpy( stpcpy(t, "gpg("), v+8), ")");
451 /*@-nullpass@*/ /* FIX: pubp->userid may be NULL */
452 u = t = xmalloc(sizeof("gpg()")+strlen(pubp->userid));
453 t = stpcpy( stpcpy( stpcpy(t, "gpg("), pubp->userid), ")");
456 evr = t = xmalloc(sizeof("4X:-")+strlen(v)+strlen(r));
457 t = stpcpy(t, (pubp->version == 4 ? "4:" : "3:"));
458 t = stpcpy( stpcpy( stpcpy(t, v), "-"), r);
461 /* Check for pre-existing header. */
463 /* Build pubkey header. */
466 xx = headerAddOrAppendEntry(h, RPMTAG_PUBKEYS,
467 RPM_STRING_ARRAY_TYPE, &enc, 1);
469 d = headerSprintf(h, afmt, rpmTagTable, rpmHeaderFormats, NULL);
473 xx = headerAddEntry(h, RPMTAG_NAME, RPM_STRING_TYPE, "gpg-pubkey", 1);
474 xx = headerAddEntry(h, RPMTAG_VERSION, RPM_STRING_TYPE, v+8, 1);
475 xx = headerAddEntry(h, RPMTAG_RELEASE, RPM_STRING_TYPE, r, 1);
476 xx = headerAddEntry(h, RPMTAG_DESCRIPTION, RPM_STRING_TYPE, d, 1);
477 xx = headerAddEntry(h, RPMTAG_GROUP, RPM_STRING_TYPE, group, 1);
478 xx = headerAddEntry(h, RPMTAG_LICENSE, RPM_STRING_TYPE, license, 1);
479 xx = headerAddEntry(h, RPMTAG_SUMMARY, RPM_STRING_TYPE, u, 1);
481 xx = headerAddEntry(h, RPMTAG_SIZE, RPM_INT32_TYPE, &zero, 1);
483 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME,
484 RPM_STRING_ARRAY_TYPE, &u, 1);
485 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION,
486 RPM_STRING_ARRAY_TYPE, &evr, 1);
487 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS,
488 RPM_INT32_TYPE, &pflags, 1);
490 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME,
491 RPM_STRING_ARRAY_TYPE, &n, 1);
492 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION,
493 RPM_STRING_ARRAY_TYPE, &evr, 1);
494 xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS,
495 RPM_INT32_TYPE, &pflags, 1);
497 xx = headerAddEntry(h, RPMTAG_RPMVERSION, RPM_STRING_TYPE, RPMVERSION, 1);
499 /* XXX W2DO: tag value inheirited from parent? */
500 xx = headerAddEntry(h, RPMTAG_BUILDHOST, RPM_STRING_TYPE, buildhost, 1);
501 { int_32 tid = rpmtsGetTid(ts);
502 xx = headerAddEntry(h, RPMTAG_INSTALLTIME, RPM_INT32_TYPE, &tid, 1);
503 /* XXX W2DO: tag value inheirited from parent? */
504 xx = headerAddEntry(h, RPMTAG_BUILDTIME, RPM_INT32_TYPE, &tid, 1);
508 /* XXX W2DO: tag value inheirited from parent? */
509 xx = headerAddEntry(h, RPMTAG_SOURCERPM, RPM_STRING_TYPE, fn, 1);
512 /* Add header to database. */
513 rc = rpmdbAdd(rpmtsGetRdb(ts), rpmtsGetTid(ts), h, NULL, NULL);
520 dig = pgpFreeDig(dig);
533 * Import public key(s).
534 * @todo Implicit --update policy for gpg-pubkey headers.
535 * @param ts transaction set
536 * @param qva mode flags and parameters
537 * @param argv array of pubkey file names (NULL terminated)
538 * @return 0 on success
540 static int rpmcliImportPubkeys(const rpmts ts,
541 /*@unused@*/ QVA_t qva,
542 /*@null@*/ const char ** argv)
543 /*@globals RPMVERSION, rpmGlobalMacroContext,
544 fileSystem, internalState @*/
545 /*@modifies ts, rpmGlobalMacroContext,
546 fileSystem, internalState @*/
549 const unsigned char * pkt = NULL;
554 if (argv == NULL) return res;
558 while ((fn = *argv++) != NULL) {
564 /* Read pgp packet. */
565 if ((rc = pgpReadPkts(fn, &pkt, &pktlen)) <= 0) {
566 rpmError(RPMERR_IMPORT, _("%s: import read failed.\n"), fn);
570 if (rc != PGPARMOR_PUBKEY) {
571 rpmError(RPMERR_IMPORT, _("%s: not an armored public key.\n"), fn);
576 /* Import pubkey packet(s). */
577 if ((rc = rpmcliImportPubkey(ts, pkt, pktlen)) != 0) {
578 rpmError(RPMERR_IMPORT, _("%s: import failed.\n"), fn);
592 static unsigned char header_magic[8] = {
593 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
597 * @todo If the GPG key was known available, the md5 digest could be skipped.
599 static int readFile(FD_t fd, const char * fn, pgpDig dig)
600 /*@globals fileSystem, internalState @*/
601 /*@modifies fd, *dig, fileSystem, internalState @*/
603 unsigned char buf[4*BUFSIZ];
610 /* Read the header from the package. */
611 { Header h = headerRead(fd, HEADER_MAGIC_YES);
613 rpmError(RPMERR_FREAD, _("%s: headerRead failed\n"), fn);
617 dig->nbytes += headerSizeof(h, HEADER_MAGIC_YES);
619 if (headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) {
623 if (!headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc)
627 rpmError(RPMERR_FREAD, _("%s: headerGetEntry failed\n"), fn);
630 dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
631 (void) rpmDigestUpdate(dig->hdrsha1ctx, header_magic, sizeof(header_magic));
632 (void) rpmDigestUpdate(dig->hdrsha1ctx, uh, uhc);
633 uh = headerFreeData(uh, uht);
638 /* Read the payload from the package. */
639 while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
640 dig->nbytes += count;
642 rpmError(RPMERR_FREAD, _("%s: Fread failed: %s\n"), fn, Fstrerror(fd));
646 /* XXX Steal the digest-in-progress from the file handle. */
647 for (i = fd->ndigests - 1; i >= 0; i--) {
648 FDDIGEST_t fddig = fd->digests + i;
649 if (fddig->hashctx == NULL)
651 if (fddig->hashalgo == PGPHASHALGO_MD5) {
652 assert(dig->md5ctx == NULL);
653 dig->md5ctx = fddig->hashctx;
654 fddig->hashctx = NULL;
657 if (fddig->hashalgo == PGPHASHALGO_SHA1) {
658 assert(dig->sha1ctx == NULL);
659 dig->sha1ctx = fddig->hashctx;
660 fddig->hashctx = NULL;
671 int rpmVerifySignatures(QVA_t qva, rpmts ts, FD_t fd,
675 struct rpmlead lead, *l = &lead;
678 char missingKeys[7164], * m;
679 char untrustedKeys[7164], * u;
692 int nodigests = !(qva->qva_flags & VERIFY_DIGEST);
693 int nosignatures = !(qva->qva_flags & VERIFY_SIGNATURE);
697 memset(l, 0, sizeof(*l));
699 rc = readLead(fd, l);
700 if (rc != RPMRC_OK) {
701 rpmError(RPMERR_READLEAD, _("%s: not an rpm package\n"), fn);
707 rpmError(RPMERR_BADSIGTYPE, _("%s: No signature available (v1.0 RPM)\n"), fn);
710 /*@notreached@*/ /*@switchbreak@*/ break;
712 /*@switchbreak@*/ break;
716 rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
719 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed: %s"), fn,
720 (msg && *msg ? msg : "\n"));
724 /*@notreached@*/ /*@switchbreak@*/ break;
727 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), fn);
731 /*@switchbreak@*/ break;
735 /* Grab a hint of what needs doing to avoid duplication. */
737 if (sigtag == 0 && !nosignatures) {
738 if (headerIsEntry(sigh, RPMSIGTAG_DSA))
739 sigtag = RPMSIGTAG_DSA;
740 else if (headerIsEntry(sigh, RPMSIGTAG_RSA))
741 sigtag = RPMSIGTAG_RSA;
742 else if (headerIsEntry(sigh, RPMSIGTAG_GPG))
743 sigtag = RPMSIGTAG_GPG;
744 else if (headerIsEntry(sigh, RPMSIGTAG_PGP))
745 sigtag = RPMSIGTAG_PGP;
747 if (sigtag == 0 && !nodigests) {
748 if (headerIsEntry(sigh, RPMSIGTAG_MD5))
749 sigtag = RPMSIGTAG_MD5;
750 else if (headerIsEntry(sigh, RPMSIGTAG_SHA1))
751 sigtag = RPMSIGTAG_SHA1; /* XXX never happens */
754 if (headerIsEntry(sigh, RPMSIGTAG_PGP)
755 || headerIsEntry(sigh, RPMSIGTAG_PGP5)
756 || headerIsEntry(sigh, RPMSIGTAG_MD5))
757 fdInitDigest(fd, PGPHASHALGO_MD5, 0);
758 if (headerIsEntry(sigh, RPMSIGTAG_GPG))
759 fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
762 sigp = rpmtsSignature(ts);
764 /* Read the file, generating digest(s) on the fly. */
765 if (dig == NULL || sigp == NULL || readFile(fd, fn, dig)) {
772 m = missingKeys; *m = '\0';
773 u = untrustedKeys; *u = '\0';
774 sprintf(b, "%s:%c", fn, (rpmIsVerbose() ? '\n' : ' ') );
777 for (hi = headerInitIterator(sigh);
778 headerNextIterator(hi, &sigtag, &sigtype, &sig, &siglen) != 0;
779 (void) rpmtsSetSig(ts, sigtag, sigtype, NULL, siglen))
782 if (sig == NULL) /* XXX can't happen */
785 (void) rpmtsSetSig(ts, sigtag, sigtype, sig, siglen);
787 /* Clean up parameters from previous sigtag. */
794 case RPMSIGTAG_PGP5: /* XXX legacy */
798 xx = pgpPrtPkts(sig, siglen, dig,
799 (_print_pkts & rpmIsDebug()));
801 /* XXX only V3 signatures for now. */
802 if (sigp->version != 3) {
803 rpmError(RPMERR_SIGVFY,
804 _("only V3 signatures can be verified, skipping V%u signature\n"),
808 /*@switchbreak@*/ break;
812 /* XXX Don't bother with header sha1 if header dsa. */
813 if (!nosignatures && sigtag == RPMSIGTAG_DSA)
815 /*@switchbreak@*/ break;
816 case RPMSIGTAG_LEMD5_2:
817 case RPMSIGTAG_LEMD5_1:
822 * Don't bother with md5 if pgp, as RSA/MD5 is more reliable
823 * than the -- now unsupported -- legacy md5 breakage.
825 if (!nosignatures && sigtag == RPMSIGTAG_PGP)
827 /*@switchbreak@*/ break;
830 /*@notreached@*/ /*@switchbreak@*/ break;
833 res3 = rpmVerifySignature(ts, result);
837 if (rpmIsVerbose()) {
839 b = stpcpy(b, result);
845 b = stpcpy(b, "SIZE ");
847 /*@switchbreak@*/ break;
849 b = stpcpy(b, "SHA1 ");
851 /*@switchbreak@*/ break;
852 case RPMSIGTAG_LEMD5_2:
853 case RPMSIGTAG_LEMD5_1:
855 b = stpcpy(b, "MD5 ");
857 /*@switchbreak@*/ break;
859 b = stpcpy(b, "RSA ");
861 /*@switchbreak@*/ break;
862 case RPMSIGTAG_PGP5: /* XXX legacy */
868 case RPMRC_NOTTRUSTED:
870 b = stpcpy(b, "(MD5) (PGP) ");
871 tempKey = strstr(result, "ey ID");
872 if (tempKey == NULL) {
873 tempKey = strstr(result, "keyid:");
877 if (res3 == RPMRC_NOKEY) {
878 m = stpcpy(m, " PGP#");
879 m = stpncpy(m, tempKey + offset, 8);
882 u = stpcpy(u, " PGP#");
883 u = stpncpy(u, tempKey + offset, 8);
887 } /*@innerbreak@*/ break;
889 b = stpcpy(b, "MD5 PGP ");
891 /*@innerbreak@*/ break;
893 /*@switchbreak@*/ break;
895 b = stpcpy(b, "(SHA1) DSA ");
897 /*@switchbreak@*/ break;
899 /* Do not consider this a failure */
902 b = stpcpy(b, "(GPG) ");
903 m = stpcpy(m, " GPG#");
904 tempKey = strstr(result, "ey ID");
906 m = stpncpy(m, tempKey+6, 8);
910 /*@innerbreak@*/ break;
912 b = stpcpy(b, "GPG ");
914 /*@innerbreak@*/ break;
916 /*@switchbreak@*/ break;
918 b = stpcpy(b, "?UnknownSignatureType? ");
920 /*@switchbreak@*/ break;
924 if (rpmIsVerbose()) {
926 b = stpcpy(b, result);
930 b = stpcpy(b, "size ");
931 /*@switchbreak@*/ break;
933 b = stpcpy(b, "sha1 ");
934 /*@switchbreak@*/ break;
935 case RPMSIGTAG_LEMD5_2:
936 case RPMSIGTAG_LEMD5_1:
938 b = stpcpy(b, "md5 ");
939 /*@switchbreak@*/ break;
941 b = stpcpy(b, "rsa ");
942 /*@switchbreak@*/ break;
943 case RPMSIGTAG_PGP5: /* XXX legacy */
945 b = stpcpy(b, "(md5) pgp ");
946 /*@switchbreak@*/ break;
948 b = stpcpy(b, "(sha1) dsa ");
949 /*@switchbreak@*/ break;
951 b = stpcpy(b, "gpg ");
952 /*@switchbreak@*/ break;
954 b = stpcpy(b, "??? ");
955 /*@switchbreak@*/ break;
961 hi = headerFreeIterator(hi);
966 if (rpmIsVerbose()) {
967 rpmError(RPMERR_SIGVFY, "%s", buf);
969 rpmError(RPMERR_SIGVFY, "%s%s%s%s%s%s%s%s\n", buf,
971 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
973 (missingKeys[0] != '\0') ? _(") ") : "",
974 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
976 (untrustedKeys[0] != '\0') ? _(")") : "");
980 if (rpmIsVerbose()) {
981 rpmError(RPMERR_SIGVFY, "%s", buf);
983 rpmError(RPMERR_SIGVFY, "%s%s%s%s%s%s%s%s\n", buf,
985 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
987 (missingKeys[0] != '\0') ? _(") ") : "",
988 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
990 (untrustedKeys[0] != '\0') ? _(")") : "");
997 sigh = rpmFreeSignature(sigh);
1002 int rpmcliSign(rpmts ts, QVA_t qva, const char ** argv)
1008 if (argv == NULL) return res;
1010 switch (qva->qva_mode) {
1011 case RPMSIGN_CHK_SIGNATURE:
1013 case RPMSIGN_IMPORT_PUBKEY:
1014 return rpmcliImportPubkeys(ts, qva, argv);
1015 /*@notreached@*/ break;
1016 case RPMSIGN_NEW_SIGNATURE:
1017 case RPMSIGN_ADD_SIGNATURE:
1018 return rpmReSign(ts, qva, argv);
1019 /*@notreached@*/ break;
1023 /*@notreached@*/ break;
1026 while ((arg = *argv++) != NULL) {
1029 if ((fd = Fopen(arg, "r.ufdio")) == NULL
1031 || rpmVerifySignatures(qva, ts, fd, arg))
1034 if (fd != NULL) xx = Fclose(fd);