aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cli/tls_client.cpp38
-rw-r--r--src/cli/tls_proxy.cpp17
-rw-r--r--src/cli/tls_server.cpp12
-rw-r--r--src/lib/tls/info.txt1
-rw-r--r--src/lib/tls/tls_blocking.cpp8
-rw-r--r--src/lib/tls/tls_blocking.h2
-rw-r--r--src/lib/tls/tls_callbacks.h106
-rw-r--r--src/lib/tls/tls_channel.cpp31
-rw-r--r--src/lib/tls/tls_channel.h23
-rw-r--r--src/lib/tls/tls_client.cpp9
-rw-r--r--src/lib/tls/tls_client.h57
-rw-r--r--src/lib/tls/tls_handshake_state.cpp10
-rw-r--r--src/lib/tls/tls_handshake_state.h14
-rw-r--r--src/lib/tls/tls_record.h4
-rw-r--r--src/lib/tls/tls_server.cpp36
-rw-r--r--src/lib/tls/tls_server.h23
-rw-r--r--src/lib/tls/tls_server_handshake_state.h48
-rw-r--r--src/tests/unit_tls.cpp93
18 files changed, 308 insertions, 224 deletions
diff --git a/src/cli/tls_client.cpp b/src/cli/tls_client.cpp
index e2fc1f027..082daf4ac 100644
--- a/src/cli/tls_client.cpp
+++ b/src/cli/tls_client.cpp
@@ -36,7 +36,7 @@
namespace Botan_CLI {
-class TLS_Client final : public Command
+class TLS_Client final : public Command, public Botan::TLS::Callbacks
{
public:
TLS_Client() : Command("tls_client host --port=443 --print-certs --policy= "
@@ -99,15 +99,10 @@ class TLS_Client final : public Command
const std::vector<std::string> protocols_to_offer = Botan::split_on("next-protocols", ',');
- int sockfd = connect_to_host(host, port, use_tcp);
+ m_sockfd = connect_to_host(host, port, use_tcp);
using namespace std::placeholders;
- auto socket_write =
- use_tcp ?
- std::bind(stream_socket_write, sockfd, _1, _2) :
- std::bind(dgram_socket_write, sockfd, _1, _2);
-
auto version = policy->latest_supported_version(!use_tcp);
if(flag_set("tls1.0"))
@@ -119,11 +114,7 @@ class TLS_Client final : public Command
version = Botan::TLS::Protocol_Version::TLS_V11;
}
- 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),
- std::bind(&TLS_Client::handshake_complete, this, _1)),
+ Botan::TLS::Client client(*this,
*session_mgr,
creds,
*policy,
@@ -138,7 +129,7 @@ class TLS_Client final : public Command
{
fd_set readfds;
FD_ZERO(&readfds);
- FD_SET(sockfd, &readfds);
+ FD_SET(m_sockfd, &readfds);
if(client.is_active())
{
@@ -154,13 +145,13 @@ class TLS_Client final : public Command
struct timeval timeout = { 1, 0 };
- ::select(sockfd + 1, &readfds, nullptr, nullptr, &timeout);
+ ::select(m_sockfd + 1, &readfds, nullptr, nullptr, &timeout);
- if(FD_ISSET(sockfd, &readfds))
+ if(FD_ISSET(m_sockfd, &readfds))
{
uint8_t buf[4*1024] = { 0 };
- ssize_t got = ::read(sockfd, buf, sizeof(buf));
+ ssize_t got = ::read(m_sockfd, buf, sizeof(buf));
if(got == 0)
{
@@ -218,7 +209,7 @@ class TLS_Client final : public Command
}
}
- ::close(sockfd);
+ ::close(m_sockfd);
}
private:
@@ -258,7 +249,7 @@ class TLS_Client final : public Command
return fd;
}
- bool handshake_complete(const Botan::TLS::Session& session)
+ bool tls_session_established(const Botan::TLS::Session& session) override
{
output() << "Handshake complete, " << session.version().to_string()
<< " using " << session.ciphersuite().to_string() << "\n";
@@ -292,13 +283,13 @@ class TLS_Client final : public Command
throw CLI_Error("Socket write failed errno=" + std::to_string(errno));
}
- static void stream_socket_write(int sockfd, const uint8_t buf[], size_t length)
+ void tls_emit_data(const uint8_t buf[], size_t length) override
{
size_t offset = 0;
while(length)
{
- ssize_t sent = ::send(sockfd, (const char*)buf + offset,
+ ssize_t sent = ::send(m_sockfd, (const char*)buf + offset,
length, MSG_NOSIGNAL);
if(sent == -1)
@@ -314,16 +305,19 @@ class TLS_Client final : public Command
}
}
- void alert_received(Botan::TLS::Alert alert)
+ void tls_alert(Botan::TLS::Alert alert)
{
output() << "Alert: " << alert.type_string() << "\n";
}
- void process_data(const uint8_t buf[], size_t buf_size)
+ void tls_record_received(uint64_t seq_no, const uint8_t buf[], size_t buf_size)
{
for(size_t i = 0; i != buf_size; ++i)
output() << buf[i];
}
+
+ private:
+ int m_sockfd;
};
BOTAN_REGISTER_COMMAND("tls_client", TLS_Client);
diff --git a/src/cli/tls_proxy.cpp b/src/cli/tls_proxy.cpp
index d52a67631..5140654de 100644
--- a/src/cli/tls_proxy.cpp
+++ b/src/cli/tls_proxy.cpp
@@ -60,7 +60,7 @@ void log_text_message(const char* where, const uint8_t buf[], size_t buf_len)
//std::cout << where << ' ' << std::string(c, c + buf_len) << std::endl;
}
-class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_session>
+class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_session>, public Botan::TLS::Callbacks
{
public:
enum { readbuf_size = 4 * 1024 };
@@ -112,10 +112,7 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio
m_server_endpoints(endpoints),
m_client_socket(io),
m_server_socket(io),
- m_tls(Botan::TLS::Callbacks(boost::bind(&tls_proxy_session::tls_proxy_write_to_client, this, _1, _2),
- boost::bind(&tls_proxy_session::tls_client_write_to_proxy, this, _1, _2),
- boost::bind(&tls_proxy_session::tls_alert_cb, this, _1),
- boost::bind(&tls_proxy_session::tls_handshake_complete, this, _1)),
+ m_tls(*this,
session_manager,
credentials,
policy,
@@ -168,7 +165,7 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio
{
m_client_socket.close();
}
- tls_proxy_write_to_client(nullptr, 0); // initiate another write if needed
+ tls_emit_data(nullptr, 0); // initiate another write if needed
}
void handle_server_write_completion(const boost::system::error_code& error)
@@ -184,13 +181,13 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio
proxy_write_to_server(nullptr, 0); // initiate another write if needed
}
- void tls_client_write_to_proxy(const uint8_t buf[], size_t buf_len)
+ void tls_record_received(uint64_t /*rec_no*/, const uint8_t buf[], size_t buf_len) override
{
// Immediately bounce message to server
proxy_write_to_server(buf, buf_len);
}
- void tls_proxy_write_to_client(const uint8_t buf[], size_t buf_len)
+ void tls_emit_data(const uint8_t buf[], size_t buf_len) override
{
if(buf_len > 0)
m_p2c_pending.insert(m_p2c_pending.end(), buf, buf + buf_len);
@@ -269,7 +266,7 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio
boost::asio::placeholders::bytes_transferred)));
}
- bool tls_handshake_complete(const Botan::TLS::Session& session)
+ bool tls_session_established(const Botan::TLS::Session& session) override
{
//std::cout << "Handshake from client complete" << std::endl;
@@ -293,7 +290,7 @@ class tls_proxy_session : public boost::enable_shared_from_this<tls_proxy_sessio
return true;
}
- void tls_alert_cb(Botan::TLS::Alert alert)
+ void tls_alert(Botan::TLS::Alert alert) override
{
if(alert.type() == Botan::TLS::Alert::CLOSE_NOTIFY)
{
diff --git a/src/cli/tls_server.cpp b/src/cli/tls_server.cpp
index dffd30f66..2496f5508 100644
--- a/src/cli/tls_server.cpp
+++ b/src/cli/tls_server.cpp
@@ -1,7 +1,6 @@
/*
* TLS echo server using BSD sockets
* (C) 2014 Jack Lloyd
-* 2016 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -107,11 +106,10 @@ class TLS_Server final : public Command
}
};
- Botan::TLS::Server server(Botan::TLS::Callbacks(
- socket_write,
- proc_fn,
- std::bind(&TLS_Server::alert_received, this, _1),
- std::bind(&TLS_Server::handshake_complete, this, _1)),
+ Botan::TLS::Server server(socket_write,
+ proc_fn,
+ std::bind(&TLS_Server::alert_received, this, _1, _2, _3),
+ std::bind(&TLS_Server::handshake_complete, this, _1),
session_manager,
creds,
policy,
@@ -238,7 +236,7 @@ class TLS_Server final : public Command
}
}
- void alert_received(Botan::TLS::Alert alert)
+ void alert_received(Botan::TLS::Alert alert, const uint8_t[], size_t)
{
std::cout << "Alert: " << alert.type_string() << std::endl;
}
diff --git a/src/lib/tls/info.txt b/src/lib/tls/info.txt
index b62adc17f..208c4ebb2 100644
--- a/src/lib/tls/info.txt
+++ b/src/lib/tls/info.txt
@@ -30,7 +30,6 @@ tls_messages.h
tls_reader.h
tls_record.h
tls_seq_numbers.h
-tls_server_handshake_state.h
tls_session_key.h
</header:internal>
diff --git a/src/lib/tls/tls_blocking.cpp b/src/lib/tls/tls_blocking.cpp
index 3910d242c..34ebc6c91 100644
--- a/src/lib/tls/tls_blocking.cpp
+++ b/src/lib/tls/tls_blocking.cpp
@@ -24,12 +24,13 @@ Blocking_Client::Blocking_Client(read_fn reader,
const Protocol_Version& offer_version,
const std::vector<std::string>& next) :
m_read(reader),
- m_channel(TLS::Callbacks(
+ m_callbacks(new TLS::Compat_Callbacks(
writer,
std::bind(&Blocking_Client::data_cb, this, _1, _2),
- std::bind(&Blocking_Client::alert_cb, this, _1),
+ std::function<void (Alert)>(std::bind(&Blocking_Client::alert_cb, this, _1)),
std::bind(&Blocking_Client::handshake_cb, this, _1)
- ),
+ )),
+ m_channel(*m_callbacks.get(),
session_manager,
creds,
policy,
@@ -38,6 +39,7 @@ Blocking_Client::Blocking_Client(read_fn reader,
offer_version,
next)
{
+ printf("hi\n");
}
bool Blocking_Client::handshake_cb(const Session& session)
diff --git a/src/lib/tls/tls_blocking.h b/src/lib/tls/tls_blocking.h
index cba44b524..0f2986710 100644
--- a/src/lib/tls/tls_blocking.h
+++ b/src/lib/tls/tls_blocking.h
@@ -33,6 +33,7 @@ class BOTAN_DLL Blocking_Client
typedef std::function<size_t (byte[], size_t)> read_fn;
typedef std::function<void (const byte[], size_t)> write_fn;
+ BOTAN_DEPRECATED("Use the regular TLS::Client interface")
Blocking_Client(read_fn reader,
write_fn writer,
Session_Manager& session_manager,
@@ -93,6 +94,7 @@ class BOTAN_DLL Blocking_Client
void alert_cb(const Alert& alert);
read_fn m_read;
+ std::unique_ptr<Compat_Callbacks> m_callbacks;
TLS::Client m_channel;
secure_vector<byte> m_plaintext;
};
diff --git a/src/lib/tls/tls_callbacks.h b/src/lib/tls/tls_callbacks.h
index 216c58ce2..db1b70693 100644
--- a/src/lib/tls/tls_callbacks.h
+++ b/src/lib/tls/tls_callbacks.h
@@ -1,6 +1,7 @@
/*
* TLS Callbacks
* (C) 2016 Matthias Gierlings
+* 2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -14,33 +15,76 @@ 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.
-*
+* Encapsulates the callbacks that a TLS channel will make which are due to
+* channel specific operations.
*/
class BOTAN_DLL Callbacks
{
public:
+ virtual ~Callbacks() {}
+
+ /**
+ * Mandatory callback: output function
+ * The channel will call this with data which needs to be sent to the peer
+ * (eg, over a socket or some other form of IPC). The array will be overwritten
+ * when the function returns so a copy must be made if the data cannot be
+ * sent immediately.
+ */
+ virtual void tls_emit_data(const uint8_t data[], size_t size) = 0;
+
+ /**
+ * Mandatory callback: process application data
+ * Called when application data record is received from the peer.
+ * Again the array is overwritten immediately after the function returns.
+ * seq_no is the underlying TLS/DTLS record sequence number.
+ */
+ virtual void tls_record_received(u64bit seq_no, const uint8_t data[], size_t size) = 0;
+
+ /**
+ * Mandary callback: alert received
+ * Called when an alert is received from the peer
+ * If fatal, the connection is closing. If not fatal, the connection may
+ * still be closing (depending on the error and the peer).
+ */
+ virtual void tls_alert(Alert alert) = 0;
+
+ /**
+ * Mandatory callback: session established
+ * Called when a session is established. Throw an exception to abort
+ * the connection. Return false to prevent the session from being cached.
+ * Return true to cache the session in the configured session manager.
+ */
+ virtual bool tls_session_established(const Session& session) = 0;
+
+ /**
+ * Optional callback: inspect handshake message
+ */
+ virtual void tls_inspect_handshake_msg(const Handshake_Message&) {}
+
+ /**
+ * Optional callback: debug logging. (not currently used)
+ */
+ virtual bool tls_log_debug(const char*) { return false; }
+ };
+
+/**
+* TLS::Callbacks using std::function for compatability with the old API signatures.
+* This type is only provided for backward compatibility.
+* New implementations should derive from TLS::Callbacks instead.
+*/
+class BOTAN_DLL Compat_Callbacks final : public Callbacks
+ {
+ public:
typedef std::function<void (const byte[], size_t)> output_fn;
typedef std::function<void (const byte[], size_t)> data_cb;
- typedef std::function<void (Alert)> alert_cb;
+ typedef std::function<void (Alert, const byte[], size_t)> alert_cb;
typedef std::function<bool (const Session&)> handshake_cb;
typedef std::function<void (const Handshake_Message&)> 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
@@ -49,48 +93,50 @@ class BOTAN_DLL Callbacks
*
* @param handshake_cb is called when a handshake is completed
*/
- BOTAN_DEPRECATED("Use TLS::Callbacks() (virtual interface).")
- Callbacks(output_fn out, data_cb app_data_cb, alert_cb alert_cb,
- handshake_cb hs_cb, handshake_msg_cb hs_msg_cb = nullptr)
+ BOTAN_DEPRECATED("Use TLS::Callbacks (virtual interface).")
+ Compat_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) {}
+ m_alert_cb(std::bind(alert_cb, std::placeholders::_1, nullptr, 0)),
+ m_hs_cb(hs_cb), m_hs_msg_cb(hs_msg_cb) {}
- Callbacks()
- : m_output_function(nullptr), m_app_data_cb(nullptr),
- m_alert_cb(nullptr), m_hs_cb(nullptr), m_hs_msg_cb(nullptr) {}
-
-
- virtual ~Callbacks() {}
+ BOTAN_DEPRECATED("Use TLS::Callbacks (virtual interface).")
+ Compat_Callbacks(output_fn out, data_cb app_data_cb,
+ std::function<void (Alert)> 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 void out_fn(const byte data[], size_t size) const
+ void tls_emit_data(const byte data[], size_t size) override
{
BOTAN_ASSERT(m_output_function != nullptr,
"Invalid TLS output function callback.");
m_output_function(data, size);
}
- virtual void app_data(const byte data[], size_t size) const
+ void tls_record_received(u64bit /*seq_no*/, const byte data[], size_t size) override
{
BOTAN_ASSERT(m_app_data_cb != nullptr,
"Invalid TLS app data callback.");
m_app_data_cb(data, size);
}
- virtual void alert(Alert alert) const
+ void tls_alert(Alert alert) override
{
BOTAN_ASSERT(m_alert_cb != nullptr,
"Invalid TLS alert callback.");
m_alert_cb(alert);
}
- virtual bool handshake(const Session& session) const
+ bool tls_session_established(const Session& session) override
{
BOTAN_ASSERT(m_hs_cb != nullptr,
"Invalid TLS handshake callback.");
return m_hs_cb(session);
}
- virtual void handshake_msg(const Handshake_Message& hmsg) const
+ void tls_inspect_handshake_msg(const Handshake_Message& hmsg) override
{
// The handshake message callback is optional so we can
// not assume it has been set.
@@ -100,7 +146,7 @@ class BOTAN_DLL Callbacks
private:
const output_fn m_output_function;
const data_cb m_app_data_cb;
- const alert_cb m_alert_cb;
+ const std::function<void (Alert)> m_alert_cb;
const handshake_cb m_hs_cb;
const handshake_msg_cb m_hs_msg_cb;
};
diff --git a/src/lib/tls/tls_channel.cpp b/src/lib/tls/tls_channel.cpp
index b78796536..5f882af64 100644
--- a/src/lib/tls/tls_channel.cpp
+++ b/src/lib/tls/tls_channel.cpp
@@ -1,6 +1,6 @@
/*
* TLS Channels
-* (C) 2011,2012,2014,2015 Jack Lloyd
+* (C) 2011,2012,2014,2015,2016 Jack Lloyd
* 2016 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
@@ -21,7 +21,7 @@ namespace TLS {
size_t TLS::Channel::IO_BUF_DEFAULT_SIZE = 10*1024;
-Channel::Channel(const Callbacks& callbacks,
+Channel::Channel(Callbacks& callbacks,
Session_Manager& session_manager,
RandomNumberGenerator& rng,
const Policy& policy,
@@ -47,7 +47,8 @@ Channel::Channel(output_fn out,
bool is_datagram,
size_t io_buf_sz) :
m_is_datagram(is_datagram),
- m_callbacks(Callbacks(out, app_data_cb, alert_cb, hs_cb, hs_msg_cb)),
+ m_compat_callbacks(new Compat_Callbacks(out, app_data_cb, alert_cb, hs_cb, hs_msg_cb)),
+ m_callbacks(*m_compat_callbacks.get()),
m_session_manager(session_manager),
m_policy(policy),
m_rng(rng)
@@ -319,15 +320,15 @@ size_t Channel::received_data(const byte input[], size_t input_size)
if(record_type == HANDSHAKE || record_type == CHANGE_CIPHER_SPEC)
{
- process_handshake_ccs(record_data, record_sequence, record_type, record_version);
+ process_handshake_ccs(record_data, record_sequence, record_type, record_version);
}
else if(record_type == APPLICATION_DATA)
{
- process_application_data(record_data);
+ process_application_data(record_sequence, record_data);
}
else if(record_type == ALERT)
{
- process_alert(record_data);
+ process_alert(record_data);
}
else if(record_type != NO_RECORD)
throw Unexpected_Message("Unexpected record type " +
@@ -359,10 +360,10 @@ size_t Channel::received_data(const byte input[], size_t input_size)
}
}
-void Channel::process_handshake_ccs(secure_vector<byte>& record,
- u64bit& record_sequence,
- Record_Type& record_type,
- Protocol_Version& record_version)
+void Channel::process_handshake_ccs(const secure_vector<byte>& record,
+ u64bit record_sequence,
+ Record_Type record_type,
+ Protocol_Version record_version)
{
if(!m_pending_state)
{
@@ -422,7 +423,7 @@ void Channel::process_handshake_ccs(secure_vector<byte>& record,
}
}
-void Channel::process_application_data(secure_vector<byte>& record)
+void Channel::process_application_data(u64bit seq_no, const secure_vector<byte>& record)
{
if(!active_state())
throw Unexpected_Message("Application data before handshake done");
@@ -433,17 +434,17 @@ void Channel::process_application_data(secure_vector<byte>& record)
* following record. Avoid spurious callbacks.
*/
if(record.size() > 0)
- m_callbacks.app_data(record.data(), record.size());
+ callbacks().tls_record_received(seq_no, record.data(), record.size());
}
-void Channel::process_alert(secure_vector<byte>& record)
+void Channel::process_alert(const secure_vector<byte>& record)
{
Alert alert_msg(record);
if(alert_msg.type() == Alert::NO_RENEGOTIATION)
m_pending_state.reset();
- m_callbacks.alert(alert_msg);
+ callbacks().tls_alert(alert_msg);
if(alert_msg.is_fatal())
{
@@ -478,7 +479,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());
+ callbacks().tls_emit_data(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 7c59e1d6f..073af760f 100644
--- a/src/lib/tls/tls_channel.h
+++ b/src/lib/tls/tls_channel.h
@@ -36,12 +36,12 @@ class BOTAN_DLL Channel
public:
typedef std::function<void (const byte[], size_t)> output_fn;
typedef std::function<void (const byte[], size_t)> data_cb;
- typedef std::function<void (Alert)> alert_cb;
+ typedef std::function<void (Alert, const byte[], size_t)> alert_cb;
typedef std::function<bool (const Session&)> handshake_cb;
typedef std::function<void (const Handshake_Message&)> handshake_msg_cb;
static size_t IO_BUF_DEFAULT_SIZE;
- Channel(const Callbacks& callbacks,
+ Channel(Callbacks& callbacks,
Session_Manager& session_manager,
RandomNumberGenerator& rng,
const Policy& policy,
@@ -215,9 +215,9 @@ 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 callbacks().tls_session_established(session); }
- Callbacks get_callbacks() const { return m_callbacks; }
+ Callbacks& callbacks() const { return m_callbacks; }
private:
void init(size_t io_buf_sze);
@@ -245,19 +245,20 @@ class BOTAN_DLL Channel
const Handshake_State* pending_state() const { return m_pending_state.get(); }
/* methods to handle incoming traffic through Channel::receive_data. */
- void process_handshake_ccs(secure_vector<byte>& record,
- u64bit& record_sequence,
- Record_Type& record_type,
- Protocol_Version& record_version);
+ void process_handshake_ccs(const secure_vector<byte>& record,
+ u64bit record_sequence,
+ Record_Type record_type,
+ Protocol_Version record_version);
- void process_application_data(secure_vector<byte>& record);
+ void process_application_data(u64bit req_no, const secure_vector<byte>& record);
- void process_alert(secure_vector<byte>& record);
+ void process_alert(const secure_vector<byte>& record);
bool m_is_datagram;
/* callbacks */
- Callbacks m_callbacks;
+ std::unique_ptr<Compat_Callbacks> m_compat_callbacks;
+ Callbacks& m_callbacks;
/* external state */
Session_Manager& m_session_manager;
diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp
index ab7beddbd..f77521c03 100644
--- a/src/lib/tls/tls_client.cpp
+++ b/src/lib/tls/tls_client.cpp
@@ -24,7 +24,7 @@ class Client_Handshake_State : public Handshake_State
public:
// using Handshake_State::Handshake_State;
- Client_Handshake_State(Handshake_IO* io, handshake_msg_cb cb) : Handshake_State(io, cb) {}
+ Client_Handshake_State(Handshake_IO* io, Callbacks& cb) : Handshake_State(io, cb) {}
const Public_Key& get_server_public_Key() const
{
@@ -43,7 +43,7 @@ class Client_Handshake_State : public Handshake_State
/*
* TLS Client Constructor
*/
-Client::Client(const Callbacks& callbacks,
+Client::Client(Callbacks& callbacks,
Session_Manager& session_manager,
Credentials_Manager& creds,
const Policy& policy,
@@ -112,10 +112,7 @@ void Client::init(const Protocol_Version& protocol_version,
Handshake_State* Client::new_handshake_state(Handshake_IO* io)
{
- return new Client_Handshake_State(io,
- std::bind(&TLS::Callbacks::handshake_msg,
- get_callbacks(),
- std::placeholders::_1));
+ return new Client_Handshake_State(io, callbacks());
}
std::vector<X509_Certificate>
diff --git a/src/lib/tls/tls_client.h b/src/lib/tls/tls_client.h
index 6452294cd..09af053af 100644
--- a/src/lib/tls/tls_client.h
+++ b/src/lib/tls/tls_client.h
@@ -23,6 +23,7 @@ namespace TLS {
class BOTAN_DLL Client final : public Channel
{
public:
+
/**
* Set up a new TLS client session
*
@@ -48,7 +49,51 @@ class BOTAN_DLL Client final : public Channel
* be preallocated for the read and write buffers. Smaller
* values just mean reallocations and copies are more likely.
*/
+ Client(Callbacks& callbacks,
+ Session_Manager& session_manager,
+ Credentials_Manager& creds,
+ const Policy& policy,
+ RandomNumberGenerator& rng,
+ const Server_Information& server_info = Server_Information(),
+ const Protocol_Version& offer_version = Protocol_Version::latest_tls_version(),
+ const std::vector<std::string>& next_protocols = {},
+ size_t reserved_io_buffer_size = TLS::Client::IO_BUF_DEFAULT_SIZE
+ );
+ /**
+ * DEPRECATED. This constructor is only provided for backward
+ * compatibility and should not be used in new code.
+ *
+ * Set up a new TLS client session
+ *
+ * @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
+ *
+ * @param session_manager manages session state
+ *
+ * @param creds manages application/user credentials
+ *
+ * @param policy specifies other connection policy information
+ *
+ * @param rng a random number generator
+ *
+ * @param server_info is identifying information about the TLS server
+ *
+ * @param offer_version specifies which version we will offer
+ * to the TLS server.
+ *
+ * @param next_protocols specifies protocols to advertise with ALPN
+ *
+ * @param reserved_io_buffer_size This many bytes of memory will
+ * be preallocated for the read and write buffers. Smaller
+ * values just mean reallocations and copies are more likely.
+ */
+ BOTAN_DEPRECATED("Use TLS::Client(TLS::Callbacks ...)")
Client(output_fn out,
data_cb app_data_cb,
alert_cb alert_cb,
@@ -82,18 +127,6 @@ class BOTAN_DLL Client final : public Channel
const std::vector<std::string>& next_protocols = {}
);
-
- Client(const Callbacks& callbacks,
- Session_Manager& session_manager,
- Credentials_Manager& creds,
- const Policy& policy,
- RandomNumberGenerator& rng,
- const Server_Information& server_info = Server_Information(),
- const Protocol_Version& offer_version = Protocol_Version::latest_tls_version(),
- const std::vector<std::string>& next_protocols = {},
- size_t reserved_io_buffer_size = TLS::Client::IO_BUF_DEFAULT_SIZE
- );
-
const std::string& application_protocol() const { return m_application_protocol; }
private:
void init(const Protocol_Version& protocol_version,
diff --git a/src/lib/tls/tls_handshake_state.cpp b/src/lib/tls/tls_handshake_state.cpp
index afc32ba87..71cacdabd 100644
--- a/src/lib/tls/tls_handshake_state.cpp
+++ b/src/lib/tls/tls_handshake_state.cpp
@@ -8,6 +8,7 @@
#include <botan/internal/tls_handshake_state.h>
#include <botan/internal/tls_messages.h>
#include <botan/internal/tls_record.h>
+#include <botan/tls_callbacks.h>
namespace Botan {
@@ -174,8 +175,8 @@ std::string handshake_mask_to_string(u32bit mask)
/*
* Initialize the SSL/TLS Handshake State
*/
-Handshake_State::Handshake_State(Handshake_IO* io, handshake_msg_cb cb) :
- m_msg_callback(cb),
+Handshake_State::Handshake_State(Handshake_IO* io, Callbacks& cb) :
+ m_callbacks(cb),
m_handshake_io(io),
m_version(m_handshake_io->initial_record_version())
{
@@ -183,6 +184,11 @@ Handshake_State::Handshake_State(Handshake_IO* io, handshake_msg_cb cb) :
Handshake_State::~Handshake_State() {}
+void Handshake_State::note_message(const Handshake_Message& msg)
+ {
+ m_callbacks.tls_inspect_handshake_msg(msg);
+ }
+
void Handshake_State::hello_verify_request(const Hello_Verify_Request& hello_verify)
{
note_message(hello_verify);
diff --git a/src/lib/tls/tls_handshake_state.h b/src/lib/tls/tls_handshake_state.h
index 2943a8637..bdec10d14 100644
--- a/src/lib/tls/tls_handshake_state.h
+++ b/src/lib/tls/tls_handshake_state.h
@@ -24,6 +24,7 @@ class KDF;
namespace TLS {
+class Callbacks;
class Policy;
class Hello_Verify_Request;
@@ -45,9 +46,7 @@ class Finished;
class Handshake_State
{
public:
- typedef std::function<void (const Handshake_Message&)> handshake_msg_cb;
-
- Handshake_State(Handshake_IO* io, handshake_msg_cb cb);
+ Handshake_State(Handshake_IO* io, Callbacks& callbacks);
virtual ~Handshake_State();
@@ -164,15 +163,10 @@ class Handshake_State
const Handshake_Hash& hash() const { return m_handshake_hash; }
- void note_message(const Handshake_Message& msg)
- {
- if(m_msg_callback)
- m_msg_callback(msg);
- }
-
+ void note_message(const Handshake_Message& msg);
private:
- handshake_msg_cb m_msg_callback;
+ Callbacks& m_callbacks;
std::unique_ptr<Handshake_IO> m_handshake_io;
diff --git a/src/lib/tls/tls_record.h b/src/lib/tls/tls_record.h
index 53e447af6..c16b919b5 100644
--- a/src/lib/tls/tls_record.h
+++ b/src/lib/tls/tls_record.h
@@ -102,10 +102,6 @@ class Record
m_type(type), m_size(data.size()) {};
secure_vector<byte>& get_data() { return m_data; }
- void set_data(secure_vector<byte> data)
- {
- m_data.swap(data);
- }
Protocol_Version* get_protocol_version() { return m_protocol_version; }
diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp
index 96af3cc90..5eccec2a7 100644
--- a/src/lib/tls/tls_server.cpp
+++ b/src/lib/tls/tls_server.cpp
@@ -8,7 +8,6 @@
#include <botan/tls_server.h>
#include <botan/internal/tls_handshake_state.h>
-#include <botan/internal/tls_server_handshake_state.h>
#include <botan/internal/tls_messages.h>
#include <botan/internal/stl_util.h>
#include <botan/tls_magic.h>
@@ -17,9 +16,34 @@ namespace Botan {
namespace TLS {
-namespace {
+class Server_Handshake_State : public Handshake_State
+ {
+ public:
+ Server_Handshake_State(Handshake_IO* io, Callbacks& cb)
+ : Handshake_State(io, cb) {}
+
+ Private_Key* server_rsa_kex_key() { return m_server_rsa_kex_key; }
+ void set_server_rsa_kex_key(Private_Key* key)
+ { m_server_rsa_kex_key = key; }
+
+ bool allow_session_resumption() const
+ { return m_allow_session_resumption; }
+ void set_allow_session_resumption(bool allow_session_resumption)
+ { m_allow_session_resumption = allow_session_resumption; }
+
+ private:
+ // Used by the server only, in case of RSA key exchange. Not owned
+ Private_Key* m_server_rsa_kex_key = nullptr;
+ /*
+ * Used by the server to know if resumption should be allowed on
+ * a server-initiated renegotiation
+ */
+ bool m_allow_session_resumption = true;
+ };
+
+namespace {
bool check_for_resume(Session& session_info,
Session_Manager& session_manager,
@@ -213,7 +237,7 @@ get_server_certs(const std::string& hostname,
/*
* TLS Server Constructor
*/
-Server::Server(const Callbacks& callbacks,
+Server::Server(Callbacks& callbacks,
Session_Manager& session_manager,
Credentials_Manager& creds,
const Policy& policy,
@@ -268,11 +292,7 @@ Server::Server(output_fn output,
Handshake_State* Server::new_handshake_state(Handshake_IO* io)
{
- std::unique_ptr<Handshake_State> state(
- new Server_Handshake_State(io,
- std::bind(&TLS::Callbacks::handshake_msg,
- get_callbacks(),
- std::placeholders::_1)));
+ std::unique_ptr<Handshake_State> state(new Server_Handshake_State(io, callbacks()));
state->set_expected_next(CLIENT_HELLO);
return state.release();
diff --git a/src/lib/tls/tls_server.h b/src/lib/tls/tls_server.h
index c0960a66e..508dde440 100644
--- a/src/lib/tls/tls_server.h
+++ b/src/lib/tls/tls_server.h
@@ -30,8 +30,29 @@ class BOTAN_DLL Server final : public Channel
/**
* Server initialization
+ *
+ * @param callbacks contains a set of callback function references
+ * required by the TLS client.
+ *
+ * @param session_manager manages session state
+ *
+ * @param creds manages application/user credentials
+ *
+ * @param policy specifies other connection policy information
+ *
+ * @param rng a random number generator
+ *
+ * @param next_proto is called with client's ALPN protocol list
+ * and returns chosen protocol.
+ *
+ * @param is_datagram set to true if this server should expect DTLS
+ * connections. Otherwise TLS connections are expected.
+ *
+ * @param reserved_io_buffer_size This many bytes of memory will
+ * be preallocated for the read and write buffers. Smaller
+ * values just mean reallocations and copies are more likely.
*/
- Server(const Callbacks& callbacks,
+ Server(Callbacks& callbacks,
Session_Manager& session_manager,
Credentials_Manager& creds,
const Policy& policy,
diff --git a/src/lib/tls/tls_server_handshake_state.h b/src/lib/tls/tls_server_handshake_state.h
deleted file mode 100644
index c65cade96..000000000
--- a/src/lib/tls/tls_server_handshake_state.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-* TLS Server
-* (C) 2004-2011,2012,2016 Jack Lloyd
-* 2016 Matthias Gierlings
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_TLS_SERVER_HANDSHAKE_STATE_H__
-#define BOTAN_TLS_SERVER_HANDSHAKE_STATE_H__
-
-#include <botan/internal/tls_handshake_state.h>
-namespace Botan {
-
-namespace TLS {
-
-class Server_Handshake_State : public Handshake_State
- {
- public:
- Server_Handshake_State(Handshake_IO* io, handshake_msg_cb cb)
- : Handshake_State(io, cb) {}
-
- Private_Key* server_rsa_kex_key() { return m_server_rsa_kex_key; }
- void set_server_rsa_kex_key(Private_Key* key)
- { m_server_rsa_kex_key = key; }
-
- bool allow_session_resumption() const
- { return m_allow_session_resumption; }
- void set_allow_session_resumption(bool allow_session_resumption)
- { m_allow_session_resumption = allow_session_resumption; }
-
-
- private:
- // Used by the server only, in case of RSA key exchange. Not owned
- Private_Key* m_server_rsa_kex_key = nullptr;
-
- /*
- * Used by the server to know if resumption should be allowed on
- * a server-initiated renegotiation
- */
- bool m_allow_session_resumption = true;
- };
-
-}
-
-}
-
-#endif
diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp
index 150ed2794..2797e7d21 100644
--- a/src/tests/unit_tls.cpp
+++ b/src/tests/unit_tls.cpp
@@ -166,6 +166,10 @@ void print_alert(Botan::TLS::Alert)
{
}
+void alert_cb_with_data(Botan::TLS::Alert, const byte[], size_t)
+ {
+ }
+
Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version,
Botan::Credentials_Manager& creds,
Botan::TLS::Policy& policy)
@@ -219,27 +223,31 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version,
{
std::vector<byte> c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent;
+ std::unique_ptr<Botan::TLS::Callbacks> server_cb(new Botan::TLS::Compat_Callbacks(
+ queue_inserter(s2c_traffic),
+ queue_inserter(server_recv),
+ std::function<void (Botan::TLS::Alert, const byte[], size_t)>(alert_cb_with_data),
+ handshake_complete));
+
// TLS::Server object constructed by new constructor using virtual callback interface.
std::unique_ptr<Botan::TLS::Server> server(
- new Botan::TLS::Server(Botan::TLS::Callbacks(
- queue_inserter(s2c_traffic),
- queue_inserter(server_recv),
- print_alert,
- handshake_complete),
- server_sessions,
- creds,
- policy,
- rng,
- next_protocol_chooser,
- false));
+ new Botan::TLS::Server(*server_cb,
+ server_sessions,
+ creds,
+ policy,
+ rng,
+ next_protocol_chooser,
+ false));
+
+ std::unique_ptr<Botan::TLS::Callbacks> client_cb(new Botan::TLS::Compat_Callbacks(
+ queue_inserter(c2s_traffic),
+ queue_inserter(client_recv),
+ std::function<void (Botan::TLS::Alert, const byte[], size_t)>(alert_cb_with_data),
+ handshake_complete));
// TLS::Client object constructed by new constructor using virtual callback interface.
std::unique_ptr<Botan::TLS::Client> client(
- new Botan::TLS::Client(Botan::TLS::Callbacks(
- queue_inserter(c2s_traffic),
- queue_inserter(client_recv),
- print_alert,
- handshake_complete),
+ new Botan::TLS::Client(*client_cb,
client_sessions,
creds,
policy,
@@ -255,11 +263,18 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version,
{
if(ctor_sel == 1)
{
+ c2s_traffic.clear();
+ s2c_traffic.clear();
+ server_recv.clear();
+ client_recv.clear();
+ client_sent.clear();
+ server_sent.clear();
+
// TLS::Server object constructed by legacy constructor.
- server = std::unique_ptr<Botan::TLS::Server>(
+ server.reset(
new Botan::TLS::Server(queue_inserter(s2c_traffic),
queue_inserter(server_recv),
- print_alert,
+ alert_cb_with_data,
handshake_complete,
server_sessions,
creds,
@@ -269,10 +284,10 @@ Test::Result test_tls_handshake(Botan::TLS::Protocol_Version offer_version,
false));
// TLS::Client object constructed by legacy constructor.
- std::unique_ptr<Botan::TLS::Client> client(
+ client.reset(
new Botan::TLS::Client(queue_inserter(c2s_traffic),
queue_inserter(client_recv),
- print_alert,
+ alert_cb_with_data,
handshake_complete,
client_sessions,
creds,
@@ -485,13 +500,21 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version,
{
std::vector<byte> c2s_traffic, s2c_traffic, client_recv, server_recv, client_sent, server_sent;
+ std::unique_ptr<Botan::TLS::Callbacks> server_cb(new Botan::TLS::Compat_Callbacks(
+ queue_inserter(s2c_traffic),
+ queue_inserter(server_recv),
+ std::function<void (Botan::TLS::Alert)>(print_alert),
+ handshake_complete));
+
+ std::unique_ptr<Botan::TLS::Callbacks> client_cb(new Botan::TLS::Compat_Callbacks(
+ queue_inserter(c2s_traffic),
+ queue_inserter(client_recv),
+ std::function<void (Botan::TLS::Alert)>(print_alert),
+ handshake_complete));
+
// TLS::Server object constructed by new constructor using virtual callback interface.
std::unique_ptr<Botan::TLS::Server> server(
- new Botan::TLS::Server(Botan::TLS::Callbacks(
- queue_inserter(s2c_traffic),
- queue_inserter(server_recv),
- print_alert,
- handshake_complete),
+ new Botan::TLS::Server(*server_cb,
server_sessions,
creds,
policy,
@@ -501,11 +524,7 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version,
// TLS::Client object constructed by new constructor using virtual callback interface.
std::unique_ptr<Botan::TLS::Client> client(
- new Botan::TLS::Client(Botan::TLS::Callbacks(
- queue_inserter(c2s_traffic),
- queue_inserter(client_recv),
- print_alert,
- handshake_complete),
+ new Botan::TLS::Client(*client_cb,
client_sessions,
creds,
policy,
@@ -521,11 +540,17 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version,
{
if(ctor_sel == 1)
{
+ c2s_traffic.clear();
+ s2c_traffic.clear();
+ server_recv.clear();
+ client_recv.clear();
+ client_sent.clear();
+ server_sent.clear();
// TLS::Server object constructed by legacy constructor.
- server = std::unique_ptr<Botan::TLS::Server>(
+ server.reset(
new Botan::TLS::Server(queue_inserter(s2c_traffic),
queue_inserter(server_recv),
- print_alert,
+ alert_cb_with_data,
handshake_complete,
server_sessions,
creds,
@@ -535,10 +560,10 @@ Test::Result test_dtls_handshake(Botan::TLS::Protocol_Version offer_version,
true));
// TLS::Client object constructed by legacy constructor.
- std::unique_ptr<Botan::TLS::Client> client(
+ client.reset(
new Botan::TLS::Client(queue_inserter(c2s_traffic),
queue_inserter(client_recv),
- print_alert,
+ alert_cb_with_data,
handshake_complete,
client_sessions,
creds,