From 4276d324bebf442299a90b5a9c4679829ab96385 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 2 Mar 2020 14:47:26 +0200 Subject: [PATCH 13/33] Stop adding rpm v3 header+payload signatures by default where not needed On packages where a separate payload digest exists (ie those built with rpm >= 4.14), rpm v3 header+payload signatures are nothing but expensive legacy baggage, as the payload digest will be signed by a header-only signature already, without having to recalculate the entire file. Automatically detect the payload digest presence and only add V3 signatures on packages that need it, but also add an override switch to force their addition if needed for compatibility or so. A particular use-case would be ability to signature-level verify the entire package on rpm older than 4.14. Fixes: #863 --- doc/rpmsign.8 | 9 +++++++++ rpmsign.c | 3 +++ sign/rpmgensig.c | 24 +++++++++++++++++------- sign/rpmsign.h | 1 + tests/rpmsigdig.at | 36 ++++++++++++++++++++++++++++++++++-- 5 files changed, 64 insertions(+), 9 deletions(-) diff --git a/doc/rpmsign.8 b/doc/rpmsign.8 index d895a3b8c..f7ceae89b 100644 --- a/doc/rpmsign.8 +++ b/doc/rpmsign.8 @@ -11,6 +11,7 @@ rpmsign \- RPM Package Signing .SS "rpmsign-options" .PP +[\fb--rpmv3\fR] [\fb--fskpath \fIKEY\fb\fR] [\fB--signfiles\fR] .SH DESCRIPTION @@ -32,6 +33,14 @@ Delete all signatures from each package \fIPACKAGE_FILE\fR given. .SS "SIGN OPTIONS" .PP .TP +\fB--rpmv3\fR +Force RPM V3 header+payload signature addition. +These are expensive and redundant baggage on packages where a separate +payload digest exists (packages built with rpm >= 4.14). Rpm will +automatically detect the need for V3 signatures, but this option can be +used to force their creation if the packages must be fully +signature verifiable with rpm < 4.14 or other interoperability reasons. +.TP \fB--fskpath \fIKEY\fB\fR Used with \fB--signfiles\fR, use file signing key \fIKey\fR. .TP diff --git a/rpmsign.c b/rpmsign.c index 57cb36919..a74948ba8 100644 --- a/rpmsign.c +++ b/rpmsign.c @@ -32,6 +32,9 @@ static struct poptOption signOptsTable[] = { N_("sign package(s) (identical to --addsign)"), NULL }, { "delsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_DELSIGN, N_("delete package signatures"), NULL }, + { "rpmv3", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), + &sargs.signflags, RPMSIGN_FLAG_RPMV3, + N_("create rpm v3 header+payload signatures") }, #ifdef WITH_IMAEVM { "signfiles", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &sargs.signflags, RPMSIGN_FLAG_IMA, diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index 6ab8c23fa..0c6646d85 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -377,14 +377,17 @@ static int replaceSignature(Header sigh, sigTarget sigt_v3, sigTarget sigt_v4) if (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0) goto exit; - rpmtdFree(sigtd); - /* Assume the same signature test holds for v3 signature too */ - if ((sigtd = makeGPGSignature(sigh, 0, sigt_v3)) == NULL) - goto exit; + if (sigt_v3) { + rpmtdFree(sigtd); - if (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0) - goto exit; + /* Assume the same signature test holds for v3 signature too */ + if ((sigtd = makeGPGSignature(sigh, 0, sigt_v3)) == NULL) + goto exit; + + if (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0) + goto exit; + } rc = 0; exit: @@ -521,6 +524,12 @@ static int rpmSign(const char *rpm, int deleting, int flags) goto exit; } + /* Always add V3 signatures if no payload digest present */ + if (!(headerIsEntry(h, RPMTAG_PAYLOADDIGEST) || + headerIsEntry(h, RPMTAG_PAYLOADDIGESTALT))) { + flags |= RPMSIGN_FLAG_RPMV3; + } + unloadImmutableRegion(&sigh, RPMTAG_HEADERSIGNATURES); origSigSize = headerSizeof(sigh, HEADER_MAGIC_YES); @@ -533,6 +542,7 @@ static int rpmSign(const char *rpm, int deleting, int flags) deleteSigs(sigh); } else { /* Signature target containing header + payload */ + int v3 = (flags & RPMSIGN_FLAG_RPMV3); sigt_v3.fd = fd; sigt_v3.start = headerStart; sigt_v3.fileName = rpm; @@ -542,7 +552,7 @@ static int rpmSign(const char *rpm, int deleting, int flags) sigt_v4 = sigt_v3; sigt_v4.size = headerSizeof(h, HEADER_MAGIC_YES); - res = replaceSignature(sigh, &sigt_v3, &sigt_v4); + res = replaceSignature(sigh, v3 ? &sigt_v3 : NULL, &sigt_v4); if (res != 0) { if (res == 1) { rpmlog(RPMLOG_WARNING, diff --git a/sign/rpmsign.h b/sign/rpmsign.h index 545e80d2d..7a770d879 100644 --- a/sign/rpmsign.h +++ b/sign/rpmsign.h @@ -16,6 +16,7 @@ extern "C" { enum rpmSignFlags_e { RPMSIGN_FLAG_NONE = 0, RPMSIGN_FLAG_IMA = (1 << 0), + RPMSIGN_FLAG_RPMV3 = (1 << 1), }; typedef rpmFlags rpmSignFlags; diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index f6ad72589..c6f95e997 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -423,7 +423,7 @@ AT_CLEANUP # ------------------------------ # Test --addsign -AT_SETUP([rpmsign --addsign ]) +AT_SETUP([rpmsign --addsign --rpmv3 ]) AT_KEYWORDS([rpmsign signature]) AT_CHECK([ RPMDB_CLEAR @@ -431,7 +431,7 @@ RPMDB_INIT rm -rf "${TOPDIR}" cp "${RPMTEST}"/data/RPMS/hello-2.0-1.x86_64.rpm "${RPMTEST}"/tmp/ -run rpmsign --key-id 1964C5FC --addsign "${RPMTEST}"/tmp/hello-2.0-1.x86_64.rpm > /dev/null +run rpmsign --key-id 1964C5FC --rpmv3 --addsign "${RPMTEST}"/tmp/hello-2.0-1.x86_64.rpm > /dev/null echo PRE-IMPORT runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm|grep -v digest echo POST-IMPORT @@ -456,6 +456,38 @@ POST-DELSIGN []) AT_CLEANUP +# Test --addsign +AT_SETUP([rpmsign --addsign ]) +AT_KEYWORDS([rpmsign signature]) +AT_CHECK([ +RPMDB_CLEAR +RPMDB_INIT +rm -rf "${TOPDIR}" + +cp "${RPMTEST}"/data/RPMS/hello-2.0-1.x86_64.rpm "${RPMTEST}"/tmp/ +run rpmsign --key-id 1964C5FC --addsign "${RPMTEST}"/tmp/hello-2.0-1.x86_64.rpm > /dev/null +echo PRE-IMPORT +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm|grep -v digest +echo POST-IMPORT +runroot rpmkeys --import /data/keys/rpm.org-rsa-2048-test.pub +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm|grep -v digest +run rpmsign --delsign "${RPMTEST}"/tmp/hello-2.0-1.x86_64.rpm > /dev/null +echo POST-DELSIGN +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm|grep -v digest +], +[0], +[PRE-IMPORT +/tmp/hello-2.0-1.x86_64.rpm: + Header V4 RSA/SHA256 Signature, key ID 1964c5fc: NOKEY +POST-IMPORT +/tmp/hello-2.0-1.x86_64.rpm: + Header V4 RSA/SHA256 Signature, key ID 1964c5fc: OK +POST-DELSIGN +/tmp/hello-2.0-1.x86_64.rpm: +], +[]) +AT_CLEANUP + # ------------------------------ # Test --delsign AT_SETUP([rpmsign --delsign ]) -- 2.13.5