id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 13128,boost asio does not initialize libressl library,ioan pomian ,chris_kohlhoff,"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()` the `ERR_remove_thread_state` and `ENGINE_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` and `openssl_locking_func` should also be available for `libressl`, 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(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 > mutexes_; #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) }}}",Bugs,new,To Be Determined,asio,Boost 1.64.0,Problem,,asio libressl,