From ef4dc3cbc9db0cff615590d0668244eca7da8445 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 31 Dec 2015 16:02:10 -0500 Subject: [PATCH] fixed race condition of openssl calls --- Crypto.cpp | 31 +++++++++++++++++++++++++++++++ Crypto.h | 3 +++ Daemon.cpp | 6 +++--- api.cpp | 7 +++++++ api.h | 1 + 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 75ece1b7..f6bb2f29 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -1,9 +1,13 @@ #include #include +#include +#include #include #include #include #include +#include +#include #include "Log.h" //#include "TunnelBase.h" #include "Crypto.h" @@ -677,6 +681,33 @@ namespace crypto m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv #endif } + + std::vector > m_OpenSSLMutexes; + static void OpensslLockingCallback(int mode, int type, const char * file, int line) + { + if (type > 0 && (size_t)type < m_OpenSSLMutexes.size ()) + { + if (mode & CRYPTO_LOCK) + m_OpenSSLMutexes[type]->lock (); + else + m_OpenSSLMutexes[type]->unlock (); + } + } + + void InitCrypto () + { + SSL_library_init (); + auto numLocks = CRYPTO_num_locks(); + for (int i = 0; i < numLocks; i++) + m_OpenSSLMutexes.emplace_back (new std::mutex); + CRYPTO_set_locking_callback (OpensslLockingCallback); + } + + void TerminateCrypto () + { + CRYPTO_set_locking_callback (nullptr); + m_OpenSSLMutexes.clear (); + } } } diff --git a/Crypto.h b/Crypto.h index fd49ebc5..dfe0da0e 100644 --- a/Crypto.h +++ b/Crypto.h @@ -272,6 +272,9 @@ namespace crypto CBCDecryption m_LayerDecryption; #endif }; + + void InitCrypto (); + void TerminateCrypto (); } } diff --git a/Daemon.cpp b/Daemon.cpp index e2d7d895..eef58c78 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -19,8 +19,7 @@ #include "HTTPServer.h" #include "I2PControl.h" #include "ClientContext.h" -// ssl.h somehow pulls Windows.h stuff that has to go after asio -#include +#include "Crypto.h" #ifdef USE_UPNP #include "UPnP.h" @@ -60,7 +59,7 @@ namespace i2p bool Daemon_Singleton::init(int argc, char* argv[]) { - SSL_library_init (); + i2p::crypto::InitCrypto (); i2p::util::config::OptionParser(argc, argv); i2p::context.Init (); @@ -171,6 +170,7 @@ namespace i2p d.m_I2PControlService->Stop (); d.m_I2PControlService = nullptr; } + i2p::crypto::TerminateCrypto (); StopLog (); return true; diff --git a/api.cpp b/api.cpp index 5858dc6d..9a9c5c46 100644 --- a/api.cpp +++ b/api.cpp @@ -7,6 +7,7 @@ #include "RouterContext.h" #include "Identity.h" #include "Destination.h" +#include "Crypto.h" #include "util.h" #include "api.h" @@ -18,9 +19,15 @@ namespace api { i2p::util::filesystem::SetAppName (appName); i2p::util::config::OptionParser(argc, argv); + i2p::crypto::InitCrypto (); i2p::context.Init (); } + void TerminateI2P () + { + i2p::crypto::TerminateCrypto (); + } + void StartI2P (std::ostream * logStream) { if (logStream) diff --git a/api.h b/api.h index d34f8ae4..05552249 100644 --- a/api.h +++ b/api.h @@ -13,6 +13,7 @@ namespace api { // initialization start and stop void InitI2P (int argc, char* argv[], const char * appName); + void TerminateI2P (); void StartI2P (std::ostream * logStream = nullptr); // write system log to logStream, if not specified to .log in application's folder void StopI2P ();