Botan 3.2.0
Crypto and TLS for C&
Classes | Public Member Functions | Protected Member Functions | Protected Attributes | Friends | List of all members
Botan::TLS::Stream< StreamLayer, ChannelT > Class Template Reference

boost::asio compatible SSL/TLS stream More...

#include <asio_stream.h>

Classes

class  StreamCore
 Helper class that implements TLS::Callbacks. More...
 

Public Member Functions

bool shutdown_received () const
 Indicates whether a close_notify alert has been received from the peer.
 
construction
template<typename... Args>
 Stream (std::shared_ptr< Context > context, Args &&... args)
 Construct a new Stream.
 
template<typename Arg >
 Stream (Arg &&arg, std::shared_ptr< Context > context)
 Construct a new Stream.
 
virtual ~Stream ()=default
 
 Stream (Stream &&other)=default
 
Streamoperator= (Stream &&other)=default
 
 Stream (const Stream &other)=delete
 
Streamoperator= (const Stream &other)=delete
 
configuration and callback setters
void set_verify_callback (Context::Verify_Callback callback)
 Override the tls_verify_cert_chain callback.
 
void set_verify_callback (Context::Verify_Callback callback, boost::system::error_code &ec)
 Compatibility overload of set_verify_callback.
 
void set_verify_depth (int depth)
 
void set_verify_depth (int depth, boost::system::error_code &ec)
 
template<typename verify_mode >
void set_verify_mode (verify_mode v)
 
template<typename verify_mode >
void set_verify_mode (verify_mode v, boost::system::error_code &ec)
 
handshake methods
void handshake (Connection_Side side)
 Performs SSL handshaking.
 
void handshake (Connection_Side side, boost::system::error_code &ec)
 Performs SSL handshaking.
 
template<typename CompletionToken >
auto async_handshake (Botan::TLS::Connection_Side side, CompletionToken &&completion_token)
 Starts an asynchronous SSL handshake.
 
template<typename ConstBufferSequence , typename BufferedHandshakeHandler >
 async_handshake (Connection_Side side, const ConstBufferSequence &buffers, BufferedHandshakeHandler &&handler)
 
shutdown methods
void shutdown (boost::system::error_code &ec)
 Shut down SSL on the stream.
 
void shutdown ()
 Shut down SSL on the stream.
 
template<typename CompletionToken >
auto async_shutdown (CompletionToken &&completion_token)
 Asynchronously shut down SSL on the stream.
 
I/O methods
template<typename MutableBufferSequence >
std::size_t read_some (const MutableBufferSequence &buffers, boost::system::error_code &ec)
 Read some data from the stream.
 
template<typename MutableBufferSequence >
std::size_t read_some (const MutableBufferSequence &buffers)
 Read some data from the stream.
 
template<typename ConstBufferSequence >
std::size_t write_some (const ConstBufferSequence &buffers, boost::system::error_code &ec)
 Write some data to the stream.
 
template<typename ConstBufferSequence >
std::size_t write_some (const ConstBufferSequence &buffers)
 Write some data to the stream.
 
template<typename ConstBufferSequence , typename CompletionToken >
auto async_write_some (const ConstBufferSequence &buffers, CompletionToken &&completion_token)
 Start an asynchronous write. The function call always returns immediately.
 
template<typename MutableBufferSequence , typename CompletionToken >
auto async_read_some (const MutableBufferSequence &buffers, CompletionToken &&completion_token)
 Start an asynchronous read. The function call always returns immediately.
 

Protected Member Functions

void consume_send_buffer (std::size_t bytesConsumed)
 Mark bytes in the send buffer as consumed, removing them from the buffer.
 
template<typename MutableBufferSequence >
std::size_t copy_received_data (MutableBufferSequence buffers)
 Copy decrypted data into the user-provided buffer.
 
bool has_data_to_send () const
 Check if encrypted data is available in the send buffer.
 
bool has_received_data () const
 Check if decrypted data is available in the receive buffer.
 
const boost::asio::mutable_buffer & input_buffer ()
 
void process_encrypted_data (const boost::asio::const_buffer &read_buffer, boost::system::error_code &ec)
 Pass encrypted data to the native handle for processing.
 
boost::asio::const_buffer send_buffer () const
 
size_t send_pending_encrypted_data (boost::system::error_code &ec)
 Synchronously write encrypted data from the send buffer to the next layer.
 
void setup_native_handle (Connection_Side side, boost::system::error_code &ec)
 Create the native handle.
 
template<typename ConstBufferSequence >
void tls_encrypt (const ConstBufferSequence &buffers, boost::system::error_code &ec)
 Pass plaintext data to the native handle for processing.
 
template<typename Fun >
void try_with_error_code (Fun f, boost::system::error_code &ec)
 Catch exceptions and set an error_code.
 

Protected Attributes

std::shared_ptr< Contextm_context
 
std::shared_ptr< StreamCorem_core
 
const boost::asio::mutable_buffer m_input_buffer
 
std::vector< uint8_t > m_input_buffer_space
 
std::unique_ptr< ChannelT > m_native_handle
 
StreamLayer m_nextLayer
 

Friends

template<class H , class S , class A >
class detail::AsyncHandshakeOperation
 
template<class H , class S , class M , class A >
class detail::AsyncReadOperation
 
template<class H , class S , class A >
class detail::AsyncWriteOperation
 

boost::asio accessor methods

using next_layer_type = typename std::remove_reference< StreamLayer >::type
 
using lowest_layer_type = typename next_layer_type::lowest_layer_type
 
using executor_type = typename next_layer_type::executor_type
 
using native_handle_type = typename std::add_pointer< ChannelT >::type
 
const next_layer_typenext_layer () const
 
next_layer_typenext_layer ()
 
lowest_layer_typelowest_layer ()
 
const lowest_layer_typelowest_layer () const
 
executor_type get_executor () noexcept
 
native_handle_type native_handle ()
 

Detailed Description

template<class StreamLayer, class ChannelT = Channel>
class Botan::TLS::Stream< StreamLayer, ChannelT >

boost::asio compatible SSL/TLS stream

Template Parameters
StreamLayertype of the next layer, usually a network socket
ChannelTtype of the native_handle, defaults to TLS::Channel, only needed for testing purposes

Definition at line 47 of file asio_stream.h.

Member Typedef Documentation

◆ executor_type

template<class StreamLayer , class ChannelT = Channel>
using Botan::TLS::Stream< StreamLayer, ChannelT >::executor_type = typename next_layer_type::executor_type

Definition at line 123 of file asio_stream.h.

◆ lowest_layer_type

template<class StreamLayer , class ChannelT = Channel>
using Botan::TLS::Stream< StreamLayer, ChannelT >::lowest_layer_type = typename next_layer_type::lowest_layer_type

Definition at line 116 of file asio_stream.h.

◆ native_handle_type

template<class StreamLayer , class ChannelT = Channel>
using Botan::TLS::Stream< StreamLayer, ChannelT >::native_handle_type = typename std::add_pointer<ChannelT>::type

Definition at line 127 of file asio_stream.h.

◆ next_layer_type

template<class StreamLayer , class ChannelT = Channel>
using Botan::TLS::Stream< StreamLayer, ChannelT >::next_layer_type = typename std::remove_reference<StreamLayer>::type

Definition at line 98 of file asio_stream.h.

Constructor & Destructor Documentation

◆ Stream() [1/4]

template<class StreamLayer , class ChannelT = Channel>
template<typename... Args>
Botan::TLS::Stream< StreamLayer, ChannelT >::Stream ( std::shared_ptr< Context context,
Args &&...  args 
)
inlineexplicit

Construct a new Stream.

Parameters
contextThe context parameter is used to set up the underlying native handle. Using code is responsible for lifetime management of the context and must ensure that it is available for the lifetime of the stream.
argsArguments to be forwarded to the construction of the next layer.

Definition at line 61 of file asio_stream.h.

61 :
62 m_context(context),
63 m_nextLayer(std::forward<Args>(args)...),
64 m_core(std::make_shared<StreamCore>(context)),
const boost::asio::mutable_buffer m_input_buffer
std::shared_ptr< StreamCore > m_core
std::vector< uint8_t > m_input_buffer_space
std::shared_ptr< Context > m_context
StreamLayer m_nextLayer
@ MAX_CIPHERTEXT_SIZE
Definition tls_magic.h:33

◆ Stream() [2/4]

template<class StreamLayer , class ChannelT = Channel>
template<typename Arg >
Botan::TLS::Stream< StreamLayer, ChannelT >::Stream ( Arg &&  arg,
std::shared_ptr< Context context 
)
inlineexplicit

Construct a new Stream.

Convenience overload for boost::asio::ssl::stream compatibility.

Parameters
argThis argument is forwarded to the construction of the next layer.
contextThe context parameter is used to set up the underlying native handle. Using code is responsible for lifetime management of the context and must ensure that is available for the lifetime of the stream.

Definition at line 79 of file asio_stream.h.

79 :
80 m_context(context),
81 m_nextLayer(std::forward<Arg>(arg)),
82 m_core(std::make_shared<StreamCore>(context)),

◆ ~Stream()

template<class StreamLayer , class ChannelT = Channel>
virtual Botan::TLS::Stream< StreamLayer, ChannelT >::~Stream ( )
virtualdefault

◆ Stream() [3/4]

template<class StreamLayer , class ChannelT = Channel>
Botan::TLS::Stream< StreamLayer, ChannelT >::Stream ( Stream< StreamLayer, ChannelT > &&  other)
default

◆ Stream() [4/4]

template<class StreamLayer , class ChannelT = Channel>
Botan::TLS::Stream< StreamLayer, ChannelT >::Stream ( const Stream< StreamLayer, ChannelT > &  other)
delete

Member Function Documentation

◆ async_handshake() [1/2]

template<class StreamLayer , class ChannelT = Channel>
template<typename CompletionToken >
auto Botan::TLS::Stream< StreamLayer, ChannelT >::async_handshake ( Botan::TLS::Connection_Side  side,
CompletionToken &&  completion_token 
)
inline

Starts an asynchronous SSL handshake.

This function call always returns immediately.

Parameters
sideThe type of handshaking to be performed, i.e. as a client or as a server.
completion_tokenThe completion handler to be called when the handshake operation completes. The completion signature of the handler must be: void(boost::system::error_code).

Definition at line 254 of file asio_stream.h.

254 {
255 return boost::asio::async_initiate<CompletionToken, void(boost::system::error_code)>(
256 [this](auto&& completion_handler, TLS::Connection_Side connection_side) {
257 using completion_handler_t = std::decay_t<decltype(completion_handler)>;
258
259 BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(completion_handler_t, completion_handler) type_check;
260
261 boost::system::error_code ec;
262 setup_native_handle(connection_side, ec);
263
264 detail::AsyncHandshakeOperation<completion_handler_t, Stream> op{
265 std::forward<completion_handler_t>(completion_handler), *this, ec};
266 },
267 completion_token,
268 side);
269 }
void setup_native_handle(Connection_Side side, boost::system::error_code &ec)
Create the native handle.

References Botan::TLS::Stream< StreamLayer, ChannelT >::setup_native_handle().

◆ async_handshake() [2/2]

