aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2013-05-13 14:05:56 +0000
committerVincent Richard <[email protected]>2013-05-13 14:05:56 +0000
commitea700d80f5d65f7d6c4cab4ccd09192467b15204 (patch)
treeda40c4504649b2b318c019e7d35ee856536d6abb
parentPut generated header files in a separate list. (diff)
downloadvmime-ea700d80f5d65f7d6c4cab4ccd09192467b15204.tar.gz
vmime-ea700d80f5d65f7d6c4cab4ccd09192467b15204.zip
Cross-platform and (truly) thread-safe OpenSSL initialization.
-rw-r--r--src/net/tls/openssl/OpenSSLInitializer.cpp70
-rw-r--r--src/net/tls/openssl/TLSSession_OpenSSL.cpp6
-rw-r--r--src/net/tls/openssl/TLSSocket_OpenSSL.cpp4
-rw-r--r--src/security/cert/openssl/X509Certificate_OpenSSL.cpp6
-rw-r--r--vmime/net/tls/openssl/OpenSSLInitializer.hpp21
5 files changed, 55 insertions, 52 deletions
diff --git a/src/net/tls/openssl/OpenSSLInitializer.cpp b/src/net/tls/openssl/OpenSSLInitializer.cpp
index dce86179..8238b864 100644
--- a/src/net/tls/openssl/OpenSSLInitializer.cpp
+++ b/src/net/tls/openssl/OpenSSLInitializer.cpp
@@ -50,79 +50,69 @@ namespace tls {
ref <vmime::utility::sync::criticalSection >* OpenSSLInitializer::sm_mutexes;
-int OpenSSLInitializer::sm_initCount(0);
-OpenSSLInitializer::OpenSSLInitializer()
+OpenSSLInitializer::autoInitializer::autoInitializer()
{
- initialize();
+ // The construction of this unique 'oneTimeInitializer' object will be triggered
+ // by the 'autoInitializer' objects from the other translation units
+ static OpenSSLInitializer::oneTimeInitializer oneTimeInitializer;
}
-OpenSSLInitializer::~OpenSSLInitializer()
+OpenSSLInitializer::autoInitializer::~autoInitializer()
{
- uninitialize();
}
-// static
-ref <vmime::utility::sync::criticalSection> OpenSSLInitializer::getMutex()
+OpenSSLInitializer::oneTimeInitializer::oneTimeInitializer()
{
- static ref <vmime::utility::sync::criticalSection> criticalSection
- = vmime::platform::getHandler()->createCriticalSection();
+ initialize();
+}
- return criticalSection;
+
+OpenSSLInitializer::oneTimeInitializer::~oneTimeInitializer()
+{
+ uninitialize();
}
// 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);
-
- if (--sm_initCount == 0)
- {
- EVP_cleanup();
- ERR_free_strings();
+ 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;
}
diff --git a/src/net/tls/openssl/TLSSession_OpenSSL.cpp b/src/net/tls/openssl/TLSSession_OpenSSL.cpp
index a18e2958..fcf82c7b 100644
--- a/src/net/tls/openssl/TLSSession_OpenSSL.cpp
+++ b/src/net/tls/openssl/TLSSession_OpenSSL.cpp
@@ -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);
diff --git a/src/net/tls/openssl/TLSSocket_OpenSSL.cpp b/src/net/tls/openssl/TLSSocket_OpenSSL.cpp
index b8ac18e9..7fda1f15 100644
--- a/src/net/tls/openssl/TLSSocket_OpenSSL.cpp
+++ b/src/net/tls/openssl/TLSSocket_OpenSSL.cpp
@@ -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 =
{
diff --git a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/security/cert/openssl/X509Certificate_OpenSSL.cpp
index 056631ec..20df3739 100644
--- a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp
+++ b/src/security/cert/openssl/X509Certificate_OpenSSL.cpp
@@ -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;
}
diff --git a/vmime/net/tls/openssl/OpenSSLInitializer.hpp b/vmime/net/tls/openssl/OpenSSLInitializer.hpp
index 9c85ef25..5277d4ff 100644
--- a/vmime/net/tls/openssl/OpenSSLInitializer.hpp
+++ b/vmime/net/tls/openssl/OpenSSLInitializer.hpp
@@ -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;
};