summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDemi Marie Obenour <demi@invisiblethingslab.com>2021-03-16 22:12:05 -0400
committerMichal Domonkos <mdomonko@redhat.com>2022-07-01 10:52:14 +0200
commitcb7f454b48017f5d21818b163a208f3c83daf9d9 (patch)
tree0c48b92faa7213527ea6bea016b5833612f23827
parent824f62a08a6a93b41b5dfb92501518e9378244fc (diff)
downloadrpm-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.c14
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/data/RPMS/hello-2.0-1.x86_64-corrupted.rpmbin0 -> 3216 bytes
-rw-r--r--tests/rpmsigdig.at40
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
new file mode 100644
index 000000000..2a6173ba0
--- /dev/null
+++ b/tests/data/RPMS/hello-2.0-1.x86_64-corrupted.rpm
Binary files differ
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])