template<class StreamLayer , class ChannelT = Channel>
template<typename ConstBufferSequence , typename BufferedHandshakeHandler >
Botan::TLS::Stream< StreamLayer, ChannelT >::async_handshake ( Connection_Side  side,
const ConstBufferSequence &  buffers,
BufferedHandshakeHandler &&  handler 
)
inline
Exceptions
Not_Implemented

Definition at line 274 of file asio_stream.h.

274 {
275 BOTAN_UNUSED(side, buffers, handler);
276 BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(BufferedHandshakeHandler, handler) type_check;
277 throw Not_Implemented("buffered async handshake is not implemented");
278 }
#define BOTAN_UNUSED
Definition assert.h:118

References BOTAN_UNUSED.

◆ async_read_some()

template<class StreamLayer , class ChannelT = Channel>
template<typename MutableBufferSequence , typename CompletionToken >
auto Botan::TLS::Stream< StreamLayer, ChannelT >::async_read_some ( const MutableBufferSequence &  buffers,
CompletionToken &&  completion_token 
)
inline

Start an asynchronous read. The function call always returns immediately.

Parameters
buffersThe 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.
completion_tokenThe completion handler to be called when the read operation completes. The completion signature of the handler must be: void(boost::system::error_code, std::size_t).

Definition at line 517 of file asio_stream.h.

517 {
518 return boost::asio::async_initiate<CompletionToken, void(boost::system::error_code, std::size_t)>(
519 [this](auto&& completion_handler, const auto& bufs) {
520 using completion_handler_t = std::decay_t<decltype(completion_handler)>;
521
522 BOOST_ASIO_READ_HANDLER_CHECK(completion_handler_t, completion_handler) type_check;
523
524 detail::AsyncReadOperation<completion_handler_t, Stream, MutableBufferSequence> op{
525 std::forward<completion_handler_t>(completion_handler), *this, bufs};
526 },
527 completion_token,
528 buffers);
529 }

◆ async_shutdown()

template<class StreamLayer , class ChannelT = Channel>
template<typename CompletionToken >
auto Botan::TLS::Stream< StreamLayer, ChannelT >::async_shutdown ( CompletionToken &&  completion_token)
inline

Asynchronously shut down SSL on the stream.

This function call always returns immediately.

Note that this can be used in reaction of a received shutdown alert from the peer.

Parameters
completion_tokenThe completion handler to be called when the shutdown operation completes. The completion signature of the handler must be: void(boost::system::error_code).

Definition at line 354 of file asio_stream.h.

354 {
355 return boost::asio::async_initiate<CompletionToken, void(boost::system::error_code)>(
356 [this](auto&& completion_handler) {
357 using completion_handler_t = std::decay_t<decltype(completion_handler)>;
358
359 BOOST_ASIO_SHUTDOWN_HANDLER_CHECK(completion_handler_t, completion_handler) type_check;
360
361 boost::system::error_code ec;
362 try_with_error_code([&] { native_handle()->close(); }, ec);
363
364 using write_handler_t = Wrapper<completion_handler_t, typename Stream::executor_type>;
365
366 TLS::detail::AsyncWriteOperation<write_handler_t, Stream> op{
367 write_handler_t{std::forward<completion_handler_t>(completion_handler), get_executor()},
368 *this,
369 boost::asio::buffer_size(send_buffer()),
370 ec};
371 },
372 completion_token);
373 }
native_handle_type native_handle()
void try_with_error_code(Fun f, boost::system::error_code &ec)
Catch exceptions and set an error_code.
boost::asio::const_buffer send_buffer() const
executor_type get_executor() noexcept

References Botan::TLS::Stream< StreamLayer, ChannelT >::get_executor(), Botan::TLS::Stream< StreamLayer, ChannelT >::native_handle(), Botan::TLS::Stream< StreamLayer, ChannelT >::send_buffer(), and Botan::TLS::Stream< StreamLayer, ChannelT >::try_with_error_code().

◆ async_write_some()

template<class StreamLayer , class ChannelT = Channel>
template<typename ConstBufferSequence , typename CompletionToken >
auto Botan::TLS::Stream< StreamLayer, ChannelT >::async_write_some ( const ConstBufferSequence &  buffers,
CompletionToken &&  completion_token 
)
inline

Start an asynchronous write. The function call always returns immediately.

Parameters
buffersThe data to be written.
completion_tokenThe completion handler to be called when the write operation completes. Copies of the handler will be made as required. The completion signature of the handler must be: void(boost::system::error_code, std::size_t).

Definition at line 481 of file asio_stream.h.

481 {
482 return boost::asio::async_initiate<CompletionToken, void(boost::system::error_code, std::size_t)>(
483 [this](auto&& completion_handler, const auto& bufs) {
484 using completion_handler_t = std::decay_t<decltype(completion_handler)>;
485
486 BOOST_ASIO_WRITE_HANDLER_CHECK(completion_handler_t, completion_handler) type_check;
487
488 boost::system::error_code ec;
489 tls_encrypt(bufs, ec);
490
491 if(ec) {
492 // we cannot be sure how many bytes were committed here so clear the send_buffer and let the
493 // AsyncWriteOperation call the handler with the error_code set
494 consume_send_buffer(m_core->send_buffer.size());
495 }
496
497 detail::AsyncWriteOperation<completion_handler_t, Stream> op{
498 std::forward<completion_handler_t>(completion_handler),
499 *this,
500 ec ? 0 : boost::asio::buffer_size(bufs),
501 ec};
502 },
503 completion_token,
504 buffers);
505 }
void consume_send_buffer(std::size_t bytesConsumed)
Mark bytes in the send buffer as consumed, removing them from the buffer.
void tls_encrypt(const ConstBufferSequence &buffers, boost::system::error_code &ec)
Pass plaintext data to the native handle for processing.

References Botan::TLS::Stream< StreamLayer, ChannelT >::consume_send_buffer(), Botan::TLS::Stream< StreamLayer, ChannelT >::m_core, and Botan::TLS::Stream< StreamLayer, ChannelT >::tls_encrypt().

◆ consume_send_buffer()

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::consume_send_buffer ( std::size_t  bytesConsumed)
inlineprotected

◆ copy_received_data()

template<class StreamLayer , class ChannelT = Channel>
template<typename MutableBufferSequence >
std::size_t Botan::TLS::Stream< StreamLayer, ChannelT >::copy_received_data ( MutableBufferSequence  buffers)
inlineprotected

Copy decrypted data into the user-provided buffer.

Definition at line 619 of file asio_stream.h.

619 {
620 // Note: It would be nice to avoid this buffer copy. This could be achieved by equipping the StreamCore with
621 // the user's desired target buffer once a read is started, and reading directly into that buffer in tls_record
622 // received. However, we need to deal with the case that the receive buffer provided by the caller is smaller
623 // than the decrypted record, so this optimization might not be worth the additional complexity.
624 const auto copiedBytes = boost::asio::buffer_copy(buffers, m_core->receive_buffer.data());
625 m_core->receive_buffer.consume(copiedBytes);
626 return copiedBytes;
627 }

References Botan::TLS::Stream< StreamLayer, ChannelT >::m_core.

Referenced by Botan::TLS::detail::AsyncReadOperation< Handler, Stream, MutableBufferSequence, Allocator >::operator()(), and Botan::TLS::Stream< StreamLayer, ChannelT >::read_some().

◆ get_executor()

template<class StreamLayer , class ChannelT = Channel>
executor_type Botan::TLS::Stream< StreamLayer, ChannelT >::get_executor ( )
inlinenoexcept

◆ handshake() [1/2]

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::handshake ( Connection_Side  side)
inline

Performs SSL handshaking.

The function call will block until handshaking is complete or an error occurs.

Parameters
sideThe type of handshaking to be performed, i.e. as a client or as a server.
Exceptions
boost::system::system_errorif error occured

Definition at line 210 of file asio_stream.h.

210 {
211 boost::system::error_code ec;
212 handshake(side, ec);
213 boost::asio::detail::throw_error(ec, "handshake");
214 }
void handshake(Connection_Side side)
Performs SSL handshaking.

References Botan::TLS::Stream< StreamLayer, ChannelT >::handshake().

Referenced by Botan::TLS::Stream< StreamLayer, ChannelT >::handshake().

◆ handshake() [2/2]

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::handshake ( Connection_Side  side,
boost::system::error_code &  ec 
)
inline

Performs SSL handshaking.

The function call will block until handshaking is complete or an error occurs.

Parameters
sideThe type of handshaking to be performed, i.e. as a client or as a server.
ecSet to indicate what error occurred, if any.

Definition at line 224 of file asio_stream.h.

224 {
225 setup_native_handle(side, ec);
226
227 if(side == Connection_Side::Client) {
228 // send client hello, which was written to the send buffer on client instantiation
230 }
231
232 while(!native_handle()->is_active() && !ec) {
233 boost::asio::const_buffer read_buffer{input_buffer().data(), m_nextLayer.read_some(input_buffer(), ec)};
234 if(ec) {
235 return;
236 }
237
238 process_encrypted_data(read_buffer, ec);
239
241 }
242 }
const boost::asio::mutable_buffer & input_buffer()
void process_encrypted_data(const boost::asio::const_buffer &read_buffer, boost::system::error_code &ec)
Pass encrypted data to the native handle for processing.
size_t send_pending_encrypted_data(boost::system::error_code &ec)
Synchronously write encrypted data from the send buffer to the next layer.

References Botan::TLS::Client, Botan::TLS::Stream< StreamLayer, ChannelT >::input_buffer(), Botan::TLS::Stream< StreamLayer, ChannelT >::m_nextLayer, Botan::TLS::Stream< StreamLayer, ChannelT >::native_handle(), Botan::TLS::Stream< StreamLayer, ChannelT >::process_encrypted_data(), Botan::TLS::Stream< StreamLayer, ChannelT >::send_pending_encrypted_data(), and Botan::TLS::Stream< StreamLayer, ChannelT >::setup_native_handle().

◆ has_data_to_send()

template<class StreamLayer , class ChannelT = Channel>
bool Botan::TLS::Stream< StreamLayer, ChannelT >::has_data_to_send ( ) const
inlineprotected

Check if encrypted data is available in the send buffer.

Definition at line 630 of file asio_stream.h.

630{ return m_core->send_buffer.size() > 0; }

References Botan::TLS::Stream< StreamLayer, ChannelT >::m_core.

Referenced by Botan::TLS::detail::AsyncWriteOperation< Handler, Stream, Allocator >::operator()(), and Botan::TLS::detail::AsyncHandshakeOperation< Handler, Stream, Allocator >::operator()().

◆ has_received_data()

template<class StreamLayer , class ChannelT = Channel>
bool Botan::TLS::Stream< StreamLayer, ChannelT >::has_received_data ( ) const
inlineprotected

Check if decrypted data is available in the receive buffer.

Definition at line 615 of file asio_stream.h.

615{ return m_core->receive_buffer.size() > 0; }

References Botan::TLS::Stream< StreamLayer, ChannelT >::m_core.

Referenced by Botan::TLS::detail::AsyncReadOperation< Handler, Stream, MutableBufferSequence, Allocator >::operator()(), and Botan::TLS::Stream< StreamLayer, ChannelT >::read_some().

◆ input_buffer()

template<class StreamLayer , class ChannelT = Channel>
const boost::asio::mutable_buffer & Botan::TLS::Stream< StreamLayer, ChannelT >::input_buffer ( )
inlineprotected

◆ lowest_layer() [1/2]

template<class StreamLayer , class ChannelT = Channel>
lowest_layer_type & Botan::TLS::Stream< StreamLayer, ChannelT >::lowest_layer ( )
inline

Definition at line 118 of file asio_stream.h.

118{ return m_nextLayer.lowest_layer(); }

References Botan::TLS::Stream< StreamLayer, ChannelT >::m_nextLayer.

◆ lowest_layer() [2/2]

template<class StreamLayer , class ChannelT = Channel>
const lowest_layer_type & Botan::TLS::Stream< StreamLayer, ChannelT >::lowest_layer ( ) const
inline

Definition at line 120 of file asio_stream.h.

120{ return m_nextLayer.lowest_layer(); }

References Botan::TLS::Stream< StreamLayer, ChannelT >::m_nextLayer.

◆ native_handle()

template<class StreamLayer , class ChannelT = Channel>
native_handle_type Botan::TLS::Stream< StreamLayer, ChannelT >::native_handle ( )
inline

◆ next_layer() [1/2]

template<class StreamLayer , class ChannelT = Channel>
next_layer_type & Botan::TLS::Stream< StreamLayer, ChannelT >::next_layer ( )
inline

Definition at line 102 of file asio_stream.h.

102{ return m_nextLayer; }

References Botan::TLS::Stream< StreamLayer, ChannelT >::m_nextLayer.

◆ next_layer() [2/2]

template<class StreamLayer , class ChannelT = Channel>
const next_layer_type & Botan::TLS::Stream< StreamLayer, ChannelT >::next_layer ( ) const
inline

◆ operator=() [1/2]

template<class StreamLayer , class ChannelT = Channel>
Stream & Botan::TLS::Stream< StreamLayer, ChannelT >::operator= ( const Stream< StreamLayer, ChannelT > &  other)
delete

◆ operator=() [2/2]

template<class StreamLayer , class ChannelT = Channel>
Stream & Botan::TLS::Stream< StreamLayer, ChannelT >::operator= ( Stream< StreamLayer, ChannelT > &&  other)
default

◆ process_encrypted_data()

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::process_encrypted_data ( const boost::asio::const_buffer &  read_buffer,
boost::system::error_code &  ec 
)
inlineprotected

Pass encrypted data to the native handle for processing.

If an exception occurs while processing the data, an error code will be set.

Parameters
read_bufferInput buffer containing the encrypted data.
ecSet to indicate what error occurred, if any.

Definition at line 728 of file asio_stream.h.

728 {
730 [&] {
731 native_handle()->received_data({static_cast<const uint8_t*>(read_buffer.data()), read_buffer.size()});
732 },
733 ec);
734 }

References Botan::TLS::Stream< StreamLayer, ChannelT >::native_handle(), and Botan::TLS::Stream< StreamLayer, ChannelT >::try_with_error_code().

Referenced by Botan::TLS::Stream< StreamLayer, ChannelT >::handshake(), Botan::TLS::detail::AsyncReadOperation< Handler, Stream, MutableBufferSequence, Allocator >::operator()(), Botan::TLS::detail::AsyncHandshakeOperation< Handler, Stream, Allocator >::operator()(), and Botan::TLS::Stream< StreamLayer, ChannelT >::read_some().

◆ read_some() [1/2]

template<class StreamLayer , class ChannelT = Channel>
template<typename MutableBufferSequence >
std::size_t Botan::TLS::Stream< StreamLayer, ChannelT >::read_some ( const MutableBufferSequence &  buffers)
inline

Read some data from the stream.

The function call will block until one or more bytes of data has been read successfully, or until an error occurs.

Parameters
buffersThe buffers into which the data will be read.
Returns
The number of bytes read. Returns 0 if an error occurred.
Exceptions
boost::system::system_errorif error occured

Definition at line 430 of file asio_stream.h.

430 {
431 boost::system::error_code ec;
432 const auto n = read_some(buffers, ec);
433 boost::asio::detail::throw_error(ec, "read_some");
434 return n;
435 }
std::size_t read_some(const MutableBufferSequence &buffers, boost::system::error_code &ec)
Read some data from the stream.

References Botan::TLS::Stream< StreamLayer, ChannelT >::read_some().

◆ read_some() [2/2]

template<class StreamLayer , class ChannelT = Channel>
template<typename MutableBufferSequence >
std::size_t Botan::TLS::Stream< StreamLayer, ChannelT >::read_some ( const MutableBufferSequence &  buffers,
boost::system::error_code &  ec 
)
inline

Read some data from the stream.

The function call will block until one or more bytes of data has been read successfully, or until an error occurs.

Parameters
buffersThe buffers into which the data will be read.
ecSet to indicate what error occurred, if any. Specifically, StreamTruncated will be set if the peer has closed the connection but did not properly shut down the SSL connection.
Returns
The number of bytes read. Returns 0 if an error occurred.

Definition at line 391 of file asio_stream.h.

391 {
392 if(has_received_data()) {
393 return copy_received_data(buffers);
394 }
395
396 boost::asio::const_buffer read_buffer{input_buffer().data(), m_nextLayer.read_some(input_buffer(), ec)};
397 if(ec) {
398 return 0;
399 }
400
401 process_encrypted_data(read_buffer, ec);
402
403 if(ec) // something went wrong in process_encrypted_data()
404 {
405 return 0;
406 }
407
408 if(shutdown_received()) {
409 // we just received a 'close_notify' from the peer and don't expect any more data
410 ec = boost::asio::error::eof;
411 } else if(ec == boost::asio::error::eof) {
412 // we did not expect this disconnection from the peer
414 }
415
416 return !ec ? copy_received_data(buffers) : 0;
417 }
std::size_t copy_received_data(MutableBufferSequence buffers)
Copy decrypted data into the user-provided buffer.
bool has_received_data() const
Check if decrypted data is available in the receive buffer.
bool shutdown_received() const
Indicates whether a close_notify alert has been received from the peer.
@ StreamTruncated
Definition asio_error.h:33

