summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDemi Marie Obenour <demi@invisiblethingslab.com>2021-04-09 13:34:12 -0400
committerMichal Domonkos <mdomonko@redhat.com>2022-07-01 10:52:14 +0200
commit09e5eac3f00144cbecd12a69390f6db98870f7eb (patch)
tree88116ebd88eaf331f4baba8e0b712500adb52e50
parent5d8d2c1be01d1e55cfa172cfe49ca97893366725 (diff)
downloadrpm-09e5eac3f00144cbecd12a69390f6db98870f7eb.tar.gz
Avoid double frees if EVP_PKEY_assign_RSA fails
Previously, the bignums would be left as dangling and double-freed. (cherry picked from commit 0a91d1f62d5b6e1cac4d0a7c2ac9f75faad50534)
-rw-r--r--rpmio/digest_openssl.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c
index 646933eed..2efcd4a6a 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);