diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2019-02-18 09:17:02 -0800 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2019-02-18 09:17:02 -0800 |
commit | 6b158e160edb37c083b9589b2cd73d1f05af8849 (patch) | |
tree | ad3edd45c72ee7673b2950c096753179e3dd842d | |
parent | 40225cc2329600ba68332fd588eb5b1330f27878 (diff) | |
download | openssl-pkcs11-export-6b158e160edb37c083b9589b2cd73d1f05af8849.tar.gz |
Fix memory leak in EVP_PKEY elements
The cache assumes that all the memory is fixed, which is usually true
because it's block allocated for the config file. However type
CACHE_PKEY is an exception because they're dynamically allocated, so
add a freeing function callback to make sure they're correctly freed
when no longer in use.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | cache.c | 3 | ||||
-rw-r--r-- | crypto.c | 5 | ||||
-rw-r--r-- | openssl-pkcs11.h | 1 |
3 files changed, 9 insertions, 0 deletions
@@ -106,6 +106,9 @@ static void cache_add_internal(struct s_s *s_s, const char *key, struct kv *kv = kv_get_alloc(s_s, key); if (!kv) return; + if (kv->value && kv->len == CACHE_PKEY) + /* discard const */ + crypto_cache_free_pkey((void *)kv->value); if (len == 0) len = strlen(value); @@ -221,6 +221,11 @@ void crypto_free_private_key(int sec_num) cache_add_by_secnum(sec_num, "pkey", NULL, CACHE_PKEY); } +void crypto_cache_free_pkey(void *pkey) +{ + EVP_PKEY_free(pkey); +} + static EVP_PKEY_CTX *get_key(int sec_num) { EVP_PKEY_CTX *ctx; diff --git a/openssl-pkcs11.h b/openssl-pkcs11.h index 1e3d673..f6120d6 100644 --- a/openssl-pkcs11.h +++ b/openssl-pkcs11.h @@ -27,6 +27,7 @@ int crypto_load_public_key(int sec_num, const char *pub); int crypto_load_private_key(int sec_num, const unsigned char *pin, int pin_len); void crypto_free_private_key(int sec_num); +void crypto_cache_free_pkey(void *pkey); void *crypto_sign_init(int sec_num, CK_MECHANISM_PTR mech); int crypto_sign(void *opdata, void *data, unsigned long data_len, void *sig, unsigned long *sig_len); |