aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <lloyd@randombit.net>2012-10-13 20:37:29 +0000
committerlloyd <lloyd@randombit.net>2012-10-13 20:37:29 +0000
commit4be75ae1e9e473fc3e939be5e54e51f552d5934b (patch)
tree39b39921601d32ab8a901a6343fb0b8285cd253f
parent9f1f35d7afc019ae03d478dc30f9552f6ba31a22 (diff)
Add TLS::Policy::negotiate_heartbeat_support which controls if the
client will offer heartbeats (or if a server will negotiate them if the client offers). Defaults to false, which is probably the right behavior in terms of minimizing surprise and attack surface.
-rw-r--r--doc/relnotes/1_11_1.rst6
-rw-r--r--doc/tls.rst8
-rw-r--r--src/tls/msg_client_hello.cpp8
-rw-r--r--src/tls/msg_server_hello.cpp7
-rw-r--r--src/tls/tls_messages.h1
-rw-r--r--src/tls/tls_policy.h5
-rw-r--r--src/tls/tls_server.cpp2
7 files changed, 31 insertions, 6 deletions
diff --git a/doc/relnotes/1_11_1.rst b/doc/relnotes/1_11_1.rst
index bfc513d04..ec4033280 100644
--- a/doc/relnotes/1_11_1.rst
+++ b/doc/relnotes/1_11_1.rst
@@ -33,9 +33,9 @@ persistent storage by 1.11.0 will not load in this version and vice
versa. In either case this will not cause any errors, the session will
simply not resume and instead a full handshake will occur.
-New policy hooks :cpp:func:`TLS::Policy::acceptable_protocol_version`
-and :cpp:func:`TLS::Policy::allow_server_initiated_renegotiation` were
-added.
+New policy hooks :cpp:func:`TLS::Policy::acceptable_protocol_version`,
+:cpp:func:`TLS::Policy::allow_server_initiated_renegotiation`, and
+:cpp:func:`TLS::Policy::negotiate_heartbeat_support` were added.
TLS clients were not sending a next protocol message during a session
resumption, which would cause resumption failures with servers that
diff --git a/doc/tls.rst b/doc/tls.rst
index a0f2c4f48..3aec3254c 100644
--- a/doc/tls.rst
+++ b/doc/tls.rst
@@ -512,6 +512,14 @@ be negotiated during a handshake.
TLS compression is not currently supported.
+ .. cpp:function:: bool negotiate_heartbeat_support() const
+
+ If this function returns true, clients will offer the heartbeat
+ support extension, and servers will respond to clients offering
+ the extension. Otherwise, clients will not offer heartbeat
+ support and servers will ignore clients offering heartbeat
+ support.
+
.. cpp:function:: bool allow_server_initiated_renegotiation() const
If this function returns true, a client will accept a
diff --git a/src/tls/msg_client_hello.cpp b/src/tls/msg_client_hello.cpp
index 3df54cd8f..6176ca6bf 100644
--- a/src/tls/msg_client_hello.cpp
+++ b/src/tls/msg_client_hello.cpp
@@ -74,13 +74,15 @@ Client_Hello::Client_Hello(Handshake_IO& io,
m_suites(ciphersuite_list(policy, m_version, (srp_identifier != ""))),
m_comp_methods(policy.compression())
{
- m_extensions.add(new Heartbeat_Support_Indicator(true));
m_extensions.add(new Renegotiation_Extension(reneg_info));
m_extensions.add(new SRP_Identifier(srp_identifier));
m_extensions.add(new Server_Name_Indicator(hostname));
m_extensions.add(new Session_Ticket());
m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves()));
+ if(policy.negotiate_heartbeat_support())
+ m_extensions.add(new Heartbeat_Support_Indicator(true));
+
if(m_version.supports_negotiable_signature_algorithms())
m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
policy.allowed_signature_methods()));
@@ -113,13 +115,15 @@ Client_Hello::Client_Hello(Handshake_IO& io,
if(!value_exists(m_comp_methods, session.compression_method()))
m_comp_methods.push_back(session.compression_method());
- m_extensions.add(new Heartbeat_Support_Indicator(true));
m_extensions.add(new Renegotiation_Extension(reneg_info));
m_extensions.add(new SRP_Identifier(session.srp_identifier()));
m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
m_extensions.add(new Session_Ticket(session.session_ticket()));
m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves()));
+ if(policy.negotiate_heartbeat_support())
+ m_extensions.add(new Heartbeat_Support_Indicator(true));
+
if(session.fragment_size() != 0)
m_extensions.add(new Maximum_Fragment_Length(session.fragment_size()));
diff --git a/src/tls/msg_server_hello.cpp b/src/tls/msg_server_hello.cpp
index 6ca5e3b30..a775e0b4b 100644
--- a/src/tls/msg_server_hello.cpp
+++ b/src/tls/msg_server_hello.cpp
@@ -21,6 +21,7 @@ namespace TLS {
*/
Server_Hello::Server_Hello(Handshake_IO& io,
Handshake_Hash& hash,
+ const Policy& policy,
const std::vector<byte>& session_id,
Protocol_Version ver,
u16bit ciphersuite,
@@ -39,9 +40,13 @@ Server_Hello::Server_Hello(Handshake_IO& io,
m_ciphersuite(ciphersuite),
m_comp_method(compression)
{
- if(client_has_heartbeat)
+ if(client_has_heartbeat && policy.negotiate_heartbeat_support())
m_extensions.add(new Heartbeat_Support_Indicator(true));
+ /*
+ * Even a client that offered SSLv3 and sent the SCSV will get an
+ * extension back. This is probably the right thing to do.
+ */
if(client_has_secure_renegotiation)
m_extensions.add(new Renegotiation_Extension(reneg_info));
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index 70745ad9c..f1d4aa887 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -254,6 +254,7 @@ class Server_Hello : public Handshake_Message
Server_Hello(Handshake_IO& io,
Handshake_Hash& hash,
+ const Policy& policy,
const std::vector<byte>& session_id,
Protocol_Version ver,
u16bit ciphersuite,
diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h
index 4379d9b0c..cc02dd9b1 100644
--- a/src/tls/tls_policy.h
+++ b/src/tls/tls_policy.h
@@ -74,6 +74,11 @@ class BOTAN_DLL Policy
virtual std::string choose_curve(const std::vector<std::string>& curve_names) const;
/**
+ * Attempt to negotiate the use of the heartbeat extension
+ */
+ virtual bool negotiate_heartbeat_support() const { return false; }
+
+ /**
* Allow renegotiation even if the counterparty doesn't
* support the secure renegotiation extension.
*
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 4468854a4..1189019bc 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -377,6 +377,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state,
new Server_Hello(
state.handshake_io(),
state.hash(),
+ m_policy,
state.client_hello()->session_id(),
Protocol_Version(session_info.version()),
session_info.ciphersuite_code(),
@@ -471,6 +472,7 @@ void Server::process_handshake_msg(const Handshake_State* active_state,
new Server_Hello(
state.handshake_io(),
state.hash(),
+ m_policy,
make_hello_random(rng()), // new session ID
state.version(),
choose_ciphersuite(m_policy,