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_initmethod 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_stateandENGINE_cleanupfunctions 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_funcandopenssl_locking_funcshould 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.