96 lines
2.7 KiB
Diff
96 lines
2.7 KiB
Diff
From 0a91d1f62d5b6e1cac4d0a7c2ac9f75faad50534 Mon Sep 17 00:00:00 2001
|
|
From: Demi Marie Obenour <demi@invisiblethingslab.com>
|
|
Date: Fri, 9 Apr 2021 13:34:12 -0400
|
|
Subject: [PATCH] Avoid double frees if EVP_PKEY_assign_RSA fails
|
|
|
|
Previously, the bignums would be left as dangling and double-freed.
|
|
---
|
|
rpmio/digest_openssl.c | 32 +++++++++++++++++---------------
|
|
1 file changed, 17 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c
|
|
index 20c272d..02f34a9 100644
|
|
--- a/rpmio/digest_openssl.c
|
|
+++ b/rpmio/digest_openssl.c
|
|
@@ -292,8 +292,8 @@ struct pgpDigKeyRSA_s {
|
|
|
|
BIGNUM *n; /* Common Modulus */
|
|
BIGNUM *e; /* Public Exponent */
|
|
-
|
|
EVP_PKEY *evp_pkey; /* Fully constructed key */
|
|
+ unsigned char immutable; /* if set, this key cannot be mutated */
|
|
};
|
|
|
|
static int constructRSASigningKey(struct pgpDigKeyRSA_s *key)
|
|
@@ -301,33 +301,34 @@ static int constructRSASigningKey(struct pgpDigKeyRSA_s *key)
|
|
if (key->evp_pkey) {
|
|
/* We've already constructed it, so just reuse it */
|
|
return 1;
|
|
- }
|
|
+ } else if (key->immutable)
|
|
+ return 0;
|
|
+ key->immutable = 1;
|
|
|
|
/* Create the RSA key */
|
|
RSA *rsa = RSA_new();
|
|
if (!rsa) return 0;
|
|
|
|
- if (!RSA_set0_key(rsa, key->n, key->e, NULL)) {
|
|
- RSA_free(rsa);
|
|
- return 0;
|
|
- }
|
|
+ if (RSA_set0_key(rsa, key->n, key->e, NULL) <= 0)
|
|
+ goto exit;
|
|
+ key->n = key->e = NULL;
|
|
|
|
/* Create an EVP_PKEY container to abstract the key-type. */
|
|
- key->evp_pkey = EVP_PKEY_new();
|
|
- if (!key->evp_pkey) {
|
|
- RSA_free(rsa);
|
|
- return 0;
|
|
- }
|
|
+ if (!(key->evp_pkey = EVP_PKEY_new()))
|
|
+ goto exit;
|
|
|
|
/* Assign the RSA key to the EVP_PKEY structure.
|
|
This will take over memory management of the RSA key */
|
|
if (!EVP_PKEY_assign_RSA(key->evp_pkey, rsa)) {
|
|
EVP_PKEY_free(key->evp_pkey);
|
|
key->evp_pkey = NULL;
|
|
- RSA_free(rsa);
|
|
+ goto exit;
|
|
}
|
|
|
|
return 1;
|
|
+exit:
|
|
+ RSA_free(rsa);
|
|
+ return 0;
|
|
}
|
|
|
|
static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
|
|
@@ -335,9 +336,10 @@ static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
|
|
size_t mlen = pgpMpiLen(p) - 2;
|
|
struct pgpDigKeyRSA_s *key = pgpkey->data;
|
|
|
|
- if (!key) {
|
|
+ if (!key)
|
|
key = pgpkey->data = xcalloc(1, sizeof(*key));
|
|
- }
|
|
+ else if (key->immutable)
|
|
+ return 1;
|
|
|
|
switch (num) {
|
|
case 0:
|
|
@@ -347,7 +349,7 @@ static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p)
|
|
return 1;
|
|
}
|
|
|
|
- key->nbytes = mlen;
|
|
+ key->nbytes = mlen;
|
|
/* Create a BIGNUM from the pointer.
|
|
Note: this assumes big-endian data as required by PGP */
|
|
key->n = BN_bin2bn(p+2, mlen, NULL);
|
|
--
|
|
1.8.3.1
|
|
|