From 383eb0fc371d65c9c3c507627a3feea50cd8955c Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Wed, 9 Apr 2025 10:35:59 +0200 Subject: [PATCH 01/22] Add macros.rpmsign-sequoia to doc dir Keep /usr/bin/sq hard coded. Automating the location would require adding sequoia-sq as a build dependency which we don't want for now. --- docs/CMakeLists.txt | 1 + docs/macros.rpmsign-sequoia | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 docs/macros.rpmsign-sequoia diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index b4b575e1b7..9758a3795d 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -54,5 +54,6 @@ install(FILES manual/tags.md manual/triggers.md manual/tsort.md + macros.rpmsign-sequoia TYPE DOC ) diff --git a/docs/macros.rpmsign-sequoia b/docs/macros.rpmsign-sequoia new file mode 100644 index 0000000000..b7f8966c76 --- /dev/null +++ b/docs/macros.rpmsign-sequoia @@ -0,0 +1,26 @@ +#============================================================================== +# ---- Sequoia signature macros. +# The signature to use and the location of configuration files for +# signing packages with Sequoia. +# +# To enable signing with sequoia-sq, just copy this file to /etc/rpm: +# cp /usr/share/doc/rpm/macros.rpmsign-sequoia /etc/rpm/ +# +# Unlike GnuPG, Sequoia doesn't support specifying the signer key by +# email or name match, you need to supply the hex fingerprint (or keyid) +#%_gpg_name +#%_gpg_path + +%__gpg /usr/bin/sq + +# Macro(s) to hold the arguments passed to Sequoia for package +# signing. Expansion result is parsed by popt, so be sure to use +# %{shescape} where needed. +# + +%__gpg_sign_cmd %{__gpg} %{__gpg} sign \ + %{?_gpg_sign_cmd_extra_args} \ + %{?_gpg_name:--signer %{_gpg_name}} \ + --binary --signature-file %{shescape:%{?__signature_filename}} \ + %{?__plaintext_filename:-- %{shescape:%{__plaintext_filename}}} + From ffc047392811837e46215047e1665f69cb32080a Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Wed, 9 Apr 2025 12:27:09 +0200 Subject: [PATCH 02/22] Add sequoia-sq to test suite Will be needed for the upcoming tests for multiple singature support. Move removal of ima plugin otherwise the installation of sequia-sq fails. --- tests/Dockerfile.fedora | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/Dockerfile.fedora b/tests/Dockerfile.fedora index 1555385f12..7b7a954db4 100644 --- a/tests/Dockerfile.fedora +++ b/tests/Dockerfile.fedora @@ -53,8 +53,21 @@ RUN dnf -y install \ pandoc \ libasan \ libubsan + +RUN if which dnf5; then \ + # Fedora 41+ \ + rpm -e --nodeps --nodb \ + rpm-plugin-ima; \ + else \ + # Fedora 40 \ + rpm -e --nodeps --nodb \ + rpm-sign-libs \ + python3-rpm; \ + fi; + # If updates to specific packages are needed, do it here # RUN dnf --enablerepo=updates update ... +RUN dnf -y --enablerepo=updates install "sequoia-sq >= 1.0" RUN dnf clean all RUN echo "%_dbpath $(rpm --eval '%_dbpath')" > /root/.rpmmacros @@ -65,17 +78,7 @@ RUN ln -sf $(rpm --eval '%{_target_platform}%{?_gnu}')-pkg-config \ /usr/bin/pkg-config # Self-destruct stock rpm -RUN if which dnf5; then \ - # Fedora 41+ \ - rpm -e --nodeps --nodb \ - rpm-plugin-ima; \ - else \ - # Fedora 40 \ - rpm -e --nodeps --nodb \ - rpm-sign-libs \ - python3-rpm; \ - fi; \ - rpm -e --nodeps --nodb \ +RUN rpm -e --nodeps --nodb \ rpm \ rpm-libs \ rpm-build-libs From c02b343f9766ba247140e62d4680355aba0edbdd Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 6 Nov 2024 09:44:34 +0200 Subject: [PATCH 03/22] Drop unused header arguments, update comments in signing internals The function comments are several generations old plain wrong. No functional changes. (cherry picked from commit 51446f475393526c5731899a7e162ad2a713ee9e) --- sign/rpmgensig.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index 835406696e..1d7b5075d9 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -129,13 +129,8 @@ static int copyFile(FD_t *sfdp, const char *sfnp, return rc; } -/* - * Validate generated signature and insert to header if it looks sane. - * RPM doesn't support everything GPG does. Basic tests to see if the - * generated signature is something we can use. - * Return generated signature tag data on success, NULL on failure. - */ -static rpmtd makeSigTag(Header sigh, int ishdr, uint8_t *pkt, size_t pktlen) +/* Wrap a raw signature in an rpmtd and sanity check, return NULL on fail */ +static rpmtd makeSigTag(int ishdr, uint8_t *pkt, size_t pktlen) { pgpDigParams sigp = NULL; rpmTagVal sigtag; @@ -319,15 +314,8 @@ static int runGPG(sigTarget sigt, const char *sigfile) return rc; } -/** - * Generate GPG signature(s) for a header+payload file. - * @param sigh signature header - * @param ishdr header-only signature? - * @param sigt signature target - * @param passPhrase private key pass phrase - * @return generated sigtag on success, 0 on failure - */ -static rpmtd makeGPGSignature(Header sigh, int ishdr, sigTarget sigt) +/* Generate an OpenPGP signature(s) for a target */ +static rpmtd makeGPGSignature(int ishdr, sigTarget sigt) { char * sigfile = rstrscat(NULL, sigt->fileName, ".sig", NULL); struct stat st; @@ -365,7 +353,7 @@ static rpmtd makeGPGSignature(Header sigh, int ishdr, sigTarget sigt) rpmlog(RPMLOG_DEBUG, "Got %zd bytes of OpenPGP sig\n", pktlen); /* Parse the signature, change signature tag as appropriate. */ - sigtd = makeSigTag(sigh, ishdr, pkt, pktlen); + sigtd = makeSigTag(ishdr, pkt, pktlen); exit: (void) unlink(sigfile); free(sigfile); @@ -420,7 +408,7 @@ static int replaceSignature(Header sigh, sigTarget sigt_v3, sigTarget sigt_v4) rpmtd sigtd = NULL; /* Make the cheaper v4 signature first */ - if ((sigtd = makeGPGSignature(sigh, 1, sigt_v4)) == NULL) + if ((sigtd = makeGPGSignature(1, sigt_v4)) == NULL) goto exit; /* See if we already have a signature by the same key and parameters */ @@ -438,7 +426,7 @@ static int replaceSignature(Header sigh, sigTarget sigt_v3, sigTarget sigt_v4) rpmtdFree(sigtd); /* Assume the same signature test holds for v3 signature too */ - if ((sigtd = makeGPGSignature(sigh, 0, sigt_v3)) == NULL) + if ((sigtd = makeGPGSignature(0, sigt_v3)) == NULL) goto exit; if (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0) From d070a2d9c8d391d7bd9b78d3e4051ac6b2f694cb Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 6 Nov 2024 10:18:34 +0200 Subject: [PATCH 04/22] Refactor signature insertion to a helper function No functional changes, just a tiny refactoring bit for the next steps. (cherry picked from commit b760b9ca1285cddaa29059eee2099e8b3af1f5f0) --- sign/rpmgensig.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index 1d7b5075d9..2c7a554743 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -402,6 +402,11 @@ static int haveSignature(rpmtd sigtd, Header h) return rc; } +static int putSignature(Header sigh, rpmtd sigtd) +{ + return (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0); +} + static int replaceSignature(Header sigh, sigTarget sigt_v3, sigTarget sigt_v4) { int rc = -1; @@ -419,7 +424,7 @@ static int replaceSignature(Header sigh, sigTarget sigt_v3, sigTarget sigt_v4) /* Nuke all signature tags */ deleteSigs(sigh); - if (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0) + if (putSignature(sigh, sigtd)) goto exit; if (sigt_v3) { @@ -429,7 +434,7 @@ static int replaceSignature(Header sigh, sigTarget sigt_v3, sigTarget sigt_v4) if ((sigtd = makeGPGSignature(0, sigt_v3)) == NULL) goto exit; - if (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0) + if (putSignature(sigh, sigtd)) goto exit; } From c4a8abfb69692af77e09a93705748367b2f562e1 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 6 Nov 2024 10:30:15 +0200 Subject: [PATCH 05/22] Simplify the v3 signature logic a bit Pass the flags down to the function that needs to do stuff. No functional changes. (cherry picked from commit 41552eee5ba97e3aad9441306fa0cbdd2a28574a) --- sign/rpmgensig.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index 2c7a554743..bad8896c3d 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -407,7 +407,8 @@ static int putSignature(Header sigh, rpmtd sigtd) return (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0); } -static int replaceSignature(Header sigh, sigTarget sigt_v3, sigTarget sigt_v4) +static int replaceSignature(Header sigh, rpmSignFlags flags, + sigTarget sigt_v3, sigTarget sigt_v4) { int rc = -1; rpmtd sigtd = NULL; @@ -427,7 +428,7 @@ static int replaceSignature(Header sigh, sigTarget sigt_v3, sigTarget sigt_v4) if (putSignature(sigh, sigtd)) goto exit; - if (sigt_v3) { + if (flags & RPMSIGN_FLAG_RPMV3) { rpmtdFree(sigtd); /* Assume the same signature test holds for v3 signature too */ @@ -653,7 +654,6 @@ 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; @@ -663,7 +663,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, v3 ? &sigt_v3 : NULL, &sigt_v4); + res = replaceSignature(sigh, flags, &sigt_v3, &sigt_v4); if (res != 0) { if (res == 1) { rpmlog(RPMLOG_WARNING, From cb1d8f7ee9ddb780716d2948cc8a99d62659e07a Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Tue, 20 Feb 2024 11:54:17 +0200 Subject: [PATCH 06/22] Add a new unique v6-only reserved signature tag below header base Unfortunately RPMSIGTAG_RESERVEDSPACE clashes with RPMTAG_INSTALLTIME so we can't use it in v6. Introduce a new tag at the top of the signature range to make sure its always the last one - on v6 packages that is. For v4 packages we're better off not messing with the existing tag at this point, we just need to handle both. (backported from commit a40b6e9a74b517370fda9aa5c9fc3db2276be563) --- include/rpm/rpmtag.h | 3 +++ sign/rpmgensig.c | 8 ++++++-- tools/rpmdump.c | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/rpm/rpmtag.h b/include/rpm/rpmtag.h index 422d5efb14..41775719ff 100644 --- a/include/rpm/rpmtag.h +++ b/include/rpm/rpmtag.h @@ -23,6 +23,7 @@ extern "C" { #define HEADER_REGIONS 64 #define HEADER_I18NTABLE 100 #define HEADER_SIGBASE 256 +#define HEADER_SIGTOP 999 #define HEADER_TAGBASE 1000 /** \ingroup rpmtag @@ -67,6 +68,7 @@ typedef enum rpmTag_e { /* RPMTAG_SIG_BASE+19 reserved for RPMSIGTAG_FILESIGNATURELENGTH */ RPMTAG_VERITYSIGNATURES = RPMTAG_SIG_BASE+20, /* s[] */ RPMTAG_VERITYSIGNATUREALGO = RPMTAG_SIG_BASE+21, /* i */ + RPMTAG_SIG_TOP = HEADER_SIGTOP, RPMTAG_NAME = 1000, /* s */ #define RPMTAG_N RPMTAG_NAME /* s */ @@ -447,6 +449,7 @@ typedef enum rpmSigTag_e { RPMSIGTAG_FILESIGNATURELENGTH = RPMTAG_SIG_BASE + 19, RPMSIGTAG_VERITYSIGNATURES = RPMTAG_VERITYSIGNATURES, RPMSIGTAG_VERITYSIGNATUREALGO = RPMTAG_VERITYSIGNATUREALGO, + RPMSIGTAG_RESERVED = RPMTAG_SIG_TOP, } rpmSigTag; diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index bad8896c3d..40ddee59e8 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -587,6 +587,7 @@ static int rpmSign(const char *rpm, int deleting, int flags) struct sigTarget_s sigt_v4; unsigned int origSigSize; int insSig = 0; + rpmTagVal reserveTag = RPMSIGTAG_RESERVEDSPACE; fprintf(stdout, "%s:\n", rpm); @@ -677,11 +678,14 @@ static int rpmSign(const char *rpm, int deleting, int flags) res = -1; } + /* Only v6 packages have this */ + if (headerIsEntry(h, RPMSIGTAG_RESERVED)) + reserveTag = RPMSIGTAG_RESERVED; + /* Adjust reserved size for added/removed signatures */ - if (headerGet(sigh, RPMSIGTAG_RESERVEDSPACE, &utd, HEADERGET_MINMEM)) { + if (headerGet(sigh, reserveTag, &utd, HEADERGET_MINMEM)) { unsigned newSize = headerSizeof(sigh, HEADER_MAGIC_YES); int diff = newSize - origSigSize; - /* diff can be zero if nothing was added or removed */ if (diff) { utd.count -= diff; diff --git a/tools/rpmdump.c b/tools/rpmdump.c index de713d8925..329ce5978a 100644 --- a/tools/rpmdump.c +++ b/tools/rpmdump.c @@ -48,6 +48,7 @@ static const char *sigTagName(uint32_t tag) case RPMSIGTAG_FILESIGNATURELENGTH: return "filesignaturelength"; case RPMSIGTAG_VERITYSIGNATURES: return "veritysignatures"; case RPMSIGTAG_VERITYSIGNATUREALGO: return "veritysignaturealgo"; + case RPMSIGTAG_RESERVED: return "Reserved"; default: break; } From 1ee45b836f47b8e7d6c49892ae5a0458fc757721 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 20 Nov 2024 15:49:35 +0200 Subject: [PATCH 07/22] Add tag extension for rpm format version detection v6 packages have RPMTAG_RPMFORMAT, but we need to differentiate between 3 and 4 too in various places. As such this is a rather simple-minded heuristic but it at least gives us a central place where to manage that detection. Contains part of af81cb8cc1896000928fc87280624166c347edd2 (backported from commit ea46f4fd83a7ed39594982edbe9e3cbabe3a7abe) --- docs/manual/tags.md | 1 + include/rpm/rpmtag.h | 1 + lib/tagexts.c | 17 +++++++++++++++++ tests/rpmgeneral.at | 1 + tests/rpmpkgfmt.at | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/docs/manual/tags.md b/docs/manual/tags.md index fed778ccfb..fe07673f46 100644 --- a/docs/manual/tags.md +++ b/docs/manual/tags.md @@ -451,6 +451,7 @@ Obsoletenevrs | 5043 | string array | Formatted `name [op version]` obso Enhancenevrs | 5061 | string array | Formatted `name [op version]` enhance dependency strings. Recommendnevrs | 5058 | string array | Formatted `name [op version]` recommend dependency strings. Requirenevrs | 5041 | string array | Formatted `name [op version]` require dependency strings. +Rpmformat | 5114 | int32 | Detected rpm format version (3/4/6) Suggestnevrs | 5059 | string array | Formatted `name [op version]` suggest dependency strings. Supplementnevrs | 5060 | string array | Formatted `name [op version]` supplement dependency strings. Sysusers | 5109 | string array | Formatted systemd-sysusers lines for the package. | diff --git a/include/rpm/rpmtag.h b/include/rpm/rpmtag.h index 41775719ff..6a8506019d 100644 --- a/include/rpm/rpmtag.h +++ b/include/rpm/rpmtag.h @@ -390,6 +390,7 @@ typedef enum rpmTag_e { RPMTAG_SYSUSERS = 5109, /* s[] extension */ RPMTAG_BUILDSYSTEM = 5110, /* internal */ RPMTAG_BUILDOPTION = 5111, /* internal */ + RPMTAG_RPMFORMAT = 5114, /* i */ RPMTAG_FIRSTFREE_TAG /*!< internal */ } rpmTag; diff --git a/lib/tagexts.c b/lib/tagexts.c index 2af0dfe725..080f1199a2 100644 --- a/lib/tagexts.c +++ b/lib/tagexts.c @@ -1003,6 +1003,22 @@ static int sysusersTag(Header h, rpmtd td, headerGetFlags hgflags) return (td->count > 0); } +static int rpmformatTag(Header h, rpmtd td, headerGetFlags hgflags) +{ + if (headerGet(h, RPMTAG_RPMFORMAT, td, HEADERGET_ALLOC)) + return 1; + + uint32_t *nump = (uint32_t *)xcalloc(1, sizeof(*nump)); + *nump = headerIsEntry(h, RPMTAG_HEADERIMMUTABLE) ? 4 : 3; + + td->data = nump; + td->count = 1; + td->type = RPM_INT32_TYPE; + td->flags = RPMTD_ALLOCED; + + return 1; +} + static const struct headerTagFunc_s rpmHeaderTagExtensions[] = { { RPMTAG_GROUP, groupTag }, { RPMTAG_DESCRIPTION, descriptionTag }, @@ -1043,6 +1059,7 @@ static const struct headerTagFunc_s rpmHeaderTagExtensions[] = { { RPMTAG_CONFLICTNEVRS, conflictnevrsTag }, { RPMTAG_FILENLINKS, filenlinksTag }, { RPMTAG_SYSUSERS, sysusersTag }, + { RPMTAG_RPMFORMAT, rpmformatTag }, { 0, NULL } }; diff --git a/tests/rpmgeneral.at b/tests/rpmgeneral.at index 68ddf676cb..918c415cd6 100644 --- a/tests/rpmgeneral.at +++ b/tests/rpmgeneral.at @@ -261,6 +261,7 @@ REQUIRENAME REQUIRENEVRS REQUIRES REQUIREVERSION +RPMFORMAT RPMVERSION RSAHEADER SHA1HEADER diff --git a/tests/rpmpkgfmt.at b/tests/rpmpkgfmt.at index f42182b92d..c311188486 100644 --- a/tests/rpmpkgfmt.at +++ b/tests/rpmpkgfmt.at @@ -13,4 +13,37 @@ runroot_other ${RPM_CONFIGDIR_PATH}/rpmdump ${pkg} [0], [expout], []) + +RPMTEST_CHECK([ +rpm -qp --qf "%{rpmformat}\n" ${RPMTEST}/build/RPMS/4/noarch/attrtest-1.0-1.noarch.rpm +], +[0], +[4 +], +[]) +RPMTEST_CLEANUP + +AT_SETUP([rpm v6 format]) +AT_KEYWORDS([rpmformat v6]) +RPMDB_INIT + +RPMTEST_CHECK([ +rpm -qp --qf "%{rpmformat}\n" ${RPMTEST}/data/RPMS/attrtest-1.0-1.noarch.rpm-v6 +], +[0], +[6 +], +[]) +RPMTEST_CLEANUP + +AT_SETUP([rpm v3 format]) +AT_KEYWORDS([rpmformat install query v3]) +RPMDB_INIT +RPMTEST_CHECK([ +rpm -qp --qf "%{rpmformat}\n" /data/RPMS/hello-1.0-1.x86_64.rpm-v3 +], +[0], +[3 +], +[ignore]) RPMTEST_CLEANUP From dc420cf60fb7a25d25d0af5b3e989bf4de447107 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 30 Oct 2024 16:46:26 +0200 Subject: [PATCH 08/22] Add support for multiple OpenPGP signatures per package, part 1/2 Add support for multiple OpenPGP header signatures per package, base64 encoded in a string array, also known as rpm v6 signatures. --addsign no longer deletes any signatures, it only creates and adds a new signature if possible. --delete and --resign behave as before: they delete ALL signatures on the package, and the latter then creates and adds a new one. For v6 packages this is the default signature type, but if requested, one v4 compat signature can be created for compatible algorithms. v6 signatures on v4 packages are also supported, but have to be explicitly requested. In that case, v3/v4 signatures are only added if none already exist and a v4 compatible algorithm is used. v3 signatures on v6 packages are not supported (out of principle, not a technical limitation) On verification, if RPMTAG_OPENPGP exists then other signature tags are ignored because they're expected to only contain compat copies of the same content. As of now, all existing signatures must validate for signature checking of a package to pass, further policies are to be added later. Fixes: #3385 (backported from commit 5630cf4bcbaae85d1b53e7a57ba6c7ed86b62e7d) --- docs/man/rpmsign.8.md | 50 +++++-- docs/manual/tags.md | 2 + include/rpm/rpmsign.h | 3 + include/rpm/rpmtag.h | 2 + include/rpm/rpmts.h | 3 + lib/package.c | 1 + lib/rpmvs.c | 46 +++++-- sign/rpmgensig.c | 130 ++++++++++++++----- tests/rpmgeneral.at | 1 + tests/rpmsigdig.at | 295 +++++++++++++++++++++++++++++++++++++++--- tests/rpmvfylevel.at | 5 +- tools/rpmsign.c | 12 +- 12 files changed, 479 insertions(+), 71 deletions(-) diff --git a/docs/man/rpmsign.8.md b/docs/man/rpmsign.8.md index 254d042eff..904ac0467d 100644 --- a/docs/man/rpmsign.8.md +++ b/docs/man/rpmsign.8.md @@ -25,22 +25,25 @@ SIGNING PACKAGES: rpmsign-options --------------- -\[**\--rpmv3**\] \[**\--fskpath** *KEY*\] \[**\--signfiles**\] +\[**\--rpmv3**\] \[**\--rpmv4**\] \[**\--rpmv6**\] \[**\--fskpath ***KEY*\] \[**\--signfiles**\] DESCRIPTION =========== -Both of the **\--addsign** and **\--resign** options generate and insert -new signatures for each package *PACKAGE\_FILE* given, replacing any -existing signatures. There are two options for historical reasons, there -is no difference in behavior currently. +**rpmsign** **\--addsign** generates and inserts a new OpenPGP signature +for each *PACKAGE\_FILE* given unless a signature with identical +parameters already exists, in which case no action is taken. +Arbitrary number of V6 signatures can be added. + +**rpmsign** **\--resign** generates and inserts a new OpenPGP signature +for each *PACKAGE\_FILE*, replacing any and all previous signatures. To create a signature rpmsign needs to verify the package\'s checksum. As a -result packages with a MD5/SHA1 checksums cannot be signed in FIPS mode. +result V4 packages with MD5/SHA1 checksums cannot be signed in FIPS mode. **rpmsign** **\--delsign** *PACKAGE\_FILE \...* -Delete all signatures from each package *PACKAGE\_FILE* given. +Delete all OpenPGP signatures from each package *PACKAGE\_FILE* given. **rpmsign** **\--delfilesign** *PACKAGE\_FILE \...* @@ -52,14 +55,41 @@ SIGN OPTIONS **\--rpmv3** -: Force RPM V3 header+payload signature addition. These are expensive +: Request RPM V3 header+payload signature addition on V4 packages. + These signatures are expensive and redundant baggage on packages where a separate payload digest exists (packages built with rpm \>= 4.14). Rpmsign 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 + request their creation if the packages must be fully signature verifiable with rpm \< 4.14 or other interoperability reasons. -**\--fskpath** *KEY* + Has no effect when signing V6 packages. + +**\--rpmv4** + +: Request RPM V4 header signature addition on V6 packages. + Useful for making V6 packages signature verifiable + with rpm 4.x versions. + + V4 compatibility signatures are only ever added if the signing algorithm + is one of those known to V4: RSA, EcDSA, EdDSA (and original DSA). + Only one V4 signature can be present in a package, so this is + added only on the first **\--addsign** with a V4 compatible + algorithm, and ignored otherwise. + + Has no effect when signing V4 packages. + +**\--rpmv6** + +: Request RPM V6 header signature addition on V4 packages. + + This generally always succeeds as there can be arbitrary number of + V6 signatures on a package. A V3/V4 compatibility signatures are + added usign the same logic as **\--rpmv4** on a V6 package. + + Has no effect when signing V6 packages. + +**\--fskpath ***KEY* : Used with **\--signfiles**, use file signing key *KEY*. diff --git a/docs/manual/tags.md b/docs/manual/tags.md index fe07673f46..6f1ffa8298 100644 --- a/docs/manual/tags.md +++ b/docs/manual/tags.md @@ -304,6 +304,7 @@ Tag Name | Value| Type | Description ------------------|------|--------------|------------ Dsaheader | 267 | bin | OpenPGP DSA signature of the header (if thus signed) Longsigsize | 270 | int64 | Header+payload size if > 4GB. +Openpgp | 278 | string array | OpenPGP signature(s) of the header, base64 encoded Payloaddigest | 5092 | string array | Cryptographic digest of the compressed payload. Payloaddigestalgo | 5093 | int32 | ID of the payload digest algorithm. Payloaddigestalt | 5097 | string array | Cryptographic digest of the uncompressed payload. @@ -444,6 +445,7 @@ Longsigsize | Header+payload size in 64bit format Tag Name | Value| Type | Description ----------------------|------|--------------|------------ +Openpgp | 278 | string array | All OpenPGP signature(s) in the header, including legacy ones (base64 encoded) Origfilenames | 5007 | string array | Original Filenames in relocated packages. Providenevrs | 5042 | string array | Formatted `name [op version]` provide dependency strings. Conflictnevrs | 5044 | string array | Formatted `name [op version]` conflict dependency strings. diff --git a/include/rpm/rpmsign.h b/include/rpm/rpmsign.h index c876ef1bda..c0dbdab533 100644 --- a/include/rpm/rpmsign.h +++ b/include/rpm/rpmsign.h @@ -18,6 +18,9 @@ enum rpmSignFlags_e { RPMSIGN_FLAG_IMA = (1 << 0), RPMSIGN_FLAG_RPMV3 = (1 << 1), RPMSIGN_FLAG_FSVERITY = (1 << 2), + RPMSIGN_FLAG_RESIGN = (1 << 3), + RPMSIGN_FLAG_RPMV4 = (1 << 4), + RPMSIGN_FLAG_RPMV6 = (1 << 5), }; typedef rpmFlags rpmSignFlags; diff --git a/include/rpm/rpmtag.h b/include/rpm/rpmtag.h index 6a8506019d..0b8e185ae6 100644 --- a/include/rpm/rpmtag.h +++ b/include/rpm/rpmtag.h @@ -68,6 +68,7 @@ typedef enum rpmTag_e { /* RPMTAG_SIG_BASE+19 reserved for RPMSIGTAG_FILESIGNATURELENGTH */ RPMTAG_VERITYSIGNATURES = RPMTAG_SIG_BASE+20, /* s[] */ RPMTAG_VERITYSIGNATUREALGO = RPMTAG_SIG_BASE+21, /* i */ + RPMTAG_OPENPGP = RPMTAG_SIG_BASE+22, /* s[] */ RPMTAG_SIG_TOP = HEADER_SIGTOP, RPMTAG_NAME = 1000, /* s */ @@ -450,6 +451,7 @@ typedef enum rpmSigTag_e { RPMSIGTAG_FILESIGNATURELENGTH = RPMTAG_SIG_BASE + 19, RPMSIGTAG_VERITYSIGNATURES = RPMTAG_VERITYSIGNATURES, RPMSIGTAG_VERITYSIGNATUREALGO = RPMTAG_VERITYSIGNATUREALGO, + RPMSIGTAG_OPENPGP = RPMTAG_OPENPGP, RPMSIGTAG_RESERVED = RPMTAG_SIG_TOP, } rpmSigTag; diff --git a/include/rpm/rpmts.h b/include/rpm/rpmts.h index 7b60338d7e..5c168820f7 100644 --- a/include/rpm/rpmts.h +++ b/include/rpm/rpmts.h @@ -105,6 +105,7 @@ enum rpmVSFlags_e { RPMVSF_NOSHA256HEADER = (1 << 9), RPMVSF_NODSAHEADER = (1 << 10), RPMVSF_NORSAHEADER = (1 << 11), + RPMVSF_NOOPENPGP = (1 << 12), /* bit(s) 12-15 unused */ RPMVSF_NOPAYLOAD = (1 << 16), RPMVSF_NOMD5 = (1 << 17), @@ -125,6 +126,7 @@ typedef rpmFlags rpmVSFlags; #define RPMVSF_MASK_NOSIGNATURES \ ( RPMVSF_NODSAHEADER | \ RPMVSF_NORSAHEADER | \ + RPMVSF_NOOPENPGP | \ RPMVSF_NODSA | \ RPMVSF_NORSA ) #define _RPMVSF_NOSIGNATURES RPMVSF_MASK_NOSIGNATURES @@ -132,6 +134,7 @@ typedef rpmFlags rpmVSFlags; #define RPMVSF_MASK_NOHEADER \ ( RPMVSF_NOSHA1HEADER | \ RPMVSF_NOSHA256HEADER | \ + RPMVSF_NOOPENPGP | \ RPMVSF_NODSAHEADER | \ RPMVSF_NORSAHEADER ) #define _RPMVSF_NOHEADER RPMVSF_MASK_NOHEADER diff --git a/lib/package.c b/lib/package.c index 2b4091a6c8..26bc978346 100644 --- a/lib/package.c +++ b/lib/package.c @@ -53,6 +53,7 @@ static struct taglate_s { { RPMSIGTAG_RSA, RPMTAG_RSAHEADER, 0, 0 }, { RPMSIGTAG_LONGSIZE, RPMTAG_LONGSIGSIZE, 1, 0 }, { RPMSIGTAG_LONGARCHIVESIZE, RPMTAG_LONGARCHIVESIZE, 1, 0 }, + { RPMSIGTAG_OPENPGP, RPMTAG_OPENPGP, 0, 0 }, { 0 } }; diff --git a/lib/rpmvs.c b/lib/rpmvs.c index 4c665b2f1a..d04f41b7e9 100644 --- a/lib/rpmvs.c +++ b/lib/rpmvs.c @@ -1,6 +1,7 @@ #include "system.h" #include +#include #include #include #include @@ -27,6 +28,7 @@ struct vfytag_s { }; static const struct vfytag_s rpmvfytags[] = { + { RPMTAG_OPENPGP, RPM_STRING_ARRAY_TYPE, 0, 0, }, { RPMSIGTAG_SIZE, RPM_BIN_TYPE, 0, 0, }, { RPMSIGTAG_PGP, RPM_BIN_TYPE, 0, 0, }, { RPMSIGTAG_MD5, RPM_BIN_TYPE, 0, 16, }, @@ -51,6 +53,9 @@ struct vfyinfo_s { }; static const struct vfyinfo_s rpmvfyitems[] = { + { RPMTAG_OPENPGP, 1, + { RPMSIG_SIGNATURE_TYPE, RPMVSF_NOOPENPGP, + (RPMSIG_HEADER), 0, 0, }, }, { RPMSIGTAG_SIZE, 1, { RPMSIG_OTHER_TYPE, 0, (RPMSIG_HEADER|RPMSIG_PAYLOAD), 0, 0, }, }, @@ -132,7 +137,7 @@ static int validHex(const char *str, size_t slen) return valid; } -static void rpmsinfoInit(const struct vfyinfo_s *vinfo, +static rpmRC rpmsinfoInit(const struct vfyinfo_s *vinfo, const struct vfytag_s *tinfo, rpmtd td, const char *origin, struct rpmsinfo_s *sinfo) @@ -140,6 +145,8 @@ static void rpmsinfoInit(const struct vfyinfo_s *vinfo, rpmRC rc = RPMRC_FAIL; const void *data = NULL; rpm_count_t dlen = 0; + uint8_t *pkt = NULL; + size_t pktlen = 0; *sinfo = vinfo->vi; /* struct assignment */ sinfo->wrapped = (vinfo->sigh == 0); @@ -193,6 +200,16 @@ static void rpmsinfoInit(const struct vfyinfo_s *vinfo, } if (sinfo->type == RPMSIG_SIGNATURE_TYPE) { + if (td->type == RPM_STRING_ARRAY_TYPE) { + if (rpmBase64Decode((const char *)data, (void **)&pkt, &pktlen)) { + rasprintf(&sinfo->msg, _("%s tag %u: invalid base64"), + origin, td->tag); + goto exit; + } + data = pkt; + dlen = pktlen; + } + char *lints = NULL; int ec = pgpPrtParams2((const uint8_t *)data, dlen, PGPTAG_SIGNATURE, &sinfo->sig, &lints); @@ -235,8 +252,10 @@ static void rpmsinfoInit(const struct vfyinfo_s *vinfo, rc = RPMRC_OK; exit: + if (pkt && pkt != td->data) + free(pkt); sinfo->rc = rc; - return; + return rc; } static void rpmsinfoFini(struct rpmsinfo_s *sinfo) @@ -290,11 +309,16 @@ const char *rpmsinfoDescr(struct rpmsinfo_s *sinfo) rangeName(sinfo->range), t); free(t); } else { - rasprintf(&sinfo->descr, _("%s%s%s %s"), - rangeName(sinfo->range), - pgpValString(PGPVAL_PUBKEYALGO, sinfo->sigalgo), - sinfo->alt ? " ALT" : "", - _("signature")); + if (sinfo->sigalgo) { + rasprintf(&sinfo->descr, _("%s%s %s"), + rangeName(sinfo->range), + pgpValString(PGPVAL_PUBKEYALGO, sinfo->sigalgo), + _("signature")); + } else { + rasprintf(&sinfo->descr, _("%sOpenPGP %s"), + rangeName(sinfo->range), + _("signature")); + } } break; } @@ -330,7 +354,13 @@ static void rpmvsAppend(struct rpmvs_s *sis, hdrblob blob, if (!rpmsinfoDisabled(&vi->vi, sis->vsflags) && rc == RPMRC_OK) { while (rpmtdNext(&td) >= 0) { - rpmsinfoInit(vi, ti, &td, o, &sis->sigs[sis->nsigs]); + if (!rpmsinfoInit(vi, ti, &td, o, &sis->sigs[sis->nsigs])) { + /* Don't bother with v3/v4 sigs when v6 sigs exist */ + if (td.tag == RPMSIGTAG_OPENPGP) { + sis->vsflags |= (RPMVSF_NODSAHEADER|RPMVSF_NORSAHEADER); + sis->vsflags |= (RPMVSF_NODSA|RPMVSF_NORSA); + } + } sis->nsigs++; } } else { diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index 40ddee59e8..91a81ef61e 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -17,6 +17,7 @@ #include "rpmsignfiles.h" #endif +#include #include /* RPMSIGTAG & related */ #include #include @@ -175,11 +176,12 @@ static rpmtd makeSigTag(int ishdr, uint8_t *pkt, size_t pktlen) /* Looks sane, create the tag data */ sigtd = rpmtdNew(); + sigtd->tag = sigtag; + sigtd->flags |= RPMTD_ALLOCED; sigtd->count = pktlen; sigtd->data = memcpy(xmalloc(pktlen), pkt, pktlen);; - sigtd->type = RPM_BIN_TYPE; sigtd->tag = sigtag; - sigtd->flags |= RPMTD_ALLOCED; + sigtd->type = RPM_BIN_TYPE; exit: pgpDigParamsFree(sigp); @@ -369,6 +371,7 @@ static void deleteSigs(Header sigh) headerDel(sigh, RPMSIGTAG_DSA); headerDel(sigh, RPMSIGTAG_RSA); headerDel(sigh, RPMSIGTAG_PGP5); + headerDel(sigh, RPMSIGTAG_OPENPGP); } static void deleteFileSigs(Header sigh) @@ -379,41 +382,83 @@ static void deleteFileSigs(Header sigh) headerDel(sigh, RPMSIGTAG_VERITYSIGNATUREALGO); } -static int haveSignature(rpmtd sigtd, Header h) +static pgpDigParams tdParams(rpmtd td) +{ + pgpDigParams sig = NULL; + if (td->tag == RPMTAG_OPENPGP) { + uint8_t *pkt = NULL; + size_t pktlen = 0; + if (rpmBase64Decode(rpmtdGetString(td), (void **)&pkt, &pktlen) == 0) { + pgpPrtParams(pkt, pktlen, PGPTAG_SIGNATURE, &sig); + free(pkt); + } + } else { + pgpPrtParams((uint8_t *)td->data, td->count, PGPTAG_SIGNATURE, &sig); + } + return sig; +} + +static int haveSignature(rpmtd sigtd, Header sigh) { - pgpDigParams sig1 = NULL; - pgpDigParams sig2 = NULL; struct rpmtd_s oldtd; int rc = 0; /* assume no */ + rpmTagVal tag = headerIsEntry(sigh, RPMSIGTAG_RESERVED) ? + RPMTAG_OPENPGP : sigtd->tag; - if (!headerGet(h, rpmtdTag(sigtd), &oldtd, HEADERGET_DEFAULT)) + if (!headerGet(sigh, tag, &oldtd, HEADERGET_DEFAULT)) return rc; - pgpPrtParams((uint8_t *)sigtd->data, sigtd->count, PGPTAG_SIGNATURE, &sig1); + pgpDigParams newsig = tdParams(sigtd); while (rpmtdNext(&oldtd) >= 0 && rc == 0) { - pgpPrtParams((uint8_t *)oldtd.data, oldtd.count, PGPTAG_SIGNATURE, &sig2); - if (pgpDigParamsCmp(sig1, sig2) == 0) + pgpDigParams oldsig = tdParams(&oldtd); + if (pgpDigParamsCmp(newsig, oldsig) == 0) rc = 1; - sig2 = pgpDigParamsFree(sig2); + pgpDigParamsFree(oldsig); } - pgpDigParamsFree(sig1); + pgpDigParamsFree(newsig); rpmtdFreeData(&oldtd); return rc; } -static int putSignature(Header sigh, rpmtd sigtd) +static int putSignature(Header sigh, rpmtd sigtd, int multisig) +{ + int rc = 1; + if (multisig) { + char *b64 = rpmBase64Encode(sigtd->data, sigtd->count, 0); + char **arr = (char **)xmalloc(1 * sizeof(*arr)); + arr[0] = b64; + + struct rpmtd_s mtd = { + .tag = RPMSIGTAG_OPENPGP, + .type = RPM_STRING_ARRAY_TYPE, + .count = 1, + .data = arr, + .flags = RPMTD_ALLOCED|RPMTD_PTR_ALLOCED, + .ix = -1, + .size = 0, + }; + rc = (headerPut(sigh, &mtd, HEADERPUT_APPEND) == 0); + rpmtdFreeData(&mtd); + } else { + rc = (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0); + } + return rc; +} + +static int haveLegacySig(Header sigh) { - return (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0); + return headerIsEntry(sigh, RPMSIGTAG_RSA) || + headerIsEntry(sigh, RPMSIGTAG_DSA); } -static int replaceSignature(Header sigh, rpmSignFlags flags, +static int addSignature(Header sigh, rpmSignFlags flags, sigTarget sigt_v3, sigTarget sigt_v4) { int rc = -1; rpmtd sigtd = NULL; - /* Make the cheaper v4 signature first */ + /* Make a header signature */ if ((sigtd = makeGPGSignature(1, sigt_v4)) == NULL) goto exit; @@ -422,21 +467,28 @@ static int replaceSignature(Header sigh, rpmSignFlags flags, rc = 1; goto exit; } - /* Nuke all signature tags */ - deleteSigs(sigh); - if (putSignature(sigh, sigtd)) - goto exit; - - if (flags & RPMSIGN_FLAG_RPMV3) { - rpmtdFree(sigtd); - - /* Assume the same signature test holds for v3 signature too */ - if ((sigtd = makeGPGSignature(0, sigt_v3)) == NULL) + /* Add a v6 signature if requested */ + if (flags & RPMSIGN_FLAG_RPMV6) + if (putSignature(sigh, sigtd, 1)) goto exit; - if (putSignature(sigh, sigtd)) + /* Add a v4 signature if requested */ + if (flags & RPMSIGN_FLAG_RPMV4) { + if (putSignature(sigh, sigtd, 0)) goto exit; + + /* Only consider v3 signature if also adding v4 */ + if (flags & RPMSIGN_FLAG_RPMV3) { + rpmtdFree(sigtd); + + /* Assume the same signature test holds for v3 signature too */ + if ((sigtd = makeGPGSignature(0, sigt_v3)) == NULL) + goto exit; + + if (putSignature(sigh, sigtd, 0)) + goto exit; + } } rc = 0; @@ -636,6 +688,23 @@ static int rpmSign(const char *rpm, int deleting, int flags) flags &= ~(RPMSIGN_FLAG_IMA | RPMSIGN_FLAG_FSVERITY); } + /* Only v6 packages have this */ + if (headerIsEntry(sigh, RPMSIGTAG_RESERVED)) { + flags |= RPMSIGN_FLAG_RPMV6; + reserveTag = RPMSIGTAG_RESERVED; + /* v3 signatures are not welcome in v6 packages */ + if (flags & RPMSIGN_FLAG_RPMV3) { + rpmlog(RPMLOG_WARNING, + _("not generating v3 signature for v6 package: %s\n"), rpm); + flags &= ~RPMSIGN_FLAG_RPMV3; + } + } else { + flags |= RPMSIGN_FLAG_RPMV4; + /* Ensure only one legacy signature is added if adding v6 signatures */ + if ((flags & RPMSIGN_FLAG_RPMV6) && haveLegacySig(sigh)) + flags &= ~(RPMSIGN_FLAG_RPMV4|RPMSIGN_FLAG_RPMV3); + } + origSigSize = headerSizeof(sigh, HEADER_MAGIC_YES); unloadImmutableRegion(&sigh, RPMTAG_HEADERSIGNATURES); @@ -664,7 +733,10 @@ 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, flags, &sigt_v3, &sigt_v4); + if (flags & RPMSIGN_FLAG_RESIGN) + deleteSigs(sigh); + + res = addSignature(sigh, flags, &sigt_v3, &sigt_v4); if (res != 0) { if (res == 1) { rpmlog(RPMLOG_WARNING, @@ -678,10 +750,6 @@ static int rpmSign(const char *rpm, int deleting, int flags) res = -1; } - /* Only v6 packages have this */ - if (headerIsEntry(h, RPMSIGTAG_RESERVED)) - reserveTag = RPMSIGTAG_RESERVED; - /* Adjust reserved size for added/removed signatures */ if (headerGet(sigh, reserveTag, &utd, HEADERGET_MINMEM)) { unsigned newSize = headerSizeof(sigh, HEADER_MAGIC_YES); diff --git a/tests/rpmgeneral.at b/tests/rpmgeneral.at index 918c415cd6..1724982d90 100644 --- a/tests/rpmgeneral.at +++ b/tests/rpmgeneral.at @@ -188,6 +188,7 @@ OLDSUGGESTS OLDSUGGESTSFLAGS OLDSUGGESTSNAME OLDSUGGESTSVERSION +OPENPGP OPTFLAGS ORDERFLAGS ORDERNAME diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index cef7d51660..e73c2147f8 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -349,8 +349,9 @@ runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hel [0], [[Checking package before importing key: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: - Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOKEY - Header DSA signature: NOTFOUND + Header OpenPGP V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY + Header OpenPGP signature: NOTFOUND + Header OpenPGP DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -413,8 +414,9 @@ runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hel [0], [Checking package before importing key: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: - Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOKEY - Header DSA signature: NOTFOUND + Header OpenPGP V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY + Header OpenPGP signature: NOTFOUND + Header OpenPGP DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -433,8 +435,9 @@ RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650 RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 invalid: key is not alive])dnl RPMOUTPUT_SEQUOIA([ because: The subkey is not live])dnl RPMOUTPUT_SEQUOIA([ because: Expired on 2022-04-12T00:00:15Z])dnl - Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOTTRUSTED - Header DSA signature: NOTFOUND + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header OpenPGP signature: NOTFOUND + Header OpenPGP DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -449,10 +452,11 @@ RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650 RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 invalid: key is not alive])dnl RPMOUTPUT_SEQUOIA([ because: The subkey is not live])dnl RPMOUTPUT_SEQUOIA([ because: Expired on 2022-04-12T00:00:15Z])dnl - Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOTTRUSTED - Header DSA signature: NOTFOUND - RSA signature: NOTFOUND - DSA signature: NOTFOUND + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header OpenPGP signature: NOTFOUND + Header OpenPGP DSA signature: NOTFOUND + Legacy OpenPGP RSA signature: NOTFOUND + Legacy OpenPGP DSA signature: NOTFOUND 1 Checking package after importing key, no signature: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: @@ -489,8 +493,9 @@ runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hel [0], [Checking package before importing key: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: - Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOKEY - Header DSA signature: NOTFOUND + Header OpenPGP V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY + Header OpenPGP signature: NOTFOUND + Header OpenPGP DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -507,8 +512,9 @@ Checking package after importing key: RPMOUTPUT_LEGACY([error: Subkey 1f71177215217ee0 of key b3a771bfeb04e625 (Alice ) has been revoked])dnl RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650C36B6F41BCB3A771BFEB04E625 (Alice ):])dnl RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 is invalid: key is revoked])dnl - Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOTTRUSTED - Header DSA signature: NOTFOUND + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header OpenPGP signature: NOTFOUND + Header OpenPGP DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -521,10 +527,11 @@ Checking package after importing key, no digest: RPMOUTPUT_LEGACY([error: Subkey 1f71177215217ee0 of key b3a771bfeb04e625 (Alice ) has been revoked])dnl RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650C36B6F41BCB3A771BFEB04E625 (Alice ):])dnl RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 is invalid: key is revoked])dnl - Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOTTRUSTED - Header DSA signature: NOTFOUND - RSA signature: NOTFOUND - DSA signature: NOTFOUND + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header OpenPGP signature: NOTFOUND + Header OpenPGP DSA signature: NOTFOUND + Legacy OpenPGP RSA signature: NOTFOUND + Legacy OpenPGP DSA signature: NOTFOUND 1 Checking package after importing key, no signature: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: @@ -1093,6 +1100,258 @@ echo $? gpgconf --kill gpg-agent RPMTEST_CLEANUP +# Signing test(s) using Sequoia +# stderr is ignored due to noisy failures from gpgconf which we don't +# care about in this test... +AT_SETUP([rpmsign --addsign sequoia]) +AT_KEYWORDS([rpmsign sequoia signature]) +AT_SKIP_IF([test x$PGP = xdummy]) +RPMDB_INIT + +RPMTEST_CHECK([ +cat << EOF >> ${HOME}/.rpmmacros +%_openpgp_sign sq +%_openpgp_sign_id 771B18D3D7BAA28734333C424344591E1964C5FC +EOF + +runroot_other sq key import /data/keys/*.secret +], +[0], +[ignore], +[ignore]) + +RPMTEST_CHECK([ +cp "${RPMTEST}"/data/RPMS/hello-2.0-1.x86_64.rpm "${RPMTEST}"/tmp/ +echo SIGN +runroot rpmsign --addsign -v /tmp/hello-2.0-1.x86_64.rpm +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 +echo DELSIGN +runroot rpmsign --delsign -v /tmp/hello-2.0-1.x86_64.rpm +echo POST-DELSIGN +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm|grep -v digest +], +[0], +[SIGN +/tmp/hello-2.0-1.x86_64.rpm +PRE-IMPORT +/tmp/hello-2.0-1.x86_64.rpm: + Header OpenPGP V4 RSA/SHA512 signature, key ID 4344591e1964c5fc: NOKEY +POST-IMPORT +/tmp/hello-2.0-1.x86_64.rpm: + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK +DELSIGN +/tmp/hello-2.0-1.x86_64.rpm +POST-DELSIGN +/tmp/hello-2.0-1.x86_64.rpm: +], +[ignore]) + +RPMTEST_CHECK([ +runroot rpmsign --addsign --key-id 152bb32fd9ca982797e835cfb0645aec757bf69e /tmp/hello-2.0-1.x86_64.rpm +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +], +[1], +[/tmp/hello-2.0-1.x86_64.rpm: + Header OpenPGP V4 EdDSA/SHA512 signature, key ID b0645aec757bf69e: NOKEY + Header SHA256 digest: OK + Payload SHA256 digest: OK +], +[ignore]) +RPMTEST_CLEANUP + +AT_SETUP([rpmsign --addsign multisig v4]) +AT_KEYWORDS([rpmsign signature multisig v4]) +AT_SKIP_IF([test x$PGP = xdummy]) +RPMDB_INIT + +RPMTEST_CHECK([ +cat << EOF >> ${HOME}/.rpmmacros +%_openpgp_sign sq +%_openpgp_sign_id 771B18D3D7BAA28734333C424344591E1964C5FC +EOF + +runroot_other sq key import /data/keys/*.secret +runroot rpmkeys --import /data/keys/*.pub +], +[0], +[ignore], +[ignore]) + +RPMTEST_CHECK([ +cp "${RPMTEST}"/data/RPMS/hello-2.0-1.x86_64.rpm "${RPMTEST}"/tmp/ +runroot rpmsign --addsign --rpmv6 /tmp/hello-2.0-1.x86_64.rpm &> /dev/null +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +], +[0], +[/tmp/hello-2.0-1.x86_64.rpm: + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header SHA256 digest: OK + Payload SHA256 digest: OK +], +[]) + +RPMTEST_CHECK([ +# resigning with identical key shouldn't add anything +runroot rpmsign --addsign --rpmv6 /tmp/hello-2.0-1.x86_64.rpm &> /dev/null +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +], +[0], +[/tmp/hello-2.0-1.x86_64.rpm: + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header SHA256 digest: OK + Payload SHA256 digest: OK +], +[]) + +RPMTEST_CHECK([ +runroot rpmsign --addsign --rpmv6 --key-id 152BB32FD9CA982797E835CFB0645AEC757BF69E /tmp/hello-2.0-1.x86_64.rpm &> /dev/null +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +], +[0], +[/tmp/hello-2.0-1.x86_64.rpm: + Header OpenPGP V4 EdDSA/SHA512 signature, key fingerprint: 152bb32fd9ca982797e835cfb0645aec757bf69e: OK + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header SHA256 digest: OK + Payload SHA256 digest: OK +], +[]) + +RPMTEST_CHECK([ +runroot rpmsign --addsign --rpmv6 --key-id E8A62C0512B06B5D2183BA207F1C21F95F65BBE8 /tmp/hello-2.0-1.x86_64.rpm &> /dev/null +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +], +[0], +[/tmp/hello-2.0-1.x86_64.rpm: + Header OpenPGP V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK + Header OpenPGP V4 EdDSA/SHA512 signature, key fingerprint: 152bb32fd9ca982797e835cfb0645aec757bf69e: OK + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header SHA256 digest: OK + Payload SHA256 digest: OK +], +[]) + +RPMTEST_CHECK([ +runroot rpmkeys --delete 152bb32fd9ca982797e835cfb0645aec757bf69e +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +], +[1], +[/tmp/hello-2.0-1.x86_64.rpm: + Header OpenPGP V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK + Header OpenPGP V4 EdDSA/SHA512 signature, key ID b0645aec757bf69e: NOKEY + Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header SHA256 digest: OK + Payload SHA256 digest: OK +], +[]) + +RPMTEST_CHECK([ +runroot rpmsign --resign --key-id E8A62C0512B06B5D2183BA207F1C21F95F65BBE8 /tmp/hello-2.0-1.x86_64.rpm &> /dev/null +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +], +[0], +[/tmp/hello-2.0-1.x86_64.rpm: + Header OpenPGP V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK + Header SHA256 digest: OK + Payload SHA256 digest: OK +], +[]) + +RPMTEST_CHECK([ +runroot rpmsign --delsign /tmp/hello-2.0-1.x86_64.rpm &> /dev/null +runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +], +[0], +[/tmp/hello-2.0-1.x86_64.rpm: + Header SHA256 digest: OK + Payload SHA256 digest: OK +], +[]) + +RPMTEST_CLEANUP + +AT_SETUP([rpmsign --addsign multisig v6]) +AT_KEYWORDS([rpmsign signature multisig v6]) +AT_SKIP_IF([test x$PGP = xdummy]) +RPMDB_INIT + +RPMTEST_CHECK([ +cat << EOF >> ${HOME}/.rpmmacros +%_openpgp_sign sq +%_openpgp_sign_id 771B18D3D7BAA28734333C424344591E1964C5FC +EOF + +runroot_other sq key import /data/keys/*.secret +runroot rpmkeys --import /data/keys/*.pub +], +[0], +[ignore], +[ignore]) + +RPMTEST_CHECK([ +runroot rpmbuild -bb --quiet \ + --define "_rpmfilever 6" \ + /data/SPECS/attrtest.spec +runroot rpmsign --addsign /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm +], +[0], +[], +[ignore]) + +RPMTEST_CHECK([ +runroot rpmkeys -K /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm +], +[0], +[/build/RPMS/noarch/attrtest-1.0-1.noarch.rpm: digests signatures OK +], +[]) + +RPMTEST_CHECK([ +for t in DSAHEADER RSAHEADER SIGGPG SIGPGP OPENPGP; do + runroot rpm -qp --qf "$t: %{$t}\n" /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm | grep \(none\) +done +], +[ignore], +[DSAHEADER: (none) +RSAHEADER: (none) +SIGGPG: (none) +SIGPGP: (none) +], +[]) + +RPMTEST_CHECK([ +runroot rpmsign --resign --rpmv4 \ + --key-id E8A62C0512B06B5D2183BA207F1C21F95F65BBE8 \ + /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm +], +[0], +[], +[ignore]) + +RPMTEST_CHECK([ +runroot rpmkeys -K /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm +], +[0], +[/build/RPMS/noarch/attrtest-1.0-1.noarch.rpm: digests signatures OK +], +[]) + +RPMTEST_CHECK([ +for t in DSAHEADER RSAHEADER SIGGPG SIGPGP OPENPGP; do + runroot rpm -qp --qf "$t: %{$t}\n" /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm | grep \(none\) +done +], +[ignore], +[RSAHEADER: (none) +SIGGPG: (none) +SIGPGP: (none) +], +[]) +RPMTEST_CLEANUP + # ------------------------------ # Test --delsign AT_SETUP([rpmsign --delsign]) diff --git a/tests/rpmvfylevel.at b/tests/rpmvfylevel.at index e188d025e5..3e8919e680 100644 --- a/tests/rpmvfylevel.at +++ b/tests/rpmvfylevel.at @@ -346,8 +346,9 @@ nohdrs 0 nosig /data/RPMS/hello-2.0-1.x86_64-signed.rpm: - Header RSA signature: NOTFOUND - Header DSA signature: NOTFOUND + Header OpenPGP signature: NOTFOUND + Header OpenPGP RSA signature: NOTFOUND + Header OpenPGP DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK diff --git a/tools/rpmsign.c b/tools/rpmsign.c index c5e3e11b49..66bc7e11c0 100644 --- a/tools/rpmsign.c +++ b/tools/rpmsign.c @@ -43,7 +43,13 @@ static struct poptOption signOptsTable[] = { #endif { "rpmv3", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &sargs.signflags, RPMSIGN_FLAG_RPMV3, - N_("create rpm v3 header+payload signatures") }, + N_("request legacy rpm v3 header+payload signatures on v4 packages") }, + { "rpmv4", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), + &sargs.signflags, RPMSIGN_FLAG_RPMV4, + N_("request legacy rpm v4 header signatures on v6 packages") }, + { "rpmv6", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), + &sargs.signflags, RPMSIGN_FLAG_RPMV6, + N_("request rpm v6 header signature on v4 packages") }, #ifdef WITH_IMAEVM { "signfiles", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &sargs.signflags, RPMSIGN_FLAG_IMA, @@ -207,8 +213,10 @@ int main(int argc, char *argv[]) #endif switch (mode) { - case MODE_ADDSIGN: case MODE_RESIGN: + sargs.signflags |= RPMSIGN_FLAG_RESIGN; + /* fallthrough */ + case MODE_ADDSIGN: ec = doSign(optCon, &sargs); break; case MODE_DELSIGN: From 5adbed27b6862f9103f8552e6287fdb8dace0d28 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 18 Nov 2024 15:50:06 +0200 Subject: [PATCH 09/22] Add support for multiple OpenPGP signatures per package, part 2/2 Add a tag extension for RPMTAG_OPENPGP (on top of the concrete tag) to handle compatibility with v3/v4 signatures: the extension collects all legacy signatures under the same umbrella so users don't need to query multiple different tags, you just query for RPMTAG_OPENPGP to get all them at once. Extend :pgpsig tag format to handle the new string array/base64 variant. Update --info/-i query to use the extension and output all existing signatures, one per line. The no-signature case of "Signature : (none)" is preserved as-is to help backwards compatibility with scripts parsing the output. Related: #3385 (backported from commit bea8f4557819449e6aec948dae192d71fe49d526) --- lib/formats.c | 24 +++++++++++++++++++++--- lib/tagexts.c | 34 ++++++++++++++++++++++++++++++++++ rpmpopt.in | 2 +- tests/rpmquery.at | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 4 deletions(-) diff --git a/lib/formats.c b/lib/formats.c index 0b1539e166..3eb0b202e1 100644 --- a/lib/formats.c +++ b/lib/formats.c @@ -413,12 +413,12 @@ static char *jsonFormat(rpmtd td, char **emsg) } /* signature fingerprint and time formatting */ -static char * pgpsigFormat(rpmtd td, char **emsg) +static char * pgpsigFormatOne(uint8_t *pkt, size_t pktlen, char **emsg) { char * val = NULL; pgpDigParams sigp = NULL; - if (pgpPrtParams((uint8_t*)td->data, td->count, PGPTAG_SIGNATURE, &sigp)) { + if (pgpPrtParams(pkt, pktlen, PGPTAG_SIGNATURE, &sigp)) { *emsg = xstrdup(_("(not an OpenPGP signature)")); } else { char dbuf[BUFSIZ]; @@ -445,6 +445,24 @@ static char * pgpsigFormat(rpmtd td, char **emsg) return val; } +static char * pgpsigFormat(rpmtd td, char **emsg) +{ + char *val = NULL; + if (rpmtdType(td) == RPM_BIN_TYPE) { + val = pgpsigFormatOne((uint8_t *)td->data, td->count, emsg); + } else if (rpmtdType(td) == RPM_STRING_ARRAY_TYPE) { + uint8_t *pkt = NULL; + size_t pktlen = 0; + if (rpmBase64Decode(rpmtdGetString(td), (void **)&pkt, &pktlen) == 0) { + val = pgpsigFormatOne(pkt, pktlen, emsg); + free(pkt); + } + } else { + *emsg = xstrdup(_("(invalid type)")); + } + return val; +} + /* dependency flags formatting */ static char * depflagsFormat(rpmtd td, char **emsg) { @@ -575,7 +593,7 @@ static const struct headerFmt_s rpmHeaderFormats[] = { { RPMTD_FORMAT_BASE64, "base64", RPM_BINARY_CLASS, base64Format }, { RPMTD_FORMAT_PGPSIG, "pgpsig", - RPM_BINARY_CLASS, pgpsigFormat }, + RPM_NULL_CLASS, pgpsigFormat }, { RPMTD_FORMAT_DEPFLAGS, "depflags", RPM_NUMERIC_CLASS, depflagsFormat }, { RPMTD_FORMAT_DEPTYPE, "deptype", diff --git a/lib/tagexts.c b/lib/tagexts.c index 080f1199a2..3350737c33 100644 --- a/lib/tagexts.c +++ b/lib/tagexts.c @@ -1003,6 +1003,39 @@ static int sysusersTag(Header h, rpmtd td, headerGetFlags hgflags) return (td->count > 0); } +static void trySigTag(Header h, rpmTagVal tag, ARGV_t *sigs) +{ + struct rpmtd_s td; + if (headerGet(h, tag, &td, HEADERGET_ALLOC)) { + char *b64 = rpmBase64Encode((uint8_t *)td.data, td.count, 0); + if (b64) { + argvAdd(sigs, b64); + free(b64); + } + rpmtdFreeData(&td); + } +} + +static int openpgpTag(Header h, rpmtd td, headerGetFlags hgflags) +{ + if (headerGet(h, RPMTAG_OPENPGP, td, HEADERGET_ALLOC)) + return 1; + + ARGV_t sigs = NULL; + trySigTag(h, RPMTAG_RSAHEADER, &sigs); + trySigTag(h, RPMTAG_DSAHEADER, &sigs); + trySigTag(h, RPMTAG_SIGPGP, &sigs); + trySigTag(h, RPMTAG_SIGGPG, &sigs); + + if (sigs) { + td->data = sigs; + td->count = argvCount(sigs); + td->type = RPM_STRING_ARRAY_TYPE; + td->flags = RPMTD_ALLOCED|RPMTD_PTR_ALLOCED; + } + return td->count != 0; +} + static int rpmformatTag(Header h, rpmtd td, headerGetFlags hgflags) { if (headerGet(h, RPMTAG_RPMFORMAT, td, HEADERGET_ALLOC)) @@ -1059,6 +1092,7 @@ static const struct headerTagFunc_s rpmHeaderTagExtensions[] = { { RPMTAG_CONFLICTNEVRS, conflictnevrsTag }, { RPMTAG_FILENLINKS, filenlinksTag }, { RPMTAG_SYSUSERS, sysusersTag }, + { RPMTAG_OPENPGP, openpgpTag }, { RPMTAG_RPMFORMAT, rpmformatTag }, { 0, NULL } }; diff --git a/rpmpopt.in b/rpmpopt.in index b45d225d97..2c55778bcc 100644 --- a/rpmpopt.in +++ b/rpmpopt.in @@ -96,7 +96,7 @@ Install Date: %|INSTALLTIME?{%{INSTALLTIME:date}}:{(not installed)}|\n\ Group : %{GROUP}\n\ Size : %{LONGSIZE}\n\ %|LICENSE?{License : %{LICENSE}}|\n\ -Signature : %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|\n\ +Signature :%|OPENPGP?{[\n %{OPENPGP:pgpsig}]}:{ (none)}|\n\ Source RPM : %{SOURCERPM}\n\ Build Date : %{BUILDTIME:date}\n\ Build Host : %{BUILDHOST}\n\ diff --git a/tests/rpmquery.at b/tests/rpmquery.at index b92fa8950b..3520e344ba 100644 --- a/tests/rpmquery.at +++ b/tests/rpmquery.at @@ -419,6 +419,18 @@ runroot rpm \ [RSA/SHA256, Thu Apr 6 13:02:33 2017, Key ID 4344591e1964c5fc], [warning: /data/RPMS/hello-2.0-1.x86_64-signed.rpm: Header V4 RSA/SHA256 Signature, key ID 1964c5fc: NOKEY ]) + +RPMTEST_CHECK([[ +runroot rpm \ + --nosignature \ + --qf "[%{openpgp:pgpsig}\n]" \ + -qp /data/RPMS/hello-2.0-1.x86_64-signed.rpm +]], +[0], +[RSA/SHA256, Thu Apr 6 13:02:33 2017, Key ID 4344591e1964c5fc +RSA/SHA256, Thu Apr 6 13:02:32 2017, Key ID 4344591e1964c5fc +], +[]) RPMTEST_CLEANUP # ------------------------------ @@ -1339,3 +1351,32 @@ Sourcepackage ], []) RPMTEST_CLEANUP + +AT_SETUP([info query output]) +AT_KEYWORDS([query signature]) +RPMTEST_CHECK([ +runroot rpm -qi --nosignature /data/RPMS/hello-2.0-1.x86_64-signed.rpm +], +[0], +[[Name : hello +Version : 2.0 +Release : 1 +Architecture: x86_64 +Install Date: (not installed) +Group : Testing +Size : 7243 +License : GPL +Signature : + RSA/SHA256, Thu Apr 6 13:02:33 2017, Key ID 4344591e1964c5fc + RSA/SHA256, Thu Apr 6 13:02:32 2017, Key ID 4344591e1964c5fc +Source RPM : hello-2.0-1.src.rpm +Build Date : Sat Nov 22 12:00:00 2008 +Build Host : localhost +Relocations : /usr +Summary : hello -- hello, world rpm +Description : +Simple rpm demonstration. +]], +[]) +RPMTEST_CLEANUP + From 5bc5f60fb0b6d61fb4818ea8dd99a383bf7b6a22 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Wed, 9 Apr 2025 15:08:52 +0200 Subject: [PATCH 10/22] Adjust signature messages in tests rpm-4.20 has adifferent message format for signatures and checksums. Have this in a separate patch for now to make it easier to review the more meaningful changes to the test cases. --- tests/data/RPMS/attrtest-1.0-1.noarch.rpm-v6 | Bin 0 -> 8643 bytes tests/data/RPMS/hello-1.0-1.x86_64.rpm-v3 | Bin 0 -> 4374 bytes tests/rpmsigdig.at | 64 +++++++++---------- tests/rpmvfylevel.at | 4 +- 4 files changed, 34 insertions(+), 34 deletions(-) create mode 100644 tests/data/RPMS/attrtest-1.0-1.noarch.rpm-v6 create mode 100644 tests/data/RPMS/hello-1.0-1.x86_64.rpm-v3 diff --git a/tests/data/RPMS/attrtest-1.0-1.noarch.rpm-v6 b/tests/data/RPMS/attrtest-1.0-1.noarch.rpm-v6 new file mode 100644 index 0000000000000000000000000000000000000000..9efbbd0d4b70fdf1ca567d836a46772728637349 GIT binary patch literal 8643 zcmeHMPl#Me8LuRr$;|jK8b#Mr=azueQ&q33UOka@!|HAVF@`0=3M$sWH`8&Zd+g~6 zSwTp24~ioGLp%t2$W26#o@7zj^Bz11?qLrrCSul$NYvHw_r0!{Nk0c&aRd)t$=AR7 zRekl)5$dLPS?bMuZgDVKmRz{9rCpw-947uPB3=*v#37~ zIfc3do@VUW+ks0ED$qUgTOj(`1$6g=v30PjP^Bw`l0ik2jEYrJmvyCiRfQBB52cl& z@ZJ@n2+>z2_)sSAtR|z2vWUPU0*eSNBCv?SA_9vDEF!Roz#;;R2rMG7h`=HOiwHCc ziT(Zkmk{s$o0znuA>GXGfS4}fIv>UrLO?V zK8=I@rEh1BeI@%#-_88}ng1;Fr+_s6rOclO()d?_wEl}TeoAG22?%?qp3nT*+~3-# zeWCvE0m+|F?5ld@J)WW zF#hX6%y)(m`MTv-GXKVmuiOH{{+Vw9p}+E_%wGgz{*|w0{wfgbS@~w>zX6i|FEhWF z`+t@B10d#G?Pvby%+F>17a+#3^34C5xdM{EuLCjP>hr+kPd?07GUO|nVAqhk9F8{n z^>8coDVN#zY17>pjwk=Bi(OfH>=tD`H^;kE_Vm@utuoshj`nV{(b!GGCcE&$?U~%Y z{euhlZr^G6gWEr8@ILt6FW0=woocMq=b{Gv3e!oEn`x`er2N7 zx{Qf?FSV?(Odmw;g>q$OxGa;aDsQz42t!d>r&EQn#iSDX;L!kQIp?8<`>Bq+kX0d~ zRj!CB+GxDB#z`%FRmlRL`Z^@33+W=_V1(k(3&=?a&P|F%<#ec`u>zYEq!ms@pR_2V zP$oFcXiC9_ca_wtwAc$}q%jC$#J=&`R>*)mQ`M@93M#@1Q8>d50$jO51~^l|>)J~p zOT-vHNNkTm23%+@lXaEA*ivd~4XxTtwh(u*=m?rbvfA5Rt5h+*_|^uI5Y@p#IbkLc3&c*HUs z(&UFDR*%PxcsF4rE^as2wi9oLeva%m9|to~XDdxBS6tM0k2 zv1`WfUUWCo)k&&{H_x-Z-87lG+0+^@XEk!NskJ^fq;avS%{-jNsu=Kr!pkru#N`dq{vpNP^Um4ag>B2)Vw_);=oxYa1-=49B=PH+O@z*+t>dNE}@w#sAUr z|HA2Sh2_0zy=IxLD}g%!7g3cd6{;4-m$;7voI64&h4;7#7YthlP(RH}{CgG`il#6&#|2~8Hix@?{HMpe?^fsgWk(RUqv-_fr-`k|vAJNg?PecajR{K3s*&Y#VBeSu%rNA*QF q{=<%bC;p-v|La*_wEO#S@Qvzq&G@$A+A|j}UHvP`c`#sTn`naM{#diVh7 z@gq~Ibfh*4jnv-c|JO_4|ISK!Jjw%)LCeSh0N*I6{O}lPM;KR70UZ4%ut?Cd@Gn|K!xllVV(sQvb(^%2(ur|%b-H*QDI&K z74i>(`6tYmV21Vx+2gmEAF3y`msGHUeSTUe+Q_L|1`|P zphEGWJRmz%7m#_dFpGc+`tuxxSq!$@!wi1AO@9xVq3;Lgz(WHStT(?TsL=cv*e(q! z6h8%2@Eh@iXJga;JE-71{=KmMCCsv0%ok69DfgpuN>cAd!g8ORI?pr8B4`1S2p2AW#AV zsbr{&Adv&;G$xDT#iGz@;3WZkIGwXpI?;>jM`uDs0RUXDqrDx1MP{-P%wP(Oi~^3^ z+X7B33YEg5kePrVixqfSOACyKqBDE}Duost280>vd+1{TtzafYYcrgdH-)CPnaS25 z)6a`R)*{h~|6@?=7|vlc1pxPAOM(57W4Ou4-?s?L6>9pLdHULDqK-FNkLay$h%rPP z8R=uRNoYf|w?5g(Ti2Tm)>&7V2tL|AXgxiWfvy+Pi%2Gu3`mALXbjoNh-d(>@NeN| z(CIATzrOzVTZm#Zh$yJC0I>15XKTBgZ*{OBNPUb3=wbFB4gBcf9Ww*V=1oK~=_q}5 z4Rw8tH-)9~x1r;<*5(!-Iw&2K-v6-bV*aZUXKw9r^rVNQrLE(?e87CcMb+)S!l`sG z(lH8^%(U_fA=@*^K9n#GfWe}Y)Q_KV^02}Ytf0IB0JHVGuZJ=+LK&d}KwmS$%!cga zgRr6d(U^1^!uYKBSu+Ni>N407|hA$@7VfKogZ0K5x)lWzVAa?X-f zLw$BH!za$|qonp740@i9p^VQYe4L@V-7NgbozArj84o7>gZFxgZ-|L!o6AtpS7frL zjf(0$Ngk&aK1XFmM`3KE*!i?5&pdOdLHrIOp6c2>M`d@M{S~u6dyg=u!baY>r%T18 zj9fSIZ7t_yMEoGSXGJt82CB%nxuVC^wUkC=qm%2u?E=dgbz41KVfZtzl1c>ig=1Hp z08&k=*40vkGi;9I^UWX0XYb?_I$RUM^VNnYUa4WWqwe{Rw8W^#fk%WEqeN1sSfd^D zzNQ8XJqs=&M~-M_|!sbr>-hShsc?65q0Tr7WCv|=S&S$>y%LH-7Xln6mtQ~$0sd5bhxNX zk(*@YN`}5pXWTJbG@O1M_3Xq)W3t;zvALR#qJU*Xvqk4BL+;zj0@1bk8%u53UoOo2 zWpF`30^1(f^V(B^(Yq{fx^wyG(TzSOTYPJDvZ(AK)o`@w{aaU~lXpJ!-laVfB-%}Q z>V66%X%lu+c*b7&d-+T6Mx(r370XXY_eou1JkG%MeY0U07uMe*S$Ec_7O`a>dZQGF zw_#7L#s`&^p1E7{t25sUA<3e7dw$&dg9EFaJB^{WQ=WMjZ6xz{^7DvBoKTm`r3qO& zIOObimb|2DDJlG}Q^%~{PvXy-=H7{;j#jqKJFf5DXQFrOO{$QbmsmHq&H>Tvle8nX zu&K$WJ7uA{gM=dtC)`FhwsRQ{gdld*z0dX?cW{C8dzr$`lhH}xrX6#5=CNs)Q)A8* z9aL-Y_3`ZTGM<&&YMfz}g`mKsK9Sg7PRanQF>`MDxkdkQ%0N(KX2ayTOVzG6a@4qJ zIU!rVKrT{HOwl-Odhm60><0gOZzXr?L230|f$4{ZIW+Kq>3{i2h)M8b<+^jr?B|>| z^PqqM;lQ3sU-=*VOp~wD`tIW zIdRFrG_7L#(fjU!UiU`Z8UMAVoEE)rv^EqxugG>e%_9(|r$@F;L=LX&H zdnWfP;?%YNN4L${{qM2!;>vO>{g~K%-l{^;d zg*|!8ry6J_qf)D18VJ4(=VL+$(*2m{W*-}rB3r&+_Uca?9C=pcU!1anC=2c$I4mNZ z$@X8$|JUxfI@8rWd;_yChj<3p%^LD>p093ohg61`s!a@u1BvT-XWBs&>E|`B$gtn523hi~Wt$eT=N|@vxZ#kUit~*V);+Z%M{sKoQzh=3Aa-+w5y0>A2k9 zn8C<0O#wn~q_DY)pvI(7hvL05FWeQZkVL~!hlG+5hWD?Ap>vi_lEFqVGMYN{BIAaF z9GvuS|JGg{HWFv(tZ>b{H^*gv+yzn$uPOV985 zqZjVJX~K7^J6#f4Xlp^fx-S9S-t2zJEVkU&f2V-Q_=~TEMRRduPr2eP-i318aksM; zvGRMC9_LxKo_6$LW*+*q{x+Cp)qUi{z7o;G-MVp3WB!~a%={#O_Eca&JXODq%~Kh` zf4XGtu&S7M_{E31KC4PV=FpGv`k3+y+3YMe`{HbYcli4E12hi^xV-Afu-}uwC z_fcvYxTdQDI33I@%_}z!Hd5*xar&gVVOjsX2|FysgU`6_B7JCgu1OW`bmD*Ds99vT zTTtyT;o&b%;`yC%d4$^cCDv&e?UipOe|B{5-%}T#ioQ{M@4;J)xX;Llngp|UZGQgi z$zzTC4~*o;M3fr8>9PH2W~4mSiV?%zJZi!3<8N=Vk68Xnt<)mr-JKL^r|o2Rb88*1 zwZkPF*PC~DOVVPf!~8TpKv#yN?cTc;BS_O4CfCf?3% z%P~2*W_r~$Hk&Mj&+-*gpi5w1a{{wh?{f~BKeAg*F577ObUx~wyGk1K)6`kd4ZXRd z9CvJZl`^KCv@WqKay%&@@7MlFsX5M}G&XuLU*0bRZ!;RI9>F+spe&t2#ZQ~O%j&%) zUh&Lw4f}hm63cxyUuqGX4{qv)vrV& z7z34`^Vx#Ldi=!OpS>$mi;H18U7v#O+lKek(_7mX33Hy(PS|pMmF%0j`<82!8WG%! z9NA=P_WIsh>=p3{Ms;_0{!g46mYpHa-EB9qJrRAXuk5F_<}#+ViX9ciiCM*e9iWHB zpU@d^^SJzu{%ndHi#*rqjLmqiZ+Ib?u<~fpOQv*Gw)FhQf?i3rcGQz(qm0g?HdXXt??D|H_PPLr-Yn$)^%+-U+M5^y-d88VQ8GdK9(Es22mtu5q5Y+ zrt#YihWPn}m+~>c23l)0zE-vS<2+aBH7hja`k}6yHyCs=*QeL5)qFVle?=_)u#8^N N5=@Hj9JK&|e*z}Gc3}Vj literal 0 HcmV?d00001 diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index e73c2147f8..9f6059f711 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -349,9 +349,9 @@ runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hel [0], [[Checking package before importing key: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: - Header OpenPGP V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY + Header V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY Header OpenPGP signature: NOTFOUND - Header OpenPGP DSA signature: NOTFOUND + Header DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -414,9 +414,9 @@ runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hel [0], [Checking package before importing key: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: - Header OpenPGP V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY + Header V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY Header OpenPGP signature: NOTFOUND - Header OpenPGP DSA signature: NOTFOUND + Header DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -435,9 +435,9 @@ RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650 RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 invalid: key is not alive])dnl RPMOUTPUT_SEQUOIA([ because: The subkey is not live])dnl RPMOUTPUT_SEQUOIA([ because: Expired on 2022-04-12T00:00:15Z])dnl - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED Header OpenPGP signature: NOTFOUND - Header OpenPGP DSA signature: NOTFOUND + Header DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -452,11 +452,11 @@ RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650 RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 invalid: key is not alive])dnl RPMOUTPUT_SEQUOIA([ because: The subkey is not live])dnl RPMOUTPUT_SEQUOIA([ because: Expired on 2022-04-12T00:00:15Z])dnl - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED Header OpenPGP signature: NOTFOUND - Header OpenPGP DSA signature: NOTFOUND - Legacy OpenPGP RSA signature: NOTFOUND - Legacy OpenPGP DSA signature: NOTFOUND + Header DSA signature: NOTFOUND + RSA signature: NOTFOUND + DSA signature: NOTFOUND 1 Checking package after importing key, no signature: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: @@ -493,9 +493,9 @@ runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hel [0], [Checking package before importing key: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: - Header OpenPGP V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY + Header V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY Header OpenPGP signature: NOTFOUND - Header OpenPGP DSA signature: NOTFOUND + Header DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -512,9 +512,9 @@ Checking package after importing key: RPMOUTPUT_LEGACY([error: Subkey 1f71177215217ee0 of key b3a771bfeb04e625 (Alice ) has been revoked])dnl RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650C36B6F41BCB3A771BFEB04E625 (Alice ):])dnl RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 is invalid: key is revoked])dnl - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED Header OpenPGP signature: NOTFOUND - Header OpenPGP DSA signature: NOTFOUND + Header DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK @@ -527,11 +527,11 @@ Checking package after importing key, no digest: RPMOUTPUT_LEGACY([error: Subkey 1f71177215217ee0 of key b3a771bfeb04e625 (Alice ) has been revoked])dnl RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650C36B6F41BCB3A771BFEB04E625 (Alice ):])dnl RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 is invalid: key is revoked])dnl - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED Header OpenPGP signature: NOTFOUND - Header OpenPGP DSA signature: NOTFOUND - Legacy OpenPGP RSA signature: NOTFOUND - Legacy OpenPGP DSA signature: NOTFOUND + Header DSA signature: NOTFOUND + RSA signature: NOTFOUND + DSA signature: NOTFOUND 1 Checking package after importing key, no signature: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: @@ -1139,10 +1139,10 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm|grep -v digest /tmp/hello-2.0-1.x86_64.rpm PRE-IMPORT /tmp/hello-2.0-1.x86_64.rpm: - Header OpenPGP V4 RSA/SHA512 signature, key ID 4344591e1964c5fc: NOKEY + Header V4 RSA/SHA512 signature, key ID 4344591e1964c5fc: NOKEY POST-IMPORT /tmp/hello-2.0-1.x86_64.rpm: - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK DELSIGN /tmp/hello-2.0-1.x86_64.rpm POST-DELSIGN @@ -1156,7 +1156,7 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [1], [/tmp/hello-2.0-1.x86_64.rpm: - Header OpenPGP V4 EdDSA/SHA512 signature, key ID b0645aec757bf69e: NOKEY + Header V4 EdDSA/SHA512 signature, key ID b0645aec757bf69e: NOKEY Header SHA256 digest: OK Payload SHA256 digest: OK ], @@ -1188,7 +1188,7 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK Header SHA256 digest: OK Payload SHA256 digest: OK ], @@ -1201,7 +1201,7 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK Header SHA256 digest: OK Payload SHA256 digest: OK ], @@ -1213,8 +1213,8 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header OpenPGP V4 EdDSA/SHA512 signature, key fingerprint: 152bb32fd9ca982797e835cfb0645aec757bf69e: OK - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 EdDSA/SHA512 signature, key fingerprint: 152bb32fd9ca982797e835cfb0645aec757bf69e: OK + Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK Header SHA256 digest: OK Payload SHA256 digest: OK ], @@ -1226,9 +1226,9 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header OpenPGP V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK - Header OpenPGP V4 EdDSA/SHA512 signature, key fingerprint: 152bb32fd9ca982797e835cfb0645aec757bf69e: OK - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK + Header V4 EdDSA/SHA512 signature, key fingerprint: 152bb32fd9ca982797e835cfb0645aec757bf69e: OK + Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK Header SHA256 digest: OK Payload SHA256 digest: OK ], @@ -1240,9 +1240,9 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [1], [/tmp/hello-2.0-1.x86_64.rpm: - Header OpenPGP V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK - Header OpenPGP V4 EdDSA/SHA512 signature, key ID b0645aec757bf69e: NOKEY - Header OpenPGP V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK + Header V4 EdDSA/SHA512 signature, key ID b0645aec757bf69e: NOKEY + Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK Header SHA256 digest: OK Payload SHA256 digest: OK ], @@ -1254,7 +1254,7 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header OpenPGP V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK + Header V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK Header SHA256 digest: OK Payload SHA256 digest: OK ], diff --git a/tests/rpmvfylevel.at b/tests/rpmvfylevel.at index 3e8919e680..431f45afae 100644 --- a/tests/rpmvfylevel.at +++ b/tests/rpmvfylevel.at @@ -347,8 +347,8 @@ nohdrs nosig /data/RPMS/hello-2.0-1.x86_64-signed.rpm: Header OpenPGP signature: NOTFOUND - Header OpenPGP RSA signature: NOTFOUND - Header OpenPGP DSA signature: NOTFOUND + Header RSA signature: NOTFOUND + Header DSA signature: NOTFOUND Header SHA256 digest: OK Header SHA1 digest: OK Payload SHA256 digest: OK From ccc004a83e1ee32d25a957fd78210db5bc252f20 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Fri, 4 Apr 2025 13:15:44 +0200 Subject: [PATCH 11/22] Adjust tests fully Output format and cli is different between rpm 6 and 4.20. Adjust the test to work with 4.20. * Use macros.rpmsign-sequoia to sign packages with sequoia. * Redirect output of rpmsign --addsign to /dev/null as everywhere else * Use short key IDs instead of long key IDs and fingerprints. * Add SHA1 and MD5 digests --- tests/rpmsigdig.at | 86 ++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 34 deletions(-) diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index 9f6059f711..146da43e92 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -349,7 +349,7 @@ runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hel [0], [[Checking package before importing key: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: - Header V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY + Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOKEY Header OpenPGP signature: NOTFOUND Header DSA signature: NOTFOUND Header SHA256 digest: OK @@ -414,7 +414,7 @@ runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hel [0], [Checking package before importing key: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: - Header V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY + Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOKEY Header OpenPGP signature: NOTFOUND Header DSA signature: NOTFOUND Header SHA256 digest: OK @@ -435,7 +435,7 @@ RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650 RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 invalid: key is not alive])dnl RPMOUTPUT_SEQUOIA([ because: The subkey is not live])dnl RPMOUTPUT_SEQUOIA([ because: Expired on 2022-04-12T00:00:15Z])dnl - Header V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOTTRUSTED Header OpenPGP signature: NOTFOUND Header DSA signature: NOTFOUND Header SHA256 digest: OK @@ -452,7 +452,7 @@ RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650 RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 invalid: key is not alive])dnl RPMOUTPUT_SEQUOIA([ because: The subkey is not live])dnl RPMOUTPUT_SEQUOIA([ because: Expired on 2022-04-12T00:00:15Z])dnl - Header V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOTTRUSTED Header OpenPGP signature: NOTFOUND Header DSA signature: NOTFOUND RSA signature: NOTFOUND @@ -493,7 +493,7 @@ runroot rpmkeys --define '_pkgverify_level all' -Kv --nosignature /data/RPMS/hel [0], [Checking package before importing key: /data/RPMS/hello-2.0-1.x86_64-signed-with-subkey.rpm: - Header V4 RSA/SHA512 signature, key ID 1f71177215217ee0: NOKEY + Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOKEY Header OpenPGP signature: NOTFOUND Header DSA signature: NOTFOUND Header SHA256 digest: OK @@ -512,7 +512,7 @@ Checking package after importing key: RPMOUTPUT_LEGACY([error: Subkey 1f71177215217ee0 of key b3a771bfeb04e625 (Alice ) has been revoked])dnl RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650C36B6F41BCB3A771BFEB04E625 (Alice ):])dnl RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 is invalid: key is revoked])dnl - Header V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOTTRUSTED Header OpenPGP signature: NOTFOUND Header DSA signature: NOTFOUND Header SHA256 digest: OK @@ -527,7 +527,7 @@ Checking package after importing key, no digest: RPMOUTPUT_LEGACY([error: Subkey 1f71177215217ee0 of key b3a771bfeb04e625 (Alice ) has been revoked])dnl RPMOUTPUT_SEQUOIA([error: Verifying a signature using certificate B6542F92F30650C36B6F41BCB3A771BFEB04E625 (Alice ):])dnl RPMOUTPUT_SEQUOIA([ Key 1F71177215217EE0 is invalid: key is revoked])dnl - Header V4 RSA/SHA512 signature, key fingerprint: b6542f92f30650c36b6f41bcb3a771bfeb04e625: NOTTRUSTED + Header V4 RSA/SHA512 Signature, key ID 15217ee0: NOTTRUSTED Header OpenPGP signature: NOTFOUND Header DSA signature: NOTFOUND RSA signature: NOTFOUND @@ -1109,11 +1109,11 @@ AT_SKIP_IF([test x$PGP = xdummy]) RPMDB_INIT RPMTEST_CHECK([ +RPM_DOCDIR=$(runroot rpm --eval '%_defaultdocdir') +cat "${RPMTEST}${RPM_DOCDIR}/rpm/macros.rpmsign-sequoia" >> ${HOME}/.rpmmacros cat << EOF >> ${HOME}/.rpmmacros -%_openpgp_sign sq -%_openpgp_sign_id 771B18D3D7BAA28734333C424344591E1964C5FC +%_gpg_name 771B18D3D7BAA28734333C424344591E1964C5FC EOF - runroot_other sq key import /data/keys/*.secret ], [0], @@ -1136,29 +1136,31 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm|grep -v digest ], [0], [SIGN -/tmp/hello-2.0-1.x86_64.rpm +/tmp/hello-2.0-1.x86_64.rpm: PRE-IMPORT /tmp/hello-2.0-1.x86_64.rpm: - Header V4 RSA/SHA512 signature, key ID 4344591e1964c5fc: NOKEY + Header V4 RSA/SHA512 Signature, key ID 1964c5fc: NOKEY POST-IMPORT /tmp/hello-2.0-1.x86_64.rpm: - Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 RSA/SHA512 Signature, key ID 1964c5fc: OK DELSIGN -/tmp/hello-2.0-1.x86_64.rpm +/tmp/hello-2.0-1.x86_64.rpm: POST-DELSIGN /tmp/hello-2.0-1.x86_64.rpm: ], [ignore]) RPMTEST_CHECK([ -runroot rpmsign --addsign --key-id 152bb32fd9ca982797e835cfb0645aec757bf69e /tmp/hello-2.0-1.x86_64.rpm +runroot rpmsign --addsign --key-id 152bb32fd9ca982797e835cfb0645aec757bf69e /tmp/hello-2.0-1.x86_64.rpm > /dev/null runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [1], [/tmp/hello-2.0-1.x86_64.rpm: - Header V4 EdDSA/SHA512 signature, key ID b0645aec757bf69e: NOKEY + Header V4 EdDSA/SHA512 Signature, key ID 757bf69e: NOKEY Header SHA256 digest: OK + Header SHA1 digest: OK Payload SHA256 digest: OK + MD5 digest: OK ], [ignore]) RPMTEST_CLEANUP @@ -1169,9 +1171,10 @@ AT_SKIP_IF([test x$PGP = xdummy]) RPMDB_INIT RPMTEST_CHECK([ +RPM_DOCDIR=$(runroot rpm --eval '%_defaultdocdir') +cat "${RPMTEST}${RPM_DOCDIR}/rpm/macros.rpmsign-sequoia" >> ${HOME}/.rpmmacros cat << EOF >> ${HOME}/.rpmmacros -%_openpgp_sign sq -%_openpgp_sign_id 771B18D3D7BAA28734333C424344591E1964C5FC +%_gpg_name 771B18D3D7BAA28734333C424344591E1964C5FC EOF runroot_other sq key import /data/keys/*.secret @@ -1188,9 +1191,11 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 RSA/SHA512 Signature, key ID 1964c5fc: OK Header SHA256 digest: OK + Header SHA1 digest: OK Payload SHA256 digest: OK + MD5 digest: OK ], []) @@ -1201,9 +1206,11 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 RSA/SHA512 Signature, key ID 1964c5fc: OK Header SHA256 digest: OK + Header SHA1 digest: OK Payload SHA256 digest: OK + MD5 digest: OK ], []) @@ -1213,10 +1220,12 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header V4 EdDSA/SHA512 signature, key fingerprint: 152bb32fd9ca982797e835cfb0645aec757bf69e: OK - Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 EdDSA/SHA512 Signature, key ID 757bf69e: OK + Header V4 RSA/SHA512 Signature, key ID 1964c5fc: OK Header SHA256 digest: OK + Header SHA1 digest: OK Payload SHA256 digest: OK + MD5 digest: OK ], []) @@ -1226,25 +1235,29 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK - Header V4 EdDSA/SHA512 signature, key fingerprint: 152bb32fd9ca982797e835cfb0645aec757bf69e: OK - Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 ECDSA/SHA512 Signature, key ID 5f65bbe8: OK + Header V4 EdDSA/SHA512 Signature, key ID 757bf69e: OK + Header V4 RSA/SHA512 Signature, key ID 1964c5fc: OK Header SHA256 digest: OK + Header SHA1 digest: OK Payload SHA256 digest: OK + MD5 digest: OK ], []) RPMTEST_CHECK([ -runroot rpmkeys --delete 152bb32fd9ca982797e835cfb0645aec757bf69e +runroot rpmkeys --delete 757bf69e-661d22a8 runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [1], [/tmp/hello-2.0-1.x86_64.rpm: - Header V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK - Header V4 EdDSA/SHA512 signature, key ID b0645aec757bf69e: NOKEY - Header V4 RSA/SHA512 signature, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK + Header V4 ECDSA/SHA512 Signature, key ID 5f65bbe8: OK + Header V4 EdDSA/SHA512 Signature, key ID 757bf69e: NOKEY + Header V4 RSA/SHA512 Signature, key ID 1964c5fc: OK Header SHA256 digest: OK + Header SHA1 digest: OK Payload SHA256 digest: OK + MD5 digest: OK ], []) @@ -1254,9 +1267,11 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], [0], [/tmp/hello-2.0-1.x86_64.rpm: - Header V4 ECDSA/SHA512 signature, key fingerprint: e8a62c0512b06b5d2183ba207f1c21f95f65bbe8: OK + Header V4 ECDSA/SHA512 Signature, key ID 5f65bbe8: OK Header SHA256 digest: OK + Header SHA1 digest: OK Payload SHA256 digest: OK + MD5 digest: OK ], []) @@ -1267,7 +1282,9 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm [0], [/tmp/hello-2.0-1.x86_64.rpm: Header SHA256 digest: OK + Header SHA1 digest: OK Payload SHA256 digest: OK + MD5 digest: OK ], []) @@ -1279,9 +1296,10 @@ AT_SKIP_IF([test x$PGP = xdummy]) RPMDB_INIT RPMTEST_CHECK([ +RPM_DOCDIR=$(runroot rpm --eval '%_defaultdocdir') +cat "${RPMTEST}${RPM_DOCDIR}/rpm/macros.rpmsign-sequoia" >> ${HOME}/.rpmmacros cat << EOF >> ${HOME}/.rpmmacros -%_openpgp_sign sq -%_openpgp_sign_id 771B18D3D7BAA28734333C424344591E1964C5FC +%_gpg_name 771B18D3D7BAA28734333C424344591E1964C5FC EOF runroot_other sq key import /data/keys/*.secret @@ -1295,7 +1313,7 @@ RPMTEST_CHECK([ runroot rpmbuild -bb --quiet \ --define "_rpmfilever 6" \ /data/SPECS/attrtest.spec -runroot rpmsign --addsign /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm +runroot rpmsign --addsign /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm > /dev/null ], [0], [], @@ -1325,7 +1343,7 @@ SIGPGP: (none) RPMTEST_CHECK([ runroot rpmsign --resign --rpmv4 \ --key-id E8A62C0512B06B5D2183BA207F1C21F95F65BBE8 \ - /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm + /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm > /dev/null ], [0], [], From 230a544b01258c93a147c226c8684d2dcd80569b Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Thu, 21 Nov 2024 13:30:20 +0200 Subject: [PATCH 12/22] Use RPMTAG_RPMFORMAT for rpm format detection in the signing code We now have a nice way to centrally get the format number, use it in the signing code instead of the various ad-hoc methods added during multi-signature development, and use 'rpmformat' as the variable name for easy grepping. No functional changes. (cherry picked from commit ef5b53820a570e14bceb8435d8e417ee3563c1c5) --- sign/rpmgensig.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index 91a81ef61e..02599398ff 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -639,7 +639,8 @@ static int rpmSign(const char *rpm, int deleting, int flags) struct sigTarget_s sigt_v4; unsigned int origSigSize; int insSig = 0; - rpmTagVal reserveTag = RPMSIGTAG_RESERVEDSPACE; + int rpmformat = 0; + rpmTagVal reserveTag = 0; fprintf(stdout, "%s:\n", rpm); @@ -671,8 +672,10 @@ static int rpmSign(const char *rpm, int deleting, int flags) goto exit; } - if (!headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) { - rpmlog(RPMLOG_ERR, _("Cannot sign RPM v3 packages\n")); + rpmformat = headerGetNumber(h, RPMTAG_RPMFORMAT); + + if (rpmformat < 4) { + rpmlog(RPMLOG_ERR, _("Cannot sign RPM v3 packages: %s\n"), rpm); goto exit; } @@ -700,6 +703,7 @@ static int rpmSign(const char *rpm, int deleting, int flags) } } else { flags |= RPMSIGN_FLAG_RPMV4; + reserveTag = RPMSIGTAG_RESERVEDSPACE; /* Ensure only one legacy signature is added if adding v6 signatures */ if ((flags & RPMSIGN_FLAG_RPMV6) && haveLegacySig(sigh)) flags &= ~(RPMSIGN_FLAG_RPMV4|RPMSIGN_FLAG_RPMV3); From 0d2e5e7a20c450fef32033185a8acc6bfacd800d Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 14 May 2025 14:29:34 +0300 Subject: [PATCH 13/22] Bump rpm-sequoia requirement to 1.8 for OpenPGP v6 support For OpenPGP v6 we need sequoia-sq >= 1.3 and rpm-sequoia >= 1.8 in the bare minimum, the latter is only available from rawhide so we need to pull it from there. This also requires a newer crypto-policies package than is available on any released version to permit ed25519 and x25519, otherwise we'll get funky "denied by policy" errors when signing. Talk about bleeding edge! (cherry picked from commit 8b1de0bd9be862a27fc66e5d9bcf5936ac4c8e7f) --- rpmio/CMakeLists.txt | 2 +- tests/Dockerfile.fedora | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rpmio/CMakeLists.txt b/rpmio/CMakeLists.txt index b54112e4fd..5448ed07c1 100644 --- a/rpmio/CMakeLists.txt +++ b/rpmio/CMakeLists.txt @@ -22,7 +22,7 @@ if (EXISTS ${CMAKE_SOURCE_DIR}/rpmio/rpmpgp_legacy/CMakeLists.txt) endif() if (WITH_SEQUOIA) - pkg_check_modules(RPMSEQUOIA REQUIRED IMPORTED_TARGET rpm-sequoia>=1.4.0) + pkg_check_modules(RPMSEQUOIA REQUIRED IMPORTED_TARGET rpm-sequoia>=1.8.0) target_sources(librpmio PRIVATE rpmpgp_sequoia.c) target_link_libraries(librpmio PRIVATE PkgConfig::RPMSEQUOIA) else() diff --git a/tests/Dockerfile.fedora b/tests/Dockerfile.fedora index 7b7a954db4..0ca9dbbbfb 100644 --- a/tests/Dockerfile.fedora +++ b/tests/Dockerfile.fedora @@ -13,6 +13,7 @@ RUN dnf -y install \ autoconf \ bubblewrap \ cmake \ + fedora-repos-rawhide \ gettext-devel \ debugedit \ doxygen \ @@ -67,7 +68,7 @@ RUN if which dnf5; then \ # If updates to specific packages are needed, do it here # RUN dnf --enablerepo=updates update ... -RUN dnf -y --enablerepo=updates install "sequoia-sq >= 1.0" +RUN dnf -y --enablerepo=rawhide install "sequoia-sq >= 1.3" "rpm-sequoia >= 1.8" "crypto-policies >= 20250402" RUN dnf clean all RUN echo "%_dbpath $(rpm --eval '%_dbpath')" > /root/.rpmmacros From f1734045688df0d067c1b0618ce06bda6bf52245 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 14 May 2025 13:50:48 +0300 Subject: [PATCH 14/22] Add OpenPGP v6 test keys Created using Sequoia SQ 1.3.1 with: sq key generate --own-key \ --userid v6-ed25519-testkey --name "rpm.org ed25519 v6 testkey" --email "ed25519-test@rpm.org" --profile rfc9580 --expiration=never --cannot-authenticate --cannot-encrypt --without-password (cherry picked from commit bffdc56efc3b901995e5bfd7f667699a16fb3e89) --- tests/data/keys/rpm.org-v6-ed25519-test.asc | 28 +++++++++++++++++ .../data/keys/rpm.org-v6-ed25519-test.secret | 30 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 tests/data/keys/rpm.org-v6-ed25519-test.asc create mode 100644 tests/data/keys/rpm.org-v6-ed25519-test.secret diff --git a/tests/data/keys/rpm.org-v6-ed25519-test.asc b/tests/data/keys/rpm.org-v6-ed25519-test.asc new file mode 100644 index 0000000000..9985bee3dc --- /dev/null +++ b/tests/data/keys/rpm.org-v6-ed25519-test.asc @@ -0,0 +1,28 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xioGaCR06hsAAAAg9FwUD1G2QkY9kp7ztkImkWqzCQilo06mCVNvOXXcpzrCpgYf +GwoAAAA3BYJoJHTqAwsJBwMVCggCmwECHgkiIQYDaCTwrGCu1vGjJW+IGQRp9tcl +Xj2OQcV3IzqgPgu50wAAAAA1riBQL82waQMi8Jze8WjwKJ58c6hFTK+JMulB6FzF +6BoGefVMDnm+o6k74FqEWSOuvIoBN0vKeg/x8msTTyG8z64O2EXQcJ5n+F2hHyPf +d7Il+fB/1lM7NFwNBViB03UJvgfNFjxlZDI1NTE5LXRlc3RAcnBtLm9yZz7CpgYT +GwoAAAA3BYJoJHTqAwsJBwMVCggCmwECHgkiIQYDaCTwrGCu1vGjJW+IGQRp9tcl +Xj2OQcV3IzqgPgu50wAAAADCbiB+59kmZO9bsC7ELr+iGGXlytoMF5BNmQl4IQcf +tRdgwDCFS4OBaYZIoZx2sib66wVlXYrzSk6Zo+jztufX9yYIPydciOW0B+9o7mdG +zYwmT+ms7mB9V8/8MispFlxBgQ7NGnJwbS5vcmcgZWQyNTUxOSB2NiB0ZXN0a2V5 +wqYGExsKAAAANwWCaCR06gMLCQcDFQoIApsBAh4JIiEGA2gk8KxgrtbxoyVviBkE +afbXJV49jkHFdyM6oD4LudMAAAAAKMcg7Bhjgdkn0WPkwGGqk5TpMqc+Nf3fWo1c +XKnn5I8/J5mzVVsY0eZ8NVEEYn1o7GQiH3/an3S7JRxLrbC++2/NWhQc/PaB1Yfy +RODxfHyKXdIhI5CNw7ByWeGAE5yRqFoOzRJ2Ni1lZDI1NTE5LXRlc3RrZXnCqQYT +GwoAAAA6BYJoJHTqAwsJBwMVCggCmQECmwECHgkiIQYDaCTwrGCu1vGjJW+IGQRp +9tclXj2OQcV3IzqgPgu50wAAAAAuDyBVmIRT8XZZuCRitpMLui84rnP5Lrku8Alk +nlnrfes3Sk+ubw3axZoibO2aha6H2cSYPHCil5/Mr7nYQb5dufEG/Bcd13MoqY37 +tsxfquqXFZn/MBJHTH2g8UWA3C0ZvQrOKgZoJHTqGwAAACATE6z5SVzOjhpWfvra +G7H4+4cxHq+UcpHVWOf/nwpeMcLAdQYYGwoAAADGBYJoJHTqApsCmaAGGRsKAAAA +KQWCaCR06iIhBmEYq+SBxBRzS7rkP9oki7uoiOXFQCm3wA4A3z7S17ZeAAAAAHZP +IMgAKkR1o+NMoRviQHzltrT5WKsAHxEORqXFcqH4IRIWQx9v8By+D31vlJ6zmTuG +2ATEk+GAhTHORo71fyneSP9P9qMn3UerviOf7NGdBJZucIhWc/Lf8Rajs3fDgfCN +ASIhBgNoJPCsYK7W8aMlb4gZBGn21yVePY5BxXcjOqA+C7nTAAAAAKsJIFPv2JrD +H0BB1bTUW6d0dXFHOt62sZM7xFDAJfs3CsGYnZLjb1Fc85tTYwytStk7HE2JUa6J +OBQeomt54pvekSqMw8dFIEEidjLBfoCUC9X1VdUFjaIDmypkaQPKyiboBQ== +=m6Lf +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/data/keys/rpm.org-v6-ed25519-test.secret b/tests/data/keys/rpm.org-v6-ed25519-test.secret new file mode 100644 index 0000000000..e5a897b66a --- /dev/null +++ b/tests/data/keys/rpm.org-v6-ed25519-test.secret @@ -0,0 +1,30 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +xUsGaCR06hsAAAAg9FwUD1G2QkY9kp7ztkImkWqzCQilo06mCVNvOXXcpzoAerF1 +ATMyhT+1NtPxWYjCQBh1+K7fJfHxG27ha+UyLx3CpgYfGwoAAAA3BYJoJHTqAwsJ +BwMVCggCmwECHgkiIQYDaCTwrGCu1vGjJW+IGQRp9tclXj2OQcV3IzqgPgu50wAA +AAA1riBQL82waQMi8Jze8WjwKJ58c6hFTK+JMulB6FzF6BoGefVMDnm+o6k74FqE +WSOuvIoBN0vKeg/x8msTTyG8z64O2EXQcJ5n+F2hHyPfd7Il+fB/1lM7NFwNBViB +03UJvgfNFjxlZDI1NTE5LXRlc3RAcnBtLm9yZz7CpgYTGwoAAAA3BYJoJHTqAwsJ +BwMVCggCmwECHgkiIQYDaCTwrGCu1vGjJW+IGQRp9tclXj2OQcV3IzqgPgu50wAA +AADCbiB+59kmZO9bsC7ELr+iGGXlytoMF5BNmQl4IQcftRdgwDCFS4OBaYZIoZx2 +sib66wVlXYrzSk6Zo+jztufX9yYIPydciOW0B+9o7mdGzYwmT+ms7mB9V8/8Misp +FlxBgQ7NGnJwbS5vcmcgZWQyNTUxOSB2NiB0ZXN0a2V5wqYGExsKAAAANwWCaCR0 +6gMLCQcDFQoIApsBAh4JIiEGA2gk8KxgrtbxoyVviBkEafbXJV49jkHFdyM6oD4L +udMAAAAAKMcg7Bhjgdkn0WPkwGGqk5TpMqc+Nf3fWo1cXKnn5I8/J5mzVVsY0eZ8 +NVEEYn1o7GQiH3/an3S7JRxLrbC++2/NWhQc/PaB1YfyRODxfHyKXdIhI5CNw7By +WeGAE5yRqFoOzRJ2Ni1lZDI1NTE5LXRlc3RrZXnCqQYTGwoAAAA6BYJoJHTqAwsJ +BwMVCggCmQECmwECHgkiIQYDaCTwrGCu1vGjJW+IGQRp9tclXj2OQcV3IzqgPgu5 +0wAAAAAuDyBVmIRT8XZZuCRitpMLui84rnP5Lrku8Alknlnrfes3Sk+ubw3axZoi +bO2aha6H2cSYPHCil5/Mr7nYQb5dufEG/Bcd13MoqY37tsxfquqXFZn/MBJHTH2g +8UWA3C0ZvQrHSwZoJHTqGwAAACATE6z5SVzOjhpWfvraG7H4+4cxHq+UcpHVWOf/ +nwpeMQAFrX9riEr/HJy20NDvHfATpwxi4MKMU/u8UuTXRCmdu8LAdQYYGwoAAADG +BYJoJHTqApsCmaAGGRsKAAAAKQWCaCR06iIhBmEYq+SBxBRzS7rkP9oki7uoiOXF +QCm3wA4A3z7S17ZeAAAAAHZPIMgAKkR1o+NMoRviQHzltrT5WKsAHxEORqXFcqH4 +IRIWQx9v8By+D31vlJ6zmTuG2ATEk+GAhTHORo71fyneSP9P9qMn3UerviOf7NGd +BJZucIhWc/Lf8Rajs3fDgfCNASIhBgNoJPCsYK7W8aMlb4gZBGn21yVePY5BxXcj +OqA+C7nTAAAAAKsJIFPv2JrDH0BB1bTUW6d0dXFHOt62sZM7xFDAJfs3CsGYnZLj +b1Fc85tTYwytStk7HE2JUa6JOBQeomt54pvekSqMw8dFIEEidjLBfoCUC9X1VdUF +jaIDmypkaQPKyiboBQ== +=DJBR +-----END PGP PRIVATE KEY BLOCK----- From 15af3866f324996a3c1d2d3e1b962800d0ac75c4 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Sun, 25 May 2025 15:16:23 +0200 Subject: [PATCH 15/22] Backport tests for v6-ed25519 keys Turns out the key / fingerprint length check isn't here yet. (backported from commit aa85c489c8e131b146a3cd4bda25ce37879c71c9) --- tests/rpmsigdig.at | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index 146da43e92..f7fd2fcd01 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -1612,3 +1612,31 @@ rpm -qp --qf "[%{filenames}:%{filesignatures}\n]" hello-2.0-1.x86_64-badima.rpm ], []) RPMTEST_CLEANUP + +AT_SETUP([openpgp v6 keys and signatures]) +AT_KEYWORDS([rpmsign sequoia signature v6]) +AT_SKIP_IF([test x$PGP = xdummy]) +RPMDB_INIT + +RPMTEST_CHECK([ +runroot rpmkeys --import /data/keys/rpm.org-v6-ed25519-test.asc +], +[0], +[], +[]) + +RPMTEST_CHECK([ +runroot rpmkeys --list +], +[0], +[ac60aed6-682474ea: v6-ed25519-testkey public key +], +[]) + +RPMTEST_CHECK([ +runroot rpmkeys --delete ac60aed6-682474ea +], +[0], +[], +[]) +RPMTEST_CLEANUP From 5cb15850bb48bd6603c79cfa5514d09ac282f7eb Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Mon, 26 May 2025 11:40:38 +0200 Subject: [PATCH 16/22] Fix v6 signatures on v6 packages tests --- tests/rpmsigdig.at | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index f7fd2fcd01..4b8a2419bc 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -1310,26 +1310,30 @@ runroot rpmkeys --import /data/keys/*.pub [ignore]) RPMTEST_CHECK([ -runroot rpmbuild -bb --quiet \ - --define "_rpmfilever 6" \ - /data/SPECS/attrtest.spec -runroot rpmsign --addsign /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm > /dev/null +runroot rpmsign --addsign /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 > /dev/null ], [0], [], [ignore]) RPMTEST_CHECK([ -runroot rpmkeys -K /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm +runroot rpmkeys -K /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 ], [0], -[/build/RPMS/noarch/attrtest-1.0-1.noarch.rpm: digests signatures OK +[/data/RPMS/attrtest-1.0-1.noarch.rpm-v6: digests signatures OK ], []) +RPMTEST_CHECK([ +runroot_other ${RPM_CONFIGDIR_PATH}/rpmdump /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 > /dev/null +], +[0], +[], +[]) + RPMTEST_CHECK([ for t in DSAHEADER RSAHEADER SIGGPG SIGPGP OPENPGP; do - runroot rpm -qp --qf "$t: %{$t}\n" /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm | grep \(none\) + runroot rpm -qp --qf "$t: %{$t}\n" /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 | grep \(none\) done ], [ignore], @@ -1343,23 +1347,23 @@ SIGPGP: (none) RPMTEST_CHECK([ runroot rpmsign --resign --rpmv4 \ --key-id E8A62C0512B06B5D2183BA207F1C21F95F65BBE8 \ - /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm > /dev/null + /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 > /dev/null ], [0], [], [ignore]) RPMTEST_CHECK([ -runroot rpmkeys -K /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm +runroot rpmkeys -K /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 ], [0], -[/build/RPMS/noarch/attrtest-1.0-1.noarch.rpm: digests signatures OK +[/data/RPMS/attrtest-1.0-1.noarch.rpm-v6: digests signatures OK ], []) RPMTEST_CHECK([ for t in DSAHEADER RSAHEADER SIGGPG SIGPGP OPENPGP; do - runroot rpm -qp --qf "$t: %{$t}\n" /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm | grep \(none\) + runroot rpm -qp --qf "$t: %{$t}\n" /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 | grep \(none\) done ], [ignore], From 9f33b79504993f40a6db2db438a9c8135ad12abd Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 26 May 2025 12:04:47 +0300 Subject: [PATCH 17/22] Fix some cases issues in rpmdump signature tag names (cherry picked from commit 1dccba4120b5d873d89eff07b2ea8eef7b7f287c) --- tools/rpmdump.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/rpmdump.c b/tools/rpmdump.c index 329ce5978a..e8ba361ff2 100644 --- a/tools/rpmdump.c +++ b/tools/rpmdump.c @@ -45,9 +45,9 @@ static const char *sigTagName(uint32_t tag) case RPMSIGTAG_LONGARCHIVESIZE: return "Longarchivesize"; case RPMSIGTAG_SHA256: return "Sha256"; case RPMSIGTAG_FILESIGNATURES: return "Filesignatures"; - case RPMSIGTAG_FILESIGNATURELENGTH: return "filesignaturelength"; - case RPMSIGTAG_VERITYSIGNATURES: return "veritysignatures"; - case RPMSIGTAG_VERITYSIGNATUREALGO: return "veritysignaturealgo"; + case RPMSIGTAG_FILESIGNATURELENGTH: return "Filesignaturelength"; + case RPMSIGTAG_VERITYSIGNATURES: return "Veritysignatures"; + case RPMSIGTAG_VERITYSIGNATUREALGO: return "Veritysignaturealgo"; case RPMSIGTAG_RESERVED: return "Reserved"; default: break; From d56980e003fd03bfd7f4439c48dcf34e3366f37f Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 26 May 2025 12:05:33 +0300 Subject: [PATCH 18/22] Teach rpmdump about RPMSIGTAG_OPENPGP Should've been in commit 5630cf4bcbaae85d1b53e7a57ba6c7ed86b62e7d (cherry picked from commit bb028ef5de36b29f4bdd6480269e26455e115a8d) --- tools/rpmdump.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/rpmdump.c b/tools/rpmdump.c index e8ba361ff2..8891b8e36d 100644 --- a/tools/rpmdump.c +++ b/tools/rpmdump.c @@ -48,6 +48,7 @@ static const char *sigTagName(uint32_t tag) case RPMSIGTAG_FILESIGNATURELENGTH: return "Filesignaturelength"; case RPMSIGTAG_VERITYSIGNATURES: return "Veritysignatures"; case RPMSIGTAG_VERITYSIGNATUREALGO: return "Veritysignaturealgo"; + case RPMSIGTAG_OPENPGP: return "Openpgp"; case RPMSIGTAG_RESERVED: return "Reserved"; default: break; From 465b5dbb25139ce949d136142d697043d1c1d30f Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 26 May 2025 12:17:55 +0300 Subject: [PATCH 19/22] Add some signature tag level tests around signing Turns out there are bugs in our signature size reservation handling, the reservation doesn't get used so the header grows when it doesn't need to (see #3768). This means we're now testing for the WRONG size values here, but at least this lets us see that the right tags are there. (cherry picked from commit 1c685659439f23ecea82736c11257c6dc59fe117) --- tests/data/misc/rpmdump4-addsign-v6.txt | 71 +++++++++++++++++++++++++ tests/data/misc/rpmdump4-delsign-v6.txt | 59 ++++++++++++++++++++ tests/data/misc/rpmdump6-addsign-v6.txt | 41 ++++++++++++++ tests/data/misc/rpmdump6-delsign-v6.txt | 35 ++++++++++++ tests/rpmsigdig.at | 40 ++++++++++++++ 5 files changed, 246 insertions(+) create mode 100644 tests/data/misc/rpmdump4-addsign-v6.txt create mode 100644 tests/data/misc/rpmdump4-delsign-v6.txt create mode 100644 tests/data/misc/rpmdump6-addsign-v6.txt create mode 100644 tests/data/misc/rpmdump6-delsign-v6.txt diff --git a/tests/data/misc/rpmdump4-addsign-v6.txt b/tests/data/misc/rpmdump4-addsign-v6.txt new file mode 100644 index 0000000000..cde6913144 --- /dev/null +++ b/tests/data/misc/rpmdump4-addsign-v6.txt @@ -0,0 +1,71 @@ +Signature: +Header magic: 1e8ad8e (reserved: 0) +Index entries: 9 (144 bytes) +Data size: 5172 bytes +Header size: 5316 bytes +Padding: 4 bytes +Region entries 9 +Region size 160 +Dribbles: 0 + +Tag #0 [region] + tagno: 62 (Headersignatures) + type: 7 (blob) + offset: 5156 + count: 16 + + region trailer + tagno: 62 (Headersignatures) + type: 7 (blob) + offset: -144 + count: 16 + +Tag #1 [region] + tagno: 268 (Rsa) + type: 7 (blob) + offset: 0 + count: 382 + +Tag #2 [region] + tagno: 269 (Sha1) + type: 6 (string) + offset: 382 + count: 1 + +Tag #3 [region] + tagno: 273 (Sha256) + type: 6 (string) + offset: 423 + count: 1 + +Tag #4 [region] + tagno: 278 (Openpgp) + type: 8 (argv) + offset: 488 + count: 1 + +Tag #5 [region] + tagno: 1000 (Size) + type: 4 (int32) + offset: 1004 + count: 1 + +Tag #6 [region] + tagno: 1004 (Md5) + type: 7 (blob) + offset: 1008 + count: 16 + +Tag #7 [region] + tagno: 1007 (Payloadsize) + type: 4 (int32) + offset: 1024 + count: 1 + +Tag #8 [region] + tagno: 1008 (Reservedspace) + type: 7 (blob) + offset: 1028 + count: 4128 + +Header: diff --git a/tests/data/misc/rpmdump4-delsign-v6.txt b/tests/data/misc/rpmdump4-delsign-v6.txt new file mode 100644 index 0000000000..b87360536f --- /dev/null +++ b/tests/data/misc/rpmdump4-delsign-v6.txt @@ -0,0 +1,59 @@ +Signature: +Header magic: 1e8ad8e (reserved: 0) +Index entries: 7 (112 bytes) +Data size: 4276 bytes +Header size: 4388 bytes +Padding: 4 bytes +Region entries 7 +Region size 128 +Dribbles: 0 + +Tag #0 [region] + tagno: 62 (Headersignatures) + type: 7 (blob) + offset: 4260 + count: 16 + + region trailer + tagno: 62 (Headersignatures) + type: 7 (blob) + offset: -112 + count: 16 + +Tag #1 [region] + tagno: 269 (Sha1) + type: 6 (string) + offset: 0 + count: 1 + +Tag #2 [region] + tagno: 273 (Sha256) + type: 6 (string) + offset: 41 + count: 1 + +Tag #3 [region] + tagno: 1000 (Size) + type: 4 (int32) + offset: 108 + count: 1 + +Tag #4 [region] + tagno: 1004 (Md5) + type: 7 (blob) + offset: 112 + count: 16 + +Tag #5 [region] + tagno: 1007 (Payloadsize) + type: 4 (int32) + offset: 128 + count: 1 + +Tag #6 [region] + tagno: 1008 (Reservedspace) + type: 7 (blob) + offset: 132 + count: 4128 + +Header: diff --git a/tests/data/misc/rpmdump6-addsign-v6.txt b/tests/data/misc/rpmdump6-addsign-v6.txt new file mode 100644 index 0000000000..5e690065df --- /dev/null +++ b/tests/data/misc/rpmdump6-addsign-v6.txt @@ -0,0 +1,41 @@ +Signature: +Header magic: 1e8ad8e (reserved: 0) +Index entries: 4 (64 bytes) +Data size: 4722 bytes +Header size: 4786 bytes +Padding: 6 bytes +Region entries 4 +Region size 80 +Dribbles: 0 + +Tag #0 [region] + tagno: 62 (Headersignatures) + type: 7 (blob) + offset: 4706 + count: 16 + + region trailer + tagno: 62 (Headersignatures) + type: 7 (blob) + offset: -64 + count: 16 + +Tag #1 [region] + tagno: 273 (Sha256) + type: 6 (string) + offset: 0 + count: 1 + +Tag #2 [region] + tagno: 278 (Openpgp) + type: 8 (argv) + offset: 65 + count: 1 + +Tag #3 [region] + tagno: 999 (Reserved) + type: 7 (blob) + offset: 578 + count: 4128 + +Header: diff --git a/tests/data/misc/rpmdump6-delsign-v6.txt b/tests/data/misc/rpmdump6-delsign-v6.txt new file mode 100644 index 0000000000..e2abe015c6 --- /dev/null +++ b/tests/data/misc/rpmdump6-delsign-v6.txt @@ -0,0 +1,35 @@ +Signature: +Header magic: 1e8ad8e (reserved: 0) +Index entries: 3 (48 bytes) +Data size: 4209 bytes +Header size: 4257 bytes +Padding: 7 bytes +Region entries 3 +Region size 64 +Dribbles: 0 + +Tag #0 [region] + tagno: 62 (Headersignatures) + type: 7 (blob) + offset: 4193 + count: 16 + + region trailer + tagno: 62 (Headersignatures) + type: 7 (blob) + offset: -48 + count: 16 + +Tag #1 [region] + tagno: 273 (Sha256) + type: 6 (string) + offset: 0 + count: 1 + +Tag #2 [region] + tagno: 999 (Reserved) + type: 7 (blob) + offset: 65 + count: 4128 + +Header: diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index 4b8a2419bc..99278f3565 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -1199,6 +1199,15 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], []) +# XXX the reserve tag size is currently WRONG here due to #3768 +RPMTEST_CHECK([ +cp /data/misc/rpmdump4-addsign-v6.txt expout +runroot ${RPM_CONFIGDIR_PATH}/rpmdump /tmp/hello-2.0-1.x86_64.rpm | sed -n '/^Signature:$/,/^Header:$/p' +], +[0], +[expout], +[]) + RPMTEST_CHECK([ # resigning with identical key shouldn't add anything runroot rpmsign --addsign --rpmv6 /tmp/hello-2.0-1.x86_64.rpm &> /dev/null @@ -1288,6 +1297,13 @@ runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm ], []) +RPMTEST_CHECK([ +cp /data/misc/rpmdump4-delsign-v6.txt expout +runroot ${RPM_CONFIGDIR_PATH}/rpmdump /tmp/hello-2.0-1.x86_64.rpm | sed -n '/^Signature:$/,/^Header:$/p' +], +[0], +[expout], +[]) RPMTEST_CLEANUP AT_SETUP([rpmsign --addsign multisig v6]) @@ -1331,6 +1347,15 @@ runroot_other ${RPM_CONFIGDIR_PATH}/rpmdump /data/RPMS/attrtest-1.0-1.noarch.rpm [], []) +# XXX the reserve tag size is currently WRONG here due to #3768 +RPMTEST_CHECK([ +cp /data/misc/rpmdump6-addsign-v6.txt expout +runroot ${RPM_CONFIGDIR_PATH}/rpmdump /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm| sed -n '/^Signature:$/,/^Header:$/p' +], +[0], +[expout], +[]) + RPMTEST_CHECK([ for t in DSAHEADER RSAHEADER SIGGPG SIGPGP OPENPGP; do runroot rpm -qp --qf "$t: %{$t}\n" /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 | grep \(none\) @@ -1372,6 +1397,21 @@ SIGGPG: (none) SIGPGP: (none) ], []) + +RPMTEST_CHECK([ +runroot rpmsign --delsign /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm +], +[0], +[], +[]) + +RPMTEST_CHECK([ +cp /data/misc/rpmdump6-delsign-v6.txt expout +runroot ${RPM_CONFIGDIR_PATH}/rpmdump /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm| sed -n '/^Signature:$/,/^Header:$/p' +], +[0], +[expout], +[]) RPMTEST_CLEANUP # ------------------------------ From 15d9bb55efb71b5dc4521d4f304ccee0809e94a1 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Mon, 26 May 2025 15:05:22 +0200 Subject: [PATCH 20/22] Fix v6 test cases --- tests/rpmsigdig.at | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index 99278f3565..f5afeb8339 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -1350,7 +1350,7 @@ runroot_other ${RPM_CONFIGDIR_PATH}/rpmdump /data/RPMS/attrtest-1.0-1.noarch.rpm # XXX the reserve tag size is currently WRONG here due to #3768 RPMTEST_CHECK([ cp /data/misc/rpmdump6-addsign-v6.txt expout -runroot ${RPM_CONFIGDIR_PATH}/rpmdump /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm| sed -n '/^Signature:$/,/^Header:$/p' +runroot ${RPM_CONFIGDIR_PATH}/rpmdump /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 | sed -n '/^Signature:$/,/^Header:$/p' ], [0], [expout], @@ -1399,15 +1399,16 @@ SIGPGP: (none) []) RPMTEST_CHECK([ -runroot rpmsign --delsign /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm +runroot rpmsign --delsign /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 ], [0], -[], +[/data/RPMS/attrtest-1.0-1.noarch.rpm-v6: +], []) RPMTEST_CHECK([ cp /data/misc/rpmdump6-delsign-v6.txt expout -runroot ${RPM_CONFIGDIR_PATH}/rpmdump /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm| sed -n '/^Signature:$/,/^Header:$/p' +runroot ${RPM_CONFIGDIR_PATH}/rpmdump /data/RPMS/attrtest-1.0-1.noarch.rpm-v6 | sed -n '/^Signature:$/,/^Header:$/p' ], [0], [expout], From 021957b7bdda6bb5be9540f3d6013c6b19852aa7 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Thu, 15 May 2025 14:50:57 +0300 Subject: [PATCH 21/22] Fix rpm v6 signing with algorithms not supported by rpm v4 signatures Adding an rpm v6 signature fails with a message such as "error: Unsupported OpenPGP pubkey algorithm 27" if the algorithm isn't supported by rpm v4 signatures. The issue here seems simple enough: makeSigTag() assumes there'll always be a legacy tag to map to, but that's not the case with new algorithms such as those added in RFC-9580. Only, this tiny thing causes a bit of an avalance: we need to move the tag decision logic to putSignature(), but to do that we also need to move the check for identical signatures there, and to do that we need to pay more attention to putSignature() retuns. And then we can finally make the decisions we need, where we need them: When adding an rpm v4 signature, suppress the error from an "unknown" algorithm if we already added an rpm v6 signature for it in the same run. Add tests to the extent we can, rpm-sequoia 1.8 doesn't fully handle OpenPGP v6 it seems: https://github.com/rpm-software-management/rpm-sequoia/issues/87 Fixes: #3752 (cherry picked from commit ad114b0174c26fa101ce9bbf82930b2c2e421a09) --- sign/rpmgensig.c | 96 ++++++++++++++++++++++++++-------------------- tests/rpmsigdig.at | 68 ++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 42 deletions(-) diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index 02599398ff..a99d8e7a39 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -131,13 +131,11 @@ static int copyFile(FD_t *sfdp, const char *sfnp, } /* Wrap a raw signature in an rpmtd and sanity check, return NULL on fail */ -static rpmtd makeSigTag(int ishdr, uint8_t *pkt, size_t pktlen) +static rpmtd makeSigTag(uint8_t *pkt, size_t pktlen) { pgpDigParams sigp = NULL; - rpmTagVal sigtag; rpmtd sigtd = NULL; unsigned int hash_algo; - unsigned int pubkey_algo; int ver; if (pgpPrtParams(pkt, pktlen, PGPTAG_SIGNATURE, &sigp)) { @@ -151,23 +149,6 @@ static rpmtd makeSigTag(int ishdr, uint8_t *pkt, size_t pktlen) goto exit; } - pubkey_algo = pgpDigParamsAlgo(sigp, PGPVAL_PUBKEYALGO); - switch (pubkey_algo) { - case PGPPUBKEYALGO_DSA: - case PGPPUBKEYALGO_ECDSA: - case PGPPUBKEYALGO_EDDSA: - sigtag = ishdr ? RPMSIGTAG_DSA : RPMSIGTAG_GPG; - break; - case PGPPUBKEYALGO_RSA: - sigtag = ishdr ? RPMSIGTAG_RSA : RPMSIGTAG_PGP; - break; - default: - rpmlog(RPMLOG_ERR, _("Unsupported OpenPGP pubkey algorithm %u\n"), - pubkey_algo); - goto exit; - break; - } - ver = pgpDigParamsVersion(sigp); if (ver < 4) { rpmlog(RPMLOG_WARNING, _("Deprecated OpenPGP signature version %d\n"), @@ -176,12 +157,12 @@ static rpmtd makeSigTag(int ishdr, uint8_t *pkt, size_t pktlen) /* Looks sane, create the tag data */ sigtd = rpmtdNew(); - sigtd->tag = sigtag; sigtd->flags |= RPMTD_ALLOCED; sigtd->count = pktlen; sigtd->data = memcpy(xmalloc(pktlen), pkt, pktlen);; - sigtd->tag = sigtag; sigtd->type = RPM_BIN_TYPE; + /* Hack: the actual tag gets decided in putSignature() based on this */ + sigtd->tag = pgpDigParamsAlgo(sigp, PGPVAL_PUBKEYALGO); exit: pgpDigParamsFree(sigp); @@ -317,7 +298,7 @@ static int runGPG(sigTarget sigt, const char *sigfile) } /* Generate an OpenPGP signature(s) for a target */ -static rpmtd makeGPGSignature(int ishdr, sigTarget sigt) +static rpmtd makeGPGSignature(sigTarget sigt) { char * sigfile = rstrscat(NULL, sigt->fileName, ".sig", NULL); struct stat st; @@ -355,7 +336,7 @@ static rpmtd makeGPGSignature(int ishdr, sigTarget sigt) rpmlog(RPMLOG_DEBUG, "Got %zd bytes of OpenPGP sig\n", pktlen); /* Parse the signature, change signature tag as appropriate. */ - sigtd = makeSigTag(ishdr, pkt, pktlen); + sigtd = makeSigTag(pkt, pktlen); exit: (void) unlink(sigfile); free(sigfile); @@ -402,10 +383,8 @@ static int haveSignature(rpmtd sigtd, Header sigh) { struct rpmtd_s oldtd; int rc = 0; /* assume no */ - rpmTagVal tag = headerIsEntry(sigh, RPMSIGTAG_RESERVED) ? - RPMTAG_OPENPGP : sigtd->tag; - if (!headerGet(sigh, tag, &oldtd, HEADERGET_DEFAULT)) + if (!headerGet(sigh, sigtd->tag, &oldtd, HEADERGET_DEFAULT)) return rc; pgpDigParams newsig = tdParams(sigtd); @@ -421,9 +400,11 @@ static int haveSignature(rpmtd sigtd, Header sigh) return rc; } -static int putSignature(Header sigh, rpmtd sigtd, int multisig) +static int putSignature(Header sigh, rpmtd sigtd, int multisig, int ishdr, + rpmSignFlags flags) { - int rc = 1; + int rc = -1; + if (multisig) { char *b64 = rpmBase64Encode(sigtd->data, sigtd->count, 0); char **arr = (char **)xmalloc(1 * sizeof(*arr)); @@ -438,11 +419,48 @@ static int putSignature(Header sigh, rpmtd sigtd, int multisig) .ix = -1, .size = 0, }; - rc = (headerPut(sigh, &mtd, HEADERPUT_APPEND) == 0); + if (haveSignature(&mtd, sigh)) { + rc = 1; + } else { + rc = (headerPut(sigh, &mtd, HEADERPUT_APPEND) == 0) ? -1 : 0; + } rpmtdFreeData(&mtd); } else { - rc = (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0); + unsigned int pubkey_algo = sigtd->tag; + uint32_t sigtag = 0; + switch (pubkey_algo) { + case PGPPUBKEYALGO_DSA: + case PGPPUBKEYALGO_ECDSA: + case PGPPUBKEYALGO_EDDSA: + sigtag = ishdr ? RPMSIGTAG_DSA : RPMSIGTAG_GPG; + break; + case PGPPUBKEYALGO_RSA: + sigtag = ishdr ? RPMSIGTAG_RSA : RPMSIGTAG_PGP; + break; + default: + break; + } + + if (sigtag) { + sigtd->tag = sigtag; + if (haveSignature(sigtd, sigh)) { + rc = 1; + } else { + rc = (headerPut(sigh, sigtd, HEADERPUT_DEFAULT) == 0) ? -1 : 0; + } + sigtd->tag = pubkey_algo; + } else { + /* If we did a v6 signature, we can ignore the error here */ + if (flags & RPMSIGN_FLAG_RPMV6) { + rc = 0; + } else { + rpmlog(RPMLOG_ERR, + _("Unsupported OpenPGP pubkey algorithm %u for rpm v3/v4 signatures\n"), + pubkey_algo); + } + } } + return rc; } @@ -459,23 +477,17 @@ static int addSignature(Header sigh, rpmSignFlags flags, rpmtd sigtd = NULL; /* Make a header signature */ - if ((sigtd = makeGPGSignature(1, sigt_v4)) == NULL) - goto exit; - - /* See if we already have a signature by the same key and parameters */ - if (haveSignature(sigtd, sigh)) { - rc = 1; + if ((sigtd = makeGPGSignature(sigt_v4)) == NULL) goto exit; - } /* Add a v6 signature if requested */ if (flags & RPMSIGN_FLAG_RPMV6) - if (putSignature(sigh, sigtd, 1)) + if ((rc = putSignature(sigh, sigtd, 1, 1, flags))) goto exit; /* Add a v4 signature if requested */ if (flags & RPMSIGN_FLAG_RPMV4) { - if (putSignature(sigh, sigtd, 0)) + if ((rc = putSignature(sigh, sigtd, 0, 1, flags))) goto exit; /* Only consider v3 signature if also adding v4 */ @@ -483,10 +495,10 @@ static int addSignature(Header sigh, rpmSignFlags flags, rpmtdFree(sigtd); /* Assume the same signature test holds for v3 signature too */ - if ((sigtd = makeGPGSignature(0, sigt_v3)) == NULL) + if ((sigtd = makeGPGSignature(sigt_v3)) == NULL) goto exit; - if (putSignature(sigh, sigtd, 0)) + if ((rc = putSignature(sigh, sigtd, 0, 0, flags))) goto exit; } } diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index f5afeb8339..e0d0e0dd10 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -1663,6 +1663,58 @@ AT_KEYWORDS([rpmsign sequoia signature v6]) AT_SKIP_IF([test x$PGP = xdummy]) RPMDB_INIT +RPMTEST_CHECK([ +cat << EOF > ${HOME}/.config/rpm/macros +%_openpgp_sign sq +%_openpgp_sign_id 036824F0AC60AED6F1A3256F88190469F6D7255E3D8E41C577233AA03E0BB9D3 +%_sq_path ${HOME}/.config/rpm/sq +EOF + +runroot sq --home ${HOME}/.config/rpm/sq key import /data/keys/*v6*.secret +], +[0], +[ignore], +[ignore]) + +RPMTEST_CHECK([ +cp "${RPMTEST}"/data/RPMS/hello-2.0-1.x86_64.rpm "${RPMTEST}"/tmp/ +runroot rpmsign --addsign /tmp/hello-2.0-1.x86_64.rpm +], +[1], +[], +[error: Unsupported OpenPGP pubkey algorithm 27 for rpm v3/v4 signatures +]) + +RPMTEST_CHECK([ +runroot rpmsign --addsign --rpmv6 /tmp/hello-2.0-1.x86_64.rpm +], +[0], +[], +[]) + +# The test reflects what I *assume* this should return as v6 key ids are the +# first 64 bits of the fingerprint, but this is very cursory skim through +# rfc-9580 and might not be right. What we're currently getting as the +# signer key is the last 64bit as with v4 keys, and when this doesn't match +# with what we get from the subkey ids, rpm does not find the key. +# In addition, rpm-sequoia 1.8 doesn't handle the v6 trailer so it's BAD +# instead of NOKEY. +# Header OpenPGP V6 Ed25519/SHA512 signature, key ID 0e00df3ed2d7b65e: BAD +#RPMTEST_CHECK([ +#runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +#], +#[0], +#[/tmp/hello-2.0-1.x86_64.rpm: +# Header OpenPGP V6 Ed25519/SHA512 signature, key ID 6118abe481c41473: NOKEY +# Header OpenPGP RSA signature: NOTFOUND +# Header OpenPGP DSA signature: NOTFOUND +# Header SHA256 digest: OK +# Payload SHA256 digest: OK +# Legacy OpenPGP RSA signature: NOTFOUND +# Legacy OpenPGP DSA signature: NOTFOUND +#], +#[]) + RPMTEST_CHECK([ runroot rpmkeys --import /data/keys/rpm.org-v6-ed25519-test.asc ], @@ -1678,6 +1730,22 @@ runroot rpmkeys --list ], []) +# This is currently failing, see the NOKEY case above +#RPMTEST_CHECK([ +#runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64.rpm +#], +#[0], +#[/tmp/hello-2.0-1.x86_64.rpm: +# Header OpenPGP V6 Ed25519/SHA512 signature, key fingerprint 036824f0ac60aed6f1a3256f88190469f6d7255e3d8e41c577233aa03e0bb9d3 OK +# Header OpenPGP RSA signature: NOTFOUND +# Header OpenPGP DSA signature: NOTFOUND +# Header SHA256 digest: OK +# Payload SHA256 digest: OK +# Legacy OpenPGP RSA signature: NOTFOUND +# Legacy OpenPGP DSA signature: NOTFOUND +#], +#[]) + RPMTEST_CHECK([ runroot rpmkeys --delete ac60aed6-682474ea ], From 0e9c2f9067438c93f4e7394c819a451c4b7c2cc4 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Tue, 3 Jun 2025 08:07:13 +0200 Subject: [PATCH 22/22] Fix test case --- tests/rpmsigdig.at | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index e0d0e0dd10..8e675d467a 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -1664,13 +1664,14 @@ AT_SKIP_IF([test x$PGP = xdummy]) RPMDB_INIT RPMTEST_CHECK([ -cat << EOF > ${HOME}/.config/rpm/macros -%_openpgp_sign sq -%_openpgp_sign_id 036824F0AC60AED6F1A3256F88190469F6D7255E3D8E41C577233AA03E0BB9D3 +RPM_DOCDIR=$(runroot rpm --eval '%_defaultdocdir') +cat "${RPMTEST}${RPM_DOCDIR}/rpm/macros.rpmsign-sequoia" >> ${HOME}/.rpmmacros +cat << EOF >> ${HOME}/.rpmmacros +%_gpg_name 036824F0AC60AED6F1A3256F88190469F6D7255E3D8E41C577233AA03E0BB9D3 %_sq_path ${HOME}/.config/rpm/sq EOF -runroot sq --home ${HOME}/.config/rpm/sq key import /data/keys/*v6*.secret +runroot_other sq key import /data/keys/*v6*.secret ], [0], [ignore], @@ -1681,7 +1682,8 @@ cp "${RPMTEST}"/data/RPMS/hello-2.0-1.x86_64.rpm "${RPMTEST}"/tmp/ runroot rpmsign --addsign /tmp/hello-2.0-1.x86_64.rpm ], [1], -[], +[/tmp/hello-2.0-1.x86_64.rpm: +], [error: Unsupported OpenPGP pubkey algorithm 27 for rpm v3/v4 signatures ]) @@ -1689,7 +1691,8 @@ RPMTEST_CHECK([ runroot rpmsign --addsign --rpmv6 /tmp/hello-2.0-1.x86_64.rpm ], [0], -[], +[/tmp/hello-2.0-1.x86_64.rpm: +], []) # The test reflects what I *assume* this should return as v6 key ids are the