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