From 93df95db45fa126725808fbd53aa978b00cf08ad Mon Sep 17 00:00:00 2001 From: Matthias Gierlings Date: Mon, 16 May 2016 20:46:50 +0200 Subject: Added virtual Callback Interface - extracted inner class TLS::Channel::Callbacks to stand-alone class TLS::Callbacks. - provided default implementations for TLS::Callbacks members executing calls to std::function members for backward compatibility. - applied changes to cli, tests and TLS::Channel related classes to be compatible with new interface. --- src/cli/tls_client.cpp | 2 +- src/cli/tls_server.cpp | 2 +- src/lib/tls/info.txt | 1 + src/lib/tls/tls_blocking.cpp | 2 +- src/lib/tls/tls_callbacks.h | 97 ++++++++++++++++++++++++++++++++++++++++++++ src/lib/tls/tls_channel.cpp | 6 +-- src/lib/tls/tls_channel.h | 47 +-------------------- src/lib/tls/tls_client.cpp | 5 ++- src/lib/tls/tls_client.h | 2 +- src/lib/tls/tls_server.cpp | 5 ++- src/tests/unit_tls.cpp | 26 ++++++------ 11 files changed, 128 insertions(+), 67 deletions(-) create mode 100644 src/lib/tls/tls_callbacks.h (limited to 'src') diff --git a/src/cli/tls_client.cpp b/src/cli/tls_client.cpp index f6cc2e518..2e7daed6e 100644 --- a/src/cli/tls_client.cpp +++ b/src/cli/tls_client.cpp @@ -119,7 +119,7 @@ class TLS_Client final : public Command version = Botan::TLS::Protocol_Version::TLS_V11; } - Botan::TLS::Client client(Botan::TLS::Client::Callbacks( + Botan::TLS::Client client(Botan::TLS::Callbacks( socket_write, std::bind(&TLS_Client::process_data, this, _1, _2), std::bind(&TLS_Client::alert_received, this, _1), diff --git a/src/cli/tls_server.cpp b/src/cli/tls_server.cpp index c9f0b0a79..dffd30f66 100644 --- a/src/cli/tls_server.cpp +++ b/src/cli/tls_server.cpp @@ -107,7 +107,7 @@ class TLS_Server final : public Command } }; - Botan::TLS::Server server(Botan::TLS::Server::Callbacks( + Botan::TLS::Server server(Botan::TLS::Callbacks( socket_write, proc_fn, std::bind(&TLS_Server::alert_received, this, _1), diff --git a/src/lib/tls/info.txt b/src/lib/tls/info.txt index de15a65e5..b62adc17f 100644 --- a/src/lib/tls/info.txt +++ b/src/lib/tls/info.txt @@ -6,6 +6,7 @@ load_on auto credentials_manager.h tls_alert.h tls_blocking.h +tls_callbacks.h tls_channel.h tls_ciphersuite.h tls_client.h diff --git a/src/lib/tls/tls_blocking.cpp b/src/lib/tls/tls_blocking.cpp index 4c78a44ce..88397336b 100644 --- a/src/lib/tls/tls_blocking.cpp +++ b/src/lib/tls/tls_blocking.cpp @@ -22,7 +22,7 @@ Blocking_Client::Blocking_Client(read_fn reader, RandomNumberGenerator& rng, TLS::Client::Properties& properties) : m_read(reader), - m_channel(TLS::Client::Callbacks( + m_channel(TLS::Callbacks( writer, std::bind(&Blocking_Client::data_cb, this, _1, _2), std::bind(&Blocking_Client::alert_cb, this, _1), diff --git a/src/lib/tls/tls_callbacks.h b/src/lib/tls/tls_callbacks.h new file mode 100644 index 000000000..854054c2b --- /dev/null +++ b/src/lib/tls/tls_callbacks.h @@ -0,0 +1,97 @@ +/* +* TLS Callbacks +* (C) 2016 Matthias Gierlings +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_TLS_CALLBACKS_H__ +#define BOTAN_TLS_CALLBACKS_H__ + +#include +#include +namespace Botan { + +namespace TLS { + +class Handshake_State; +class Handshake_Message; + +/** +* Virtual Interface for TLS-Channel related callback handling. The default +* implementations involving std::function are only provided for compatibility +* purposes. New implementations should override the virtual member methods +* out_fn(), app_data(), alert(), handshake() and handshake_msg() instead. +* +*/ +class BOTAN_DLL Callbacks + { + public: + typedef std::function output_fn; + typedef std::function data_cb; + typedef std::function alert_cb; + typedef std::function handshake_cb; + typedef std::function handshake_msg_cb; + + /** + * DEPRECATED: This constructor is only provided for backward + * compatibility. New implementations should override the + * virtual member methods out_fn(), app_data(), alert(), + * handshake() and handshake_msg() and use the default constructor + * Callbacks(). + * + * Encapsulates a set of callback functions required by a TLS Channel. + * @param output_fn is called with data for the outbound socket + * + * @param app_data_cb is called when new application data is received + * + * @param alert_cb is called when a TLS alert is received + * + * @param handshake_cb is called when a handshake is completed + */ + + Callbacks(output_fn out, data_cb app_data_cb, alert_cb alert_cb, + handshake_cb hs_cb, handshake_msg_cb hs_msg_cb = nullptr) + : m_output_function(out), m_app_data_cb(app_data_cb), + m_alert_cb(alert_cb), m_hs_cb(hs_cb), m_hs_msg_cb(hs_msg_cb) {} + + virtual ~Callbacks() {} + + virtual void out_fn(const byte data[], size_t size) const + { + if (m_output_function != nullptr) { m_output_function(data, size); } + } + + virtual void app_data(const byte data[], size_t size) const + { + if (m_app_data_cb != nullptr) { m_app_data_cb(data, size); } + } + + virtual void alert(Alert alert) const + { + if (m_alert_cb != nullptr) { m_alert_cb(alert); } + } + + virtual bool handshake(const Session& session) const + { + if (m_hs_cb != nullptr) { return m_hs_cb(session); } + } + + virtual void handshake_msg(const Handshake_Message& hmsg) + { + if (m_hs_msg_cb != nullptr) { m_hs_msg_cb(hmsg); } + } + + private: + const output_fn m_output_function; + const data_cb m_app_data_cb; + const alert_cb m_alert_cb; + const handshake_cb m_hs_cb; + const handshake_msg_cb m_hs_msg_cb; + }; + +} + +} + +#endif diff --git a/src/lib/tls/tls_channel.cpp b/src/lib/tls/tls_channel.cpp index 6300bd52b..9bd3e5603 100644 --- a/src/lib/tls/tls_channel.cpp +++ b/src/lib/tls/tls_channel.cpp @@ -409,7 +409,7 @@ void Channel::process_application_data(secure_vector& record) * following record. Avoid spurious callbacks. */ if(record.size() > 0) - m_callbacks.app_data()(record.data(), record.size()); + m_callbacks.app_data(record.data(), record.size()); } void Channel::process_alert(secure_vector& record) @@ -419,7 +419,7 @@ void Channel::process_alert(secure_vector& record) if(alert_msg.type() == Alert::NO_RENEGOTIATION) m_pending_state.reset(); - m_callbacks.alert()(alert_msg); + m_callbacks.alert(alert_msg); if(alert_msg.is_fatal()) { @@ -454,7 +454,7 @@ void Channel::write_record(Connection_Cipher_State* cipher_state, u16bit epoch, cipher_state, m_rng); - m_callbacks.out_fn()(m_writebuf.data(), m_writebuf.size()); + m_callbacks.out_fn(m_writebuf.data(), m_writebuf.size()); } void Channel::send_record_array(u16bit epoch, byte type, const byte input[], size_t length) diff --git a/src/lib/tls/tls_channel.h b/src/lib/tls/tls_channel.h index 71356f382..d10ac2b6e 100644 --- a/src/lib/tls/tls_channel.h +++ b/src/lib/tls/tls_channel.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -35,50 +36,6 @@ class BOTAN_DLL Channel public: static size_t IO_BUF_DEFAULT_SIZE; - class Callbacks - { - public: - typedef std::function output_fn; - typedef std::function data_cb; - typedef std::function alert_cb; - typedef std::function handshake_cb; - typedef std::function handshake_msg_cb; - /** - * Encapsulates a set of callback functions required by a TLS Channel. - * @param output_fn is called with data for the outbound socket - * - * @param app_data_cb is called when new application data is received - * - * @param alert_cb is called when a TLS alert is received - * - * @param handshake_cb is called when a handshake is completed - */ - Callbacks(output_fn out, data_cb app_data_cb, alert_cb alert_cb, - handshake_cb hs_cb) - : m_output_function(out), m_app_data_cb(app_data_cb), - m_alert_cb(alert_cb), m_hs_cb(hs_cb), m_hs_msg_cb() {} - - Callbacks(output_fn out, data_cb app_data_cb, alert_cb alert_cb, - handshake_cb hs_cb, handshake_msg_cb hs_msg_cb) - : m_output_function(out), m_app_data_cb(app_data_cb), - m_alert_cb(alert_cb), m_hs_cb(hs_cb), m_hs_msg_cb(hs_msg_cb) {} - - const output_fn& out_fn() const { return m_output_function; } - const data_cb& app_data() const { return m_app_data_cb; } - const alert_cb& alert() const { return m_alert_cb; } - const handshake_cb& handshake() const { return m_hs_cb; } - const handshake_msg_cb& handshake_msg() const { return m_hs_msg_cb; } - - private: - const output_fn m_output_function; - const data_cb m_app_data_cb; - const alert_cb m_alert_cb; - const handshake_cb m_hs_cb; - const handshake_msg_cb m_hs_msg_cb; - }; - - - Channel(const Callbacks& callbacks, Session_Manager& session_manager, RandomNumberGenerator& rng, @@ -237,7 +194,7 @@ class BOTAN_DLL Channel const Policy& policy() const { return m_policy; } - bool save_session(const Session& session) const { return m_callbacks.handshake()(session); } + bool save_session(const Session& session) const { return m_callbacks.handshake(session); } Callbacks get_callbacks() const { return m_callbacks; } private: diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp index cc94aa11a..ab733d7a5 100644 --- a/src/lib/tls/tls_client.cpp +++ b/src/lib/tls/tls_client.cpp @@ -64,7 +64,10 @@ Client::Client(const Callbacks& callbacks, Handshake_State* Client::new_handshake_state(Handshake_IO* io) { - return new Client_Handshake_State(io, get_callbacks().handshake_msg()); + return new Client_Handshake_State(io, + std::bind(&TLS::Callbacks::handshake_msg, + get_callbacks(), + std::placeholders::_1)); } std::vector diff --git a/src/lib/tls/tls_client.h b/src/lib/tls/tls_client.h index f73de0108..7fb4af89a 100644 --- a/src/lib/tls/tls_client.h +++ b/src/lib/tls/tls_client.h @@ -95,7 +95,7 @@ class BOTAN_DLL Client final : public Channel const Policy& policy, RandomNumberGenerator& rng, Properties properties, - size_t reserved_io_buffer_size = 16*1024 + size_t reserved_io_buffer_size = TLS::Client::IO_BUF_DEFAULT_SIZE ); const std::string& application_protocol() const { return m_application_protocol; } diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp index b1fff5fec..f864df391 100644 --- a/src/lib/tls/tls_server.cpp +++ b/src/lib/tls/tls_server.cpp @@ -231,7 +231,10 @@ Server::Server(const Callbacks& callbacks, Handshake_State* Server::new_handshake_state(Handshake_IO* io) { std::unique_ptr state( - new Server_Handshake_State(io, get_callbacks().handshake_msg())); + new Server_Handshake_State(io, + std::bind(&TLS::Callbacks::handshake_msg, + get_callbacks(), + std::placeholders::_1))); state->set_expected_next(CLIENT_HELLO); return state.release(); diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp index d520752ee..621a803c8 100644 --- a/src/tests/unit_tls.cpp +++ b/src/tests/unit_tls.cpp @@ -220,7 +220,7 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, std::vector c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent; - Botan::TLS::Server server(Botan::TLS::Server::Callbacks( + Botan::TLS::Server server(Botan::TLS::Callbacks( queue_inserter(s2c_traffic), queue_inserter(server_recv), print_alert, @@ -232,10 +232,10 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version, next_protocol_chooser, false); - Botan::TLS::Client::Callbacks client_callbacks(queue_inserter(c2s_traffic), - queue_inserter(client_recv), - print_alert, - handshake_complete); + Botan::TLS::Callbacks client_callbacks(queue_inserter(c2s_traffic), + queue_inserter(client_recv), + print_alert, + handshake_complete); Botan::TLS::Client client(client_callbacks, client_sessions, creds, @@ -449,10 +449,10 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, { std::vector c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent; - Botan::TLS::Server::Callbacks server_callbacks(queue_inserter(s2c_traffic), - queue_inserter(server_recv), - print_alert, - handshake_complete); + Botan::TLS::Callbacks server_callbacks(queue_inserter(s2c_traffic), + queue_inserter(server_recv), + print_alert, + handshake_complete); Botan::TLS::Server server(server_callbacks, server_sessions, creds, @@ -461,10 +461,10 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version, next_protocol_chooser, true); - Botan::TLS::Client::Callbacks client_callbacks(queue_inserter(c2s_traffic), - queue_inserter(client_recv), - print_alert, - handshake_complete); + Botan::TLS::Callbacks client_callbacks(queue_inserter(c2s_traffic), + queue_inserter(client_recv), + print_alert, + handshake_complete); Botan::TLS::Client client(client_callbacks, client_sessions, creds, -- cgit v1.2.3