raven-rhel6/rpm/rpm-4.8.0-sigcompare.patch
2024-02-21 20:14:44 +06:00

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: