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@16
|
6 // Copyright (c) 2005-2013 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@16
|
67 ::ERR_remove_state(0);
|
Chris@16
|
68 ::EVP_cleanup();
|
Chris@16
|
69 ::CRYPTO_cleanup_all_ex_data();
|
Chris@16
|
70 ::CONF_modules_unload(1);
|
Chris@16
|
71 #if !defined(OPENSSL_NO_ENGINE)
|
Chris@16
|
72 ::ENGINE_cleanup();
|
Chris@16
|
73 #endif // !defined(OPENSSL_NO_ENGINE)
|
Chris@16
|
74 }
|
Chris@16
|
75
|
Chris@16
|
76 #if !defined(SSL_OP_NO_COMPRESSION) \
|
Chris@16
|
77 && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
78 STACK_OF(SSL_COMP)* get_null_compression_methods() const
|
Chris@16
|
79 {
|
Chris@16
|
80 return null_compression_methods_;
|
Chris@16
|
81 }
|
Chris@16
|
82 #endif // !defined(SSL_OP_NO_COMPRESSION)
|
Chris@16
|
83 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
84
|
Chris@16
|
85 private:
|
Chris@16
|
86 static unsigned long openssl_id_func()
|
Chris@16
|
87 {
|
Chris@16
|
88 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
Chris@16
|
89 return ::GetCurrentThreadId();
|
Chris@16
|
90 #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
Chris@16
|
91 void* id = instance()->thread_id_;
|
Chris@16
|
92 if (id == 0)
|
Chris@16
|
93 instance()->thread_id_ = id = &id; // Ugh.
|
Chris@16
|
94 BOOST_ASIO_ASSERT(sizeof(unsigned long) >= sizeof(void*));
|
Chris@16
|
95 return reinterpret_cast<unsigned long>(id);
|
Chris@16
|
96 #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
Chris@16
|
97 }
|
Chris@16
|
98
|
Chris@16
|
99 static void openssl_locking_func(int mode, int n,
|
Chris@16
|
100 const char* /*file*/, int /*line*/)
|
Chris@16
|
101 {
|
Chris@16
|
102 if (mode & CRYPTO_LOCK)
|
Chris@16
|
103 instance()->mutexes_[n]->lock();
|
Chris@16
|
104 else
|
Chris@16
|
105 instance()->mutexes_[n]->unlock();
|
Chris@16
|
106 }
|
Chris@16
|
107
|
Chris@16
|
108 // Mutexes to be used in locking callbacks.
|
Chris@16
|
109 std::vector<boost::asio::detail::shared_ptr<
|
Chris@16
|
110 boost::asio::detail::mutex> > mutexes_;
|
Chris@16
|
111
|
Chris@16
|
112 #if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
|
Chris@16
|
113 // The thread identifiers to be used by openssl.
|
Chris@16
|
114 boost::asio::detail::tss_ptr<void> thread_id_;
|
Chris@16
|
115 #endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
|
Chris@16
|
116
|
Chris@16
|
117 #if !defined(SSL_OP_NO_COMPRESSION) \
|
Chris@16
|
118 && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
119 STACK_OF(SSL_COMP)* null_compression_methods_;
|
Chris@16
|
120 #endif // !defined(SSL_OP_NO_COMPRESSION)
|
Chris@16
|
121 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
122 };
|
Chris@16
|
123
|
Chris@16
|
124 boost::asio::detail::shared_ptr<openssl_init_base::do_init>
|
Chris@16
|
125 openssl_init_base::instance()
|
Chris@16
|
126 {
|
Chris@16
|
127 static boost::asio::detail::shared_ptr<do_init> init(new do_init);
|
Chris@16
|
128 return init;
|
Chris@16
|
129 }
|
Chris@16
|
130
|
Chris@16
|
131 #if !defined(SSL_OP_NO_COMPRESSION) \
|
Chris@16
|
132 && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
133 STACK_OF(SSL_COMP)* openssl_init_base::get_null_compression_methods()
|
Chris@16
|
134 {
|
Chris@16
|
135 return instance()->get_null_compression_methods();
|
Chris@16
|
136 }
|
Chris@16
|
137 #endif // !defined(SSL_OP_NO_COMPRESSION)
|
Chris@16
|
138 // && (OPENSSL_VERSION_NUMBER >= 0x00908000L)
|
Chris@16
|
139
|
Chris@16
|
140 } // namespace detail
|
Chris@16
|
141 } // namespace ssl
|
Chris@16
|
142 } // namespace asio
|
Chris@16
|
143 } // namespace boost
|
Chris@16
|
144
|
Chris@16
|
145 #include <boost/asio/detail/pop_options.hpp>
|
Chris@16
|
146
|
Chris@16
|
147 #endif // BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP
|