Allow caller to disable SSL Initialization, so it can be done outside of Poco.

This commit is contained in:
bobstabler 2015-04-30 16:37:21 -05:00
parent b565d72d4c
commit 6ccfaa53d0
2 changed files with 39 additions and 20 deletions

View File

@ -44,7 +44,7 @@ namespace Crypto {
class Crypto_API OpenSSLInitializer class Crypto_API OpenSSLInitializer
/// Initializes the OpenSSL library. /// Initalizes the OpenSSL library.
/// ///
/// The class ensures the earliest initialization and the /// The class ensures the earliest initialization and the
/// latest shutdown of the OpenSSL library. /// latest shutdown of the OpenSSL library.
@ -68,6 +68,8 @@ public:
static void enableFIPSMode(bool enabled); static void enableFIPSMode(bool enabled);
// Enable or disable FIPS mode. If FIPS is not available, this method doesn't do anything. // Enable or disable FIPS mode. If FIPS is not available, this method doesn't do anything.
static void disableSSLInitialization(); // Call if OpenSSL is already being initialized by another component before constructing any OpenSSLInitializers.
protected: protected:
enum enum
{ {
@ -84,6 +86,8 @@ protected:
private: private:
static Poco::FastMutex* _mutexes; static Poco::FastMutex* _mutexes;
static Poco::AtomicCounter _rc; static Poco::AtomicCounter _rc;
static bool _disableSSLInitialization;
static bool _setupMultiThreadSupport;
}; };
@ -110,6 +114,11 @@ inline void OpenSSLInitializer::enableFIPSMode(bool /*enabled*/)
} }
#endif #endif
inline void OpenSSLInitializer::disableSSLInitialization()
{
_disableSSLInitialization = true;
}
} } // namespace Poco::Crypto } } // namespace Poco::Crypto

View File

@ -36,7 +36,7 @@ namespace Crypto {
Poco::FastMutex* OpenSSLInitializer::_mutexes(0); Poco::FastMutex* OpenSSLInitializer::_mutexes(0);
Poco::AtomicCounter OpenSSLInitializer::_rc; Poco::AtomicCounter OpenSSLInitializer::_rc;
bool OpenSSLInitializer::_disableSSLInitialization = false;
OpenSSLInitializer::OpenSSLInitializer() OpenSSLInitializer::OpenSSLInitializer()
{ {
@ -64,18 +64,21 @@ void OpenSSLInitializer::initialize()
#if OPENSSL_VERSION_NUMBER >= 0x0907000L #if OPENSSL_VERSION_NUMBER >= 0x0907000L
OPENSSL_config(NULL); OPENSSL_config(NULL);
#endif #endif
SSL_library_init(); if(! _disableSSLInitialization) {
SSL_load_error_strings(); SSL_library_init();
OpenSSL_add_all_algorithms(); SSL_load_error_strings();
OpenSSL_add_all_algorithms();
}
char seed[SEEDSIZE]; char seed[SEEDSIZE];
RandomInputStream rnd; RandomInputStream rnd;
rnd.read(seed, sizeof(seed)); rnd.read(seed, sizeof(seed));
RAND_seed(seed, SEEDSIZE); RAND_seed(seed, SEEDSIZE);
int nMutexes = CRYPTO_num_locks(); if(CRYPTO_get_locking_callback() == NULL) {
_mutexes = new Poco::FastMutex[nMutexes]; int nMutexes = CRYPTO_num_locks();
CRYPTO_set_locking_callback(&OpenSSLInitializer::lock); _mutexes = new Poco::FastMutex[nMutexes];
CRYPTO_set_locking_callback(&OpenSSLInitializer::lock);
#ifndef POCO_OS_FAMILY_WINDOWS #ifndef POCO_OS_FAMILY_WINDOWS
// Not needed on Windows (see SF #110: random unhandled exceptions when linking with ssl). // Not needed on Windows (see SF #110: random unhandled exceptions when linking with ssl).
// https://sourceforge.net/p/poco/bugs/110/ // https://sourceforge.net/p/poco/bugs/110/
@ -84,11 +87,12 @@ void OpenSSLInitializer::initialize()
// "If the application does not register such a callback using CRYPTO_THREADID_set_callback(), // "If the application does not register such a callback using CRYPTO_THREADID_set_callback(),
// then a default implementation is used - on Windows and BeOS this uses the system's // then a default implementation is used - on Windows and BeOS this uses the system's
// default thread identifying APIs" // default thread identifying APIs"
CRYPTO_set_id_callback(&OpenSSLInitializer::id); CRYPTO_set_id_callback(&OpenSSLInitializer::id);
#endif #endif
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);
}
} }
} }
@ -97,15 +101,21 @@ void OpenSSLInitializer::uninitialize()
{ {
if (--_rc == 0) if (--_rc == 0)
{ {
EVP_cleanup(); if(_mutexes != NULL) {
ERR_free_strings(); CRYPTO_set_dynlock_create_callback(0);
CRYPTO_set_locking_callback(0); CRYPTO_set_dynlock_lock_callback(0);
CRYPTO_set_dynlock_destroy_callback(0);
CRYPTO_set_locking_callback(0);
#ifndef POCO_OS_FAMILY_WINDOWS #ifndef POCO_OS_FAMILY_WINDOWS
CRYPTO_set_id_callback(0); CRYPTO_set_id_callback(0);
#endif #endif
delete [] _mutexes; delete [] _mutexes;
}
CONF_modules_free(); if(! _disableSSLInitialization) {
EVP_cleanup();
ERR_free_strings();
CONF_modules_free();
}
} }
} }