This adds support to remove an ASN.1 or PKEY method from the app methods. The app methods are a way to add such methods that are specific to an application. However, the disability to remove such methods makes unit-testings very difficult. We use a lot of unit tests where openssl is initialized including memory debugging, some tests are performed and then it checks for memory leaks. These tests fails because of the still assigned app methods.
The registered app methods also have issues if app methods refers to implementation provided by an engine which is loaded and unloaded multiple times during a unit-test. Having the EVP_PKEY_meth_delete and EVP_PKEY_asn1_delete functions allows to remove the previously registered app methods during shutdown of a unit test case and allows the next unit test case to start with a clean system. The patch was created against a current openssl/master. It is also available in the github branch https://github.com/myrkr/openssl/commits/allow-remove-of-app-method The code was well tested with openssl 1.0.0k. I would like to see this patch in openssl 1.0.0, 1.0.1 and 1.0.2 stable branches too. With regards, Torsten
commit d1602652ff6bdd0f8e9748a3fbe31afb80b530e8 Author: Axel Kühn <axel.ku...@secunet.com> Date: Wed Jan 8 08:01:06 2014 +0100 asn1,evp: Add delete functions for app methods This adds support to remove an ASN.1 or PKEY method from the app methods. The app methods are a way to add such methods that are specific to an application. However, the disability to remove such methods makes unit-testings very difficult. We use a lot of unit tests where openssl is initialized including memory debugging, some tests are performed and then it checks for memory leaks. These tests fails because of the still assigned app methods. The registered app methods also have issues if app methods refers to implementation provided by an engine which is loaded and unloaded multiple times during a unit-test. Having the EVP_PKEY_meth_delete and EVP_PKEY_asn1_delete functions allows to remove the previously registered app methods during shutdown of a unit test case and allows the next unit test case to start with a clean system. Signed-off-by: Torsten Hilbrich <torsten.hilbr...@gmx.net> diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c index 5fff226..842d862 100644 --- a/crypto/asn1/ameth_lib.c +++ b/crypto/asn1/ameth_lib.c @@ -255,6 +255,13 @@ int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) return 1; } +void EVP_PKEY_asn1_delete(const EVP_PKEY_ASN1_METHOD *ameth) + { + if (app_methods == NULL || ameth == NULL) + return; + (void)sk_EVP_PKEY_ASN1_METHOD_delete_ptr(app_methods, ameth); + } + int EVP_PKEY_asn1_add_alias(int to, int from) { EVP_PKEY_ASN1_METHOD *ameth; diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index a5aa4c8..1767323 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -1074,6 +1074,7 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len); int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_delete(const EVP_PKEY_ASN1_METHOD *ameth); int EVP_PKEY_asn1_add_alias(int to, int from); int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags, const char **pinfo, const char **ppem_str, @@ -1187,6 +1188,7 @@ void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); +void EVP_PKEY_meth_delete(const EVP_PKEY_METHOD *pmeth); EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index c64f907..43074d2 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -366,6 +366,13 @@ int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) return 1; } +void EVP_PKEY_meth_delete(const EVP_PKEY_METHOD *pmeth) + { + if (app_pkey_methods == NULL || pmeth == NULL) + return; + (void)sk_EVP_PKEY_METHOD_delete_ptr(app_pkey_methods, pmeth); + } + void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { if (ctx == NULL)