summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDemi Marie Obenour <demi@invisiblethingslab.com>2022-03-03 23:34:01 -0500
committerMichal Domonkos <mdomonko@redhat.com>2023-03-13 15:32:25 +0100
commit1423ff3b43b12da7fef8c3fc82f0e47af2ff9122 (patch)
tree740a932a05099f857f1664a7970ec3da4467c5d2
parentf97c3992d28766a139ba806d9375b0e18e6ea2ea (diff)
downloadrpm-1423ff3b43b12da7fef8c3fc82f0e47af2ff9122.tar.gz
Avoid type confusion when verifying signatures
In RPM, both signatures and public keys are stored as heap-allocated opaque structs. The type of the struct is determined by whether this is a signature or a key and by the public-key algorithm in the associated pgpDigParams_s struct. However, when verifying a signature, RPM did not check that the signature and public key used the same public-key algorithm. If they did not, the signature verification code will interpret a pointer to the struct specified by the public key’s public-key algorithm as a pointer to the struct specified by the signature’s public-key algorithm. This is not a problem when verifying package signatures, as findbySig() (in rpmio/rpmkeyring.c) checks that the public-key algorithms used by the signature and the public key match. If they do not, it returns NULL, causing both rpmKeyringLookup() and rpmKeyringVerifySig() to return RPMRC_NOKEY. However, the code that checks subkey binding signatures does *not* check this, so the type confusion can be triggered when importing a crafted key. This is demonstrated by the included test case, which segfaults when OpenSSL is used as the underlying cryptographic library. Fix the problem by checking that the algorithms match in pgpVerifySignature(). (backported from commit ec13083f46a1efe8700925538b4f98dc45af93bc)
-rw-r--r--rpmio/rpmpgp_internal.c2
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/data/keys/type-confusion.asc29
-rw-r--r--tests/rpmsigdig.at12
4 files changed, 43 insertions, 1 deletions
diff --git a/rpmio/rpmpgp_internal.c b/rpmio/rpmpgp_internal.c
index 19947bed3..964c5fe57 100644
--- a/rpmio/rpmpgp_internal.c
+++ b/rpmio/rpmpgp_internal.c
@@ -1228,7 +1228,7 @@ rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx)
if (key && key->alg) {
pgpDigAlg sa = sig->alg;
pgpDigAlg ka = key->alg;
- if (sa && sa->verify) {
+ if (sa && sa->verify && sig->pubkey_algo == key->pubkey_algo) {
if (sa->verify(ka, sa, hash, hashlen, sig->hash_algo) == 0) {
res = RPMRC_OK;
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5094a02ed..d0188c9b6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -129,6 +129,7 @@ EXTRA_DIST += data/keys/CVE-2021-3521-badbind.asc
EXTRA_DIST += data/keys/CVE-2021-3521-nosubsig.asc
EXTRA_DIST += data/keys/CVE-2021-3521-nosubsig-last.asc
EXTRA_DIST += data/keys/different-creation-times.asc
+EXTRA_DIST += data/keys/type-confusion.asc
EXTRA_DIST += data/keys/different-creation-times.secret
EXTRA_DIST += data/keys/neal.pgp
EXTRA_DIST += data/sigs/neal-hi.pgp
diff --git a/tests/data/keys/type-confusion.asc b/tests/data/keys/type-confusion.asc
new file mode 100644
index 000000000..e9099b32a
--- /dev/null
+++ b/tests/data/keys/type-confusion.asc
@@ -0,0 +1,29 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: rpm-4.17.90 (NSS-3)
+
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAGI7wQYFgoAIBYhBE4a4toFRMSN
+eB4aItofX/zLIgMfBQJiF/h6AhsCAIEJENofX/zLIgMfdiAEGRYKAB0WIQTc1zsT
+3tx9EJeerHXL9SUWmxSfwgUCYhf4egAKCRDL9SUWmxSfwrjXAPwJf7n8qpEvee1/
+wCFr0XwObuhOZ+vBZeubWyEpWe/XqwEA1WCah/7cgAhYf4u1V7Ciel0kQskE0aAO
+vtJE/EZqCwgauwEA14PxZWyO0PrU8AeKR2U/A9jM/81SpWjNMT7X52UYFmgBAL3G
+aEXFIC5STG9Qsopdt1vfoExOCG5Ewg7CWOeLF9EB
+=ch+A
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at
index 586058c97..17cec56ff 100644
--- a/tests/rpmsigdig.at
+++ b/tests/rpmsigdig.at
@@ -426,6 +426,18 @@ gpg(a72b7d4f62837bea) = 4:a72b7d4f62837bea-62553e62
[])
AT_CLEANUP
+AT_SETUP([rpmkeys type confusion])
+AT_CHECK([
+RPMDB_INIT
+
+runroot rpmkeys --import /data/keys/type-confusion.asc
+],
+[1],
+[],
+[error: /data/keys/type-confusion.asc: key 1 import failed.]
+)
+AT_CLEANUP
+
# ------------------------------
# Test pre-built package verification
AT_SETUP([rpmkeys -K <signed> 1])