9 #ifndef BOTAN_ASIO_STREAM_H_
10 #define BOTAN_ASIO_STREAM_H_
12 #include <botan/build.h>
15 #include <boost/version.hpp>
16 #if BOOST_VERSION >= 106600
18 #include <botan/asio_async_ops.h>
19 #include <botan/asio_context.h>
20 #include <botan/asio_error.h>
22 #include <botan/tls_callbacks.h>
23 #include <botan/tls_channel.h>
24 #include <botan/tls_client.h>
25 #include <botan/tls_magic.h>
29 #define BOOST_ASIO_DISABLE_SERIAL_PORT
30 #include <boost/asio.hpp>
31 #include <boost/beast/core/flat_buffer.hpp>
35 #include <type_traits>
48 template <
class StreamLayer,
class ChannelT = Channel>
63 template <
typename... Args>
82 template <
typename Arg>
167 template <
typename verify_mode>
179 template <
typename verify_mode>
200 boost::system::error_code ec;
202 boost::asio::detail::throw_error(ec,
"handshake");
228 native_handle()->received_data(static_cast<const uint8_t*>(read_buffer.data()), read_buffer.size());
238 catch(
const std::exception&)
257 template <
typename HandshakeHandler>
263 boost::system::error_code ec;
268 boost::asio::async_completion<HandshakeHandler, void(boost::system::error_code)>
init(
handler);
271 op{std::move(init.completion_handler), *
this, ec};
273 return init.result.get();
277 template <
typename ConstBufferSequence,
typename BufferedHandshakeHandler>
279 void(boost::system::error_code, std::size_t))
281 BufferedHandshakeHandler&&
handler)
314 catch(
const std::exception&)
333 boost::system::error_code ec;
335 boost::asio::detail::throw_error(ec,
"shutdown");
346 template <
typename ShutdownHandler>
370 template <
typename MutableBufferSequence>
372 boost::system::error_code& ec)
383 native_handle()->received_data(static_cast<const uint8_t*>(read_buffer.data()), read_buffer.size());
393 catch(
const std::exception&)
411 template <
typename MutableBufferSequence>
414 boost::system::error_code ec;
416 boost::asio::detail::throw_error(ec,
"read_some");
430 template <
typename ConstBufferSequence>
432 boost::system::error_code& ec)
436 return !ec ? boost::asio::buffer_size(buffers) : 0;
449 template <
typename ConstBufferSequence>
452 boost::system::error_code ec;
454 boost::asio::detail::throw_error(ec,
"write_some");
466 template <
typename ConstBufferSequence,
typename WriteHandler>
469 void(boost::system::error_code, std::size_t))
471 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler,
handler) type_check;
473 boost::asio::async_completion<WriteHandler, void(boost::system::error_code, std::size_t)>
init(
handler);
475 boost::system::error_code ec;
483 op{std::move(init.completion_handler), *
this, std::size_t(0), ec};
484 return init.result.get();
488 op{std::move(init.completion_handler), *
this, boost::asio::buffer_size(
buffers)};
490 return init.result.get();
503 template <
typename MutableBufferSequence,
typename ReadHandler>
506 void(boost::system::error_code, std::size_t))
508 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler,
handler) type_check;
510 boost::asio::async_completion<ReadHandler, void(boost::system::error_code, std::size_t)>
init(
handler);
513 op{std::move(init.completion_handler), *
this,
buffers};
514 return init.result.get();
544 boost::asio::buffer_copy(
m_send_buffer.prepare(size), boost::asio::buffer(data, size))
551 boost::asio::buffer_copy(
m_receive_buffer.prepare(size), boost::asio::const_buffer(data, size))
562 return std::chrono::milliseconds(1000);
572 const std::vector<X509_Certificate>& cert_chain,
573 const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses,
574 const std::vector<Certificate_Store*>& trusted_roots,
576 const std::string& hostname,
601 template <
typename MutableBufferSequence>
608 const auto copiedBytes = boost::asio::buffer_copy(buffers,
m_receive_buffer.data());
623 template<
class T = ChannelT>
624 typename std::enable_if<!std::is_same<Channel, T>::value>
::type
636 template<
class T = ChannelT>
637 typename std::enable_if<std::is_same<Channel, T>::value>
::type
668 template <
typename ConstBufferSequence>
674 for(
auto it = boost::asio::buffer_sequence_begin(buffers);
675 !ec && it != boost::asio::buffer_sequence_end(buffers);
678 const boost::asio::const_buffer buffer = *it;
681 native_handle()->send(static_cast<const uint8_t*>(buffer.data()), buffer.size());
691 catch(
const std::exception&)
715 #endif // BOOST_VERSION
716 #endif // BOTAN_ASIO_STREAM_H_
RandomNumberGenerator & m_rng
void shutdown(boost::system::error_code &ec)
Shut down SSL on the stream.
size_t send_pending_encrypted_data(boost::system::error_code &ec)
std::enable_if<!std::is_same< Channel, T >::value >::type setup_native_handle(Connection_Side, boost::system::error_code &)
void set_verify_mode(verify_mode v, boost::system::error_code &ec)
void set_verify_callback(Verify_Callback callback)
Override the tls_verify_cert_chain callback.
const next_layer_type & next_layer() const
BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(BufferedHandshakeHandler, handler) type_check
const ConstBufferSequence & buffers
StreamCore(boost::beast::flat_buffer &receive_buffer, boost::beast::flat_buffer &send_buffer, Context &context)
const boost::asio::mutable_buffer m_input_buffer
Helper class that implements Botan::TLS::Callbacks.
virtual ErrorType error_type() const noexcept
void set_verify_depth(int depth)
auto async_handshake(Connection_Side side, HandshakeHandler &&handler) ->
Starts an asynchronous SSL handshake.
std::enable_if< std::is_same< Channel, T >::value >::type setup_native_handle(Connection_Side side, boost::system::error_code &ec)
Create the native handle.
throw Not_Implemented("buffered async handshake is not implemented")
typename std::remove_reference< StreamLayer >::type next_layer_type
void set_verify_callback(Context::Verify_Callback callback)
Override the tls_verify_cert_chain callback.
std::size_t write_some(const ConstBufferSequence &buffers, boost::system::error_code &ec)
Write some data to the stream.
auto async_read_some(const MutableBufferSequence &buffers, ReadHandler &&handler) -> BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void(boost::system::error_code, std::size_t))
Start an asynchronous read. The function call always returns immediately.
virtual void tls_verify_cert_chain(const std::vector< X509_Certificate > &cert_chain, const std::vector< std::shared_ptr< const OCSP::Response >> &ocsp_responses, const std::vector< Certificate_Store * > &trusted_roots, Usage_Type usage, const std::string &hostname, const TLS::Policy &policy)
std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const override
void async_shutdown(ShutdownHandler &&handler)
Asynchronously shut down SSL on the stream.
Credentials_Manager & m_credentials_manager
void tls_record_received(uint64_t, const uint8_t data[], std::size_t size) override
typename next_layer_type::executor_type executor_type
void handshake(Connection_Side side, boost::system::error_code &ec)
Performs SSL handshaking.
Stream & operator=(Stream &&other)=default
void tls_emit_data(const uint8_t data[], std::size_t size) override
Server_Information m_server_info
virtual ~Stream()=default
const boost::asio::mutable_buffer & input_buffer()
std::size_t write_some(const ConstBufferSequence &buffers)
Write some data to the stream.
std::size_t read_some(const MutableBufferSequence &buffers, boost::system::error_code &ec)
Read some data from the stream.
next_layer_type & next_layer()
boost::beast::flat_buffer & m_send_buffer
const ConstBufferSequence BufferedHandshakeHandler && handler
lowest_layer_type & lowest_layer()
std::size_t copy_received_data(MutableBufferSequence buffers)
Copy decrypted data into the user-provided buffer.
native_handle_type native_handle()
bool tls_session_established(const Botan::TLS::Session &) override
executor_type get_executor() noexcept
auto async_write_some(const ConstBufferSequence &buffers, WriteHandler &&handler) -> BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void(boost::system::error_code, std::size_t))
Start an asynchronous write. The function call always returns immediately.
boost::asio compatible SSL/TLS stream
boost::beast::flat_buffer m_send_buffer
std::size_t read_some(const MutableBufferSequence &buffers)
Read some data from the stream.
void set_verify_depth(int depth, boost::system::error_code &ec)
boost::asio::const_buffer send_buffer() const
#define BOTAN_UNUSED(...)
void tls_encrypt(const ConstBufferSequence &buffers, boost::system::error_code &ec)
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void(boost::system::error_code, std::size_t)) async_handshake(Connection_Side side
boost::beast::flat_buffer & m_receive_buffer
void handshake(Connection_Side side)
Performs SSL handshaking.
const lowest_layer_type & lowest_layer() const
const Verify_Callback & get_verify_callback() const
bool has_data_to_send() const
Check if encrypted data is available in the send buffer.
bool has_verify_callback() const
virtual ~StreamCore()=default
void shutdown()
Shut down SSL on the stream.
void tls_alert(Botan::TLS::Alert alert) override
void set_verify_mode(verify_mode v)
std::vector< uint8_t > m_input_buffer_space
Session_Manager & m_session_manager
bool has_received_data() const
Check if decrypted data is available in the receive buffer.
typename std::add_pointer< ChannelT >::type native_handle_type
typename next_layer_type::lowest_layer_type lowest_layer_type
Stream(Context &context, Args &&...args)
Construct a new Stream.
void consume_send_buffer(std::size_t bytesConsumed)
Mark bytes in the send buffer as consumed, removing them from the buffer.
std::unique_ptr< ChannelT > m_native_handle
void tls_verify_cert_chain(const std::vector< X509_Certificate > &cert_chain, const std::vector< std::shared_ptr< const OCSP::Response >> &ocsp_responses, const std::vector< Certificate_Store * > &trusted_roots, Usage_Type usage, const std::string &hostname, const TLS::Policy &policy) override
detail::fn_signature_helper< decltype(&Callbacks::tls_verify_cert_chain)>::type Verify_Callback
void set_verify_callback(Context::Verify_Callback callback, boost::system::error_code &ec)
Compatibility overload of set_verify_callback.
boost::beast::flat_buffer m_receive_buffer
Stream(Arg &&arg, Context &context)
Construct a new Stream.