From 031b8481a0dfe875e9cf0f5d440b9379a62651a6 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 2 Mar 2020 14:47:26 +0200 Subject: [PATCH 12/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 1981981f4..4903a4de1 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: @@ -528,6 +531,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); @@ -540,6 +549,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; @@ -549,7 +559,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 880e5edd0..12e2221b3 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -391,7 +391,7 @@ AT_CLEANUP # ------------------------------ # Test --addsign -AT_SETUP([rpmsign --addsign ]) +AT_SETUP([rpmsign --addsign --rpmv3 ]) AT_KEYWORDS([rpmsign signature]) AT_CHECK([ RPMDB_CLEAR @@ -399,7 +399,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 @@ -424,6 +424,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.27.0