update boost
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
// ssl/context.hpp
|
||||
// ~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -44,6 +44,9 @@ public:
|
||||
/// Constructor.
|
||||
BOOST_ASIO_DECL explicit context(method m);
|
||||
|
||||
/// Construct to take ownership of a native handle.
|
||||
BOOST_ASIO_DECL explicit context(native_handle_type native_handle);
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a context from another.
|
||||
/**
|
||||
@@ -739,6 +742,9 @@ private:
|
||||
// Helper function to make a BIO from a memory buffer.
|
||||
BOOST_ASIO_DECL BIO* make_buffer_bio(const const_buffer& b);
|
||||
|
||||
// Translate an SSL error into an error code.
|
||||
BOOST_ASIO_DECL static boost::system::error_code translate_error(long error);
|
||||
|
||||
// The underlying native implementation.
|
||||
native_handle_type handle_;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/context_base.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -106,60 +106,60 @@ public:
|
||||
};
|
||||
|
||||
/// Bitmask type for SSL options.
|
||||
typedef long options;
|
||||
typedef uint64_t options;
|
||||
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
/// Implement various bug workarounds.
|
||||
static const long default_workarounds = implementation_defined;
|
||||
static const uint64_t default_workarounds = implementation_defined;
|
||||
|
||||
/// Always create a new key when using tmp_dh parameters.
|
||||
static const long single_dh_use = implementation_defined;
|
||||
static const uint64_t single_dh_use = implementation_defined;
|
||||
|
||||
/// Disable SSL v2.
|
||||
static const long no_sslv2 = implementation_defined;
|
||||
static const uint64_t no_sslv2 = implementation_defined;
|
||||
|
||||
/// Disable SSL v3.
|
||||
static const long no_sslv3 = implementation_defined;
|
||||
static const uint64_t no_sslv3 = implementation_defined;
|
||||
|
||||
/// Disable TLS v1.
|
||||
static const long no_tlsv1 = implementation_defined;
|
||||
static const uint64_t no_tlsv1 = implementation_defined;
|
||||
|
||||
/// Disable TLS v1.1.
|
||||
static const long no_tlsv1_1 = implementation_defined;
|
||||
static const uint64_t no_tlsv1_1 = implementation_defined;
|
||||
|
||||
/// Disable TLS v1.2.
|
||||
static const long no_tlsv1_2 = implementation_defined;
|
||||
static const uint64_t no_tlsv1_2 = implementation_defined;
|
||||
|
||||
/// Disable TLS v1.3.
|
||||
static const long no_tlsv1_3 = implementation_defined;
|
||||
static const uint64_t no_tlsv1_3 = implementation_defined;
|
||||
|
||||
/// Disable compression. Compression is disabled by default.
|
||||
static const long no_compression = implementation_defined;
|
||||
static const uint64_t no_compression = implementation_defined;
|
||||
#else
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, default_workarounds = SSL_OP_ALL);
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, single_dh_use = SSL_OP_SINGLE_DH_USE);
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_sslv2 = SSL_OP_NO_SSLv2);
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_sslv3 = SSL_OP_NO_SSLv3);
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_tlsv1 = SSL_OP_NO_TLSv1);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, default_workarounds = SSL_OP_ALL);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, single_dh_use = SSL_OP_SINGLE_DH_USE);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_sslv2 = SSL_OP_NO_SSLv2);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_sslv3 = SSL_OP_NO_SSLv3);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_tlsv1 = SSL_OP_NO_TLSv1);
|
||||
# if defined(SSL_OP_NO_TLSv1_1)
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = SSL_OP_NO_TLSv1_1);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_tlsv1_1 = SSL_OP_NO_TLSv1_1);
|
||||
# else // defined(SSL_OP_NO_TLSv1_1)
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_tlsv1_1 = 0x10000000L);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_tlsv1_1 = 0x10000000L);
|
||||
# endif // defined(SSL_OP_NO_TLSv1_1)
|
||||
# if defined(SSL_OP_NO_TLSv1_2)
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = SSL_OP_NO_TLSv1_2);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_tlsv1_2 = SSL_OP_NO_TLSv1_2);
|
||||
# else // defined(SSL_OP_NO_TLSv1_2)
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_tlsv1_2 = 0x08000000L);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_tlsv1_2 = 0x08000000L);
|
||||
# endif // defined(SSL_OP_NO_TLSv1_2)
|
||||
# if defined(SSL_OP_NO_TLSv1_3)
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_tlsv1_3 = SSL_OP_NO_TLSv1_3);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_tlsv1_3 = SSL_OP_NO_TLSv1_3);
|
||||
# else // defined(SSL_OP_NO_TLSv1_3)
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_tlsv1_3 = 0x20000000L);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_tlsv1_3 = 0x20000000L);
|
||||
# endif // defined(SSL_OP_NO_TLSv1_3)
|
||||
# if defined(SSL_OP_NO_COMPRESSION)
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_compression = SSL_OP_NO_COMPRESSION);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_compression = SSL_OP_NO_COMPRESSION);
|
||||
# else // defined(SSL_OP_NO_COMPRESSION)
|
||||
BOOST_ASIO_STATIC_CONSTANT(long, no_compression = 0x20000L);
|
||||
BOOST_ASIO_STATIC_CONSTANT(uint64_t, no_compression = 0x20000L);
|
||||
# endif // defined(SSL_OP_NO_COMPRESSION)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/buffered_handshake_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -30,6 +30,11 @@ template <typename ConstBufferSequence>
|
||||
class buffered_handshake_op
|
||||
{
|
||||
public:
|
||||
static BOOST_ASIO_CONSTEXPR const char* tracking_name()
|
||||
{
|
||||
return "ssl::stream<>::async_buffered_handshake";
|
||||
}
|
||||
|
||||
buffered_handshake_op(stream_base::handshake_type type,
|
||||
const ConstBufferSequence& buffers)
|
||||
: type_(type),
|
||||
@@ -52,7 +57,7 @@ public:
|
||||
const boost::system::error_code& ec,
|
||||
const std::size_t& bytes_transferred) const
|
||||
{
|
||||
handler(ec, bytes_transferred);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/engine.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -59,9 +59,22 @@ public:
|
||||
// Construct a new engine for the specified context.
|
||||
BOOST_ASIO_DECL explicit engine(SSL_CTX* context);
|
||||
|
||||
// Construct a new engine for an existing native SSL implementation.
|
||||
BOOST_ASIO_DECL explicit engine(SSL* ssl_impl);
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
// Move construct from another engine.
|
||||
BOOST_ASIO_DECL engine(engine&& other) BOOST_ASIO_NOEXCEPT;
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
// Destructor.
|
||||
BOOST_ASIO_DECL ~engine();
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
// Move assign from another engine.
|
||||
BOOST_ASIO_DECL engine& operator=(engine&& other) BOOST_ASIO_NOEXCEPT;
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
// Get the underlying implementation in the native type.
|
||||
BOOST_ASIO_DECL SSL* native_handle();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/handshake_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -29,6 +29,11 @@ namespace detail {
|
||||
class handshake_op
|
||||
{
|
||||
public:
|
||||
static BOOST_ASIO_CONSTEXPR const char* tracking_name()
|
||||
{
|
||||
return "ssl::stream<>::async_handshake";
|
||||
}
|
||||
|
||||
handshake_op(stream_base::handshake_type type)
|
||||
: type_(type)
|
||||
{
|
||||
@@ -47,7 +52,7 @@ public:
|
||||
const boost::system::error_code& ec,
|
||||
const std::size_t&) const
|
||||
{
|
||||
handler(ec);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/impl/engine.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -56,18 +56,63 @@ engine::engine(SSL_CTX* context)
|
||||
::SSL_set_bio(ssl_, int_bio, int_bio);
|
||||
}
|
||||
|
||||
engine::engine(SSL* ssl_impl)
|
||||
: ssl_(ssl_impl)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
|
||||
accept_mutex().init();
|
||||
#endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)
|
||||
|
||||
::SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
::SSL_set_mode(ssl_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
#if defined(SSL_MODE_RELEASE_BUFFERS)
|
||||
::SSL_set_mode(ssl_, SSL_MODE_RELEASE_BUFFERS);
|
||||
#endif // defined(SSL_MODE_RELEASE_BUFFERS)
|
||||
|
||||
::BIO* int_bio = 0;
|
||||
::BIO_new_bio_pair(&int_bio, 0, &ext_bio_, 0);
|
||||
::SSL_set_bio(ssl_, int_bio, int_bio);
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
engine::engine(engine&& other) BOOST_ASIO_NOEXCEPT
|
||||
: ssl_(other.ssl_),
|
||||
ext_bio_(other.ext_bio_)
|
||||
{
|
||||
other.ssl_ = 0;
|
||||
other.ext_bio_ = 0;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
engine::~engine()
|
||||
{
|
||||
if (SSL_get_app_data(ssl_))
|
||||
if (ssl_ && SSL_get_app_data(ssl_))
|
||||
{
|
||||
delete static_cast<verify_callback_base*>(SSL_get_app_data(ssl_));
|
||||
SSL_set_app_data(ssl_, 0);
|
||||
}
|
||||
|
||||
::BIO_free(ext_bio_);
|
||||
::SSL_free(ssl_);
|
||||
if (ext_bio_)
|
||||
::BIO_free(ext_bio_);
|
||||
|
||||
if (ssl_)
|
||||
::SSL_free(ssl_);
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
engine& engine::operator=(engine&& other) BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
ssl_ = other.ssl_;
|
||||
ext_bio_ = other.ext_bio_;
|
||||
other.ssl_ = 0;
|
||||
other.ext_bio_ = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
SSL* engine::native_handle()
|
||||
{
|
||||
return ssl_;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -86,9 +86,13 @@ public:
|
||||
#endif // (OPENSSL_VERSION_NUMBER >= 0x10002000L)
|
||||
// && (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
// && !defined(SSL_OP_NO_COMPRESSION)
|
||||
#if !defined(OPENSSL_IS_BORINGSSL)
|
||||
#if !defined(OPENSSL_IS_BORINGSSL) \
|
||||
&& !defined(BOOST_ASIO_USE_WOLFSSL) \
|
||||
&& (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
||||
::CONF_modules_unload(1);
|
||||
#endif // !defined(OPENSSL_IS_BORINGSSL)
|
||||
// && !defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
// && (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
||||
#if !defined(OPENSSL_NO_ENGINE) \
|
||||
&& (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
::ENGINE_cleanup();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/io.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#include <boost/asio/detail/base_from_cancellation_state.hpp>
|
||||
#include <boost/asio/detail/handler_tracking.hpp>
|
||||
#include <boost/asio/ssl/detail/engine.hpp>
|
||||
#include <boost/asio/ssl/detail/stream_core.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
@@ -94,11 +96,13 @@ std::size_t io(Stream& next_layer, stream_core& core,
|
||||
|
||||
template <typename Stream, typename Operation, typename Handler>
|
||||
class io_op
|
||||
: public boost::asio::detail::base_from_cancellation_state<Handler>
|
||||
{
|
||||
public:
|
||||
io_op(Stream& next_layer, stream_core& core,
|
||||
const Operation& op, Handler& handler)
|
||||
: next_layer_(next_layer),
|
||||
: boost::asio::detail::base_from_cancellation_state<Handler>(handler),
|
||||
next_layer_(next_layer),
|
||||
core_(core),
|
||||
op_(op),
|
||||
start_(0),
|
||||
@@ -110,7 +114,8 @@ public:
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
io_op(const io_op& other)
|
||||
: next_layer_(other.next_layer_),
|
||||
: boost::asio::detail::base_from_cancellation_state<Handler>(other),
|
||||
next_layer_(other.next_layer_),
|
||||
core_(other.core_),
|
||||
op_(other.op_),
|
||||
start_(other.start_),
|
||||
@@ -122,7 +127,11 @@ public:
|
||||
}
|
||||
|
||||
io_op(io_op&& other)
|
||||
: next_layer_(other.next_layer_),
|
||||
: boost::asio::detail::base_from_cancellation_state<Handler>(
|
||||
BOOST_ASIO_MOVE_CAST(
|
||||
boost::asio::detail::base_from_cancellation_state<Handler>)(
|
||||
other)),
|
||||
next_layer_(other.next_layer_),
|
||||
core_(other.core_),
|
||||
op_(BOOST_ASIO_MOVE_CAST(Operation)(other.op_)),
|
||||
start_(other.start_),
|
||||
@@ -163,6 +172,9 @@ public:
|
||||
// Prevent other read operations from being started.
|
||||
core_.pending_read_.expires_at(core_.pos_infin());
|
||||
|
||||
BOOST_ASIO_HANDLER_LOCATION((
|
||||
__FILE__, __LINE__, Operation::tracking_name()));
|
||||
|
||||
// Start reading some data from the underlying transport.
|
||||
next_layer_.async_read_some(
|
||||
boost::asio::buffer(core_.input_buffer_),
|
||||
@@ -170,6 +182,9 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASIO_HANDLER_LOCATION((
|
||||
__FILE__, __LINE__, Operation::tracking_name()));
|
||||
|
||||
// Wait until the current read operation completes.
|
||||
core_.pending_read_.async_wait(BOOST_ASIO_MOVE_CAST(io_op)(*this));
|
||||
}
|
||||
@@ -190,6 +205,9 @@ public:
|
||||
// Prevent other write operations from being started.
|
||||
core_.pending_write_.expires_at(core_.pos_infin());
|
||||
|
||||
BOOST_ASIO_HANDLER_LOCATION((
|
||||
__FILE__, __LINE__, Operation::tracking_name()));
|
||||
|
||||
// Start writing all the data to the underlying transport.
|
||||
boost::asio::async_write(next_layer_,
|
||||
core_.engine_.get_output(core_.output_buffer_),
|
||||
@@ -197,6 +215,9 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASIO_HANDLER_LOCATION((
|
||||
__FILE__, __LINE__, Operation::tracking_name()));
|
||||
|
||||
// Wait until the current write operation completes.
|
||||
core_.pending_write_.async_wait(BOOST_ASIO_MOVE_CAST(io_op)(*this));
|
||||
}
|
||||
@@ -214,6 +235,9 @@ public:
|
||||
// read so the handler runs "as-if" posted using io_context::post().
|
||||
if (start)
|
||||
{
|
||||
BOOST_ASIO_HANDLER_LOCATION((
|
||||
__FILE__, __LINE__, Operation::tracking_name()));
|
||||
|
||||
next_layer_.async_read_some(
|
||||
boost::asio::buffer(core_.input_buffer_, 0),
|
||||
BOOST_ASIO_MOVE_CAST(io_op)(*this));
|
||||
@@ -247,6 +271,13 @@ public:
|
||||
// Release any waiting read operations.
|
||||
core_.pending_read_.expires_at(core_.neg_infin());
|
||||
|
||||
// Check for cancellation before continuing.
|
||||
if (this->cancelled() != cancellation_type::none)
|
||||
{
|
||||
ec_ = boost::asio::error::operation_aborted;
|
||||
break;
|
||||
}
|
||||
|
||||
// Try the operation again.
|
||||
continue;
|
||||
|
||||
@@ -255,6 +286,13 @@ public:
|
||||
// Release any waiting write operations.
|
||||
core_.pending_write_.expires_at(core_.neg_infin());
|
||||
|
||||
// Check for cancellation before continuing.
|
||||
if (this->cancelled() != cancellation_type::none)
|
||||
{
|
||||
ec_ = boost::asio::error::operation_aborted;
|
||||
break;
|
||||
}
|
||||
|
||||
// Try the operation again.
|
||||
continue;
|
||||
|
||||
@@ -294,19 +332,29 @@ public:
|
||||
};
|
||||
|
||||
template <typename Stream, typename Operation, typename Handler>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
inline asio_handler_allocate_is_deprecated
|
||||
asio_handler_allocate(std::size_t size,
|
||||
io_op<Stream, Operation, Handler>* this_handler)
|
||||
{
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
|
||||
return asio_handler_allocate_is_no_longer_used();
|
||||
#else // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return boost_asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Stream, typename Operation, typename Handler>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
inline asio_handler_deallocate_is_deprecated
|
||||
asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
io_op<Stream, Operation, Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_deallocate_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Stream, typename Operation, typename Handler>
|
||||
@@ -319,20 +367,28 @@ inline bool asio_handler_is_continuation(
|
||||
|
||||
template <typename Function, typename Stream,
|
||||
typename Operation, typename Handler>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(Function& function,
|
||||
io_op<Stream, Operation, Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Function, typename Stream,
|
||||
typename Operation, typename Handler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
inline asio_handler_invoke_is_deprecated
|
||||
asio_handler_invoke(const Function& function,
|
||||
io_op<Stream, Operation, Handler>* this_handler)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
#if defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
return asio_handler_invoke_is_no_longer_used();
|
||||
#endif // defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
}
|
||||
|
||||
template <typename Stream, typename Operation, typename Handler>
|
||||
@@ -347,31 +403,29 @@ inline void async_io(Stream& next_layer, stream_core& core,
|
||||
} // namespace detail
|
||||
} // namespace ssl
|
||||
|
||||
template <typename Stream, typename Operation,
|
||||
typename Handler, typename Allocator>
|
||||
struct associated_allocator<
|
||||
ssl::detail::io_op<Stream, Operation, Handler>, Allocator>
|
||||
template <template <typename, typename> class Associator,
|
||||
typename Stream, typename Operation,
|
||||
typename Handler, typename DefaultCandidate>
|
||||
struct associator<Associator,
|
||||
ssl::detail::io_op<Stream, Operation, Handler>,
|
||||
DefaultCandidate>
|
||||
: Associator<Handler, DefaultCandidate>
|
||||
{
|
||||
typedef typename associated_allocator<Handler, Allocator>::type type;
|
||||
|
||||
static type get(const ssl::detail::io_op<Stream, Operation, Handler>& h,
|
||||
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
|
||||
static typename Associator<Handler, DefaultCandidate>::type
|
||||
get(const ssl::detail::io_op<Stream, Operation, Handler>& h)
|
||||
BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Stream, typename Operation,
|
||||
typename Handler, typename Executor>
|
||||
struct associated_executor<
|
||||
ssl::detail::io_op<Stream, Operation, Handler>, Executor>
|
||||
{
|
||||
typedef typename associated_executor<Handler, Executor>::type type;
|
||||
|
||||
static type get(const ssl::detail::io_op<Stream, Operation, Handler>& h,
|
||||
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
|
||||
static BOOST_ASIO_AUTO_RETURN_TYPE_PREFIX2(
|
||||
typename Associator<Handler, DefaultCandidate>::type)
|
||||
get(const ssl::detail::io_op<Stream, Operation, Handler>& h,
|
||||
const DefaultCandidate& c) BOOST_ASIO_NOEXCEPT
|
||||
BOOST_ASIO_AUTO_RETURN_TYPE_SUFFIX((
|
||||
Associator<Handler, DefaultCandidate>::get(h.handler_, c)))
|
||||
{
|
||||
return associated_executor<Handler, Executor>::get(h.handler_, ex);
|
||||
return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/openssl_init.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/openssl_types.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <boost/asio/detail/socket_types.hpp>
|
||||
#if defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
# include <wolfssl/options.h>
|
||||
#endif // defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/ssl.h>
|
||||
#if !defined(OPENSSL_NO_ENGINE)
|
||||
@@ -25,6 +28,7 @@
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/password_callback.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/read_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -31,6 +31,11 @@ template <typename MutableBufferSequence>
|
||||
class read_op
|
||||
{
|
||||
public:
|
||||
static BOOST_ASIO_CONSTEXPR const char* tracking_name()
|
||||
{
|
||||
return "ssl::stream<>::async_read_some";
|
||||
}
|
||||
|
||||
read_op(const MutableBufferSequence& buffers)
|
||||
: buffers_(buffers)
|
||||
{
|
||||
@@ -52,7 +57,7 @@ public:
|
||||
const boost::system::error_code& ec,
|
||||
const std::size_t& bytes_transferred) const
|
||||
{
|
||||
handler(ec, bytes_transferred);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/shutdown_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -29,6 +29,11 @@ namespace detail {
|
||||
class shutdown_op
|
||||
{
|
||||
public:
|
||||
static BOOST_ASIO_CONSTEXPR const char* tracking_name()
|
||||
{
|
||||
return "ssl::stream<>::async_shutdown";
|
||||
}
|
||||
|
||||
engine::want operator()(engine& eng,
|
||||
boost::system::error_code& ec,
|
||||
std::size_t& bytes_transferred) const
|
||||
@@ -47,11 +52,11 @@ public:
|
||||
// The engine only generates an eof when the shutdown notification has
|
||||
// been received from the peer. This indicates that the shutdown has
|
||||
// completed successfully, and thus need not be passed on to the handler.
|
||||
handler(boost::system::error_code());
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler)(boost::system::error_code());
|
||||
}
|
||||
else
|
||||
{
|
||||
handler(ec);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/stream_core.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -52,10 +52,96 @@ struct stream_core
|
||||
pending_write_.expires_at(neg_infin());
|
||||
}
|
||||
|
||||
template <typename Executor>
|
||||
stream_core(SSL* ssl_impl, const Executor& ex)
|
||||
: engine_(ssl_impl),
|
||||
pending_read_(ex),
|
||||
pending_write_(ex),
|
||||
output_buffer_space_(max_tls_record_size),
|
||||
output_buffer_(boost::asio::buffer(output_buffer_space_)),
|
||||
input_buffer_space_(max_tls_record_size),
|
||||
input_buffer_(boost::asio::buffer(input_buffer_space_))
|
||||
{
|
||||
pending_read_.expires_at(neg_infin());
|
||||
pending_write_.expires_at(neg_infin());
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
stream_core(stream_core&& other)
|
||||
: engine_(BOOST_ASIO_MOVE_CAST(engine)(other.engine_)),
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
pending_read_(
|
||||
BOOST_ASIO_MOVE_CAST(boost::asio::deadline_timer)(
|
||||
other.pending_read_)),
|
||||
pending_write_(
|
||||
BOOST_ASIO_MOVE_CAST(boost::asio::deadline_timer)(
|
||||
other.pending_write_)),
|
||||
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
pending_read_(
|
||||
BOOST_ASIO_MOVE_CAST(boost::asio::steady_timer)(
|
||||
other.pending_read_)),
|
||||
pending_write_(
|
||||
BOOST_ASIO_MOVE_CAST(boost::asio::steady_timer)(
|
||||
other.pending_write_)),
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
output_buffer_space_(
|
||||
BOOST_ASIO_MOVE_CAST(std::vector<unsigned char>)(
|
||||
other.output_buffer_space_)),
|
||||
output_buffer_(other.output_buffer_),
|
||||
input_buffer_space_(
|
||||
BOOST_ASIO_MOVE_CAST(std::vector<unsigned char>)(
|
||||
other.input_buffer_space_)),
|
||||
input_buffer_(other.input_buffer_),
|
||||
input_(other.input_)
|
||||
{
|
||||
other.output_buffer_ = boost::asio::mutable_buffer(0, 0);
|
||||
other.input_buffer_ = boost::asio::mutable_buffer(0, 0);
|
||||
other.input_ = boost::asio::const_buffer(0, 0);
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
~stream_core()
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE)
|
||||
stream_core& operator=(stream_core&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
engine_ = BOOST_ASIO_MOVE_CAST(engine)(other.engine_);
|
||||
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
pending_read_ =
|
||||
BOOST_ASIO_MOVE_CAST(boost::asio::deadline_timer)(
|
||||
other.pending_read_);
|
||||
pending_write_ =
|
||||
BOOST_ASIO_MOVE_CAST(boost::asio::deadline_timer)(
|
||||
other.pending_write_);
|
||||
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
pending_read_ =
|
||||
BOOST_ASIO_MOVE_CAST(boost::asio::steady_timer)(
|
||||
other.pending_read_);
|
||||
pending_write_ =
|
||||
BOOST_ASIO_MOVE_CAST(boost::asio::steady_timer)(
|
||||
other.pending_write_);
|
||||
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
|
||||
output_buffer_space_ =
|
||||
BOOST_ASIO_MOVE_CAST(std::vector<unsigned char>)(
|
||||
other.output_buffer_space_);
|
||||
output_buffer_ = other.output_buffer_;
|
||||
input_buffer_space_ =
|
||||
BOOST_ASIO_MOVE_CAST(std::vector<unsigned char>)(
|
||||
other.input_buffer_space_);
|
||||
input_buffer_ = other.input_buffer_;
|
||||
input_ = other.input_;
|
||||
other.output_buffer_ = boost::asio::mutable_buffer(0, 0);
|
||||
other.input_buffer_ = boost::asio::mutable_buffer(0, 0);
|
||||
other.input_ = boost::asio::const_buffer(0, 0);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE)
|
||||
|
||||
// The SSL engine.
|
||||
engine engine_;
|
||||
|
||||
@@ -115,13 +201,13 @@ struct stream_core
|
||||
std::vector<unsigned char> output_buffer_space_;
|
||||
|
||||
// A buffer that may be used to prepare output intended for the transport.
|
||||
const boost::asio::mutable_buffer output_buffer_;
|
||||
boost::asio::mutable_buffer output_buffer_;
|
||||
|
||||
// Buffer space used to read input intended for the engine.
|
||||
std::vector<unsigned char> input_buffer_space_;
|
||||
|
||||
// A buffer that may be used to read input intended for the engine.
|
||||
const boost::asio::mutable_buffer input_buffer_;
|
||||
boost::asio::mutable_buffer input_buffer_;
|
||||
|
||||
// The buffer pointing to the engine's unconsumed input.
|
||||
boost::asio::const_buffer input_;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/verify_callback.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/detail/write_op.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -31,6 +31,11 @@ template <typename ConstBufferSequence>
|
||||
class write_op
|
||||
{
|
||||
public:
|
||||
static BOOST_ASIO_CONSTEXPR const char* tracking_name()
|
||||
{
|
||||
return "ssl::stream<>::async_write_some";
|
||||
}
|
||||
|
||||
write_op(const ConstBufferSequence& buffers)
|
||||
: buffers_(buffers)
|
||||
{
|
||||
@@ -40,9 +45,13 @@ public:
|
||||
boost::system::error_code& ec,
|
||||
std::size_t& bytes_transferred) const
|
||||
{
|
||||
unsigned char storage[
|
||||
boost::asio::detail::buffer_sequence_adapter<boost::asio::const_buffer,
|
||||
ConstBufferSequence>::linearisation_storage_size];
|
||||
|
||||
boost::asio::const_buffer buffer =
|
||||
boost::asio::detail::buffer_sequence_adapter<boost::asio::const_buffer,
|
||||
ConstBufferSequence>::first(buffers_);
|
||||
ConstBufferSequence>::linearise(buffers_, boost::asio::buffer(storage));
|
||||
|
||||
return eng.write(buffer, ec, bytes_transferred);
|
||||
}
|
||||
@@ -52,7 +61,7 @@ public:
|
||||
const boost::system::error_code& ec,
|
||||
const std::size_t& bytes_transferred) const
|
||||
{
|
||||
handler(ec, bytes_transferred);
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/error.hpp
|
||||
// ~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -55,7 +55,9 @@ enum stream_errors
|
||||
/// call.
|
||||
unexpected_result
|
||||
#else // defined(GENERATING_DOCUMENTATION)
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_IS_BORINGSSL)
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x10100000L) \
|
||||
&& !defined(OPENSSL_IS_BORINGSSL) \
|
||||
&& !defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
stream_truncated = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ),
|
||||
# else
|
||||
stream_truncated = 1,
|
||||
|
||||
92
linx64/include/boost/asio/ssl/host_name_verification.hpp
Normal file
92
linx64/include/boost/asio/ssl/host_name_verification.hpp
Normal file
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// ssl/host_name_verification.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_SSL_HOST_NAME_VERIFICATION_HPP
|
||||
#define BOOST_ASIO_SSL_HOST_NAME_VERIFICATION_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <boost/asio/ssl/detail/openssl_types.hpp>
|
||||
#include <boost/asio/ssl/verify_context.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
/// Verifies a certificate against a host_name according to the rules described
|
||||
/// in RFC 6125.
|
||||
/**
|
||||
* @par Example
|
||||
* The following example shows how to synchronously open a secure connection to
|
||||
* a given host name:
|
||||
* @code
|
||||
* using boost::asio::ip::tcp;
|
||||
* namespace ssl = boost::asio::ssl;
|
||||
* typedef ssl::stream<tcp::socket> ssl_socket;
|
||||
*
|
||||
* // Create a context that uses the default paths for finding CA certificates.
|
||||
* ssl::context ctx(ssl::context::sslv23);
|
||||
* ctx.set_default_verify_paths();
|
||||
*
|
||||
* // Open a socket and connect it to the remote host.
|
||||
* boost::asio::io_context io_context;
|
||||
* ssl_socket sock(io_context, ctx);
|
||||
* tcp::resolver resolver(io_context);
|
||||
* tcp::resolver::query query("host.name", "https");
|
||||
* boost::asio::connect(sock.lowest_layer(), resolver.resolve(query));
|
||||
* sock.lowest_layer().set_option(tcp::no_delay(true));
|
||||
*
|
||||
* // Perform SSL handshake and verify the remote host's certificate.
|
||||
* sock.set_verify_mode(ssl::verify_peer);
|
||||
* sock.set_verify_callback(ssl::host_name_verification("host.name"));
|
||||
* sock.handshake(ssl_socket::client);
|
||||
*
|
||||
* // ... read and write as normal ...
|
||||
* @endcode
|
||||
*/
|
||||
class host_name_verification
|
||||
{
|
||||
public:
|
||||
/// The type of the function object's result.
|
||||
typedef bool result_type;
|
||||
|
||||
/// Constructor.
|
||||
explicit host_name_verification(const std::string& host)
|
||||
: host_(host)
|
||||
{
|
||||
}
|
||||
|
||||
/// Perform certificate verification.
|
||||
BOOST_ASIO_DECL bool operator()(bool preverified, verify_context& ctx) const;
|
||||
|
||||
private:
|
||||
// Helper function to check a host name against an IPv4 address
|
||||
// The host name to be checked.
|
||||
std::string host_;
|
||||
};
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HEADER_ONLY)
|
||||
# include <boost/asio/ssl/impl/host_name_verification.ipp>
|
||||
#endif // defined(BOOST_ASIO_HEADER_ONLY)
|
||||
|
||||
#endif // BOOST_ASIO_SSL_HOST_NAME_VERIFICATION_HPP
|
||||
@@ -3,7 +3,7 @@
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
|
||||
// Copyright (c) 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -48,6 +48,7 @@ struct context::evp_pkey_cleanup
|
||||
~evp_pkey_cleanup() { if (p) ::EVP_PKEY_free(p); }
|
||||
};
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
||||
struct context::rsa_cleanup
|
||||
{
|
||||
RSA* p;
|
||||
@@ -59,6 +60,7 @@ struct context::dh_cleanup
|
||||
DH* p;
|
||||
~dh_cleanup() { if (p) ::DH_free(p); }
|
||||
};
|
||||
#endif // (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
||||
|
||||
context::context(context::method m)
|
||||
: handle_(0)
|
||||
@@ -358,15 +360,23 @@ context::context(context::method m)
|
||||
|
||||
if (handle_ == 0)
|
||||
{
|
||||
boost::system::error_code ec(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
boost::system::error_code ec = translate_error(::ERR_get_error());
|
||||
boost::asio::detail::throw_error(ec, "context");
|
||||
}
|
||||
|
||||
set_options(no_compression);
|
||||
}
|
||||
|
||||
context::context(context::native_handle_type native_handle)
|
||||
: handle_(native_handle)
|
||||
{
|
||||
if (!handle_)
|
||||
{
|
||||
boost::asio::detail::throw_error(
|
||||
boost::asio::error::invalid_argument, "context");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
context::context(context&& other)
|
||||
{
|
||||
@@ -387,7 +397,10 @@ context::~context()
|
||||
{
|
||||
if (handle_)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
||||
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
||||
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
||||
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
||||
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
void* cb_userdata = handle_->default_passwd_callback_userdata;
|
||||
@@ -398,7 +411,10 @@ context::~context()
|
||||
static_cast<detail::password_callback_base*>(
|
||||
cb_userdata);
|
||||
delete callback;
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
||||
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
||||
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
||||
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
::SSL_CTX_set_default_passwd_cb_userdata(handle_, 0);
|
||||
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
handle_->default_passwd_callback_userdata = 0;
|
||||
@@ -530,9 +546,7 @@ BOOST_ASIO_SYNC_OP_VOID context::load_verify_file(
|
||||
|
||||
if (::SSL_CTX_load_verify_locations(handle_, filename.c_str(), 0) != 1)
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -557,17 +571,23 @@ BOOST_ASIO_SYNC_OP_VOID context::add_certificate_authority(
|
||||
{
|
||||
if (X509_STORE* store = ::SSL_CTX_get_cert_store(handle_))
|
||||
{
|
||||
for (;;)
|
||||
for (bool added = false;; added = true)
|
||||
{
|
||||
x509_cleanup cert = { ::PEM_read_bio_X509(bio.p, 0, 0, 0) };
|
||||
if (!cert.p)
|
||||
break;
|
||||
{
|
||||
unsigned long err = ::ERR_get_error();
|
||||
if (added && ERR_GET_LIB(err) == ERR_LIB_PEM
|
||||
&& ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
|
||||
break;
|
||||
|
||||
ec = translate_error(err);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
if (::X509_STORE_add_cert(store, cert.p) != 1)
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
}
|
||||
@@ -592,9 +612,7 @@ BOOST_ASIO_SYNC_OP_VOID context::set_default_verify_paths(
|
||||
|
||||
if (::SSL_CTX_set_default_verify_paths(handle_) != 1)
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -616,9 +634,7 @@ BOOST_ASIO_SYNC_OP_VOID context::add_verify_path(
|
||||
|
||||
if (::SSL_CTX_load_verify_locations(handle_, 0, path.c_str()) != 1)
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -672,9 +688,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate(
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -710,9 +724,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_file(
|
||||
|
||||
if (::SSL_CTX_use_certificate_file(handle_, filename.c_str(), file_type) != 1)
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -735,7 +747,10 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain(
|
||||
bio_cleanup bio = { make_buffer_bio(chain) };
|
||||
if (bio.p)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
||||
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
||||
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
||||
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
||||
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
||||
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
@@ -748,21 +763,21 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain(
|
||||
cb_userdata) };
|
||||
if (!cert.p)
|
||||
{
|
||||
ec = boost::system::error_code(ERR_R_PEM_LIB,
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(ERR_R_PEM_LIB);
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
int result = ::SSL_CTX_use_certificate(handle_, cert.p);
|
||||
if (result == 0 || ::ERR_peek_error() != 0)
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if ((OPENSSL_VERSION_NUMBER >= 0x10002000L) \
|
||||
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
||||
|| LIBRESSL_VERSION_NUMBER >= 0x2090100fL)) \
|
||||
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
::SSL_CTX_clear_chain_certs(handle_);
|
||||
#else
|
||||
if (handle_->extra_certs)
|
||||
@@ -778,9 +793,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain(
|
||||
{
|
||||
if (!::SSL_CTX_add_extra_chain_cert(handle_, cacert))
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
}
|
||||
@@ -795,9 +808,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain(
|
||||
}
|
||||
}
|
||||
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -815,9 +826,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_certificate_chain_file(
|
||||
|
||||
if (::SSL_CTX_use_certificate_chain_file(handle_, filename.c_str()) != 1)
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -839,7 +848,10 @@ BOOST_ASIO_SYNC_OP_VOID context::use_private_key(
|
||||
{
|
||||
::ERR_clear_error();
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
||||
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
||||
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
||||
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
||||
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
||||
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
@@ -878,9 +890,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_private_key(
|
||||
}
|
||||
}
|
||||
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -906,17 +916,55 @@ BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key(
|
||||
{
|
||||
::ERR_clear_error();
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
||||
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
||||
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
||||
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
||||
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
||||
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
||||
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
||||
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
pem_password_cb* callback = handle_->default_passwd_callback;
|
||||
void* cb_userdata = handle_->default_passwd_callback_userdata;
|
||||
pem_password_cb* callback = handle_->default_passwd_callback;
|
||||
void* cb_userdata = handle_->default_passwd_callback_userdata;
|
||||
#endif // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
|
||||
bio_cleanup bio = { make_buffer_bio(private_key) };
|
||||
if (bio.p)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
evp_pkey_cleanup evp_private_key = { 0 };
|
||||
switch (format)
|
||||
{
|
||||
case context_base::asn1:
|
||||
evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0);
|
||||
break;
|
||||
case context_base::pem:
|
||||
evp_private_key.p = ::PEM_read_bio_PrivateKey(
|
||||
bio.p, 0, callback,
|
||||
cb_userdata);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ec = boost::asio::error::invalid_argument;
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
}
|
||||
|
||||
if (evp_private_key.p)
|
||||
{
|
||||
if (::EVP_PKEY_is_a(evp_private_key.p, "RSA") == 0)
|
||||
{
|
||||
ec = translate_error(
|
||||
ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY));
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1)
|
||||
{
|
||||
ec = boost::system::error_code();
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
}
|
||||
#else // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
rsa_cleanup rsa_private_key = { 0 };
|
||||
switch (format)
|
||||
{
|
||||
@@ -943,11 +991,10 @@ BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key(
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
}
|
||||
#endif // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
}
|
||||
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -975,9 +1022,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_private_key_file(
|
||||
|
||||
if (::SSL_CTX_use_PrivateKey_file(handle_, filename.c_str(), file_type) != 1)
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -997,6 +1042,53 @@ BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key_file(
|
||||
const std::string& filename, context::file_format format,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
::ERR_clear_error();
|
||||
|
||||
pem_password_cb* callback = ::SSL_CTX_get_default_passwd_cb(handle_);
|
||||
void* cb_userdata = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
||||
|
||||
bio_cleanup bio = { ::BIO_new_file(filename.c_str(), "r") };
|
||||
if (bio.p)
|
||||
{
|
||||
evp_pkey_cleanup evp_private_key = { 0 };
|
||||
switch (format)
|
||||
{
|
||||
case context_base::asn1:
|
||||
evp_private_key.p = ::d2i_PrivateKey_bio(bio.p, 0);
|
||||
break;
|
||||
case context_base::pem:
|
||||
evp_private_key.p = ::PEM_read_bio_PrivateKey(
|
||||
bio.p, 0, callback,
|
||||
cb_userdata);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ec = boost::asio::error::invalid_argument;
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
}
|
||||
|
||||
if (evp_private_key.p)
|
||||
{
|
||||
if (::EVP_PKEY_is_a(evp_private_key.p, "RSA") == 0)
|
||||
{
|
||||
ec = translate_error(
|
||||
ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY));
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
if (::SSL_CTX_use_PrivateKey(handle_, evp_private_key.p) == 1)
|
||||
{
|
||||
ec = boost::system::error_code();
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
#else // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
int file_type;
|
||||
switch (format)
|
||||
{
|
||||
@@ -1018,14 +1110,13 @@ BOOST_ASIO_SYNC_OP_VOID context::use_rsa_private_key_file(
|
||||
if (::SSL_CTX_use_RSAPrivateKey_file(
|
||||
handle_, filename.c_str(), file_type) != 1)
|
||||
{
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
ec = boost::system::error_code();
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
#endif // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
}
|
||||
|
||||
void context::use_tmp_dh(const const_buffer& dh)
|
||||
@@ -1046,9 +1137,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_tmp_dh(
|
||||
return do_use_tmp_dh(bio.p, ec);
|
||||
}
|
||||
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -1070,9 +1159,7 @@ BOOST_ASIO_SYNC_OP_VOID context::use_tmp_dh_file(
|
||||
return do_use_tmp_dh(bio.p, ec);
|
||||
}
|
||||
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -1081,6 +1168,19 @@ BOOST_ASIO_SYNC_OP_VOID context::do_use_tmp_dh(
|
||||
{
|
||||
::ERR_clear_error();
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
EVP_PKEY* p = ::PEM_read_bio_Parameters(bio, 0);
|
||||
if (p)
|
||||
{
|
||||
if (::SSL_CTX_set0_tmp_dh_pkey(handle_, p) == 1)
|
||||
{
|
||||
ec = boost::system::error_code();
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
else
|
||||
::EVP_PKEY_free(p);
|
||||
}
|
||||
#else // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
dh_cleanup dh = { ::PEM_read_bio_DHparams(bio, 0, 0, 0) };
|
||||
if (dh.p)
|
||||
{
|
||||
@@ -1090,10 +1190,9 @@ BOOST_ASIO_SYNC_OP_VOID context::do_use_tmp_dh(
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
}
|
||||
#endif // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
|
||||
ec = boost::system::error_code(
|
||||
static_cast<int>(::ERR_get_error()),
|
||||
boost::asio::error::get_ssl_category());
|
||||
ec = translate_error(::ERR_get_error());
|
||||
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
@@ -1145,7 +1244,10 @@ int context::verify_callback_function(int preverified, X509_STORE_CTX* ctx)
|
||||
BOOST_ASIO_SYNC_OP_VOID context::do_set_password_callback(
|
||||
detail::password_callback_base* callback, boost::system::error_code& ec)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if ((OPENSSL_VERSION_NUMBER >= 0x10100000L) \
|
||||
&& (!defined(LIBRESSL_VERSION_NUMBER) \
|
||||
|| LIBRESSL_VERSION_NUMBER >= 0x2070000fL)) \
|
||||
|| defined(BOOST_ASIO_USE_WOLFSSL)
|
||||
void* old_callback = ::SSL_CTX_get_default_passwd_cb_userdata(handle_);
|
||||
::SSL_CTX_set_default_passwd_cb_userdata(handle_, callback);
|
||||
#else // (OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
@@ -1197,6 +1299,21 @@ BIO* context::make_buffer_bio(const const_buffer& b)
|
||||
static_cast<int>(b.size()));
|
||||
}
|
||||
|
||||
boost::system::error_code context::translate_error(long error)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
if (ERR_SYSTEM_ERROR(error))
|
||||
{
|
||||
return boost::system::error_code(
|
||||
static_cast<int>(ERR_GET_REASON(error)),
|
||||
boost::asio::error::get_system_category());
|
||||
}
|
||||
#endif // (OPENSSL_VERSION_NUMBER >= 0x30000000L)
|
||||
|
||||
return boost::system::error_code(static_cast<int>(error),
|
||||
boost::asio::error::get_ssl_category());
|
||||
}
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/impl/error.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -36,8 +36,30 @@ public:
|
||||
|
||||
std::string message(int value) const
|
||||
{
|
||||
const char* s = ::ERR_reason_error_string(value);
|
||||
return s ? s : "asio.ssl error";
|
||||
const char* reason = ::ERR_reason_error_string(value);
|
||||
if (reason)
|
||||
{
|
||||
const char* lib = ::ERR_lib_error_string(value);
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
||||
const char* func = ::ERR_func_error_string(value);
|
||||
#else // (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
||||
const char* func = 0;
|
||||
#endif // (OPENSSL_VERSION_NUMBER < 0x30000000L)
|
||||
std::string result(reason);
|
||||
if (lib || func)
|
||||
{
|
||||
result += " (";
|
||||
if (lib)
|
||||
result += lib;
|
||||
if (lib && func)
|
||||
result += ", ";
|
||||
if (func)
|
||||
result += func;
|
||||
result += ")";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return "asio.ssl error";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// ssl/impl/host_name_verification.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_ASIO_SSL_IMPL_HOST_NAME_VERIFICATION_IPP
|
||||
#define BOOST_ASIO_SSL_IMPL_HOST_NAME_VERIFICATION_IPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
#include <boost/asio/ssl/host_name_verification.hpp>
|
||||
#include <boost/asio/ssl/detail/openssl_types.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
bool host_name_verification::operator()(
|
||||
bool preverified, verify_context& ctx) const
|
||||
{
|
||||
using namespace std; // For memcmp.
|
||||
|
||||
// Don't bother looking at certificates that have failed pre-verification.
|
||||
if (!preverified)
|
||||
return false;
|
||||
|
||||
// We're only interested in checking the certificate at the end of the chain.
|
||||
int depth = X509_STORE_CTX_get_error_depth(ctx.native_handle());
|
||||
if (depth > 0)
|
||||
return true;
|
||||
|
||||
// Try converting the host name to an address. If it is an address then we
|
||||
// need to look for an IP address in the certificate rather than a host name.
|
||||
boost::system::error_code ec;
|
||||
ip::address address = ip::make_address(host_, ec);
|
||||
const bool is_address = !ec;
|
||||
(void)address;
|
||||
|
||||
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
|
||||
|
||||
if (is_address)
|
||||
{
|
||||
return X509_check_ip_asc(cert, host_.c_str(), 0) == 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char* peername = 0;
|
||||
const int result = X509_check_host(cert,
|
||||
host_.c_str(), host_.size(), 0, &peername);
|
||||
OPENSSL_free(peername);
|
||||
return result == 1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ssl
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // BOOST_ASIO_SSL_IMPL_HOST_NAME_VERIFICATION_IPP
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/impl/rfc2818_verification.ipp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
@@ -159,4 +161,6 @@ bool rfc2818_verification::match_pattern(const char* pattern,
|
||||
|
||||
#include <boost/asio/detail/pop_options.hpp>
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
#endif // BOOST_ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// impl/ssl/src.hpp
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <boost/asio/ssl/impl/error.ipp>
|
||||
#include <boost/asio/ssl/detail/impl/engine.ipp>
|
||||
#include <boost/asio/ssl/detail/impl/openssl_init.ipp>
|
||||
#include <boost/asio/ssl/impl/host_name_verification.ipp>
|
||||
#include <boost/asio/ssl/impl/rfc2818_verification.ipp>
|
||||
|
||||
#endif // BOOST_ASIO_SSL_IMPL_SRC_HPP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/rfc2818_verification.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
#include <string>
|
||||
#include <boost/asio/ssl/detail/openssl_types.hpp>
|
||||
#include <boost/asio/ssl/verify_context.hpp>
|
||||
@@ -27,8 +29,8 @@ namespace boost {
|
||||
namespace asio {
|
||||
namespace ssl {
|
||||
|
||||
/// Verifies a certificate against a hostname according to the rules described
|
||||
/// in RFC 2818.
|
||||
/// (Deprecated. Use ssl::host_name_verification.) Verifies a certificate
|
||||
/// against a hostname according to the rules described in RFC 2818.
|
||||
/**
|
||||
* @par Example
|
||||
* The following example shows how to synchronously open a secure connection to
|
||||
@@ -93,4 +95,6 @@ private:
|
||||
# include <boost/asio/ssl/impl/rfc2818_verification.ipp>
|
||||
#endif // defined(BOOST_ASIO_HEADER_ONLY)
|
||||
|
||||
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
||||
|
||||
#endif // BOOST_ASIO_SSL_RFC2818_VERIFICATION_HPP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/stream.hpp
|
||||
// ~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -66,6 +66,13 @@ class stream :
|
||||
public stream_base,
|
||||
private noncopyable
|
||||
{
|
||||
private:
|
||||
class initiate_async_handshake;
|
||||
class initiate_async_buffered_handshake;
|
||||
class initiate_async_shutdown;
|
||||
class initiate_async_write_some;
|
||||
class initiate_async_read_some;
|
||||
|
||||
public:
|
||||
/// The native handle type of the SSL stream.
|
||||
typedef SSL* native_handle_type;
|
||||
@@ -101,6 +108,23 @@ public:
|
||||
core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct a stream from an existing native implementation.
|
||||
/**
|
||||
* This constructor creates a stream and initialises the underlying stream
|
||||
* object. On success, ownership of the native implementation is transferred
|
||||
* to the stream, and it will be cleaned up when the stream is destroyed.
|
||||
*
|
||||
* @param arg The argument to be passed to initialise the underlying stream.
|
||||
*
|
||||
* @param handle An existing native SSL implementation.
|
||||
*/
|
||||
template <typename Arg>
|
||||
stream(Arg&& arg, native_handle_type handle)
|
||||
: next_layer_(BOOST_ASIO_MOVE_CAST(Arg)(arg)),
|
||||
core_(handle, next_layer_.lowest_layer().get_executor())
|
||||
{
|
||||
}
|
||||
#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
template <typename Arg>
|
||||
stream(Arg& arg, context& ctx)
|
||||
@@ -108,6 +132,45 @@ public:
|
||||
core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Arg>
|
||||
stream(Arg& arg, native_handle_type handle)
|
||||
: next_layer_(arg),
|
||||
core_(handle, next_layer_.lowest_layer().get_executor())
|
||||
{
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
/// Move-construct a stream from another.
|
||||
/**
|
||||
* @param other The other stream object from which the move will occur. Must
|
||||
* have no outstanding asynchronous operations associated with it. Following
|
||||
* the move, @c other has a valid but unspecified state where the only safe
|
||||
* operation is destruction, or use as the target of a move assignment.
|
||||
*/
|
||||
stream(stream&& other)
|
||||
: next_layer_(BOOST_ASIO_MOVE_CAST(Stream)(other.next_layer_)),
|
||||
core_(BOOST_ASIO_MOVE_CAST(detail::stream_core)(other.core_))
|
||||
{
|
||||
}
|
||||
|
||||
/// Move-assign a stream from another.
|
||||
/**
|
||||
* @param other The other stream object from which the move will occur. Must
|
||||
* have no outstanding asynchronous operations associated with it. Following
|
||||
* the move, @c other has a valid but unspecified state where the only safe
|
||||
* operation is destruction, or use as the target of a move assignment.
|
||||
*/
|
||||
stream& operator=(stream&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
next_layer_ = BOOST_ASIO_MOVE_CAST(Stream)(other.next_layer_);
|
||||
core_ = BOOST_ASIO_MOVE_CAST(detail::stream_core)(other.core_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
|
||||
|
||||
/// Destructor.
|
||||
@@ -419,33 +482,63 @@ public:
|
||||
/// Start an asynchronous SSL handshake.
|
||||
/**
|
||||
* This function is used to asynchronously perform an SSL handshake on the
|
||||
* stream. This function call always returns immediately.
|
||||
* stream. It is an initiating function for an @ref asynchronous_operation,
|
||||
* and always returns immediately.
|
||||
*
|
||||
* @param type The type of handshaking to be performed, i.e. as a client or as
|
||||
* a server.
|
||||
*
|
||||
* @param handler The handler to be called when the handshake operation
|
||||
* completes. Copies will be made of the handler as required. The equivalent
|
||||
* function signature of the handler must be:
|
||||
* @param token The @ref completion_token that will be used to produce a
|
||||
* completion handler, which will be called when the handshake completes.
|
||||
* Potential completion tokens include @ref use_future, @ref use_awaitable,
|
||||
* @ref yield_context, or a function object with the correct completion
|
||||
* signature. The function signature of the completion handler must be:
|
||||
* @code void handler(
|
||||
* const boost::system::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the completion handler will not be invoked from within this function.
|
||||
* On immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Completion Signature
|
||||
* @code void(boost::system::error_code) @endcode
|
||||
*
|
||||
* @par Per-Operation Cancellation
|
||||
* This asynchronous operation supports cancellation for the following
|
||||
* boost::asio::cancellation_type values:
|
||||
*
|
||||
* @li @c cancellation_type::terminal
|
||||
*
|
||||
* @li @c cancellation_type::partial
|
||||
*
|
||||
* if they are also supported by the @c Stream type's @c async_read_some and
|
||||
* @c async_write_some operations.
|
||||
*/
|
||||
template <typename HandshakeHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler,
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
||||
HandshakeToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(HandshakeToken,
|
||||
void (boost::system::error_code))
|
||||
async_handshake(handshake_type type,
|
||||
BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(HandshakeToken) token
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<HandshakeToken,
|
||||
void (boost::system::error_code)>(
|
||||
declval<initiate_async_handshake>(), token, type)))
|
||||
{
|
||||
return async_initiate<HandshakeHandler,
|
||||
return async_initiate<HandshakeToken,
|
||||
void (boost::system::error_code)>(
|
||||
initiate_async_handshake(), handler, this, type);
|
||||
initiate_async_handshake(this), token, type);
|
||||
}
|
||||
|
||||
/// Start an asynchronous SSL handshake.
|
||||
/**
|
||||
* This function is used to asynchronously perform an SSL handshake on the
|
||||
* stream. This function call always returns immediately.
|
||||
* stream. It is an initiating function for an @ref asynchronous_operation,
|
||||
* and always returns immediately.
|
||||
*
|
||||
* @param type The type of handshaking to be performed, i.e. as a client or as
|
||||
* a server.
|
||||
@@ -453,25 +546,53 @@ public:
|
||||
* @param buffers The buffered data to be reused for the handshake. Although
|
||||
* the buffers object may be copied as necessary, ownership of the underlying
|
||||
* buffers is retained by the caller, which must guarantee that they remain
|
||||
* valid until the handler is called.
|
||||
* valid until the completion handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the handshake operation
|
||||
* completes. Copies will be made of the handler as required. The equivalent
|
||||
* function signature of the handler must be:
|
||||
* @param token The @ref completion_token that will be used to produce a
|
||||
* completion handler, which will be called when the handshake completes.
|
||||
* Potential completion tokens include @ref use_future, @ref use_awaitable,
|
||||
* @ref yield_context, or a function object with the correct completion
|
||||
* signature. The function signature of the completion handler must be:
|
||||
* @code void handler(
|
||||
* const boost::system::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Amount of buffers used in handshake.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the completion handler will not be invoked from within this function.
|
||||
* On immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Completion Signature
|
||||
* @code void(boost::system::error_code, std::size_t) @endcode
|
||||
*
|
||||
* @par Per-Operation Cancellation
|
||||
* This asynchronous operation supports cancellation for the following
|
||||
* boost::asio::cancellation_type values:
|
||||
*
|
||||
* @li @c cancellation_type::terminal
|
||||
*
|
||||
* @li @c cancellation_type::partial
|
||||
*
|
||||
* if they are also supported by the @c Stream type's @c async_read_some and
|
||||
* @c async_write_some operations.
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler,
|
||||
template <typename ConstBufferSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) BufferedHandshakeToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(BufferedHandshakeToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_handshake(handshake_type type, const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeToken) token
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<BufferedHandshakeToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<initiate_async_buffered_handshake>(), token, type, buffers)))
|
||||
{
|
||||
return async_initiate<BufferedHandshakeHandler,
|
||||
return async_initiate<BufferedHandshakeToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_buffered_handshake(), handler, this, type, buffers);
|
||||
initiate_async_buffered_handshake(this), token, type, buffers);
|
||||
}
|
||||
|
||||
/// Shut down SSL on the stream.
|
||||
@@ -503,24 +624,54 @@ public:
|
||||
|
||||
/// Asynchronously shut down SSL on the stream.
|
||||
/**
|
||||
* This function is used to asynchronously shut down SSL on the stream. This
|
||||
* function call always returns immediately.
|
||||
* This function is used to asynchronously shut down SSL on the stream. It is
|
||||
* an initiating function for an @ref asynchronous_operation, and always
|
||||
* returns immediately.
|
||||
*
|
||||
* @param handler The handler to be called when the handshake operation
|
||||
* completes. Copies will be made of the handler as required. The equivalent
|
||||
* function signature of the handler must be:
|
||||
* @param token The @ref completion_token that will be used to produce a
|
||||
* completion handler, which will be called when the shutdown completes.
|
||||
* Potential completion tokens include @ref use_future, @ref use_awaitable,
|
||||
* @ref yield_context, or a function object with the correct completion
|
||||
* signature. The function signature of the completion handler must be:
|
||||
* @code void handler(
|
||||
* const boost::system::error_code& error // Result of operation.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the completion handler will not be invoked from within this function.
|
||||
* On immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Completion Signature
|
||||
* @code void(boost::system::error_code) @endcode
|
||||
*
|
||||
* @par Per-Operation Cancellation
|
||||
* This asynchronous operation supports cancellation for the following
|
||||
* boost::asio::cancellation_type values:
|
||||
*
|
||||
* @li @c cancellation_type::terminal
|
||||
*
|
||||
* @li @c cancellation_type::partial
|
||||
*
|
||||
* if they are also supported by the @c Stream type's @c async_read_some and
|
||||
* @c async_write_some operations.
|
||||
*/
|
||||
template <typename ShutdownHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ShutdownHandler,
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
|
||||
ShutdownToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ShutdownToken,
|
||||
void (boost::system::error_code))
|
||||
async_shutdown(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
|
||||
async_shutdown(
|
||||
BOOST_ASIO_MOVE_ARG(ShutdownToken) token
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<ShutdownToken,
|
||||
void (boost::system::error_code)>(
|
||||
declval<initiate_async_shutdown>(), token)))
|
||||
{
|
||||
return async_initiate<ShutdownHandler,
|
||||
return async_initiate<ShutdownToken,
|
||||
void (boost::system::error_code)>(
|
||||
initiate_async_shutdown(), handler, this);
|
||||
initiate_async_shutdown(this), token);
|
||||
}
|
||||
|
||||
/// Write some data to the stream.
|
||||
@@ -575,35 +726,64 @@ public:
|
||||
/// Start an asynchronous write.
|
||||
/**
|
||||
* This function is used to asynchronously write one or more bytes of data to
|
||||
* the stream. The function call always returns immediately.
|
||||
* the stream. It is an initiating function for an @ref
|
||||
* asynchronous_operation, and always returns immediately.
|
||||
*
|
||||
* @param buffers The data to be written to the stream. Although the buffers
|
||||
* object may be copied as necessary, ownership of the underlying buffers is
|
||||
* retained by the caller, which must guarantee that they remain valid until
|
||||
* the handler is called.
|
||||
* the completion handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the write operation completes.
|
||||
* Copies will be made of the handler as required. The equivalent function
|
||||
* signature of the handler must be:
|
||||
* @param token The @ref completion_token that will be used to produce a
|
||||
* completion handler, which will be called when the write completes.
|
||||
* Potential completion tokens include @ref use_future, @ref use_awaitable,
|
||||
* @ref yield_context, or a function object with the correct completion
|
||||
* signature. The function signature of the completion handler must be:
|
||||
* @code void handler(
|
||||
* const boost::system::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes written.
|
||||
* std::size_t bytes_transferred // Number of bytes written.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the completion handler will not be invoked from within this function.
|
||||
* On immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Completion Signature
|
||||
* @code void(boost::system::error_code, std::size_t) @endcode
|
||||
*
|
||||
* @note The async_write_some operation may not transmit all of the data to
|
||||
* the peer. Consider using the @ref async_write function if you need to
|
||||
* ensure that all data is written before the asynchronous operation
|
||||
* completes.
|
||||
*
|
||||
* @par Per-Operation Cancellation
|
||||
* This asynchronous operation supports cancellation for the following
|
||||
* boost::asio::cancellation_type values:
|
||||
*
|
||||
* @li @c cancellation_type::terminal
|
||||
*
|
||||
* @li @c cancellation_type::partial
|
||||
*
|
||||
* if they are also supported by the @c Stream type's @c async_read_some and
|
||||
* @c async_write_some operations.
|
||||
*/
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
|
||||
template <typename ConstBufferSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) WriteToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_write_some(const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(WriteToken) token
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<initiate_async_write_some>(), token, buffers)))
|
||||
{
|
||||
return async_initiate<WriteHandler,
|
||||
return async_initiate<WriteToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_write_some(), handler, this, buffers);
|
||||
initiate_async_write_some(this), token, buffers);
|
||||
}
|
||||
|
||||
/// Read some data from the stream.
|
||||
@@ -658,60 +838,117 @@ public:
|
||||
/// Start an asynchronous read.
|
||||
/**
|
||||
* This function is used to asynchronously read one or more bytes of data from
|
||||
* the stream. The function call always returns immediately.
|
||||
* the stream. It is an initiating function for an @ref
|
||||
* asynchronous_operation, and always returns immediately.
|
||||
*
|
||||
* @param buffers The buffers into which the data will be read. Although the
|
||||
* buffers object may be copied as necessary, ownership of the underlying
|
||||
* buffers is retained by the caller, which must guarantee that they remain
|
||||
* valid until the handler is called.
|
||||
* valid until the completion handler is called.
|
||||
*
|
||||
* @param handler The handler to be called when the read operation completes.
|
||||
* Copies will be made of the handler as required. The equivalent function
|
||||
* signature of the handler must be:
|
||||
* @param token The @ref completion_token that will be used to produce a
|
||||
* completion handler, which will be called when the read completes.
|
||||
* Potential completion tokens include @ref use_future, @ref use_awaitable,
|
||||
* @ref yield_context, or a function object with the correct completion
|
||||
* signature. The function signature of the completion handler must be:
|
||||
* @code void handler(
|
||||
* const boost::system::error_code& error, // Result of operation.
|
||||
* std::size_t bytes_transferred // Number of bytes read.
|
||||
* std::size_t bytes_transferred // Number of bytes read.
|
||||
* ); @endcode
|
||||
* Regardless of whether the asynchronous operation completes immediately or
|
||||
* not, the completion handler will not be invoked from within this function.
|
||||
* On immediate completion, invocation of the handler will be performed in a
|
||||
* manner equivalent to using boost::asio::post().
|
||||
*
|
||||
* @par Completion Signature
|
||||
* @code void(boost::system::error_code, std::size_t) @endcode
|
||||
*
|
||||
* @note The async_read_some operation may not read all of the requested
|
||||
* number of bytes. Consider using the @ref async_read function if you need to
|
||||
* ensure that the requested amount of data is read before the asynchronous
|
||||
* operation completes.
|
||||
*
|
||||
* @par Per-Operation Cancellation
|
||||
* This asynchronous operation supports cancellation for the following
|
||||
* boost::asio::cancellation_type values:
|
||||
*
|
||||
* @li @c cancellation_type::terminal
|
||||
*
|
||||
* @li @c cancellation_type::partial
|
||||
*
|
||||
* if they are also supported by the @c Stream type's @c async_read_some and
|
||||
* @c async_write_some operations.
|
||||
*/
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
|
||||
template <typename MutableBufferSequence,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
|
||||
std::size_t)) ReadToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
|
||||
void (boost::system::error_code, std::size_t))
|
||||
async_read_some(const MutableBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
BOOST_ASIO_MOVE_ARG(ReadToken) token
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
|
||||
async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
declval<initiate_async_read_some>(), token, buffers)))
|
||||
{
|
||||
return async_initiate<ReadHandler,
|
||||
return async_initiate<ReadToken,
|
||||
void (boost::system::error_code, std::size_t)>(
|
||||
initiate_async_read_some(), handler, this, buffers);
|
||||
initiate_async_read_some(this), token, buffers);
|
||||
}
|
||||
|
||||
private:
|
||||
struct initiate_async_handshake
|
||||
class initiate_async_handshake
|
||||
{
|
||||
public:
|
||||
typedef typename stream::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_handshake(stream* self)
|
||||
: self_(self)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return self_->get_executor();
|
||||
}
|
||||
|
||||
template <typename HandshakeHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
|
||||
stream* self, handshake_type type) const
|
||||
handshake_type type) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
// does not meet the documented type requirements for a HandshakeHandler.
|
||||
BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
|
||||
|
||||
boost::asio::detail::non_const_lvalue<HandshakeHandler> handler2(handler);
|
||||
detail::async_io(self->next_layer_, self->core_,
|
||||
detail::async_io(self_->next_layer_, self_->core_,
|
||||
detail::handshake_op(type), handler2.value);
|
||||
}
|
||||
|
||||
private:
|
||||
stream* self_;
|
||||
};
|
||||
|
||||
struct initiate_async_buffered_handshake
|
||||
class initiate_async_buffered_handshake
|
||||
{
|
||||
public:
|
||||
typedef typename stream::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_buffered_handshake(stream* self)
|
||||
: self_(self)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return self_->get_executor();
|
||||
}
|
||||
|
||||
template <typename BufferedHandshakeHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,
|
||||
stream* self, handshake_type type,
|
||||
const ConstBufferSequence& buffers) const
|
||||
handshake_type type, const ConstBufferSequence& buffers) const
|
||||
{
|
||||
// If you get an error on the following line it means that your
|
||||
// handler does not meet the documented type requirements for a
|
||||
@@ -721,58 +958,108 @@ private:
|
||||
|
||||
boost::asio::detail::non_const_lvalue<
|
||||
BufferedHandshakeHandler> handler2(handler);
|
||||
detail::async_io(self->next_layer_, self->core_,
|
||||
detail::async_io(self_->next_layer_, self_->core_,
|
||||
detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
|
||||
handler2.value);
|
||||
}
|
||||
|
||||
private:
|
||||
stream* self_;
|
||||
};
|
||||
|
||||
struct initiate_async_shutdown
|
||||
class initiate_async_shutdown
|
||||
{
|
||||
public:
|
||||
typedef typename stream::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_shutdown(stream* self)
|
||||
: self_(self)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return self_->get_executor();
|
||||
}
|
||||
|
||||
template <typename ShutdownHandler>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler,
|
||||
stream* self) const
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
// does not meet the documented type requirements for a ShutdownHandler.
|
||||
BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(ShutdownHandler, handler) type_check;
|
||||
|
||||
boost::asio::detail::non_const_lvalue<ShutdownHandler> handler2(handler);
|
||||
detail::async_io(self->next_layer_, self->core_,
|
||||
detail::async_io(self_->next_layer_, self_->core_,
|
||||
detail::shutdown_op(), handler2.value);
|
||||
}
|
||||
|
||||
private:
|
||||
stream* self_;
|
||||
};
|
||||
|
||||
struct initiate_async_write_some
|
||||
class initiate_async_write_some
|
||||
{
|
||||
public:
|
||||
typedef typename stream::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_write_some(stream* self)
|
||||
: self_(self)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return self_->get_executor();
|
||||
}
|
||||
|
||||
template <typename WriteHandler, typename ConstBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
|
||||
stream* self, const ConstBufferSequence& buffers) const
|
||||
const ConstBufferSequence& buffers) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
// does not meet the documented type requirements for a WriteHandler.
|
||||
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
|
||||
|
||||
boost::asio::detail::non_const_lvalue<WriteHandler> handler2(handler);
|
||||
detail::async_io(self->next_layer_, self->core_,
|
||||
detail::async_io(self_->next_layer_, self_->core_,
|
||||
detail::write_op<ConstBufferSequence>(buffers), handler2.value);
|
||||
}
|
||||
|
||||
private:
|
||||
stream* self_;
|
||||
};
|
||||
|
||||
struct initiate_async_read_some
|
||||
class initiate_async_read_some
|
||||
{
|
||||
public:
|
||||
typedef typename stream::executor_type executor_type;
|
||||
|
||||
explicit initiate_async_read_some(stream* self)
|
||||
: self_(self)
|
||||
{
|
||||
}
|
||||
|
||||
executor_type get_executor() const BOOST_ASIO_NOEXCEPT
|
||||
{
|
||||
return self_->get_executor();
|
||||
}
|
||||
|
||||
template <typename ReadHandler, typename MutableBufferSequence>
|
||||
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
|
||||
stream* self, const MutableBufferSequence& buffers) const
|
||||
const MutableBufferSequence& buffers) const
|
||||
{
|
||||
// If you get an error on the following line it means that your handler
|
||||
// does not meet the documented type requirements for a ReadHandler.
|
||||
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
|
||||
|
||||
boost::asio::detail::non_const_lvalue<ReadHandler> handler2(handler);
|
||||
detail::async_io(self->next_layer_, self->core_,
|
||||
detail::async_io(self_->next_layer_, self_->core_,
|
||||
detail::read_op<MutableBufferSequence>(buffers), handler2.value);
|
||||
}
|
||||
|
||||
private:
|
||||
stream* self_;
|
||||
};
|
||||
|
||||
Stream next_layer_;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/stream_base.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/verify_context.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ssl/verify_mode.hpp
|
||||
// ~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
Reference in New Issue
Block a user