aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/tls/c_hello.cpp31
-rw-r--r--src/tls/info.txt2
-rw-r--r--src/tls/rec_read.cpp3
-rw-r--r--src/tls/s_hello.cpp14
-rw-r--r--src/tls/tls_alert.cpp5
-rw-r--r--src/tls/tls_alert.h4
-rw-r--r--src/tls/tls_channel.cpp48
-rw-r--r--src/tls/tls_channel.h14
-rw-r--r--src/tls/tls_client.cpp3
-rw-r--r--src/tls/tls_extensions.cpp3
-rw-r--r--src/tls/tls_extensions.h27
-rw-r--r--src/tls/tls_heartbeats.cpp78
-rw-r--r--src/tls/tls_heartbeats.h40
-rw-r--r--src/tls/tls_magic.h3
-rw-r--r--src/tls/tls_messages.h37
-rw-r--r--src/tls/tls_record.h3
-rw-r--r--src/tls/tls_server.cpp5
17 files changed, 282 insertions, 38 deletions
diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp
index d3fff8b00..e52d34bc6 100644
--- a/src/tls/c_hello.cpp
+++ b/src/tls/c_hello.cpp
@@ -77,7 +77,9 @@ Client_Hello::Client_Hello(Record_Writer& writer,
m_secure_renegotiation(true),
m_renegotiation_info(reneg_info),
m_supported_curves(policy.allowed_ecc_curves()),
- m_supports_session_ticket(true)
+ m_supports_session_ticket(true),
+ m_supports_heartbeats(true),
+ m_peer_can_send_heartbeats(true)
{
std::vector<std::string> hashes = policy.allowed_hashes();
std::vector<std::string> sigs = policy.allowed_signature_methods();
@@ -110,7 +112,9 @@ Client_Hello::Client_Hello(Record_Writer& writer,
m_secure_renegotiation(session.secure_renegotiation()),
m_supported_curves(policy.allowed_ecc_curves()),
m_supports_session_ticket(true),
- m_session_ticket(session.session_ticket())
+ m_session_ticket(session.session_ticket()),
+ m_supports_heartbeats(true),
+ m_peer_can_send_heartbeats(true)
{
if(!value_exists(m_suites, session.ciphersuite_code()))
m_suites.push_back(session.ciphersuite_code());
@@ -136,6 +140,8 @@ Client_Hello::Client_Hello(const MemoryRegion<byte>& buf, Handshake_Type type)
m_next_protocol = false;
m_secure_renegotiation = false;
m_supports_session_ticket = false;
+ m_supports_heartbeats = false;
+ m_peer_can_send_heartbeats = false;
m_fragment_size = 0;
if(type == CLIENT_HELLO)
@@ -168,29 +174,24 @@ MemoryVector<byte> Client_Hello::serialize() const
Extensions extensions;
- // Initial handshake
+ // Extensions only used on an initial handshake
if(m_renegotiation_info.empty())
{
- extensions.add(new Renegotation_Extension(m_renegotiation_info));
extensions.add(new Server_Name_Indicator(m_hostname));
extensions.add(new SRP_Identifier(m_srp_identifier));
extensions.add(new Supported_Elliptic_Curves(m_supported_curves));
+ extensions.add(new Heartbeat_Support_Indicator(true));
if(m_version >= Protocol_Version::TLS_V12)
extensions.add(new Signature_Algorithms(m_supported_algos));
if(m_next_protocol)
extensions.add(new Next_Protocol_Notification());
-
- extensions.add(new Session_Ticket(m_session_ticket));
- }
- else
- {
- // renegotiation
- extensions.add(new Renegotation_Extension(m_renegotiation_info));
- extensions.add(new Session_Ticket(m_session_ticket));
}
+ extensions.add(new Renegotation_Extension(m_renegotiation_info));
+ extensions.add(new Session_Ticket(m_session_ticket));
+
buf += extensions.serialize();
return buf;
@@ -338,6 +339,12 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf)
m_session_ticket = ticket->contents();
}
+ if(Heartbeat_Support_Indicator* hb = extensions.get<Heartbeat_Support_Indicator>())
+ {
+ m_supports_heartbeats = true;
+ m_peer_can_send_heartbeats = hb->peer_allowed_to_send();
+ }
+
if(Renegotation_Extension* reneg = extensions.get<Renegotation_Extension>())
{
// checked by TLS_Client / TLS_Server as they know the handshake state
diff --git a/src/tls/info.txt b/src/tls/info.txt
index 229cf658f..77ffb4585 100644
--- a/src/tls/info.txt
+++ b/src/tls/info.txt
@@ -29,6 +29,7 @@ tls_extensions.h
tls_handshake_hash.h
tls_handshake_reader.h
tls_handshake_state.h
+tls_heartbeats.h
tls_messages.h
tls_reader.h
tls_session_key.h
@@ -55,6 +56,7 @@ tls_extensions.cpp
tls_handshake_hash.cpp
tls_handshake_reader.cpp
tls_handshake_state.cpp
+tls_heartbeats.cpp
tls_policy.cpp
tls_server.cpp
tls_session.cpp
diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp
index d1fab4692..5d46ec1fa 100644
--- a/src/tls/rec_read.cpp
+++ b/src/tls/rec_read.cpp
@@ -216,7 +216,8 @@ size_t Record_Reader::add_input(const byte input_array[], size_t input_sz,
if(m_readbuf[0] != CHANGE_CIPHER_SPEC &&
m_readbuf[0] != ALERT &&
m_readbuf[0] != HANDSHAKE &&
- m_readbuf[0] != APPLICATION_DATA)
+ m_readbuf[0] != APPLICATION_DATA &&
+ m_readbuf[0] != HEARTBEAT)
{
throw Unexpected_Message(
"Unknown record type " + to_string(m_readbuf[0]) + " from counterparty");
diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp
index bb93108d9..1244dd2d8 100644
--- a/src/tls/s_hello.cpp
+++ b/src/tls/s_hello.cpp
@@ -31,6 +31,7 @@ Server_Hello::Server_Hello(Record_Writer& writer,
bool offer_session_ticket,
bool client_has_npn,
const std::vector<std::string>& next_protocols,
+ bool client_has_heartbeat,
RandomNumberGenerator& rng) :
m_version(ver),
m_session_id(session_id),
@@ -42,7 +43,9 @@ Server_Hello::Server_Hello(Record_Writer& writer,
m_renegotiation_info(reneg_info),
m_next_protocol(client_has_npn),
m_next_protocols(next_protocols),
- m_supports_session_ticket(offer_session_ticket)
+ m_supports_session_ticket(offer_session_ticket),
+ m_supports_heartbeats(client_has_heartbeat),
+ m_peer_can_send_heartbeats(true)
{
hash.update(writer.send(*this));
}
@@ -104,6 +107,12 @@ Server_Hello::Server_Hello(const MemoryRegion<byte>& buf)
throw Decoding_Error("TLS server sent non-empty session ticket extension");
m_supports_session_ticket = true;
}
+
+ if(Heartbeat_Support_Indicator* hb = extensions.get<Heartbeat_Support_Indicator>())
+ {
+ m_supports_heartbeats = true;
+ m_peer_can_send_heartbeats = hb->peer_allowed_to_send();
+ }
}
/*
@@ -126,6 +135,9 @@ MemoryVector<byte> Server_Hello::serialize() const
Extensions extensions;
+ if(m_supports_heartbeats)
+ extensions.add(new Heartbeat_Support_Indicator(m_peer_can_send_heartbeats));
+
if(m_secure_renegotiation)
extensions.add(new Renegotation_Extension(m_renegotiation_info));
diff --git a/src/tls/tls_alert.cpp b/src/tls/tls_alert.cpp
index 2461854e1..83205bb74 100644
--- a/src/tls/tls_alert.cpp
+++ b/src/tls/tls_alert.cpp
@@ -102,7 +102,10 @@ std::string Alert::type_string() const
return "unknown_psk_identity";
case NULL_ALERT:
- return "";
+ return "none";
+
+ case HEARTBEAT_PAYLOAD:
+ return "heartbeat_payload";
}
/*
diff --git a/src/tls/tls_alert.h b/src/tls/tls_alert.h
index 8b4b963f0..3dfff3d29 100644
--- a/src/tls/tls_alert.h
+++ b/src/tls/tls_alert.h
@@ -53,7 +53,9 @@ class BOTAN_DLL Alert
BAD_CERTIFICATE_HASH_VALUE = 114,
UNKNOWN_PSK_IDENTITY = 115,
- NULL_ALERT = 255
+ NULL_ALERT = 255,
+
+ HEARTBEAT_PAYLOAD = 256
};
/**
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp
index f45ce4bda..2464d339a 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>
@@ -23,7 +24,9 @@ Channel::Channel(std::tr1::function<void (const byte[], size_t)> socket_output_f
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);
@@ -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())
diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h
index 53af0bdfc..05fb7e82f 100644
--- a/src/tls/tls_channel.h
+++ b/src/tls/tls_channel.h
@@ -58,6 +58,18 @@ class BOTAN_DLL Channel
virtual void renegotiate() = 0;
/**
+ * Attempt to send a heartbeat message (if negotiated with counterparty)
+ * @param payload will be echoed back
+ * @param countents_size size of payload in bytes
+ */
+ void heartbeat(const byte payload[], size_t payload_size);
+
+ /**
+ * Attempt to send a heartbeat message (if negotiated with counterparty)
+ */
+ void heartbeat() { heartbeat(0, 0); }
+
+ /**
* @return certificate chain of the peer (may be empty)
*/
std::vector<X509_Certificate> peer_cert_chain() const { return peer_certs; }
@@ -130,6 +142,8 @@ class BOTAN_DLL Channel
bool handshake_completed;
bool connection_closed;
+ bool m_peer_supports_heartbeats;
+ bool m_heartbeat_sending_allowed;
};
}
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index 850d053a2..f6266ee6a 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -188,6 +188,9 @@ void Client::process_handshake_msg(Handshake_Type type,
secure_renegotiation.update(state->server_hello);
+ m_peer_supports_heartbeats = state->server_hello->supports_heartbeats();
+ m_heartbeat_sending_allowed = state->server_hello->peer_can_send_heartbeats();
+
state->suite = Ciphersuite::by_id(state->server_hello->ciphersuite());
const bool server_returned_same_session_id =
diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp
index 59ab64374..f1361bbb9 100644
--- a/src/tls/tls_extensions.cpp
+++ b/src/tls/tls_extensions.cpp
@@ -42,6 +42,9 @@ Extension* make_extension(TLS_Data_Reader& reader,
case TLSEXT_NEXT_PROTOCOL:
return new Next_Protocol_Notification(reader, size);
+ case TLSEXT_HEARTBEAT_SUPPORT:
+ return new Heartbeat_Support_Indicator(reader, size);
+
case TLSEXT_SESSION_TICKET:
return new Session_Ticket(reader, size);
diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h
index 6a97d2560..3fe3f7399 100644
--- a/src/tls/tls_extensions.h
+++ b/src/tls/tls_extensions.h
@@ -32,6 +32,7 @@ enum Handshake_Extension_Type {
TLSEXT_EC_POINT_FORMATS = 11,
TLSEXT_SRP_IDENTIFIER = 12,
TLSEXT_SIGNATURE_ALGORITHMS = 13,
+ TLSEXT_HEARTBEAT_SUPPORT = 15,
TLSEXT_SESSION_TICKET = 35,
@@ -309,6 +310,32 @@ class Signature_Algorithms : public Extension
};
/**
+* Heartbeat Extension (RFC 6520)
+*/
+class Heartbeat_Support_Indicator : public Extension
+ {
+ public:
+ static Handshake_Extension_Type static_type()
+ { return TLSEXT_HEARTBEAT_SUPPORT; }
+
+ Handshake_Extension_Type type() const { return static_type(); }
+
+ bool peer_allowed_to_send() const { return m_peer_allowed_to_send; }
+
+ MemoryVector<byte> serialize() const;
+
+ bool empty() const { return false; }
+
+ Heartbeat_Support_Indicator(bool peer_allowed_to_send) :
+ m_peer_allowed_to_send(peer_allowed_to_send) {}
+
+ Heartbeat_Support_Indicator(TLS_Data_Reader& reader, u16bit extension_size);
+
+ private:
+ bool m_peer_allowed_to_send;
+ };
+
+/**
* Represents a block of extensions in a hello message
*/
class Extensions
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);
+ }
+
+}
+
+}
diff --git a/src/tls/tls_heartbeats.h b/src/tls/tls_heartbeats.h
new file mode 100644
index 000000000..4fa49501b
--- /dev/null
+++ b/src/tls/tls_heartbeats.h
@@ -0,0 +1,40 @@
+/*
+* TLS Heartbeats
+* (C) 2012 Jack Lloyd
+*
+* Released under the terms of the Botan license
+*/
+
+#ifndef BOTAN_TLS_HEARTBEATS_H__
+#define BOTAN_TLS_HEARTBEATS_H__
+
+#include <botan/secmem.h>
+
+namespace Botan {
+
+namespace TLS {
+
+class Heartbeat_Message
+ {
+ public:
+ enum Type { REQUEST = 1, RESPONSE = 2 };
+
+ MemoryVector<byte> contents() const;
+
+ const MemoryRegion<byte>& payload() const { return m_payload; }
+
+ bool is_request() const { return m_type == REQUEST; }
+
+ Heartbeat_Message(const MemoryRegion<byte>& buf);
+
+ Heartbeat_Message(Type type, const byte payload[], size_t payload_len);
+ private:
+ Type m_type;
+ MemoryVector<byte> m_payload;
+ };
+
+}
+
+}
+
+#endif
diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h
index 6dd50ead2..2972321c9 100644
--- a/src/tls/tls_magic.h
+++ b/src/tls/tls_magic.h
@@ -32,7 +32,8 @@ enum Record_Type {
CHANGE_CIPHER_SPEC = 20,
ALERT = 21,
HANDSHAKE = 22,
- APPLICATION_DATA = 23
+ APPLICATION_DATA = 23,
+ HEARTBEAT = 24,
};
enum Handshake_Type {
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index c8a9382d6..4c2b1b797 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -73,15 +73,10 @@ class Client_Hello : public Handshake_Message
{
public:
Handshake_Type type() const { return CLIENT_HELLO; }
+
Protocol_Version version() const { return m_version; }
- const MemoryVector<byte>& session_id() const { return m_session_id; }
- std::vector<byte> session_id_vector() const
- {
- std::vector<byte> v;
- v.insert(v.begin(), &m_session_id[0], &m_session_id[m_session_id.size()]);
- return v;
- }
+ const MemoryVector<byte>& session_id() const { return m_session_id; }
const std::vector<std::pair<std::string, std::string> >& supported_algos() const
{ return m_supported_algos; }
@@ -114,6 +109,10 @@ class Client_Hello : public Handshake_Message
const MemoryRegion<byte>& session_ticket() const
{ return m_session_ticket; }
+ bool supports_heartbeats() const { return m_supports_heartbeats; }
+
+ bool peer_can_send_heartbeats() const { return m_peer_can_send_heartbeats; }
+
Client_Hello(Record_Writer& writer,
Handshake_Hash& hash,
const Policy& policy,
@@ -155,6 +154,9 @@ class Client_Hello : public Handshake_Message
bool m_supports_session_ticket;
MemoryVector<byte> m_session_ticket;
+
+ bool m_supports_heartbeats;
+ bool m_peer_can_send_heartbeats;
};
/**
@@ -164,17 +166,16 @@ class Server_Hello : public Handshake_Message
{
public:
Handshake_Type type() const { return SERVER_HELLO; }
+
Protocol_Version version() { return m_version; }
+
+ const MemoryVector<byte>& random() const { return m_random; }
+
const MemoryVector<byte>& session_id() const { return m_session_id; }
+
u16bit ciphersuite() const { return m_ciphersuite; }
- byte compression_method() const { return m_comp_method; }
- std::vector<byte> session_id_vector() const
- {
- std::vector<byte> v;
- v.insert(v.begin(), &m_session_id[0], &m_session_id[m_session_id.size()]);
- return v;
- }
+ byte compression_method() const { return m_comp_method; }
bool secure_renegotiation() const { return m_secure_renegotiation; }
@@ -190,7 +191,9 @@ class Server_Hello : public Handshake_Message
const MemoryVector<byte>& renegotiation_info()
{ return m_renegotiation_info; }
- const MemoryVector<byte>& random() const { return m_random; }
+ bool supports_heartbeats() const { return m_supports_heartbeats; }
+
+ bool peer_can_send_heartbeats() const { return m_peer_can_send_heartbeats; }
Server_Hello(Record_Writer& writer,
Handshake_Hash& hash,
@@ -204,6 +207,7 @@ class Server_Hello : public Handshake_Message
bool offer_session_ticket,
bool client_has_npn,
const std::vector<std::string>& next_protocols,
+ bool client_has_heartbeat,
RandomNumberGenerator& rng);
Server_Hello(const MemoryRegion<byte>& buf);
@@ -222,6 +226,9 @@ class Server_Hello : public Handshake_Message
bool m_next_protocol;
std::vector<std::string> m_next_protocols;
bool m_supports_session_ticket;
+
+ bool m_supports_heartbeats;
+ bool m_peer_can_send_heartbeats;
};
/**
diff --git a/src/tls/tls_record.h b/src/tls/tls_record.h
index fb27db5e2..38eae7823 100644
--- a/src/tls/tls_record.h
+++ b/src/tls/tls_record.h
@@ -46,6 +46,9 @@ class BOTAN_DLL Record_Writer
void send(byte type, const byte input[], size_t length);
void send(byte type, byte val) { send(type, &val, 1); }
+ void send(byte type, const MemoryRegion<byte>& input)
+ { send(type, &input[0], input.size()); }
+
MemoryVector<byte> send(class Handshake_Message& msg);
void send_alert(const Alert& alert);
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 10872a825..c591a45c5 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -286,6 +286,9 @@ void Server::process_handshake_msg(Handshake_Type type,
secure_renegotiation.update(state->client_hello);
+ m_peer_supports_heartbeats = state->client_hello->supports_heartbeats();
+ m_heartbeat_sending_allowed = state->client_hello->peer_can_send_heartbeats();
+
writer.set_version(state->version());
reader.set_version(state->version());
@@ -324,6 +327,7 @@ void Server::process_handshake_msg(Handshake_Type type,
have_session_ticket_key),
state->client_hello->next_protocol_notification(),
m_possible_protocols,
+ state->client_hello->supports_heartbeats(),
rng);
if(session_info.fragment_size())
@@ -395,6 +399,7 @@ void Server::process_handshake_msg(Handshake_Type type,
state->client_hello->supports_session_ticket() && have_session_ticket_key,
state->client_hello->next_protocol_notification(),
m_possible_protocols,
+ state->client_hello->supports_heartbeats(),
rng);
if(state->client_hello->fragment_size())