#3562: fixed OpenSSL setup/shutdown

This commit is contained in:
Günter Obiltschnig
2022-04-15 17:22:01 +02:00
parent 4b0e1848b2
commit 720dbe1262
2 changed files with 44 additions and 18 deletions

View File

@@ -74,16 +74,22 @@ protected:
SEEDSIZE = 256 SEEDSIZE = 256
}; };
#if OPENSSL_VERSION_NUMBER < 0x10100000L
// OpenSSL multithreading support // OpenSSL multithreading support
static void lock(int mode, int n, const char* file, int line); static void lock(int mode, int n, const char* file, int line);
static unsigned long id(); static unsigned long id();
static struct CRYPTO_dynlock_value* dynlockCreate(const char* file, int line); static struct CRYPTO_dynlock_value* dynlockCreate(const char* file, int line);
static void dynlock(int mode, struct CRYPTO_dynlock_value* lock, const char* file, int line); static void dynlock(int mode, struct CRYPTO_dynlock_value* lock, const char* file, int line);
static void dynlockDestroy(struct CRYPTO_dynlock_value* lock, const char* file, int line); static void dynlockDestroy(struct CRYPTO_dynlock_value* lock, const char* file, int line);
#endif
private: private:
static Poco::FastMutex* _mutexes;
static Poco::AtomicCounter _rc; static Poco::AtomicCounter _rc;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
static Poco::FastMutex* _mutexes;
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30000000L #if OPENSSL_VERSION_NUMBER >= 0x30000000L
static OSSL_PROVIDER* _defaultProvider; static OSSL_PROVIDER* _defaultProvider;
static OSSL_PROVIDER* _legacyProvider; static OSSL_PROVIDER* _legacyProvider;

View File

@@ -13,12 +13,15 @@
#include "Poco/Crypto/OpenSSLInitializer.h" #include "Poco/Crypto/OpenSSLInitializer.h"
#include "Poco/Crypto/CryptoException.h"
#include "Poco/RandomStream.h" #include "Poco/RandomStream.h"
#include "Poco/Thread.h" #include "Poco/Thread.h"
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/err.h> #include <openssl/err.h>
#if OPENSSL_VERSION_NUMBER >= 0x0907000L #if OPENSSL_VERSION_NUMBER >= 0x0907000L
#include <openssl/conf.h> #include <openssl/conf.h>
#endif #endif
@@ -58,8 +61,12 @@ namespace Poco {
namespace Crypto { namespace Crypto {
Poco::FastMutex* OpenSSLInitializer::_mutexes(0);
Poco::AtomicCounter OpenSSLInitializer::_rc; Poco::AtomicCounter OpenSSLInitializer::_rc;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
Poco::FastMutex* OpenSSLInitializer::_mutexes(0);
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30000000L #if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PROVIDER* OpenSSLInitializer::_defaultProvider(0); OSSL_PROVIDER* OpenSSLInitializer::_defaultProvider(0);
OSSL_PROVIDER* OpenSSLInitializer::_legacyProvider(0); OSSL_PROVIDER* OpenSSLInitializer::_legacyProvider(0);
@@ -94,20 +101,12 @@ void OpenSSLInitializer::initialize()
#elif OPENSSL_VERSION_NUMBER >= 0x0907000L #elif OPENSSL_VERSION_NUMBER >= 0x0907000L
OPENSSL_config(NULL); OPENSSL_config(NULL);
#endif #endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSL_library_init(); SSL_library_init();
SSL_load_error_strings(); SSL_load_error_strings();
OpenSSL_add_all_algorithms(); OpenSSL_add_all_algorithms();
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
_defaultProvider = OSSL_PROVIDER_load(NULL, "default");
_legacyProvider = OSSL_PROVIDER_load(NULL, "legacy");
#endif
char seed[SEEDSIZE];
RandomInputStream rnd;
rnd.read(seed, sizeof(seed));
RAND_seed(seed, SEEDSIZE);
int nMutexes = CRYPTO_num_locks(); int nMutexes = CRYPTO_num_locks();
_mutexes = new Poco::FastMutex[nMutexes]; _mutexes = new Poco::FastMutex[nMutexes];
CRYPTO_set_locking_callback(&OpenSSLInitializer::lock); CRYPTO_set_locking_callback(&OpenSSLInitializer::lock);
@@ -124,6 +123,25 @@ void OpenSSLInitializer::initialize()
CRYPTO_set_dynlock_create_callback(&OpenSSLInitializer::dynlockCreate); CRYPTO_set_dynlock_create_callback(&OpenSSLInitializer::dynlockCreate);
CRYPTO_set_dynlock_lock_callback(&OpenSSLInitializer::dynlock); CRYPTO_set_dynlock_lock_callback(&OpenSSLInitializer::dynlock);
CRYPTO_set_dynlock_destroy_callback(&OpenSSLInitializer::dynlockDestroy); CRYPTO_set_dynlock_destroy_callback(&OpenSSLInitializer::dynlockDestroy);
char seed[SEEDSIZE];
RandomInputStream rnd;
rnd.read(seed, sizeof(seed));
RAND_seed(seed, SEEDSIZE);
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (!_defaultProvider)
{
_defaultProvider = OSSL_PROVIDER_load(NULL, "default");
if (!_defaultProvider) throw CryptoException("Failed to load OpenSSL default provider");
}
if (!_legacyProvider)
{
_legacyProvider = OSSL_PROVIDER_load(NULL, "legacy");
if (!_defaultProvider) throw CryptoException("Failed to load OpenSSL legacy provider");
}
#endif
} }
} }
@@ -132,6 +150,7 @@ void OpenSSLInitializer::uninitialize()
{ {
if (--_rc == 0) if (--_rc == 0)
{ {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_cleanup(); EVP_cleanup();
ERR_free_strings(); ERR_free_strings();
CRYPTO_set_locking_callback(0); CRYPTO_set_locking_callback(0);
@@ -139,17 +158,15 @@ void OpenSSLInitializer::uninitialize()
CRYPTO_set_id_callback(0); CRYPTO_set_id_callback(0);
#endif #endif
delete [] _mutexes; delete [] _mutexes;
CONF_modules_free();
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PROVIDER_unload(_defaultProvider);
OSSL_PROVIDER_unload(_legacyProvider);
#endif #endif
} }
} }
#if OPENSSL_VERSION_NUMBER < 0x10100000L
void OpenSSLInitializer::lock(int mode, int n, const char* file, int line) void OpenSSLInitializer::lock(int mode, int n, const char* file, int line)
{ {
if (mode & CRYPTO_LOCK) if (mode & CRYPTO_LOCK)
@@ -191,6 +208,9 @@ void OpenSSLInitializer::dynlockDestroy(struct CRYPTO_dynlock_value* lock, const
} }
#endif // OPENSSL_VERSION_NUMBER < 0x10100000L
void initializeCrypto() void initializeCrypto()
{ {
OpenSSLInitializer::initialize(); OpenSSLInitializer::initialize();