2 // ssl/detail/impl/openssl_init.ipp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
6 // Copyright (c) 2005-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
12 #ifndef BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP
13 #define BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
19 #include <boost/asio/detail/config.hpp>
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>
27 #include <boost/asio/detail/push_options.hpp>
34 class openssl_init_base::do_init
39 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
41 ::SSL_load_error_strings();
42 ::OpenSSL_add_all_algorithms();
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)
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)
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)
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);
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)
95 #endif // !defined(OPENSSL_NO_ENGINE)
96 // && (OPENSSL_VERSION_NUMBER < 0x10100000L)
99 #if !defined(SSL_OP_NO_COMPRESSION) \
100 && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
101 STACK_OF(SSL_COMP)* get_null_compression_methods() const
103 return null_compression_methods_;
105 #endif // !defined(SSL_OP_NO_COMPRESSION)
106 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
109 #if (OPENSSL_VERSION_NUMBER < 0x10000000L)
110 static unsigned long openssl_id_func()
112 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
113 return ::GetCurrentThreadId();
114 #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
116 BOOST_ASIO_ASSERT(sizeof(unsigned long) >= sizeof(void*));
117 return reinterpret_cast<unsigned long>(id);
118 #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
120 #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)
122 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
123 static void openssl_locking_func(int mode, int n,
124 const char* /*file*/, int /*line*/)
126 if (mode & CRYPTO_LOCK)
127 instance()->mutexes_[n]->lock();
129 instance()->mutexes_[n]->unlock();
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)
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)
144 boost::asio::detail::shared_ptr<openssl_init_base::do_init>
145 openssl_init_base::instance()
147 static boost::asio::detail::shared_ptr<do_init> init(new do_init);
151 #if !defined(SSL_OP_NO_COMPRESSION) \
152 && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
153 STACK_OF(SSL_COMP)* openssl_init_base::get_null_compression_methods()
155 return instance()->get_null_compression_methods();
157 #endif // !defined(SSL_OP_NO_COMPRESSION)
158 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
160 } // namespace detail
165 #include <boost/asio/detail/pop_options.hpp>
167 #endif // BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP