aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHannes Rantzsch <[email protected]>2019-04-24 17:31:54 +0200
committerHannes Rantzsch <[email protected]>2019-04-24 17:31:54 +0200
commitbaa0725609df52014b43bb28297594c7a9c3c320 (patch)
tree4f02328618472bad3dacf7d019f497f889f732c3 /src
parentcd0580600fd3bbdd49fe60a1333c5ea5df9d5bfc (diff)
start restructuring asio stream headers
StreamCore is now a nested class of Stream and will soon be hidden from the public interface. The goal is to offer buffer-handling methods (like CopyReceivedData) directly in Steam and have StreamCore be responsible for Botan::TLS::Callbacks implementation only. This will remove the need to provide StreamCore as a parameter for Async Ops construction. StreamBase has been removed. Stream no longer decides whether it is a Client or a Server when constructed, but when performing the handshake. This resembles the interface of boost::asio::ssl::stream and hides the implementation detail from the user. In order to allow testing with mocked TLS::Channels anyways, we use SPHINAE to setup either a real channel or a mocked channel.
Diffstat (limited to 'src')
-rw-r--r--src/lib/tls/asio/asio_async_handshake_op.h5
-rw-r--r--src/lib/tls/asio/asio_async_read_op.h5
-rw-r--r--src/lib/tls/asio/asio_async_write_op.h5
-rw-r--r--src/lib/tls/asio/asio_stream.h266
-rw-r--r--src/lib/tls/asio/asio_stream_base.h88
-rw-r--r--src/lib/tls/asio/asio_stream_core.h124
-rw-r--r--src/lib/tls/asio/info.txt2
-rw-r--r--src/tests/unit_asio_stream.cpp81
8 files changed, 202 insertions, 374 deletions
diff --git a/src/lib/tls/asio/asio_async_handshake_op.h b/src/lib/tls/asio/asio_async_handshake_op.h
index 23875ba7f..f3eea7d16 100644
--- a/src/lib/tls/asio/asio_async_handshake_op.h
+++ b/src/lib/tls/asio/asio_async_handshake_op.h
@@ -17,7 +17,6 @@
#include <botan/asio_error.h>
#include <botan/internal/asio_async_write_op.h>
#include <botan/internal/asio_includes.h>
-#include <botan/internal/asio_stream_core.h>
#include <boost/asio/yield.hpp>
@@ -41,7 +40,7 @@ class AsyncHandshakeOperation : public AsyncBase<Handler, typename Stream::execu
AsyncHandshakeOperation(
HandlerT&& handler,
Stream& stream,
- StreamCore& core,
+ typename Stream::StreamCore& core,
const boost::system::error_code& ec = {})
: AsyncBase<Handler, typename Stream::executor_type, Allocator>(
std::forward<HandlerT>(handler),
@@ -118,7 +117,7 @@ class AsyncHandshakeOperation : public AsyncBase<Handler, typename Stream::execu
private:
Stream& m_stream;
- StreamCore& m_core;
+ typename Stream::StreamCore& m_core;
boost::system::error_code m_ec;
};
diff --git a/src/lib/tls/asio/asio_async_read_op.h b/src/lib/tls/asio/asio_async_read_op.h
index 5902fd388..12f8da8e8 100644
--- a/src/lib/tls/asio/asio_async_read_op.h
+++ b/src/lib/tls/asio/asio_async_read_op.h
@@ -17,7 +17,6 @@
#include <botan/asio_error.h>
#include <botan/internal/asio_async_base.h>
#include <botan/internal/asio_includes.h>
-#include <botan/internal/asio_stream_core.h>
#include <boost/asio/yield.hpp>
@@ -41,7 +40,7 @@ class AsyncReadOperation : public AsyncBase<Handler, typename Stream::executor_t
template <class HandlerT>
AsyncReadOperation(HandlerT&& handler,
Stream& stream,
- StreamCore& core,
+ typename Stream::StreamCore& core,
const MutableBufferSequence& buffers,
const boost::system::error_code& ec = {})
: AsyncBase<Handler, typename Stream::executor_type, Allocator>(
@@ -112,7 +111,7 @@ class AsyncReadOperation : public AsyncBase<Handler, typename Stream::executor_t
private:
Stream& m_stream;
- StreamCore& m_core;
+ typename Stream::StreamCore& m_core;
MutableBufferSequence m_buffers;
std::size_t m_decodedBytes;
diff --git a/src/lib/tls/asio/asio_async_write_op.h b/src/lib/tls/asio/asio_async_write_op.h
index db347e5c5..44bd211e3 100644
--- a/src/lib/tls/asio/asio_async_write_op.h
+++ b/src/lib/tls/asio/asio_async_write_op.h
@@ -16,7 +16,6 @@
#include <botan/internal/asio_async_base.h>
#include <botan/internal/asio_includes.h>
-#include <botan/internal/asio_stream_core.h>
#include <boost/asio/yield.hpp>
@@ -43,7 +42,7 @@ class AsyncWriteOperation : public AsyncBase<Handler, typename Stream::executor_
template <class HandlerT>
AsyncWriteOperation(HandlerT&& handler,
Stream& stream,
- StreamCore& core,
+ typename Stream::StreamCore& core,
std::size_t plainBytesTransferred,
const boost::system::error_code& ec = {})
: AsyncBase<Handler, typename Stream::executor_type, Allocator>(
@@ -89,7 +88,7 @@ class AsyncWriteOperation : public AsyncBase<Handler, typename Stream::executor_
private:
Stream& m_stream;
- StreamCore& m_core;
+ typename Stream::StreamCore& m_core;
std::size_t m_plainBytesTransferred;
boost::system::error_code m_ec;
diff --git a/src/lib/tls/asio/asio_stream.h b/src/lib/tls/asio/asio_stream.h
index 1654aa658..af257dbd2 100644
--- a/src/lib/tls/asio/asio_stream.h
+++ b/src/lib/tls/asio/asio_stream.h
@@ -21,10 +21,15 @@
#include <botan/internal/asio_async_read_op.h>
#include <botan/internal/asio_async_write_op.h>
#include <botan/internal/asio_includes.h>
-#include <botan/internal/asio_stream_base.h>
-#include <botan/internal/asio_stream_core.h>
#include <botan/asio_context.h>
+#include <botan/tls_callbacks.h>
+#include <botan/tls_channel.h>
+#include <botan/tls_client.h>
+#include <botan/tls_magic.h>
+
+#include <boost/beast/core/flat_buffer.hpp>
+
#include <algorithm>
#include <memory>
#include <thread>
@@ -38,27 +43,30 @@ namespace TLS {
* boost::asio compatible SSL/TLS stream
*
* Currently only the TLS::Client specialization is implemented.
+ *
+ * \tparam StreamLayer type of the next layer, usually a network socket
+ * \tparam ChannelT type of the native_handle, defaults to Botan::TLS::Channel, only needed for testing purposes
*/
-template <class StreamLayer, class Channel>
-class Stream : public StreamBase<Channel>
+template <class StreamLayer, class ChannelT = Channel>
+class Stream
{
public:
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<Channel>::type;
-
- using StreamBase<Channel>::validate_connection_side;
+ using native_handle_type = typename std::add_pointer<ChannelT>::type;
public:
template <typename... Args>
explicit Stream(Context& context, Args&& ... args)
- : StreamBase<Channel>(context), m_nextLayer(std::forward<Args>(args)...) {}
+ : m_context(context), m_nextLayer(std::forward<Args>(args)...) {}
// overload for boost::asio::ssl::stream compatibility
template <typename Arg>
explicit Stream(Arg&& arg, Context& context)
- : StreamBase<Channel>(context), m_nextLayer(std::forward<Arg>(arg)) {}
+ : m_context(context), m_nextLayer(std::forward<Arg>(arg)) {}
+
+ virtual ~Stream() = default;
Stream(Stream&& other) = default;
Stream& operator=(Stream&& other) = default;
@@ -78,7 +86,7 @@ class Stream : public StreamBase<Channel>
lowest_layer_type& lowest_layer() { return m_nextLayer.lowest_layer(); }
const lowest_layer_type& lowest_layer() const { return m_nextLayer.lowest_layer(); }
- native_handle_type native_handle() { return &this->m_channel; }
+ native_handle_type native_handle() { return m_channel.get(); }
//
// -- -- configuration and callback setters
@@ -155,22 +163,27 @@ class Stream : public StreamBase<Channel>
/**
* Performs SSL handshaking.
* The function call will block until handshaking is complete or an error occurs.
+ * @param type The type of handshaking to be performed, i.e. as a client or as a server.
* @throws boost::system::system_error if error occured
+ * @throws Invalid_Argument if Connection_Side could not be validated
*/
- void handshake()
+ void handshake(Connection_Side side)
{
boost::system::error_code ec;
- handshake(ec);
+ handshake(side, ec);
boost::asio::detail::throw_error(ec, "handshake");
}
/**
* Performs SSL handshaking.
* The function call will block until handshaking is complete or an error occurs.
+ * @param type The type of handshaking to be performed, i.e. as a client or as a server.
* @param ec Set to indicate what error occurred, if any.
*/
- void handshake(boost::system::error_code& ec)
+ void handshake(Connection_Side side, boost::system::error_code& ec)
{
+ setup_channel(side);
+
while(!native_handle()->is_active())
{
sendPendingEncryptedData(ec);
@@ -201,7 +214,7 @@ class Stream : public StreamBase<Channel>
ec = e.error_type();
return;
}
- catch(const std::exception &)
+ catch(const std::exception&)
{
ec = Botan::ErrorType::Unknown;
return;
@@ -214,16 +227,20 @@ class Stream : public StreamBase<Channel>
/**
* Starts an asynchronous SSL handshake.
* This function call 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.
* The equivalent function signature of the handler must be: void(boost::system::error_code)
+ * @throws Invalid_Argument if Connection_Side could not be validated
*/
template <typename HandshakeHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler,
void(boost::system::error_code))
- async_handshake(HandshakeHandler&& handler)
+ async_handshake(Connection_Side side, HandshakeHandler&& handler)
{
BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
+ setup_channel(side);
+
boost::asio::async_completion<HandshakeHandler, void(boost::system::error_code)> init(handler);
AsyncHandshakeOperation<typename std::decay<HandshakeHandler>::type, Stream>
@@ -232,83 +249,6 @@ class Stream : public StreamBase<Channel>
return init.result.get();
}
- //
- // -- -- asio::ssl::stream compatibility methods
- //
- // The OpenSSL-based stream contains an operation flag that tells
- // the stream to either impersonate a TLS server or client. This
- // implementation defines those modes at compile time (via template
- // specialization of the StreamBase class) and merely checks the
- // flag's consistency before performing the respective handshakes.
- //
-
- /**
- * Performs SSL handshaking.
- * The function call will block until handshaking is complete or an error occurs.
- * @param type The type of handshaking to be performed, i.e. as a client or as a server.
- * @throws boost::system::system_error if error occured
- * @throws Invalid_Argument if Connection_Side could not be validated
- */
- void handshake(Connection_Side side)
- {
- validate_connection_side(side);
- handshake();
- }
-
- /**
- * Performs SSL handshaking.
- * The function call will block until handshaking is complete or an error occurs.
- * @param type The type of handshaking to be performed, i.e. as a client or as a server.
- * @param ec Set to indicate what error occurred, if any.
- */
- void handshake(Connection_Side side, boost::system::error_code& ec)
- {
- if(validate_connection_side(side, ec))
- { handshake(ec); }
- }
-
- /**
- * Starts an asynchronous SSL handshake.
- * This function call 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.
- * The equivalent function signature of the handler must be: void(boost::system::error_code)
- * @throws Invalid_Argument if Connection_Side could not be validated
- */
- template <typename HandshakeHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler,
- void(boost::system::error_code))
- async_handshake(Connection_Side side, HandshakeHandler&& handler)
- {
- validate_connection_side(side);
- return async_handshake(std::forward<HandshakeHandler>(handler));
- }
-
- /**
- * @throws Not_Implemented
- */
- template<typename ConstBufferSequence>
- void handshake(Connection_Side side, const ConstBufferSequence& buffers)
- {
- BOTAN_UNUSED(buffers);
- validate_connection_side(side);
- throw Not_Implemented("buffered handshake is not implemented");
- }
-
- /**
- * Not Implemented.
- * @param ec Will be set to `Botan::ErrorType::NotImplemented`
- */
- template<typename ConstBufferSequence>
- void handshake(Connection_Side side,
- const ConstBufferSequence& buffers,
- boost::system::error_code& ec)
- {
- BOTAN_UNUSED(buffers);
- if(validate_connection_side(side, ec))
- { ec = Botan::ErrorType::NotImplemented; }
- }
-
/**
* @throws Not_Implemented
*/
@@ -349,7 +289,7 @@ class Stream : public StreamBase<Channel>
ec = e.error_type();
return;
}
- catch(const std::exception &)
+ catch(const std::exception&)
{
ec = Botan::ErrorType::Unknown;
return;
@@ -527,7 +467,138 @@ class Stream : public StreamBase<Channel>
return init.result.get();
}
+ // TODO: remove StreamCore from public interface
+ /**
+ * Contains the buffers for reading/sending, and the needed botan callbacks
+ */
+ class StreamCore : public Botan::TLS::Callbacks
+ {
+ public:
+ StreamCore()
+ : m_input_buffer_space(MAX_CIPHERTEXT_SIZE, '\0'),
+ input_buffer(m_input_buffer_space.data(), m_input_buffer_space.size()) {}
+
+ virtual ~StreamCore() = default;
+
+ void tls_emit_data(const uint8_t data[], std::size_t size) override
+ {
+ // Provide the encrypted TLS data in the sendBuffer. Actually sending the data is done
+ // using (async_)write_some either in the stream or in an async operation.
+ m_send_buffer.commit(
+ boost::asio::buffer_copy(m_send_buffer.prepare(size), boost::asio::buffer(data, size)));
+ }
+
+ void tls_record_received(uint64_t, const uint8_t data[], std::size_t size) override
+ {
+ // TODO: It would be nice to avoid this buffer copy. However, we need to deal with the case
+ // that the receive buffer provided by the caller is smaller than the decrypted record.
+ auto buffer = m_receive_buffer.prepare(size);
+ auto copySize =
+ boost::asio::buffer_copy(buffer, boost::asio::const_buffer(data, size));
+ m_receive_buffer.commit(copySize);
+ }
+
+ void tls_alert(Botan::TLS::Alert alert) override
+ {
+ if(alert.type() == Botan::TLS::Alert::CLOSE_NOTIFY)
+ {
+ // TODO
+ }
+ }
+
+ std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const override
+ {
+ return std::chrono::milliseconds(1000);
+ }
+
+ bool tls_session_established(const Botan::TLS::Session&) override
+ {
+ // TODO: it should be possible to configure this in the using application (via callback?)
+ return true;
+ }
+
+ bool hasReceivedData() const
+ {
+ return m_receive_buffer.size() > 0;
+ }
+
+ template <typename MutableBufferSequence>
+ std::size_t copyReceivedData(MutableBufferSequence buffers)
+ {
+ const auto copiedBytes =
+ boost::asio::buffer_copy(buffers, m_receive_buffer.data());
+ m_receive_buffer.consume(copiedBytes);
+ return copiedBytes;
+ }
+
+ bool hasDataToSend() const { return m_send_buffer.size() > 0; }
+
+ boost::asio::const_buffer sendBuffer() const
+ {
+ return m_send_buffer.data();
+ }
+
+ void consumeSendBuffer(std::size_t bytesConsumed)
+ {
+ m_send_buffer.consume(bytesConsumed);
+ }
+
+ void clearSendBuffer()
+ {
+ consumeSendBuffer(m_send_buffer.size());
+ }
+
+ private:
+ // Buffer space used to read input intended for the engine.
+ std::vector<uint8_t> m_input_buffer_space;
+ boost::beast::flat_buffer m_receive_buffer;
+ boost::beast::flat_buffer m_send_buffer;
+
+ public:
+ // A buffer that may be used to read input intended for the engine.
+ const boost::asio::mutable_buffer input_buffer;
+ };
+
protected:
+ // TODO: explain, note: c++17 makes this much better with constexpr if
+ template<class T = ChannelT>
+ typename std::enable_if<!std::is_same<Channel, T>::value>::type
+ setup_channel(Connection_Side) {}
+
+ template<class T = ChannelT>
+ typename std::enable_if<std::is_same<Channel, T>::value>::type
+ setup_channel(Connection_Side side)
+ {
+ assert(side == CLIENT);
+ m_channel = std::unique_ptr<Client>(new Client(m_core,
+ *m_context.sessionManager,
+ *m_context.credentialsManager,
+ *m_context.policy,
+ *m_context.randomNumberGenerator,
+ m_context.serverInfo));
+ }
+
+ //! \brief validate the connection side (OpenSSL compatibility)
+ void validate_connection_side(Connection_Side side)
+ {
+ if(side != CLIENT)
+ {
+ throw Invalid_Argument("wrong connection_side");
+ }
+ }
+
+ //! \brief validate the connection side (OpenSSL compatibility)
+ bool validate_connection_side(Connection_Side side, boost::system::error_code& ec)
+ {
+ if(side != CLIENT)
+ {
+ ec = Botan::ErrorType::InvalidArgument;
+ return false;
+ }
+
+ return true;
+ }
+
size_t sendPendingEncryptedData(boost::system::error_code& ec)
{
auto writtenBytes = boost::asio::write(m_nextLayer, this->m_core.sendBuffer(), ec);
@@ -562,7 +633,7 @@ class Stream : public StreamBase<Channel>
ec = e.error_type();
return;
}
- catch(const std::exception &)
+ catch(const std::exception&)
{
ec = Botan::ErrorType::Unknown;
return;
@@ -601,7 +672,7 @@ class Stream : public StreamBase<Channel>
ec = e.error_type();
return 0;
}
- catch(const std::exception &)
+ catch(const std::exception&)
{
ec = Botan::ErrorType::Unknown;
return 0;
@@ -612,7 +683,10 @@ class Stream : public StreamBase<Channel>
return sent;
}
- StreamLayer m_nextLayer;
+ Context m_context;
+ StreamLayer m_nextLayer;
+ StreamCore m_core;
+ std::unique_ptr<ChannelT> m_channel;
};
} // namespace TLS
diff --git a/src/lib/tls/asio/asio_stream_base.h b/src/lib/tls/asio/asio_stream_base.h
deleted file mode 100644
index 9a9cc568b..000000000
--- a/src/lib/tls/asio/asio_stream_base.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-* TLS Stream Helper
-* (C) 2018-2019 Jack Lloyd
-* 2018-2019 Hannes Rantzsch, Tim Oesterreich, Rene Meusel
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_ASIO_STREAM_BASE_H_
-#define BOTAN_ASIO_STREAM_BASE_H_
-
-#include <botan/build.h>
-
-#include <boost/version.hpp>
-#if BOOST_VERSION >= 106600
-
-#include <botan/asio_context.h>
-#include <botan/asio_error.h>
-#include <botan/internal/asio_stream_core.h>
-#include <botan/tls_client.h>
-#include <botan/tls_magic.h>
-
-namespace Botan {
-
-namespace TLS {
-
-/** Base class for all Botan::TLS::Stream implementations.
- *
- * This template must be specialized for all the Botan::TLS::Channel to be used.
- * Currently it only supports the Botan::TLS::Client channel that impersonates
- * the client-side of a TLS connection.
- *
- * TODO: create a Botan::TLS::Server specialization
- */
-template <class Channel>
-class StreamBase
- {
- };
-
-template <>
-class StreamBase<Botan::TLS::Client>
- {
- public:
- StreamBase(Context& context)
- : m_channel(m_core,
- *context.sessionManager,
- *context.credentialsManager,
- *context.policy,
- *context.randomNumberGenerator,
- context.serverInfo)
- {
- }
-
- StreamBase(const StreamBase&) = delete;
- StreamBase& operator=(const StreamBase&) = delete;
-
- protected:
- //! \brief validate the connection side (OpenSSL compatibility)
- void validate_connection_side(Connection_Side side)
- {
- if(side != CLIENT)
- {
- throw Invalid_Argument("wrong connection_side");
- }
- }
-
- //! \brief validate the connection side (OpenSSL compatibility)
- bool validate_connection_side(Connection_Side side, boost::system::error_code& ec)
- {
- if(side != CLIENT)
- {
- ec = Botan::ErrorType::InvalidArgument;
- return false;
- }
-
- return true;
- }
-
- Botan::TLS::StreamCore m_core;
- Botan::TLS::Client m_channel;
- };
-
-} // namespace TLS
-
-} // namespace Botan
-
-#endif // BOOST_VERSION
-#endif // BOTAN_ASIO_STREAM_BASE_H_
diff --git a/src/lib/tls/asio/asio_stream_core.h b/src/lib/tls/asio/asio_stream_core.h
deleted file mode 100644
index dbf95c37a..000000000
--- a/src/lib/tls/asio/asio_stream_core.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-* TLS Stream Helper
-* (C) 2018-2019 Jack Lloyd
-* 2018-2019 Hannes Rantzsch, Tim Oesterreich, Rene Meusel
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_ASIO_STREAM_CORE_H_
-#define BOTAN_ASIO_STREAM_CORE_H_
-
-#include <botan/build.h>
-
-#include <boost/version.hpp>
-#if BOOST_VERSION >= 106600
-
-#include <boost/beast/core/flat_buffer.hpp>
-#include <botan/internal/asio_includes.h>
-#include <botan/tls_callbacks.h>
-#include <botan/tls_magic.h>
-#include <mutex>
-#include <vector>
-
-namespace Botan {
-
-namespace TLS {
-
-/**
- * Contains the buffers for reading/sending, and the needed botan callbacks
- */
-class StreamCore : public Botan::TLS::Callbacks
- {
- public:
- StreamCore()
- : m_input_buffer_space(MAX_CIPHERTEXT_SIZE, '\0'),
- input_buffer(m_input_buffer_space.data(), m_input_buffer_space.size()) {}
-
- virtual ~StreamCore() = default;
-
- void tls_emit_data(const uint8_t data[], std::size_t size) override
- {
- // Provide the encrypted TLS data in the sendBuffer. Actually sending the data is done
- // using (async_)write_some either in the stream or in an async operation.
- m_send_buffer.commit(
- boost::asio::buffer_copy(m_send_buffer.prepare(size), boost::asio::buffer(data, size)));
- }
-
- void tls_record_received(uint64_t, const uint8_t data[], std::size_t size) override
- {
- // TODO: It would be nice to avoid this buffer copy. However, we need to deal with the case
- // that the receive buffer provided by the caller is smaller than the decrypted record.
- auto buffer = m_receive_buffer.prepare(size);
- auto copySize =
- boost::asio::buffer_copy(buffer, boost::asio::const_buffer(data, size));
- m_receive_buffer.commit(copySize);
- }
-
- void tls_alert(Botan::TLS::Alert alert) override
- {
- if(alert.type() == Botan::TLS::Alert::CLOSE_NOTIFY)
- {
- // TODO
- }
- }
-
- std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const override
- {
- return std::chrono::milliseconds(1000);
- }
-
- bool tls_session_established(const Botan::TLS::Session&) override
- {
- // TODO: it should be possible to configure this in the using application (via callback?)
- return true;
- }
-
- bool hasReceivedData() const
- {
- return m_receive_buffer.size() > 0;
- }
-
- template <typename MutableBufferSequence>
- std::size_t copyReceivedData(MutableBufferSequence buffers)
- {
- const auto copiedBytes =
- boost::asio::buffer_copy(buffers, m_receive_buffer.data());
- m_receive_buffer.consume(copiedBytes);
- return copiedBytes;
- }
-
- bool hasDataToSend() const { return m_send_buffer.size() > 0; }
-
- boost::asio::const_buffer sendBuffer() const
- {
- return m_send_buffer.data();
- }
-
- void consumeSendBuffer(std::size_t bytesConsumed)
- {
- m_send_buffer.consume(bytesConsumed);
- }
-
- void clearSendBuffer()
- {
- consumeSendBuffer(m_send_buffer.size());
- }
-
- private:
- // Buffer space used to read input intended for the engine.
- std::vector<uint8_t> m_input_buffer_space;
- boost::beast::flat_buffer m_receive_buffer;
- boost::beast::flat_buffer m_send_buffer;
-
- public:
- // A buffer that may be used to read input intended for the engine.
- const boost::asio::mutable_buffer input_buffer;
- };
-
-} // namespace TLS
-
-} // namespace Botan
-
-#endif // BOOST_VERSION
-#endif // BOTAN_ASIO_STREAM_CORE_H_
diff --git a/src/lib/tls/asio/info.txt b/src/lib/tls/asio/info.txt
index 075ecb795..1e37ea2a3 100644
--- a/src/lib/tls/asio/info.txt
+++ b/src/lib/tls/asio/info.txt
@@ -13,8 +13,6 @@ asio_async_base.h
asio_async_handshake_op.h
asio_async_read_op.h
asio_async_write_op.h
-asio_stream_base.h
-asio_stream_core.h
asio_includes.h
</header:internal>
diff --git a/src/tests/unit_asio_stream.cpp b/src/tests/unit_asio_stream.cpp
index 8c2343ffb..0cbc85de9 100644
--- a/src/tests/unit_asio_stream.cpp
+++ b/src/tests/unit_asio_stream.cpp
@@ -35,12 +35,10 @@ static_assert(sizeof(TEST_DATA) == TEST_DATA_SIZE, "size of TEST_DATA must match
class MockChannel
{
public:
- MockChannel(Botan::TLS::StreamCore& core)
+ MockChannel(Botan::TLS::Callbacks& core)
: m_callbacks(core)
, m_bytes_till_complete_record(TEST_DATA_SIZE)
- , m_active(false)
- {
- }
+ , m_active(false) {}
public:
std::size_t received_data(const uint8_t[], std::size_t buf_size)
@@ -60,9 +58,13 @@ class MockChannel
bool is_active() { return m_active; }
protected:
- Botan::TLS::StreamCore& m_callbacks;
+ Botan::TLS::Callbacks& m_callbacks;
std::size_t m_bytes_till_complete_record; // number of bytes still to read before tls record is completed
bool m_active;
+
+ Botan::TLS::Session_Manager_Noop m_session_manager;
+ Botan::Null_RNG m_rng;
+ Botan::TLS::Default_Policy m_policy;
};
class ThrowingMockChannel : public MockChannel
@@ -73,7 +75,7 @@ class ThrowingMockChannel : public MockChannel
return Botan::TLS::Alert::UNEXPECTED_MESSAGE;
}
- ThrowingMockChannel(Botan::TLS::StreamCore& core) : MockChannel(core)
+ ThrowingMockChannel(Botan::TLS::Callbacks& core) : MockChannel(core)
{
}
@@ -87,62 +89,36 @@ class ThrowingMockChannel : public MockChannel
throw Botan::TLS::Unexpected_Message("test_error");
}
};
-}
+using TestStream = boost::beast::test::stream;
+using FailCount = boost::beast::test::fail_count;
-namespace Botan {
-
-namespace TLS {
-
-/**
- * A specification of StreamBase for the MockChannel used in this test. It
- * matches the specifications for StreamBase<Botan::TLS::Client> and
- * StreamBase<Botan::TLS::Server> except for the underlying channel type and the
- * simplified constructor.
- */
-template <>
-class StreamBase<Botan_Tests::MockChannel>
+class AsioStream : public Botan::TLS::Stream<TestStream, MockChannel>
{
public:
- StreamBase(Context& /*ignored*/)
- : m_channel(m_core)
+ template <typename... Args>
+ AsioStream(Botan::TLS::Context& context, Args&& ... args)
+ : Stream(context, args...)
{
+ m_channel = std::unique_ptr<MockChannel>(new MockChannel(m_core));
}
- StreamBase(const StreamBase&) = delete;
- StreamBase& operator=(const StreamBase&) = delete;
-
- protected:
- StreamCore m_core;
- Botan_Tests::MockChannel m_channel;
-
- void validate_connection_side(Connection_Side) {}
-
- bool validate_connection_side(Connection_Side, boost::system::error_code&) { return true; }
+ virtual ~AsioStream() = default;
};
-template <>
-class StreamBase<Botan_Tests::ThrowingMockChannel> : public StreamBase<Botan_Tests::MockChannel>
+class ThrowingAsioStream : public Botan::TLS::Stream<TestStream, ThrowingMockChannel>
{
public:
- StreamBase(Context& c)
- : StreamBase<Botan_Tests::MockChannel>(c), m_channel(m_core)
+ template <typename... Args>
+ ThrowingAsioStream(Botan::TLS::Context& context, Args&& ... args)
+ : Stream(context, args...)
{
+ m_channel = std::unique_ptr<ThrowingMockChannel>(new ThrowingMockChannel(m_core));
}
- StreamBase(const StreamBase&) = delete;
- StreamBase& operator=(const StreamBase&) = delete;
-
- protected:
- Botan_Tests::ThrowingMockChannel m_channel;
+ virtual ~ThrowingAsioStream() = default;
};
-} // namespace TLS
-
-} // namespace Botan
-
-namespace Botan_Tests {
-
/**
* Synchronous tests for Botan::Stream.
*
@@ -153,11 +129,6 @@ namespace Botan_Tests {
*/
class Asio_Stream_Tests final : public Test
{
- using TestStream = boost::beast::test::stream;
- using FailCount = boost::beast::test::fail_count;
- using AsioStream = Botan::TLS::Stream<TestStream, MockChannel>;
- using ThrowingAsioStream = Botan::TLS::Stream<TestStream, ThrowingMockChannel>;
-
// use memcmp to check if the data in a is a prefix of the data in b
bool contains(const void* a, const void* b, const std::size_t size) { return memcmp(a, b, size) == 0; }
@@ -389,7 +360,7 @@ class Asio_Stream_Tests final : public Test
}
void test_sync_read_zero_buffer(std::vector<Test::Result>& results)
- {
+ {
net::io_context ioc;
Botan::TLS::Context ctx;
@@ -408,7 +379,7 @@ class Asio_Stream_Tests final : public Test
result.confirm("does not report an error", !ec);
results.push_back(result);
- }
+ }
void test_async_read_some_success(std::vector<Test::Result>& results)
{
@@ -515,7 +486,7 @@ class Asio_Stream_Tests final : public Test
}
void test_async_read_zero_buffer(std::vector<Test::Result>& results)
- {
+ {
net::io_context ioc;
TestStream remote{ioc};
@@ -539,7 +510,7 @@ class Asio_Stream_Tests final : public Test
ssl.next_layer().close_remote();
ioc.run();
results.push_back(result);
- }
+ }
void test_sync_write_some_success(std::vector<Test::Result>& results)
{