From 7e5b06813d2cf4d314d577d9b11f2cac13835faa Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 2 Jun 2006 17:09:17 +0000 Subject: [PATCH] Automatically free up dynamically allocated public key methods when and ENGINE is destroyed. --- crypto/engine/eng_int.h | 4 ++++ crypto/engine/eng_lib.c | 2 ++ crypto/engine/eng_list.c | 1 + crypto/engine/engine.h | 2 +- crypto/engine/tb_pkmeth.c | 25 ++++++++++++++++++++++++- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h index 1596bd8f33..d93f5e5b17 100644 --- a/crypto/engine/eng_int.h +++ b/crypto/engine/eng_int.h @@ -143,6 +143,10 @@ void engine_set_all_null(ENGINE *e); /* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed * in engine.h. */ +/* Free up dynamically allocated public key methods associated with ENGINE */ + +void engine_pkey_meths_free(ENGINE *e); + /* This is a structure for storing implementations of various crypto * algorithms and functions. */ struct engine_st diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c index 5815b867f4..6ee8a90c15 100644 --- a/crypto/engine/eng_lib.c +++ b/crypto/engine/eng_lib.c @@ -125,6 +125,8 @@ int engine_free_util(ENGINE *e, int locked) abort(); } #endif + /* Free up any dynamically allocated public key methods */ + engine_pkey_meths_free(e); /* Give the ENGINE a chance to do any structural cleanup corresponding * to allocation it did in its constructor (eg. unload error strings) */ if(e->destroy) diff --git a/crypto/engine/eng_list.c b/crypto/engine/eng_list.c index bd511944ba..66a52b89e0 100644 --- a/crypto/engine/eng_list.c +++ b/crypto/engine/eng_list.c @@ -336,6 +336,7 @@ static void engine_cpy(ENGINE *dest, const ENGINE *src) dest->store_meth = src->store_meth; dest->ciphers = src->ciphers; dest->digests = src->digests; + dest->pkey_meths = src->pkey_meths; dest->destroy = src->destroy; dest->init = src->init; dest->finish = src->finish; diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h index ba70d8981a..7285c004c4 100644 --- a/crypto/engine/engine.h +++ b/crypto/engine/engine.h @@ -293,7 +293,7 @@ typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, * parameter is non-NULL it is set to the size of the returned array. */ typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int); typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int); -typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, const EVP_PKEY_METHOD **, const int **, int); +typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int); /* STRUCTURE functions ... all of these functions deal with pointers to ENGINE * structures where the pointers have a "structural reference". This means that * their reference is to allowed access to the structure but it does not imply diff --git a/crypto/engine/tb_pkmeth.c b/crypto/engine/tb_pkmeth.c index b99dea2190..999fc0ac41 100644 --- a/crypto/engine/tb_pkmeth.c +++ b/crypto/engine/tb_pkmeth.c @@ -118,7 +118,7 @@ ENGINE *ENGINE_get_pkey_meth_engine(int nid) /* Obtains a pkey_meth implementation from an ENGINE functional reference */ const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid) { - const EVP_PKEY_METHOD *ret; + EVP_PKEY_METHOD *ret; ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e); if(!fn || !fn(e, &ret, NULL, nid)) { @@ -141,3 +141,26 @@ int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f) e->pkey_meths = f; return 1; } + +/* Internal function to free up EVP_PKEY_METHOD structures before an + * ENGINE is destroyed + */ + +void engine_pkey_meths_free(ENGINE *e) + { + int i; + EVP_PKEY_METHOD *pkm; + if (e->pkey_meths) + { + const int *pknids; + int npknids; + npknids = e->pkey_meths(e, NULL, &pknids, 0); + for (i = 0; i < npknids; i++) + { + if (e->pkey_meths(e, &pkm, NULL, pknids[i])) + { + EVP_PKEY_meth_free(pkm); + } + } + } + }