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)

Reply via email to