211 lines
6.5 KiB
Diff
211 lines
6.5 KiB
Diff
|
Backport of the signature comparison on package resigning fixes:
|
||
|
http://rpm.org/gitweb?p=rpm.git;a=commitdiff;h=e29313061313a9e29d38a005f1b5f5bdc47ccd84
|
||
|
http://rpm.org/gitweb?p=rpm.git;a=commitdiff;h=c0aad81e9b17afcbea4008485d354673495eb148
|
||
|
http://rpm.org/gitweb?p=rpm.git;a=commitdiff;h=17b433ce8c8613199e40b3b27e9ca5398a2027e3
|
||
|
diff --git a/lib/rpmchecksig.c b/lib/rpmchecksig.c
|
||
|
index babbe76..1545269 100644
|
||
|
--- a/lib/rpmchecksig.c
|
||
|
+++ b/lib/rpmchecksig.c
|
||
|
@@ -105,28 +105,96 @@ exit:
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
- * Retrieve signer fingerprint from an OpenPGP signature tag.
|
||
|
- * @param sig signature header
|
||
|
+ * Retrieve signature from header tag
|
||
|
+ * @param sigh signature header
|
||
|
* @param sigtag signature tag
|
||
|
- * @retval signid signer fingerprint
|
||
|
- * @return 0 on success
|
||
|
+ * @return parsed pgp dig or NULL
|
||
|
*/
|
||
|
-static int getSignid(Header sig, rpmSigTag sigtag, pgpKeyID_t signid)
|
||
|
+static pgpDig getSig(Header sigh, rpmSigTag sigtag)
|
||
|
{
|
||
|
struct rpmtd_s pkt;
|
||
|
- int rc = 1;
|
||
|
+ pgpDig dig = NULL;
|
||
|
|
||
|
- if (headerGet(sig, sigtag, &pkt, HEADERGET_DEFAULT) && pkt.data != NULL) {
|
||
|
- pgpDig dig = pgpNewDig();
|
||
|
+ if (headerGet(sigh, sigtag, &pkt, HEADERGET_DEFAULT) && pkt.data != NULL) {
|
||
|
+ dig = pgpNewDig();
|
||
|
|
||
|
- if (!pgpPrtPkts(pkt.data, pkt.count, dig, 0)) {
|
||
|
- memcpy(signid, dig->signature.signid, sizeof(dig->signature.signid));
|
||
|
- rc = 0;
|
||
|
+ if (pgpPrtPkts(pkt.data, pkt.count, dig, 0) != 0) {
|
||
|
+ dig = pgpFreeDig(dig);
|
||
|
}
|
||
|
-
|
||
|
- dig = pgpFreeDig(dig);
|
||
|
rpmtdFreeData(&pkt);
|
||
|
}
|
||
|
+ return dig;
|
||
|
+}
|
||
|
+
|
||
|
+static void deleteSigs(Header sigh)
|
||
|
+{
|
||
|
+ headerDel(sigh, RPMSIGTAG_GPG);
|
||
|
+ headerDel(sigh, RPMSIGTAG_PGP);
|
||
|
+ headerDel(sigh, RPMSIGTAG_DSA);
|
||
|
+ headerDel(sigh, RPMSIGTAG_RSA);
|
||
|
+ headerDel(sigh, RPMSIGTAG_PGP5);
|
||
|
+}
|
||
|
+
|
||
|
+static int sameSignature(rpmSigTag sigtag, Header h1, Header h2)
|
||
|
+{
|
||
|
+ pgpDig dig1 = getSig(h1, sigtag);
|
||
|
+ pgpDig dig2 = getSig(h2, sigtag);
|
||
|
+ int rc = 0; /* assume different, eg if either signature doesn't exist */
|
||
|
+
|
||
|
+ /* XXX This part really belongs to rpmpgp.[ch] */
|
||
|
+ if (dig1 && dig2) {
|
||
|
+ pgpDigParams sig1 = &dig1->signature;
|
||
|
+ pgpDigParams sig2 = &dig2->signature;
|
||
|
+
|
||
|
+ /* XXX Should we compare something else too? */
|
||
|
+ if (sig1->hash_algo != sig2->hash_algo)
|
||
|
+ goto exit;
|
||
|
+ if (sig1->pubkey_algo != sig2->pubkey_algo)
|
||
|
+ goto exit;
|
||
|
+ if (sig1->version != sig2->version)
|
||
|
+ goto exit;
|
||
|
+ if (sig1->sigtype != sig2->sigtype)
|
||
|
+ goto exit;
|
||
|
+ if (memcmp(sig1->signid, sig2->signid, sizeof(sig1->signid)) != 0)
|
||
|
+ goto exit;
|
||
|
+
|
||
|
+ /* Parameters match, assume same signature */
|
||
|
+ rc = 1;
|
||
|
+ }
|
||
|
+
|
||
|
+exit:
|
||
|
+ pgpFreeDig(dig1);
|
||
|
+ pgpFreeDig(dig2);
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+static int replaceSignature(Header sigh, const char *sigtarget,
|
||
|
+ const char *passPhrase)
|
||
|
+{
|
||
|
+ /* Grab a copy of the header so we can compare the result */
|
||
|
+ Header oldsigh = headerCopy(sigh);
|
||
|
+ int rc = -1;
|
||
|
+
|
||
|
+ /* Nuke all signature tags */
|
||
|
+ deleteSigs(sigh);
|
||
|
+
|
||
|
+ /*
|
||
|
+ * rpmAddSignature() internals parse the actual signing result and
|
||
|
+ * use appropriate DSA/RSA tags regardless of what we pass from here.
|
||
|
+ * RPMSIGTAG_GPG is only used to signal its an actual signature
|
||
|
+ * and not just a digest we're adding, and says nothing
|
||
|
+ * about the actual tags that gets created.
|
||
|
+ */
|
||
|
+ if (rpmAddSignature(sigh, sigtarget, RPMSIGTAG_GPG, passPhrase) == 0) {
|
||
|
+ /* Lets see what we got and whether its the same signature as before */
|
||
|
+ rpmSigTag sigtag = headerIsEntry(sigh, RPMSIGTAG_DSA) ?
|
||
|
+ RPMSIGTAG_DSA : RPMSIGTAG_RSA;
|
||
|
+
|
||
|
+ rc = sameSignature(sigtag, sigh, oldsigh);
|
||
|
+
|
||
|
+ }
|
||
|
+
|
||
|
+ headerFree(oldsigh);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
@@ -253,62 +321,18 @@ static int rpmReSign(rpmts ts, QVA_t qva, ARGV_const_t argv)
|
||
|
}
|
||
|
|
||
|
if (deleting) { /* Nuke all the signature tags. */
|
||
|
- xx = headerDel(sigh, RPMSIGTAG_GPG);
|
||
|
- xx = headerDel(sigh, RPMSIGTAG_DSA);
|
||
|
- xx = headerDel(sigh, RPMSIGTAG_PGP5);
|
||
|
- xx = headerDel(sigh, RPMSIGTAG_PGP);
|
||
|
- xx = headerDel(sigh, RPMSIGTAG_RSA);
|
||
|
- } else /* If gpg/pgp is configured, replace the signature. */
|
||
|
- if ((sigtag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
|
||
|
- pgpKeyID_t oldsignid, newsignid;
|
||
|
-
|
||
|
- /* Grab the old signature fingerprint (if any) */
|
||
|
- memset(oldsignid, 0, sizeof(oldsignid));
|
||
|
- xx = getSignid(sigh, sigtag, oldsignid);
|
||
|
-
|
||
|
- switch (sigtag) {
|
||
|
- case RPMSIGTAG_DSA:
|
||
|
- xx = headerDel(sigh, RPMSIGTAG_GPG);
|
||
|
- break;
|
||
|
- case RPMSIGTAG_RSA:
|
||
|
- xx = headerDel(sigh, RPMSIGTAG_PGP);
|
||
|
- break;
|
||
|
- case RPMSIGTAG_GPG:
|
||
|
- xx = headerDel(sigh, RPMSIGTAG_DSA);
|
||
|
- case RPMSIGTAG_PGP5:
|
||
|
- case RPMSIGTAG_PGP:
|
||
|
- xx = headerDel(sigh, RPMSIGTAG_RSA);
|
||
|
- break;
|
||
|
- default:
|
||
|
- break;
|
||
|
- }
|
||
|
-
|
||
|
- xx = headerDel(sigh, sigtag);
|
||
|
- if (rpmAddSignature(sigh, sigtarget, sigtag, qva->passPhrase)) {
|
||
|
- goto exit;
|
||
|
- }
|
||
|
-
|
||
|
- /* If package was previously signed, check for same signer. */
|
||
|
- memset(newsignid, 0, sizeof(newsignid));
|
||
|
- if (memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
|
||
|
-
|
||
|
- /* Grab the new signature fingerprint */
|
||
|
- xx = getSignid(sigh, sigtag, newsignid);
|
||
|
-
|
||
|
- /* If same signer, skip resigning the package. */
|
||
|
- if (!memcmp(oldsignid, newsignid, sizeof(oldsignid))) {
|
||
|
-
|
||
|
- char *signid = pgpHexStr(newsignid+4, sizeof(newsignid)-4);
|
||
|
+ deleteSigs(sigh);
|
||
|
+ } else if ((sigtag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0) {
|
||
|
+ res = replaceSignature(sigh, sigtarget, qva->passPhrase);
|
||
|
+ if (res != 0) {
|
||
|
+ if (res == 1) {
|
||
|
rpmlog(RPMLOG_WARNING,
|
||
|
- _("%s: was already signed by key ID %s, skipping\n"),
|
||
|
- rpm, signid);
|
||
|
- free(signid);
|
||
|
-
|
||
|
- /* Clean up intermediate target */
|
||
|
- xx = unlink(sigtarget);
|
||
|
- sigtarget = _free(sigtarget);
|
||
|
- continue;
|
||
|
+ _("%s already contains identical signature, skipping\n"),
|
||
|
+ rpm);
|
||
|
+ /* Identical signature is not an error */
|
||
|
+ res = 0;
|
||
|
}
|
||
|
+ goto exit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff --git a/lib/signature.c b/lib/signature.c
|
||
|
index 7d50db7..d5aad52 100644
|
||
|
--- a/lib/signature.c
|
||
|
+++ b/lib/signature.c
|
||
|
@@ -584,12 +584,12 @@ int rpmAddSignature(Header sigh, const char * file, rpmSigTag sigTag,
|
||
|
case RPMSIGTAG_PGP5: /* XXX legacy */
|
||
|
case RPMSIGTAG_PGP:
|
||
|
case RPMSIGTAG_GPG: {
|
||
|
- rpmSigTag hdrtag = (sigTag == RPMSIGTAG_GPG) ?
|
||
|
- RPMSIGTAG_DSA : RPMSIGTAG_RSA;
|
||
|
+ rpmSigTag hdrtag;
|
||
|
if (makeGPGSignature(file, &sigTag, &pkt, &pktlen, passPhrase)
|
||
|
|| !sighdrPut(sigh, sigTag, RPM_BIN_TYPE, pkt, pktlen))
|
||
|
break;
|
||
|
/* XXX Piggyback a header-only DSA/RSA signature as well. */
|
||
|
+ hdrtag = (sigTag == RPMSIGTAG_GPG) ? RPMSIGTAG_DSA : RPMSIGTAG_RSA;
|
||
|
ret = makeHDRSignature(sigh, file, hdrtag, passPhrase);
|
||
|
} break;
|
||
|
case RPMSIGTAG_RSA:
|