openssl_init.ipp 5.5 KB

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