summaryrefslogtreecommitdiff
path: root/rpmio
diff options
context:
space:
mode:
authorDemi Marie Obenour <demi@invisiblethingslab.com>2022-03-03 23:34:01 -0500
committerPanu Matilainen <pmatilai@redhat.com>2022-11-03 09:43:17 +0200
commitec13083f46a1efe8700925538b4f98dc45af93bc (patch)
tree41dd16a02263e8d5302a9d7dc42fc998bf707898 /rpmio
parent752ed08d1026aeb4aa1716f32064453005e12d5e (diff)
downloadrpm-ec13083f46a1efe8700925538b4f98dc45af93bc.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().
Diffstat (limited to 'rpmio')
-rw-r--r--rpmio/rpmpgp_internal.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/rpmio/rpmpgp_internal.c b/rpmio/rpmpgp_internal.c
index 8d0d76869..e2615a22c 100644
--- a/rpmio/rpmpgp_internal.c
+++ b/rpmio/rpmpgp_internal.c
@@ -1152,7 +1152,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;
}