aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls/tls_channel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tls/tls_channel.cpp')
-rw-r--r--src/tls/tls_channel.cpp58
1 files changed, 48 insertions, 10 deletions
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp
index 736b37654..86d9db8bd 100644
--- a/src/tls/tls_channel.cpp
+++ b/src/tls/tls_channel.cpp
@@ -8,6 +8,7 @@
#include <botan/tls_channel.h>
#include <botan/internal/tls_handshake_state.h>
#include <botan/internal/tls_messages.h>
+#include <botan/internal/tls_heartbeats.h>
#include <botan/internal/assert.h>
#include <botan/loadstor.h>
@@ -15,15 +16,17 @@ namespace Botan {
namespace TLS {
-Channel::Channel(std::function<void (const byte[], size_t)> socket_output_fn,
- std::function<void (const byte[], size_t, Alert)> proc_fn,
- std::function<bool (const Session&)> handshake_complete) :
+Channel::Channel(std::tr1::function<void (const byte[], size_t)> socket_output_fn,
+ std::tr1::function<void (const byte[], size_t, Alert)> proc_fn,
+ std::tr1::function<bool (const Session&)> handshake_complete) :
proc_fn(proc_fn),
handshake_fn(handshake_complete),
writer(socket_output_fn),
state(0),
handshake_completed(false),
- connection_closed(false)
+ connection_closed(false),
+ m_peer_supports_heartbeats(false),
+ m_heartbeat_sending_allowed(false)
{
}
@@ -56,7 +59,30 @@ size_t Channel::received_data(const byte buf[], size_t buf_size)
if(buf_size == 0 && needed != 0)
return needed; // need more data to complete record
- if(rec_type == APPLICATION_DATA)
+ if(rec_type == HANDSHAKE || rec_type == CHANGE_CIPHER_SPEC)
+ {
+ read_handshake(rec_type, record);
+ }
+ else if(rec_type == HEARTBEAT && m_peer_supports_heartbeats)
+ {
+ Heartbeat_Message heartbeat(record);
+
+ const MemoryRegion<byte>& payload = heartbeat.payload();
+
+ if(heartbeat.is_request() && !state)
+ {
+ Heartbeat_Message response(Heartbeat_Message::RESPONSE,
+ payload, payload.size());
+
+ writer.send(HEARTBEAT, response.contents());
+ }
+ else
+ {
+ // pass up to the application
+ proc_fn(&payload[0], payload.size(), Alert(Alert::HEARTBEAT_PAYLOAD));
+ }
+ }
+ else if(rec_type == APPLICATION_DATA)
{
if(handshake_completed)
{
@@ -73,10 +99,6 @@ size_t Channel::received_data(const byte buf[], size_t buf_size)
throw Unexpected_Message("Application data before handshake done");
}
}
- else if(rec_type == HANDSHAKE || rec_type == CHANGE_CIPHER_SPEC)
- {
- read_handshake(rec_type, record);
- }
else if(rec_type == ALERT)
{
Alert alert_msg(record);
@@ -106,7 +128,7 @@ size_t Channel::received_data(const byte buf[], size_t buf_size)
}
else
throw Unexpected_Message("Unknown TLS message type " +
- std::to_string(rec_type) + " received");
+ to_string(rec_type) + " received");
}
return 0; // on a record boundary
@@ -178,6 +200,20 @@ void Channel::read_handshake(byte rec_type,
}
}
+void Channel::heartbeat(const byte payload[], size_t payload_size)
+ {
+ if(!is_active())
+ throw std::runtime_error("Heartbeat cannot be sent on inactive TLS connection");
+
+ if(m_heartbeat_sending_allowed)
+ {
+ Heartbeat_Message heartbeat(Heartbeat_Message::REQUEST,
+ payload, payload_size);
+
+ writer.send(HEARTBEAT, heartbeat.contents());
+ }
+ }
+
void Channel::send(const byte buf[], size_t buf_size)
{
if(!is_active())
@@ -287,3 +323,5 @@ void Channel::Secure_Renegotiation_State::update(Finished* client_finished,
}
}
+
+}