1// 2// ssl/detail/impl/openssl_init.ipp 3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4// 5// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com 6// Copyright (c) 2005-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com) 7// 8// Distributed under the Boost Software License, Version 1.0. (See accompanying 9// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10// 11 12#ifndef BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP 13#define BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP 14 15#if defined(_MSC_VER) && (_MSC_VER >= 1200) 16# pragma once 17#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 19#include <boost/asio/detail/config.hpp> 20#include <vector> 21#include <boost/asio/detail/assert.hpp> 22#include <boost/asio/detail/mutex.hpp> 23#include <boost/asio/detail/tss_ptr.hpp> 24#include <boost/asio/ssl/detail/openssl_init.hpp> 25#include <boost/asio/ssl/detail/openssl_types.hpp> 26 27#include <boost/asio/detail/push_options.hpp> 28 29namespace boost { 30namespace asio { 31namespace ssl { 32namespace detail { 33 34class openssl_init_base::do_init 35{ 36public: 37 do_init() 38 { 39#if (OPENSSL_VERSION_NUMBER < 0x10100000L) 40 ::SSL_library_init(); 41 ::SSL_load_error_strings(); 42 ::OpenSSL_add_all_algorithms(); 43 44 mutexes_.resize(::CRYPTO_num_locks()); 45 for (size_t i = 0; i < mutexes_.size(); ++i) 46 mutexes_[i].reset(new boost::asio::detail::mutex); 47 ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func); 48#endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) 49#if (OPENSSL_VERSION_NUMBER < 0x10000000L) 50 ::CRYPTO_set_id_callback(&do_init::openssl_id_func); 51#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) 52 53#if !defined(SSL_OP_NO_COMPRESSION) \ 54 && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 55 null_compression_methods_ = sk_SSL_COMP_new_null(); 56#endif // !defined(SSL_OP_NO_COMPRESSION) 57 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 58 } 59 60 ~do_init() 61 { 62#if !defined(SSL_OP_NO_COMPRESSION) \ 63 && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 64 sk_SSL_COMP_free(null_compression_methods_); 65#endif // !defined(SSL_OP_NO_COMPRESSION) 66 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 67 68#if (OPENSSL_VERSION_NUMBER < 0x10000000L) 69 ::CRYPTO_set_id_callback(0); 70#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) 71#if (OPENSSL_VERSION_NUMBER < 0x10100000L) 72 ::CRYPTO_set_locking_callback(0); 73 ::ERR_free_strings(); 74 ::EVP_cleanup(); 75 ::CRYPTO_cleanup_all_ex_data(); 76#endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) 77#if (OPENSSL_VERSION_NUMBER < 0x10000000L) 78 ::ERR_remove_state(0); 79#elif (OPENSSL_VERSION_NUMBER < 0x10100000L) 80 ::ERR_remove_thread_state(NULL); 81#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) 82#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) \ 83 && (OPENSSL_VERSION_NUMBER < 0x10100000L) \ 84 && !defined(SSL_OP_NO_COMPRESSION) 85 ::SSL_COMP_free_compression_methods(); 86#endif // (OPENSSL_VERSION_NUMBER >= 0x10002000L) 87 // && (OPENSSL_VERSION_NUMBER < 0x10100000L) 88 // && !defined(SSL_OP_NO_COMPRESSION) 89#if !defined(OPENSSL_IS_BORINGSSL) && !defined(BOOST_ASIO_USE_WOLFSSL) 90 ::CONF_modules_unload(1); 91#endif // !defined(OPENSSL_IS_BORINGSSL) && !defined(BOOST_ASIO_USE_WOLFSSL) 92#if !defined(OPENSSL_NO_ENGINE) \ 93 && (OPENSSL_VERSION_NUMBER < 0x10100000L) 94 ::ENGINE_cleanup(); 95#endif // !defined(OPENSSL_NO_ENGINE) 96 // && (OPENSSL_VERSION_NUMBER < 0x10100000L) 97 } 98 99#if !defined(SSL_OP_NO_COMPRESSION) \ 100 && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 101 STACK_OF(SSL_COMP)* get_null_compression_methods() const 102 { 103 return null_compression_methods_; 104 } 105#endif // !defined(SSL_OP_NO_COMPRESSION) 106 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 107 108private: 109#if (OPENSSL_VERSION_NUMBER < 0x10000000L) 110 static unsigned long openssl_id_func() 111 { 112#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) 113 return ::GetCurrentThreadId(); 114#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) 115 void* id = &errno; 116 BOOST_ASIO_ASSERT(sizeof(unsigned long) >= sizeof(void*)); 117 return reinterpret_cast<unsigned long>(id); 118#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) 119 } 120#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) 121 122#if (OPENSSL_VERSION_NUMBER < 0x10100000L) 123 static void openssl_locking_func(int mode, int n, 124 const char* /*file*/, int /*line*/) 125 { 126 if (mode & CRYPTO_LOCK) 127 instance()->mutexes_[n]->lock(); 128 else 129 instance()->mutexes_[n]->unlock(); 130 } 131 132 // Mutexes to be used in locking callbacks. 133 std::vector<boost::asio::detail::shared_ptr< 134 boost::asio::detail::mutex> > mutexes_; 135#endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) 136 137#if !defined(SSL_OP_NO_COMPRESSION) \ 138 && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 139 STACK_OF(SSL_COMP)* null_compression_methods_; 140#endif // !defined(SSL_OP_NO_COMPRESSION) 141 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 142}; 143 144boost::asio::detail::shared_ptr<openssl_init_base::do_init> 145openssl_init_base::instance() 146{ 147 static boost::asio::detail::shared_ptr<do_init> init(new do_init); 148 return init; 149} 150 151#if !defined(SSL_OP_NO_COMPRESSION) \ 152 && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 153STACK_OF(SSL_COMP)* openssl_init_base::get_null_compression_methods() 154{ 155 return instance()->get_null_compression_methods(); 156} 157#endif // !defined(SSL_OP_NO_COMPRESSION) 158 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) 159 160} // namespace detail 161} // namespace ssl 162} // namespace asio 163} // namespace boost 164 165#include <boost/asio/detail/pop_options.hpp> 166 167#endif // BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP 168