From 097ca6bf0b6f3de92eb4e938c8ebf5dddef8b79e Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 10 Apr 2022 00:19:02 +0300 Subject: [PATCH] OpenSSL: Unload providers on deinit This frees up the allocated resources and makes memory leak detection more convenient without the known allocations being left behind. Signed-off-by: Jouni Malinen --- src/crypto/crypto_openssl.c | 30 ++++++++++++++++++++++-------- src/crypto/tls_openssl.c | 3 +++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index 42c501363..4fdac0afe 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -130,20 +130,34 @@ static int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, #endif /* OpenSSL version < 1.1.1 */ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +static OSSL_PROVIDER *openssl_default_provider = NULL; +static OSSL_PROVIDER *openssl_legacy_provider = NULL; +#endif /* OpenSSL version >= 3.0 */ + void openssl_load_legacy_provider(void) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L - static bool loaded = false; - OSSL_PROVIDER *legacy; - - if (loaded) + if (openssl_legacy_provider) return; - legacy = OSSL_PROVIDER_load(NULL, "legacy"); + openssl_legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (openssl_legacy_provider && !openssl_default_provider) + openssl_default_provider = OSSL_PROVIDER_load(NULL, "default"); +#endif /* OpenSSL version >= 3.0 */ +} - if (legacy) { - OSSL_PROVIDER_load(NULL, "default"); - loaded = true; + +void openssl_unload_legacy_provider(void) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (openssl_legacy_provider) { + OSSL_PROVIDER_unload(openssl_legacy_provider); + openssl_legacy_provider = NULL; + } + if (openssl_default_provider) { + OSSL_PROVIDER_unload(openssl_default_provider); + openssl_default_provider = NULL; } #endif /* OpenSSL version >= 3.0 */ } diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 3eca7b17c..e6b7d411d 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -1130,6 +1130,8 @@ void tls_deinit(void *ssl_ctx) tls_openssl_ref_count--; if (tls_openssl_ref_count == 0) { + void openssl_unload_legacy_provider(void); + #if OPENSSL_VERSION_NUMBER < 0x10100000L || \ (defined(LIBRESSL_VERSION_NUMBER) && \ LIBRESSL_VERSION_NUMBER < 0x20700000L) @@ -1145,6 +1147,7 @@ void tls_deinit(void *ssl_ctx) tls_global->ocsp_stapling_response = NULL; os_free(tls_global); tls_global = NULL; + openssl_unload_legacy_provider(); } os_free(data->check_cert_subject);