Cross-platform and (truly) thread-safe OpenSSL initialization.
This commit is contained in:
parent
20c1358402
commit
ea700d80f5
@ -50,79 +50,69 @@ namespace tls {
|
||||
|
||||
|
||||
ref <vmime::utility::sync::criticalSection >* OpenSSLInitializer::sm_mutexes;
|
||||
int OpenSSLInitializer::sm_initCount(0);
|
||||
|
||||
|
||||
OpenSSLInitializer::OpenSSLInitializer()
|
||||
OpenSSLInitializer::autoInitializer::autoInitializer()
|
||||
{
|
||||
// The construction of this unique 'oneTimeInitializer' object will be triggered
|
||||
// by the 'autoInitializer' objects from the other translation units
|
||||
static OpenSSLInitializer::oneTimeInitializer oneTimeInitializer;
|
||||
}
|
||||
|
||||
|
||||
OpenSSLInitializer::autoInitializer::~autoInitializer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OpenSSLInitializer::oneTimeInitializer::oneTimeInitializer()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
|
||||
OpenSSLInitializer::~OpenSSLInitializer()
|
||||
OpenSSLInitializer::oneTimeInitializer::~oneTimeInitializer()
|
||||
{
|
||||
uninitialize();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ref <vmime::utility::sync::criticalSection> OpenSSLInitializer::getMutex()
|
||||
{
|
||||
static ref <vmime::utility::sync::criticalSection> criticalSection
|
||||
= vmime::platform::getHandler()->createCriticalSection();
|
||||
|
||||
return criticalSection;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void OpenSSLInitializer::initialize()
|
||||
{
|
||||
ref <vmime::utility::sync::criticalSection> mutex = getMutex();
|
||||
vmime::utility::sync::autoLock <vmime::utility::sync::criticalSection> lock(mutex);
|
||||
|
||||
if (++sm_initCount == 1)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0907000L
|
||||
OPENSSL_config(NULL);
|
||||
OPENSSL_config(NULL);
|
||||
#endif
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
OpenSSL_add_all_algorithms();
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
unsigned char seed[SEEDSIZE];
|
||||
vmime::platform::getHandler()->generateRandomBytes(seed, SEEDSIZE);
|
||||
RAND_seed(seed, SEEDSIZE);
|
||||
unsigned char seed[SEEDSIZE];
|
||||
vmime::platform::getHandler()->generateRandomBytes(seed, SEEDSIZE);
|
||||
RAND_seed(seed, SEEDSIZE);
|
||||
|
||||
int numMutexes = CRYPTO_num_locks();
|
||||
sm_mutexes = new ref <vmime::utility::sync::criticalSection>[numMutexes];
|
||||
int numMutexes = CRYPTO_num_locks();
|
||||
sm_mutexes = new ref <vmime::utility::sync::criticalSection>[numMutexes];
|
||||
|
||||
for (int i = 0 ; i < numMutexes ; ++i)
|
||||
sm_mutexes[i] = vmime::platform::getHandler()->createCriticalSection();
|
||||
for (int i = 0 ; i < numMutexes ; ++i)
|
||||
sm_mutexes[i] = vmime::platform::getHandler()->createCriticalSection();
|
||||
|
||||
CRYPTO_set_locking_callback(&OpenSSLInitializer::lock);
|
||||
CRYPTO_set_id_callback(&OpenSSLInitializer::id);
|
||||
}
|
||||
CRYPTO_set_locking_callback(&OpenSSLInitializer::lock);
|
||||
CRYPTO_set_id_callback(&OpenSSLInitializer::id);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void OpenSSLInitializer::uninitialize()
|
||||
{
|
||||
ref <vmime::utility::sync::criticalSection> mutex = getMutex();
|
||||
vmime::utility::sync::autoLock <vmime::utility::sync::criticalSection> lock(mutex);
|
||||
EVP_cleanup();
|
||||
ERR_free_strings();
|
||||
|
||||
if (--sm_initCount == 0)
|
||||
{
|
||||
EVP_cleanup();
|
||||
ERR_free_strings();
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
|
||||
delete [] sm_mutexes;
|
||||
}
|
||||
delete [] sm_mutexes;
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,6 +41,9 @@ namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
static OpenSSLInitializer::autoInitializer openSSLInitializer;
|
||||
|
||||
|
||||
// static
|
||||
ref <TLSSession> TLSSession::create(ref <security::cert::certificateVerifier> cv)
|
||||
{
|
||||
@ -51,9 +54,6 @@ ref <TLSSession> TLSSession::create(ref <security::cert::certificateVerifier> cv
|
||||
TLSSession_OpenSSL::TLSSession_OpenSSL(ref <vmime::security::cert::certificateVerifier> cv)
|
||||
: m_sslctx(0), m_certVerifier(cv)
|
||||
{
|
||||
// Thread-safe OpenSSL initialization
|
||||
static OpenSSLInitializer openSSLInitialization;
|
||||
|
||||
m_sslctx = SSL_CTX_new(SSLv23_client_method());
|
||||
SSL_CTX_set_options(m_sslctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
|
||||
SSL_CTX_set_mode(m_sslctx, SSL_MODE_AUTO_RETRY);
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp"
|
||||
#include "vmime/net/tls/openssl/TLSSession_OpenSSL.hpp"
|
||||
#include "vmime/net/tls/openssl/OpenSSLInitializer.hpp"
|
||||
|
||||
#include "vmime/platform.hpp"
|
||||
|
||||
@ -45,6 +46,9 @@ namespace net {
|
||||
namespace tls {
|
||||
|
||||
|
||||
static OpenSSLInitializer::autoInitializer openSSLInitializer;
|
||||
|
||||
|
||||
// static
|
||||
BIO_METHOD TLSSocket_OpenSSL::sm_customBIOMethod =
|
||||
{
|
||||
|
@ -59,6 +59,9 @@ namespace security {
|
||||
namespace cert {
|
||||
|
||||
|
||||
static net::tls::OpenSSLInitializer::autoInitializer openSSLInitializer;
|
||||
|
||||
|
||||
#ifndef VMIME_BUILDING_DOC
|
||||
|
||||
class monthMap
|
||||
@ -107,9 +110,6 @@ struct OpenSSLX509CertificateInternalData
|
||||
{
|
||||
OpenSSLX509CertificateInternalData()
|
||||
{
|
||||
// Thread-safe OpenSSL initialization
|
||||
static net::tls::OpenSSLInitializer openSSLInitialization;
|
||||
|
||||
cert = 0;
|
||||
}
|
||||
|
||||
|
@ -48,19 +48,29 @@ namespace tls {
|
||||
*/
|
||||
class OpenSSLInitializer
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/** Automatically initialize OpenSSL
|
||||
*/
|
||||
OpenSSLInitializer();
|
||||
class autoInitializer
|
||||
{
|
||||
public:
|
||||
|
||||
/** Automatically uninitialize OpenSSL
|
||||
*/
|
||||
~OpenSSLInitializer();
|
||||
autoInitializer();
|
||||
~autoInitializer();
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
class oneTimeInitializer
|
||||
{
|
||||
public:
|
||||
|
||||
oneTimeInitializer();
|
||||
~oneTimeInitializer();
|
||||
};
|
||||
|
||||
|
||||
/** Initializes the OpenSSL lib
|
||||
*/
|
||||
static void initialize();
|
||||
@ -85,7 +95,6 @@ protected:
|
||||
private:
|
||||
|
||||
static ref <vmime::utility::sync::criticalSection >* sm_mutexes;
|
||||
static int sm_initCount;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user