diff options
author | Hannes Rantzsch <[email protected]> | 2020-02-26 15:19:23 +0700 |
---|---|---|
committer | Hannes Rantzsch <[email protected]> | 2020-03-17 07:19:54 +0700 |
commit | 9501a897a8cbb200b1001f82e373157afc9ba438 (patch) | |
tree | d4b7ed69413f273baab071e6a569a50a084ee958 /src/lib/tls/asio | |
parent | f8eff7dd074069507b5c4b1684423511f819dd03 (diff) |
implement server-side of TLS::Stream
Allows the TLS::Stream to perform the handshake as the server-side. Also
adds a client-server integration test for the stream.
Diffstat (limited to 'src/lib/tls/asio')
-rw-r--r-- | src/lib/tls/asio/asio_context.h | 4 | ||||
-rw-r--r-- | src/lib/tls/asio/asio_stream.h | 63 |
2 files changed, 38 insertions, 29 deletions
diff --git a/src/lib/tls/asio/asio_context.h b/src/lib/tls/asio/asio_context.h index e5e99e83a..e225fde6a 100644 --- a/src/lib/tls/asio/asio_context.h +++ b/src/lib/tls/asio/asio_context.h @@ -1,7 +1,7 @@ /* * TLS Context - * (C) 2018-2019 Jack Lloyd - * 2018-2019 Hannes Rantzsch, Tim Oesterreich, Rene Meusel + * (C) 2018-2020 Jack Lloyd + * 2018-2020 Hannes Rantzsch, Tim Oesterreich, Rene Meusel * * Botan is released under the Simplified BSD License (see license.txt) */ diff --git a/src/lib/tls/asio/asio_stream.h b/src/lib/tls/asio/asio_stream.h index 6dfd130f7..cb49f259b 100644 --- a/src/lib/tls/asio/asio_stream.h +++ b/src/lib/tls/asio/asio_stream.h @@ -23,6 +23,7 @@ #include <botan/tls_channel.h> #include <botan/tls_client.h> #include <botan/tls_magic.h> +#include <botan/tls_server.h> // We need to define BOOST_ASIO_DISABLE_SERIAL_PORT before any asio imports. Otherwise asio will include <termios.h>, // which interferes with Botan's amalgamation by defining macros like 'B0' and 'FF1'. @@ -40,8 +41,6 @@ namespace TLS { /** * @brief 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 */ @@ -200,7 +199,7 @@ class Stream * The function call will block until handshaking is complete or an error occurs. * * @param side The type of handshaking to be performed, i.e. as a client or as a server. - * @throws boost::system::system_error if error occured, or if the chosen Connection_Side is not available + * @throws boost::system::system_error if error occured */ void handshake(Connection_Side side) { @@ -221,8 +220,11 @@ class Stream { setup_native_handle(side, ec); - // send client hello, which was written to the send buffer on client instantiation - send_pending_encrypted_data(ec); + if(side == CLIENT) + { + // send client hello, which was written to the send buffer on client instantiation + send_pending_encrypted_data(ec); + } while(!native_handle()->is_active() && !ec) { @@ -244,11 +246,10 @@ class Stream * @param side 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 NotImplemented if Connection_Side is not CLIENT */ template <typename HandshakeHandler> auto async_handshake(Connection_Side side, HandshakeHandler&& handler) -> - BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void(boost::system::error_code)) + BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void(boost::system::error_code)) { BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check; @@ -492,8 +493,8 @@ class Stream */ template <typename ConstBufferSequence, typename WriteHandler> auto async_write_some(const ConstBufferSequence& buffers, WriteHandler&& handler) -> - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void(boost::system::error_code, std::size_t)) + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void(boost::system::error_code, std::size_t)) { BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; @@ -529,8 +530,8 @@ class Stream */ template <typename MutableBufferSequence, typename ReadHandler> auto async_read_some(const MutableBufferSequence& buffers, ReadHandler&& handler) -> - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void(boost::system::error_code, std::size_t)) + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void(boost::system::error_code, std::size_t)) { BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; @@ -667,28 +668,36 @@ class Stream * Botan::TLS::Server. * * @param side The desired connection side (client or server) - * @param ec Set to NotImplemented when side is SERVER - currently only CLIENT is implemented + * @param ec Set to indicate what error occurred, if any. */ template<class T = ChannelT> typename std::enable_if<std::is_same<Channel, T>::value>::type setup_native_handle(Connection_Side side, boost::system::error_code& ec) { - if(side == CLIENT) - { - m_native_handle = std::unique_ptr<Client>( - new Client(m_core, - m_context.m_session_manager, - m_context.m_credentials_manager, - m_context.m_policy, - m_context.m_rng, - m_context.m_server_info)); - } - else + try_with_error_code([&] { - // TODO: First steps in order to support the server side of this stream would be to instantiate a - // Botan::TLS::Server instance as the stream's native_handle and implement the handshake appropriately. - ec = Botan::ErrorType::NotImplemented; - } + if(side == CLIENT) + { + m_native_handle = std::unique_ptr<Client>( + new Client(m_core, + m_context.m_session_manager, + m_context.m_credentials_manager, + m_context.m_policy, + m_context.m_rng, + m_context.m_server_info, + Protocol_Version::latest_tls_version())); + } + else + { + m_native_handle = std::unique_ptr<Server>( + new Server(m_core, + m_context.m_session_manager, + m_context.m_credentials_manager, + m_context.m_policy, + m_context.m_rng, + false /* no DTLS */)); + } + }, ec); } /** @brief Synchronously write encrypted data from the send buffer to the next layer. |