Chris@16: // Chris@16: // ssl/detail/impl/openssl_init.ipp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@16: // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com Chris@101: // Copyright (c) 2005-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP Chris@16: #define BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace ssl { Chris@16: namespace detail { Chris@16: Chris@16: class openssl_init_base::do_init Chris@16: { Chris@16: public: Chris@16: do_init() Chris@16: { Chris@16: ::SSL_library_init(); Chris@16: ::SSL_load_error_strings(); Chris@16: ::OpenSSL_add_all_algorithms(); Chris@16: Chris@16: mutexes_.resize(::CRYPTO_num_locks()); Chris@16: for (size_t i = 0; i < mutexes_.size(); ++i) Chris@16: mutexes_[i].reset(new boost::asio::detail::mutex); Chris@16: ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func); Chris@16: ::CRYPTO_set_id_callback(&do_init::openssl_id_func); Chris@16: Chris@16: #if !defined(SSL_OP_NO_COMPRESSION) \ Chris@16: && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: null_compression_methods_ = sk_SSL_COMP_new_null(); Chris@16: #endif // !defined(SSL_OP_NO_COMPRESSION) Chris@16: // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: } Chris@16: Chris@16: ~do_init() Chris@16: { Chris@16: #if !defined(SSL_OP_NO_COMPRESSION) \ Chris@16: && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: sk_SSL_COMP_free(null_compression_methods_); Chris@16: #endif // !defined(SSL_OP_NO_COMPRESSION) Chris@16: // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: Chris@16: ::CRYPTO_set_id_callback(0); Chris@16: ::CRYPTO_set_locking_callback(0); Chris@16: ::ERR_free_strings(); Chris@101: #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) Chris@101: ::ERR_remove_thread_state(NULL); Chris@101: #else // (OPENSSL_VERSION_NUMBER >= 0x10000000L) Chris@16: ::ERR_remove_state(0); Chris@101: #endif // (OPENSSL_VERSION_NUMBER >= 0x10000000L) Chris@16: ::EVP_cleanup(); Chris@16: ::CRYPTO_cleanup_all_ex_data(); Chris@16: ::CONF_modules_unload(1); Chris@16: #if !defined(OPENSSL_NO_ENGINE) Chris@16: ::ENGINE_cleanup(); Chris@16: #endif // !defined(OPENSSL_NO_ENGINE) Chris@16: } Chris@16: Chris@16: #if !defined(SSL_OP_NO_COMPRESSION) \ Chris@16: && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: STACK_OF(SSL_COMP)* get_null_compression_methods() const Chris@16: { Chris@16: return null_compression_methods_; Chris@16: } Chris@16: #endif // !defined(SSL_OP_NO_COMPRESSION) Chris@16: // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: Chris@16: private: Chris@16: static unsigned long openssl_id_func() Chris@16: { Chris@16: #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) Chris@16: return ::GetCurrentThreadId(); Chris@16: #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) Chris@16: void* id = instance()->thread_id_; Chris@16: if (id == 0) Chris@16: instance()->thread_id_ = id = &id; // Ugh. Chris@16: BOOST_ASIO_ASSERT(sizeof(unsigned long) >= sizeof(void*)); Chris@16: return reinterpret_cast(id); Chris@16: #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) Chris@16: } Chris@16: Chris@16: static void openssl_locking_func(int mode, int n, Chris@16: const char* /*file*/, int /*line*/) Chris@16: { Chris@16: if (mode & CRYPTO_LOCK) Chris@16: instance()->mutexes_[n]->lock(); Chris@16: else Chris@16: instance()->mutexes_[n]->unlock(); Chris@16: } Chris@16: Chris@16: // Mutexes to be used in locking callbacks. Chris@16: std::vector > mutexes_; Chris@16: Chris@16: #if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__) Chris@16: // The thread identifiers to be used by openssl. Chris@16: boost::asio::detail::tss_ptr thread_id_; Chris@16: #endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__) Chris@16: Chris@16: #if !defined(SSL_OP_NO_COMPRESSION) \ Chris@16: && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: STACK_OF(SSL_COMP)* null_compression_methods_; Chris@16: #endif // !defined(SSL_OP_NO_COMPRESSION) Chris@16: // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: }; Chris@16: Chris@16: boost::asio::detail::shared_ptr Chris@16: openssl_init_base::instance() Chris@16: { Chris@16: static boost::asio::detail::shared_ptr init(new do_init); Chris@16: return init; Chris@16: } Chris@16: Chris@16: #if !defined(SSL_OP_NO_COMPRESSION) \ Chris@16: && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: STACK_OF(SSL_COMP)* openssl_init_base::get_null_compression_methods() Chris@16: { Chris@16: return instance()->get_null_compression_methods(); Chris@16: } Chris@16: #endif // !defined(SSL_OP_NO_COMPRESSION) Chris@16: // && (OPENSSL_VERSION_NUMBER >= 0x00908000L) Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace ssl Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_ASIO_SSL_DETAIL_IMPL_OPENSSL_INIT_IPP