diff options
author | Demi Marie Obenour <demi@invisiblethingslab.com> | 2021-03-16 22:12:05 -0400 |
---|---|---|
committer | Michal Domonkos <mdomonko@redhat.com> | 2022-07-01 10:52:14 +0200 |
commit | cb7f454b48017f5d21818b163a208f3c83daf9d9 (patch) | |
tree | 0c48b92faa7213527ea6bea016b5833612f23827 | |
parent | 824f62a08a6a93b41b5dfb92501518e9378244fc (diff) | |
download | rpm-cb7f454b48017f5d21818b163a208f3c83daf9d9.tar.gz |
Header signatures alone are not sufficient
This fixes how RPM handles packages that contain a header signature, but
neither header+payload signature nor payload digests. Such packages are
obviously not properly signed, but RPM previously accepted them.
This could be used to confuse both ‘rpmkeys -K’ and old versions of DNF.
Both would report that the package has been properly signed even when it
has not. The included regression tests demonstrates the change in
behavior.
(cherry picked from commit 0e9f6fdc63f09ebd00516e6f2f46a7297b743bcd)
-rw-r--r-- | lib/rpmvs.c | 14 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm | bin | 0 -> 3216 bytes | |||
-rw-r--r-- | tests/rpmsigdig.at | 40 |
4 files changed, 52 insertions, 3 deletions
diff --git a/lib/rpmvs.c b/lib/rpmvs.c index 20a3e28a2..88f2b200f 100644 --- a/lib/rpmvs.c +++ b/lib/rpmvs.c @@ -451,7 +451,7 @@ int rpmvsVerify(struct rpmvs_s *sis, int type, { int failed = 0; int cont = 1; - int range = 0; + int range = 0, vfylevel = sis->vfylevel; int verified[3] = { 0, 0, 0 }; /* sort for consistency and rough "better comes first" semantics*/ @@ -478,6 +478,14 @@ int rpmvsVerify(struct rpmvs_s *sis, int type, } } + /* Unconditionally reject partially signed packages */ + if (verified[RPMSIG_SIGNATURE_TYPE]) + vfylevel |= RPMSIG_SIGNATURE_TYPE; + + /* Cannot verify payload if RPMVSF_NEEDPAYLOAD is set */ + if (sis->vsflags & RPMVSF_NEEDPAYLOAD) + range &= ~RPMSIG_PAYLOAD; + for (int i = 0; i < sis->nsigs && cont; i++) { struct rpmsinfo_s *sinfo = &sis->sigs[i]; int strength = (sinfo->type | sinfo->strength); @@ -490,11 +498,11 @@ int rpmvsVerify(struct rpmvs_s *sis, int type, sinfo->rc = RPMRC_NOTFOUND; } - if (sis->vfylevel & strength & RPMSIG_DIGEST_TYPE) { + if (vfylevel & strength & RPMSIG_DIGEST_TYPE) { int missing = (range & ~verified[RPMSIG_DIGEST_TYPE]); required |= (missing & sinfo->range); } - if (sis->vfylevel & strength & RPMSIG_SIGNATURE_TYPE) { + if (vfylevel & strength & RPMSIG_SIGNATURE_TYPE) { int missing = (range & ~verified[RPMSIG_SIGNATURE_TYPE]); required |= (missing & sinfo->range); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 0840075fb..c66e801da 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -103,6 +103,7 @@ EXTRA_DIST += data/RPMS/hello-2.0-1.x86_64.rpm EXTRA_DIST += data/RPMS/hello-2.0-1.x86_64-signed.rpm EXTRA_DIST += data/RPMS/hlinktest-1.0-1.noarch.rpm EXTRA_DIST += data/RPMS/imatest-1.0-1.fc34.noarch.rpm +EXTRA_DIST += data/RPMS/hello-2.0-1.x86_64-corrupted.rpm EXTRA_DIST += data/SRPMS/foo-1.0-1.src.rpm EXTRA_DIST += data/SRPMS/hello-1.0-1.src.rpm EXTRA_DIST += data/SOURCES/hello.c diff --git a/tests/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm b/tests/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm Binary files differnew file mode 100644 index 000000000..2a6173ba0 --- /dev/null +++ b/tests/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index d60c58869..f8373c640 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -445,12 +445,52 @@ runroot rpmkeys -Kv /tmp/${pkg} Payload SHA256 digest: BAD (Expected 84a7338287bf19715c4eed0243f5cdb447eeb0ade37b2af718d4060aefca2f7c != bea903609dceac36e1f26a983c493c98064d320fdfeb423034ed63d649b2c8dc) Payload SHA256 ALT digest: NOTFOUND V4 RSA/SHA256 Signature, key ID 1964c5fc: BAD + DSA signature: NOTFOUND MD5 digest: BAD (Expected 137ca1d8b35cca02a1854ba301c5432e != d662cd0d81601a7107312684ad1ddf38) ], []) AT_CLEANUP # ------------------------------ +# Test pre-built corrupted package verification (corrupted payload) +AT_SETUP([rpmkeys -Kv <corrupted signed> 4]) +AT_KEYWORDS([rpmkeys digest signature]) +AT_CHECK([ +RPMDB_INIT[( + +dorpm () { + runroot rpmkeys --define '_pkgverify_level digest' \ + --define '_pkgverify_flags 0x10000' "$1" \ + /data/RPMS/hello-2.0-1.x86_64-corrupted.rpm + [ "$?" -eq 1 ] || exit 1 +} + +dorpm -K +dorpm -Kv +runroot rpmkeys --import /data/keys/rpm.org-rsa-2048-test.pub +dorpm -K +dorpm -Kv +)]], +[0], +[[/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm: digests SIGNATURES NOT OK +/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm: + Header V4 RSA/SHA256 Signature, key ID 1964c5fc: NOKEY + Header SHA256 digest: OK + MD5 digest: OK +/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm: DIGESTS SIGNATURES NOT OK +/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm: + Header V4 RSA/SHA256 Signature, key ID 1964c5fc: OK + Header SHA256 digest: OK + Payload SHA256 digest: NOTFOUND + Payload SHA256 ALT digest: NOTFOUND + RSA signature: NOTFOUND + DSA signature: NOTFOUND + MD5 digest: OK +]], +[]) +AT_CLEANUP + +# ------------------------------ # Test --addsign AT_SETUP([rpmsign --addsign]) AT_KEYWORDS([rpmsign signature]) |