summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/engine/eng_int.h4
-rw-r--r--crypto/engine/eng_lib.c2
-rw-r--r--crypto/engine/eng_list.c1
-rw-r--r--crypto/engine/engine.h2
-rw-r--r--crypto/engine/tb_pkmeth.c25
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);
+ }
+ }
+ }
+ }