Opened 5 years ago
Last modified 4 years ago
#13128 new Bugs
boost asio does not initialize libressl library
Reported by: | Owned by: | chris_kohlhoff | |
---|---|---|---|
Milestone: | To Be Determined | Component: | asio |
Version: | Boost 1.64.0 | Severity: | Problem |
Keywords: | asio libressl | Cc: |
Description
When using the libressl
library with boost asio, there is some library initialization code that depends on OPENSSL_VERSION_NUMBER
that should be executed but it is not because libressl
identifies itself with OPENSSL_VERSION_NUMBER 0x20000000L
and the code in question is inside an #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
or an #if (OPENSSL_VERSION_NUMBER < 0x10000000L)
The code I'm referring to is in boost/asio/ssl/detail/impl/openssl_init.ipp
as follows:
- in
openssl_init_base::do_init
method there is the following code:#if (OPENSSL_VERSION_NUMBER < 0x10100000L) ::SSL_library_init(); ::SSL_load_error_strings(); ::OpenSSL_add_all_algorithms(); mutexes_.resize(::CRYPTO_num_locks()); for (size_t i = 0; i < mutexes_.size(); ++i) mutexes_[i].reset(new boost::asio::detail::mutex); ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func); #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) #if (OPENSSL_VERSION_NUMBER < 0x10000000L) ::CRYPTO_set_id_callback(&do_init::openssl_id_func); #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)
- similarly, in
~do_init()
the following sequence should also execute for libressl:#if (OPENSSL_VERSION_NUMBER < 0x10000000L) ::CRYPTO_set_id_callback(0); #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) #if (OPENSSL_VERSION_NUMBER < 0x10100000L) ::CRYPTO_set_locking_callback(0); ::ERR_free_strings(); ::EVP_cleanup(); ::CRYPTO_cleanup_all_ex_data(); #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L)
- also in
~do_init()
theERR_remove_thread_state
andENGINE_cleanup
functions should be called#elif (OPENSSL_VERSION_NUMBER < 0x10100000L) ::ERR_remove_thread_state(NULL); #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)
#if !defined(OPENSSL_NO_ENGINE) \ && (OPENSSL_VERSION_NUMBER < 0x10100000L) ::ENGINE_cleanup(); #endif // !defined(OPENSSL_NO_ENGINE) // && (OPENSSL_VERSION_NUMBER < 0x10100000L)
- the following
openssl_id_func
andopenssl_locking_func
should also be available forlibressl
, along with the vector of mutexes:#if (OPENSSL_VERSION_NUMBER < 0x10000000L) static unsigned long openssl_id_func() { #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) return ::GetCurrentThreadId(); #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) void* id = &errno; BOOST_ASIO_ASSERT(sizeof(unsigned long) >= sizeof(void*)); return reinterpret_cast<unsigned long>(id); #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) } #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) #if (OPENSSL_VERSION_NUMBER < 0x10100000L) static void openssl_locking_func(int mode, int n, const char* /*file*/, int /*line*/) { if (mode & CRYPTO_LOCK) instance()->mutexes_[n]->lock(); else instance()->mutexes_[n]->unlock(); } // Mutexes to be used in locking callbacks. std::vector<boost::asio::detail::shared_ptr< boost::asio::detail::mutex> > mutexes_; #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L)
Change History (2)
Note:
See TracTickets
for help on using tickets.
You should not attempt to initialize OpenSSL from boost code at all -- doing so conflicts with other initializations made by user code (or other libraries). These initialization (and un-initialization) routines aren't thread-safe. You also can't just stomp in and replace locks provided by user with those of your choosing.