1 // 2 // ssl/detail/engine.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef BOOST_ASIO_SSL_DETAIL_ENGINE_HPP 12 #define BOOST_ASIO_SSL_DETAIL_ENGINE_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 20 #include <boost/asio/buffer.hpp> 21 #include <boost/asio/detail/static_mutex.hpp> 22 #include <boost/asio/ssl/detail/openssl_types.hpp> 23 #include <boost/asio/ssl/detail/verify_callback.hpp> 24 #include <boost/asio/ssl/stream_base.hpp> 25 #include <boost/asio/ssl/verify_mode.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 engine 35 { 36 public: 37 enum want 38 { 39 // Returned by functions to indicate that the engine wants input. The input 40 // buffer should be updated to point to the data. The engine then needs to 41 // be called again to retry the operation. 42 want_input_and_retry = -2, 43 44 // Returned by functions to indicate that the engine wants to write output. 45 // The output buffer points to the data to be written. The engine then 46 // needs to be called again to retry the operation. 47 want_output_and_retry = -1, 48 49 // Returned by functions to indicate that the engine doesn't need input or 50 // output. 51 want_nothing = 0, 52 53 // Returned by functions to indicate that the engine wants to write output. 54 // The output buffer points to the data to be written. After that the 55 // operation is complete, and the engine does not need to be called again. 56 want_output = 1 57 }; 58 59 // Construct a new engine for the specified context. 60 BOOST_ASIO_DECL explicit engine(SSL_CTX* context); 61 62 #if defined(BOOST_ASIO_HAS_MOVE) 63 // Move construct from another engine. 64 BOOST_ASIO_DECL engine(engine&& other) BOOST_ASIO_NOEXCEPT; 65 #endif // defined(BOOST_ASIO_HAS_MOVE) 66 67 // Destructor. 68 BOOST_ASIO_DECL ~engine(); 69 70 // Get the underlying implementation in the native type. 71 BOOST_ASIO_DECL SSL* native_handle(); 72 73 // Set the peer verification mode. 74 BOOST_ASIO_DECL boost::system::error_code set_verify_mode( 75 verify_mode v, boost::system::error_code& ec); 76 77 // Set the peer verification depth. 78 BOOST_ASIO_DECL boost::system::error_code set_verify_depth( 79 int depth, boost::system::error_code& ec); 80 81 // Set a peer certificate verification callback. 82 BOOST_ASIO_DECL boost::system::error_code set_verify_callback( 83 verify_callback_base* callback, boost::system::error_code& ec); 84 85 // Perform an SSL handshake using either SSL_connect (client-side) or 86 // SSL_accept (server-side). 87 BOOST_ASIO_DECL want handshake( 88 stream_base::handshake_type type, boost::system::error_code& ec); 89 90 // Perform a graceful shutdown of the SSL session. 91 BOOST_ASIO_DECL want shutdown(boost::system::error_code& ec); 92 93 // Write bytes to the SSL session. 94 BOOST_ASIO_DECL want write(const boost::asio::const_buffer& data, 95 boost::system::error_code& ec, std::size_t& bytes_transferred); 96 97 // Read bytes from the SSL session. 98 BOOST_ASIO_DECL want read(const boost::asio::mutable_buffer& data, 99 boost::system::error_code& ec, std::size_t& bytes_transferred); 100 101 // Get output data to be written to the transport. 102 BOOST_ASIO_DECL boost::asio::mutable_buffer get_output( 103 const boost::asio::mutable_buffer& data); 104 105 // Put input data that was read from the transport. 106 BOOST_ASIO_DECL boost::asio::const_buffer put_input( 107 const boost::asio::const_buffer& data); 108 109 // Map an error::eof code returned by the underlying transport according to 110 // the type and state of the SSL session. Returns a const reference to the 111 // error code object, suitable for passing to a completion handler. 112 BOOST_ASIO_DECL const boost::system::error_code& map_error_code( 113 boost::system::error_code& ec) const; 114 115 private: 116 // Disallow copying and assignment. 117 engine(const engine&); 118 engine& operator=(const engine&); 119 120 // Callback used when the SSL implementation wants to verify a certificate. 121 BOOST_ASIO_DECL static int verify_callback_function( 122 int preverified, X509_STORE_CTX* ctx); 123 124 #if (OPENSSL_VERSION_NUMBER < 0x10000000L) 125 // The SSL_accept function may not be thread safe. This mutex is used to 126 // protect all calls to the SSL_accept function. 127 BOOST_ASIO_DECL static boost::asio::detail::static_mutex& accept_mutex(); 128 #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) 129 130 // Perform one operation. Returns >= 0 on success or error, want_read if the 131 // operation needs more input, or want_write if it needs to write some output 132 // before the operation can complete. 133 BOOST_ASIO_DECL want perform(int (engine::* op)(void*, std::size_t), 134 void* data, std::size_t length, boost::system::error_code& ec, 135 std::size_t* bytes_transferred); 136 137 // Adapt the SSL_accept function to the signature needed for perform(). 138 BOOST_ASIO_DECL int do_accept(void*, std::size_t); 139 140 // Adapt the SSL_connect function to the signature needed for perform(). 141 BOOST_ASIO_DECL int do_connect(void*, std::size_t); 142 143 // Adapt the SSL_shutdown function to the signature needed for perform(). 144 BOOST_ASIO_DECL int do_shutdown(void*, std::size_t); 145 146 // Adapt the SSL_read function to the signature needed for perform(). 147 BOOST_ASIO_DECL int do_read(void* data, std::size_t length); 148 149 // Adapt the SSL_write function to the signature needed for perform(). 150 BOOST_ASIO_DECL int do_write(void* data, std::size_t length); 151 152 SSL* ssl_; 153 BIO* ext_bio_; 154 }; 155 156 } // namespace detail 157 } // namespace ssl 158 } // namespace asio 159 } // namespace boost 160 161 #include <boost/asio/detail/pop_options.hpp> 162 163 #if defined(BOOST_ASIO_HEADER_ONLY) 164 # include <boost/asio/ssl/detail/impl/engine.ipp> 165 #endif // defined(BOOST_ASIO_HEADER_ONLY) 166 167 #endif // BOOST_ASIO_SSL_DETAIL_ENGINE_HPP 168