References Botan::TLS::Stream< StreamLayer, ChannelT >::copy_received_data(), Botan::TLS::Stream< StreamLayer, ChannelT >::has_received_data(), Botan::TLS::Stream< StreamLayer, ChannelT >::input_buffer(), Botan::TLS::Stream< StreamLayer, ChannelT >::m_nextLayer, Botan::TLS::Stream< StreamLayer, ChannelT >::process_encrypted_data(), Botan::TLS::Stream< StreamLayer, ChannelT >::shutdown_received(), and Botan::TLS::StreamTruncated.

Referenced by Botan::TLS::Stream< StreamLayer, ChannelT >::read_some().

◆ send_buffer()

template<class StreamLayer , class ChannelT = Channel>
boost::asio::const_buffer Botan::TLS::Stream< StreamLayer, ChannelT >::send_buffer ( ) const
inlineprotected

◆ send_pending_encrypted_data()

template<class StreamLayer , class ChannelT = Channel>
size_t Botan::TLS::Stream< StreamLayer, ChannelT >::send_pending_encrypted_data ( boost::system::error_code &  ec)
inlineprotected

Synchronously write encrypted data from the send buffer to the next layer.

If this function is called with an error code other than 'Success', it will do nothing and return 0.

Parameters
ecSet to indicate what error occurred, if any. Specifically, StreamTruncated will be set if the peer has closed the connection but did not properly shut down the SSL connection.
Returns
The number of bytes written.

Definition at line 682 of file asio_stream.h.

682 {
683 if(ec) {
684 return 0;
685 }
686
687 auto writtenBytes = boost::asio::write(m_nextLayer, send_buffer(), ec);
688 consume_send_buffer(writtenBytes);
689
690 if(ec == boost::asio::error::eof && !shutdown_received()) {
691 // transport layer was closed by peer without receiving 'close_notify'
693 }
694
695 return writtenBytes;
696 }

References Botan::TLS::Stream< StreamLayer, ChannelT >::consume_send_buffer(), Botan::TLS::Stream< StreamLayer, ChannelT >::m_nextLayer, Botan::TLS::Stream< StreamLayer, ChannelT >::send_buffer(), Botan::TLS::Stream< StreamLayer, ChannelT >::shutdown_received(), and Botan::TLS::StreamTruncated.

Referenced by Botan::TLS::Stream< StreamLayer, ChannelT >::handshake(), Botan::TLS::Stream< StreamLayer, ChannelT >::shutdown(), and Botan::TLS::Stream< StreamLayer, ChannelT >::write_some().

◆ set_verify_callback() [1/2]

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::set_verify_callback ( Context::Verify_Callback  callback)
inline

Override the tls_verify_cert_chain callback.

This changes the verify_callback in the stream's TLS::Context, and hence the tls_verify_cert_chain callback used in the handshake. Using this function is equivalent to setting the callback via

See also
Botan::TLS::Context::set_verify_callback
Note
This function should only be called before initiating the TLS handshake

Definition at line 149 of file asio_stream.h.

149 {
150 m_context->set_verify_callback(std::move(callback));
151 }

References Botan::TLS::Stream< StreamLayer, ChannelT >::m_context.

◆ set_verify_callback() [2/2]

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::set_verify_callback ( Context::Verify_Callback  callback,
boost::system::error_code &  ec 
)
inline

Compatibility overload of set_verify_callback.

Parameters
callbackthe callback implementation
ecThis parameter is unused.

Definition at line 159 of file asio_stream.h.

159 {
160 BOTAN_UNUSED(ec);
161 m_context->set_verify_callback(std::move(callback));
162 }

References BOTAN_UNUSED, and Botan::TLS::Stream< StreamLayer, ChannelT >::m_context.

◆ set_verify_depth() [1/2]

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::set_verify_depth ( int  depth)
inline
Exceptions
Not_Implemented

Definition at line 165 of file asio_stream.h.

165 {
166 BOTAN_UNUSED(depth);
167 throw Not_Implemented("set_verify_depth is not implemented");
168 }

References BOTAN_UNUSED.

◆ set_verify_depth() [2/2]

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::set_verify_depth ( int  depth,
boost::system::error_code &  ec 
)
inline

Not Implemented.

Parameters
depththe desired verification depth
ecWill be set to Botan::ErrorType::NotImplemented

Definition at line 175 of file asio_stream.h.

175 {
176 BOTAN_UNUSED(depth);
178 }

References BOTAN_UNUSED, and Botan::NotImplemented.

◆ set_verify_mode() [1/2]

template<class StreamLayer , class ChannelT = Channel>
template<typename verify_mode >
void Botan::TLS::Stream< StreamLayer, ChannelT >::set_verify_mode ( verify_mode  v)
inline
Exceptions
Not_Implemented

Definition at line 182 of file asio_stream.h.

182 {
183 BOTAN_UNUSED(v);
184 throw Not_Implemented("set_verify_mode is not implemented");
185 }

References BOTAN_UNUSED.

◆ set_verify_mode() [2/2]

template<class StreamLayer , class ChannelT = Channel>
template<typename verify_mode >
void Botan::TLS::Stream< StreamLayer, ChannelT >::set_verify_mode ( verify_mode  v,
boost::system::error_code &  ec 
)
inline

Not Implemented.

