Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / asio / ssl / detail / impl / openssl_init.ipp
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-2017 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
29 namespace boost {
30 namespace asio {
31 namespace ssl {
32 namespace detail {
33
34 class openssl_init_base::do_init
35 {
36 public:
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 !defined(SSL_OP_NO_COMPRESSION) \
83   && (OPENSSL_VERSION_NUMBER >= 0x10002000L) \
84   && (OPENSSL_VERSION_NUMBER < 0x10100000L)
85     ::SSL_COMP_free_compression_methods();
86 #endif // (OPENSSL_VERSION_NUMBER >= 0x10002000L)
87        // && (OPENSSL_VERSION_NUMBER < 0x10100000L)
88 #if !defined(OPENSSL_IS_BORINGSSL)
89     ::CONF_modules_unload(1);
90 #endif // !defined(OPENSSL_IS_BORINGSSL)
91 #if !defined(OPENSSL_NO_ENGINE) \
92   && (OPENSSL_VERSION_NUMBER < 0x10100000L)
93     ::ENGINE_cleanup();
94 #endif // !defined(OPENSSL_NO_ENGINE)
95        // && (OPENSSL_VERSION_NUMBER < 0x10100000L)
96   }
97
98 #if !defined(SSL_OP_NO_COMPRESSION) \
99   && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
100   STACK_OF(SSL_COMP)* get_null_compression_methods() const
101   {
102     return null_compression_methods_;
103   }
104 #endif // !defined(SSL_OP_NO_COMPRESSION)
105        // && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
106
107 private:
108 #if (OPENSSL_VERSION_NUMBER < 0x10000000L)
109   static unsigned long openssl_id_func()
110   {
111 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
112     return ::GetCurrentThreadId();
113 #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
114     void* id = &errno;
115     BOOST_ASIO_ASSERT(sizeof(unsigned long) >= sizeof(void*));
116     return reinterpret_cast<unsigned long>(id);
117 #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
118   }
119 #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)
120
121 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
122   static void openssl_locking_func(int mode, int n, 
123     const char* /*file*/, int /*line*/)
124   {
125     if (mode & CRYPTO_LOCK)
126       instance()->mutexes_[n]->lock();
127     else
128       instance()->mutexes_[n]->unlock();
129   }
130
131   // Mutexes to be used in locking callbacks.
132   std::vector<boost::asio::detail::shared_ptr<
133         boost::asio::detail::mutex> > mutexes_;
134 #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L)
135
136 #if !defined(SSL_OP_NO_COMPRESSION) \
137   && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
138   STACK_OF(SSL_COMP)* null_compression_methods_;
139 #endif // !defined(SSL_OP_NO_COMPRESSION)
140        // && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
141 };
142
143 boost::asio::detail::shared_ptr<openssl_init_base::do_init>
144 openssl_init_base::instance()
145 {
146   static boost::asio::detail::shared_ptr<do_init> init(new do_init);
147   return init;
148 }
149
150 #if !defined(SSL_OP_NO_COMPRESSION) \
151   && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
152 STACK_OF(SSL_COMP)* openssl_init_base::get_null_compression_methods()
153 {
154   return instance()->get_null_compression_methods();
155 }
156 #endif // !defined(SSL_OP_NO_COMPRESSION)
157        // && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
158
159 } // namespace detail
160 } // namespace ssl
161 } // namespace asio
162 } // namespace boost
163
164 #include <boost/asio/detail/pop_options.hpp>
165
166 #endif // BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP