diff options
author | lloyd <[email protected]> | 2012-04-16 19:00:49 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-04-16 19:00:49 +0000 |
commit | b224e899c8846f17a36dc41c53dd94ba037ada79 (patch) | |
tree | 81e2b0391b436b7620ffbeaa15252c75ae3c9039 /src/tls/tls_heartbeats.cpp | |
parent | c09b208d5d3ead81ef7ad662f71f55f1e00f61bc (diff) |
Add support for TLS heartbeats (RFC 6520). Heartbeat initiations from
the peer are automatically responded to. TLS::Channel::heartbeat can
initiate a new heartbeat if the peer allows it. Heartbeat replies are
passed back to the application processing function with an Alert value
of HEARTBEAT_PAYLOAD (a 'fake' value, 256, which is out of range of
the valid TLS alert space), along with the sent payload.
The RFC requires us to have no more than one heartbeat 'in flight' at
a time, ie without getting a response (or a timeout in the case of
DTLS). Currently we do not prevent an application from requesting
more.
Diffstat (limited to 'src/tls/tls_heartbeats.cpp')
-rw-r--r-- | src/tls/tls_heartbeats.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/tls/tls_heartbeats.cpp b/src/tls/tls_heartbeats.cpp new file mode 100644 index 000000000..a77d23534 --- /dev/null +++ b/src/tls/tls_heartbeats.cpp @@ -0,0 +1,78 @@ +/* +* TLS Heartbeats +* (C) 2012 Jack Lloyd +* +* Released under the terms of the Botan license +*/ + +#include <botan/internal/tls_heartbeats.h> +#include <botan/internal/tls_extensions.h> +#include <botan/internal/tls_reader.h> +#include <botan/tls_exceptn.h> + +namespace Botan { + +namespace TLS { + +Heartbeat_Message::Heartbeat_Message(const MemoryRegion<byte>& buf) + { + TLS_Data_Reader reader(buf); + + const byte type = reader.get_byte(); + + if(type != 1 && type != 2) + throw TLS_Exception(Alert::ILLEGAL_PARAMETER, + "Unknown heartbeat message type"); + + m_type = static_cast<Type>(type); + + m_payload = reader.get_range<byte>(2, 0, 16*1024); + + // padding follows and is ignored + } + +Heartbeat_Message::Heartbeat_Message(Type type, + const byte payload[], + size_t payload_len) : + m_type(type), + m_payload(payload, payload_len) + { + } + +MemoryVector<byte> Heartbeat_Message::contents() const + { + MemoryVector<byte> send_buf(3 + m_payload.size() + 16); + send_buf[0] = m_type; + send_buf[1] = get_byte<u16bit>(0, m_payload.size()); + send_buf[2] = get_byte<u16bit>(1, m_payload.size()); + copy_mem(&send_buf[3], &m_payload[0], m_payload.size()); + // leave padding as all zeros + + return send_buf; + } + +MemoryVector<byte> Heartbeat_Support_Indicator::serialize() const + { + MemoryVector<byte> heartbeat(1); + heartbeat[0] = (m_peer_allowed_to_send ? 1 : 2); + return heartbeat; + } + +Heartbeat_Support_Indicator::Heartbeat_Support_Indicator(TLS_Data_Reader& reader, + u16bit extension_size) + { + if(extension_size != 1) + throw Decoding_Error("Strange size for heartbeat extension"); + + const byte code = reader.get_byte(); + + if(code != 1 && code != 2) + throw TLS_Exception(Alert::ILLEGAL_PARAMETER, + "Unknown heartbeat code " + to_string(code)); + + m_peer_allowed_to_send = (code == 1); + } + +} + +} |