Parameters
vthe desired verify mode
ecWill be set to Botan::ErrorType::NotImplemented

Definition at line 193 of file asio_stream.h.

193 {
194 BOTAN_UNUSED(v);
196 }

References BOTAN_UNUSED, and Botan::NotImplemented.

◆ setup_native_handle()

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::setup_native_handle ( Connection_Side  side,
boost::system::error_code &  ec 
)
inlineprotected

Create the native handle.

Depending on the desired connection side, this function will create a TLS::Client or a TLS::Server.

Parameters
sideThe desired connection side (client or server)
ecSet to indicate what error occurred, if any.

Definition at line 644 of file asio_stream.h.

644 {
645 BOTAN_UNUSED(side); // workaround: GCC 9 produces a warning claiming side is unused
646
647 // Do not attempt to instantiate the native_handle when a custom (mocked) channel type template parameter has
648 // been specified. This allows mocking the native_handle in test code.
649 if constexpr(std::is_same<ChannelT, Channel>::value) {
651 [&] {
652 if(side == Connection_Side::Client) {
653 m_native_handle = std::unique_ptr<Client>(
654 new Client(m_core,
655 m_context->m_session_manager,
656 m_context->m_credentials_manager,
657 m_context->m_policy,
658 m_context->m_rng,
659 m_context->m_server_info,
660 m_context->m_policy->latest_supported_version(false /* no DTLS */)));
661 } else {
662 m_native_handle = std::unique_ptr<Server>(new Server(m_core,
663 m_context->m_session_manager,
664 m_context->m_credentials_manager,
665 m_context->m_policy,
666 m_context->m_rng,
667 false /* no DTLS */));
668 }
669 },
670 ec);
671 }
672 }

References BOTAN_UNUSED, Botan::TLS::Client, Botan::TLS::Stream< StreamLayer, ChannelT >::m_context, Botan::TLS::Stream< StreamLayer, ChannelT >::m_core, Botan::TLS::Stream< StreamLayer, ChannelT >::m_native_handle, and Botan::TLS::Stream< StreamLayer, ChannelT >::try_with_error_code().

Referenced by Botan::TLS::Stream< StreamLayer, ChannelT >::async_handshake(), and Botan::TLS::Stream< StreamLayer, ChannelT >::handshake().

◆ shutdown() [1/2]

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::shutdown ( )
inline

Shut down SSL on the stream.

This function is used to shut down SSL on the stream. The function call will block until SSL has been shut down or an error occurs. Note that this will not close the lowest layer.

Note that this can be used in reaction of a received shutdown alert from the peer.

Exceptions
boost::system::system_errorif error occured

Definition at line 310 of file asio_stream.h.

310 {
311 boost::system::error_code ec;
312 shutdown(ec);
313 boost::asio::detail::throw_error(ec, "shutdown");
314 }
void shutdown()
Shut down SSL on the stream.

References Botan::TLS::Stream< StreamLayer, ChannelT >::shutdown().

Referenced by Botan::TLS::Stream< StreamLayer, ChannelT >::shutdown().

◆ shutdown() [2/2]

template<class StreamLayer , class ChannelT = Channel>
void Botan::TLS::Stream< StreamLayer, ChannelT >::shutdown ( boost::system::error_code &  ec)
inline

Shut down SSL on the stream.

This function is used to shut down SSL on the stream. The function call will block until SSL has been shut down or an error occurs. Note that this will not close the lowest layer.

Note that this can be used in reaction of a received shutdown alert from the peer.

Parameters
ecSet to indicate what error occured, if any.

Definition at line 294 of file asio_stream.h.

294 {
295 try_with_error_code([&] { native_handle()->close(); }, ec);
296
298 }

References Botan::TLS::Stream< StreamLayer, ChannelT >::native_handle(), Botan::TLS::Stream< StreamLayer, ChannelT >::send_pending_encrypted_data(), and Botan::TLS::Stream< StreamLayer, ChannelT >::try_with_error_code().

◆ shutdown_received()

template<class StreamLayer , class ChannelT = Channel>
bool Botan::TLS::Stream< StreamLayer, ChannelT >::shutdown_received ( ) const
inline

Indicates whether a close_notify alert has been received from the peer.

Note that we cannot m_core.is_closed_for_reading() because this wants to explicitly check that the peer sent close_notify.

Definition at line 537 of file asio_stream.h.

537{ return m_core->shutdown_received; }

References Botan::TLS::Stream< StreamLayer, ChannelT >::m_core.

Referenced by Botan::TLS::detail::AsyncReadOperation< Handler, Stream, MutableBufferSequence, Allocator >::operator()(), Botan::TLS::detail::AsyncWriteOperation< Handler, Stream, Allocator >::operator()(), Botan::TLS::Stream< StreamLayer, ChannelT >::read_some(), and Botan::TLS::Stream< StreamLayer, ChannelT >::send_pending_encrypted_data().

◆ tls_encrypt()

template<class StreamLayer , class ChannelT = Channel>
template<typename ConstBufferSequence >
void Botan::TLS::Stream< StreamLayer, ChannelT >::tls_encrypt ( const ConstBufferSequence &  buffers,
boost::system::error_code &  ec 
)
inlineprotected

Pass plaintext data to the native handle for processing.

The native handle will then create TLS records and hand them back to the Stream via the tls_emit_data callback.

Definition at line 704 of file asio_stream.h.

704 {
705 // NOTE: This is not asynchronous: it encrypts the data synchronously.
706 // The data encrypted by native_handle()->send() is synchronously stored in the send_buffer of m_core,
707 // but is not actually written to the wire, yet.
708 for(auto it = boost::asio::buffer_sequence_begin(buffers);
709 !ec && it != boost::asio::buffer_sequence_end(buffers);
710 it++) {
711 const boost::asio::const_buffer buffer = *it;
713 [&] {
714 native_handle()->send({static_cast<const uint8_t*>(buffer.data()), buffer.size()});
715 },
716 ec);
717 }
718 }

References Botan::TLS::Stream< StreamLayer, ChannelT >::native_handle(), and Botan::TLS::Stream< StreamLayer, ChannelT >::try_with_error_code().

Referenced by Botan::TLS::Stream< StreamLayer, ChannelT >::async_write_some(), and Botan::TLS::Stream< StreamLayer, ChannelT >::write_some().

◆ try_with_error_code()

template<class StreamLayer , class ChannelT = Channel>
template<typename Fun >
void Botan::TLS::Stream< StreamLayer, ChannelT >::try_with_error_code ( Fun  f,
boost::system::error_code &  ec 
)
inlineprotected

Catch exceptions and set an error_code.

Definition at line 738 of file asio_stream.h.

738 {
739 try {
740 f();
741 } catch(const TLS_Exception& e) {
742 ec = e.type();
743 } catch(const Exception& e) {
744 ec = e.error_type();
745 } catch(const std::exception&) {
747 }
748 }

References Botan::TLS::TLS_Exception::error_type(), Botan::TLS::TLS_Exception::type(), and Botan::Unknown.

Referenced by Botan::TLS::Stream< StreamLayer, ChannelT >::async_shutdown(), Botan::TLS::Stream< StreamLayer, ChannelT >::process_encrypted_data(), Botan::TLS::Stream< StreamLayer, ChannelT >::setup_native_handle(), Botan::TLS::Stream< StreamLayer, ChannelT >::shutdown(), and Botan::TLS::Stream< StreamLayer, ChannelT >::tls_encrypt().

◆ write_some() [1/2]

template<class StreamLayer , class ChannelT = Channel>
template<typename ConstBufferSequence >
std::size_t Botan::TLS::Stream< StreamLayer, ChannelT >::write_some ( const ConstBufferSequence &  buffers)
inline

Write some data to the stream.

The function call will block until one or more bytes of data has been written successfully, or until an error occurs.

Parameters
buffersThe data to be written.
Returns
The number of bytes written.
Exceptions
boost::system::system_errorif error occured

Definition at line 465 of file asio_stream.h.

465 {
466 boost::system::error_code ec;
467 const auto n = write_some(buffers, ec);
468 boost::asio::detail::throw_error(ec, "write_some");
469 return n;
470 }
std::size_t write_some(const ConstBufferSequence &buffers, boost::system::error_code &ec)
Write some data to the stream.

References Botan::TLS::Stream< StreamLayer, ChannelT >::write_some().

◆ write_some() [2/2]

template<class StreamLayer , class ChannelT = Channel>
template<typename ConstBufferSequence >
std::size_t Botan::TLS::Stream< StreamLayer, ChannelT >::write_some ( const ConstBufferSequence &  buffers,
boost::system::error_code &  ec 
)
inline

Write some data to the stream.

The function call will block until one or more bytes of data has been written successfully, or until an error occurs.

Parameters
buffersThe data to be written.
ecSet to indicate what error occurred, if any.
Returns
The number of bytes processed from the input buffers.

Definition at line 448 of file asio_stream.h.

448 {
449 tls_encrypt(buffers, ec);
451 return !ec ? boost::asio::buffer_size(buffers) : 0;
452 }

References Botan::TLS::Stream< StreamLayer, ChannelT >::send_pending_encrypted_data(), and Botan::TLS::Stream< StreamLayer, ChannelT >::tls_encrypt().

Referenced by Botan::TLS::Stream< StreamLayer, ChannelT >::write_some().

Friends And Related Symbol Documentation

◆ detail::AsyncHandshakeOperation

template<class StreamLayer , class ChannelT = Channel>
template<class H , class S , class A >
friend class detail::AsyncHandshakeOperation
friend

Definition at line 545 of file asio_stream.h.

◆ detail::AsyncReadOperation

template<class StreamLayer , class ChannelT = Channel>
template<class H , class S , class M , class A >
friend class detail::AsyncReadOperation
friend

Definition at line 541 of file asio_stream.h.

◆ detail::AsyncWriteOperation

template<class StreamLayer , class ChannelT = Channel>
template<class H , class S , class A >
friend class detail::AsyncWriteOperation
friend

Definition at line 543 of file asio_stream.h.

Member Data Documentation

◆ m_context

template<class StreamLayer , class ChannelT = Channel>
std::shared_ptr<Context> Botan::TLS::Stream< StreamLayer, ChannelT >::m_context
protected

◆ m_core

template<class StreamLayer , class ChannelT = Channel>
std::shared_ptr<StreamCore> Botan::TLS::Stream< StreamLayer, ChannelT >::m_core
protected

◆ m_input_buffer

template<class StreamLayer , class ChannelT = Channel>
const boost::asio::mutable_buffer Botan::TLS::Stream< StreamLayer, ChannelT >::m_input_buffer
protected

◆ m_input_buffer_space

template<class StreamLayer , class ChannelT = Channel>
std::vector<uint8_t> Botan::TLS::Stream< StreamLayer, ChannelT >::m_input_buffer_space
protected

Definition at line 757 of file asio_stream.h.

◆ m_native_handle

template<class StreamLayer , class ChannelT = Channel>
std::unique_ptr<ChannelT> Botan::TLS::Stream< StreamLayer, ChannelT >::m_native_handle
protected

◆ m_nextLayer

template<class StreamLayer , class ChannelT = Channel>
StreamLayer Botan::TLS::Stream< StreamLayer, ChannelT >::m_nextLayer
protected

The documentation for this class was generated from the following file: