aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/tls/msg_server_hello.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2015-01-04 17:43:34 +0000
committerlloyd <[email protected]>2015-01-04 17:43:34 +0000
commit8fcc2825c5aa7d6c359bba63eb883088a7650c86 (patch)
tree47d2f503ee43d57fe947d608e133ec06edf9d24c /src/lib/tls/msg_server_hello.cpp
parent5fb44f29a4b27905668d90a4ff46d882a41f5951 (diff)
Add DTLS-SRTP key establishment from RFC 5764 (required for WebRTC).
Github issue 27. Refactor server hello handling to make it easier to handle other extensions. The manual specified that 224 bit NIST primes were disabled by default for TLS but they were not. Additionaly disable the 256k1 curve and reorder the remaining curves by size. Rewrite the max fragment length extension code to roughly what an ideal compiler would have turned the original code into, using a switch instead of a lookup into a small constant std::map.
Diffstat (limited to 'src/lib/tls/msg_server_hello.cpp')
-rw-r--r--src/lib/tls/msg_server_hello.cpp98
1 files changed, 76 insertions, 22 deletions
diff --git a/src/lib/tls/msg_server_hello.cpp b/src/lib/tls/msg_server_hello.cpp
index 79c16e53a..8dd7d3595 100644
--- a/src/lib/tls/msg_server_hello.cpp
+++ b/src/lib/tls/msg_server_hello.cpp
@@ -1,6 +1,6 @@
;/*
* TLS Server Hello and Server Hello Done
-* (C) 2004-2011 Jack Lloyd
+* (C) 2004-2011,2015 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -16,49 +16,103 @@ namespace Botan {
namespace TLS {
-/*
-* Create a new Server Hello message
-*/
+// New session case
Server_Hello::Server_Hello(Handshake_IO& io,
Handshake_Hash& hash,
const Policy& policy,
- const std::vector<byte>& session_id,
- Protocol_Version ver,
+ RandomNumberGenerator& rng,
+ const std::vector<byte>& reneg_info,
+ const Client_Hello& client_hello,
+ const std::vector<byte>& new_session_id,
+ Protocol_Version new_session_version,
u16bit ciphersuite,
byte compression,
- size_t max_fragment_size,
- bool client_has_secure_renegotiation,
- const std::vector<byte>& reneg_info,
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),
+ const std::vector<std::string>& next_protocols) :
+ m_version(new_session_version),
+ m_session_id(new_session_id),
m_random(make_hello_random(rng, policy)),
m_ciphersuite(ciphersuite),
m_comp_method(compression)
{
- 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)
+ if(client_hello.secure_renegotiation())
m_extensions.add(new Renegotiation_Extension(reneg_info));
- if(max_fragment_size)
+ if(client_hello.supports_session_ticket() && offer_session_ticket)
+ m_extensions.add(new Session_Ticket());
+
+ if(size_t max_fragment_size = client_hello.fragment_size())
m_extensions.add(new Maximum_Fragment_Length(max_fragment_size));
- if(client_has_npn)
+ if(policy.negotiate_heartbeat_support() && client_hello.supports_heartbeats())
+ m_extensions.add(new Heartbeat_Support_Indicator(true));
+
+ if(client_hello.next_protocol_notification())
m_extensions.add(new Next_Protocol_Notification(next_protocols));
- if(offer_session_ticket)
+ if(m_version.is_datagram_protocol())
+ {
+ const std::vector<u16bit> server_srtp = policy.srtp_profiles();
+ const std::vector<u16bit> client_srtp = client_hello.srtp_profiles();
+
+ if(!server_srtp.empty() && !client_srtp.empty())
+ {
+ u16bit shared = 0;
+ // always using server preferences for now
+ for(auto s : server_srtp)
+ for(auto c : client_srtp)
+ {
+ if(shared == 0 && s == c)
+ shared = s;
+ }
+
+ if(shared)
+ m_extensions.add(new SRTP_Protection_Profiles(shared));
+ }
+ }
+
+ hash.update(io.send(*this));
+ }
+
+// Resuming
+Server_Hello::Server_Hello(Handshake_IO& io,
+ Handshake_Hash& hash,
+ const Policy& policy,
+ RandomNumberGenerator& rng,
+ const std::vector<byte>& reneg_info,
+ const Client_Hello& client_hello,
+ Session& resumed_session,
+ bool offer_session_ticket,
+ const std::vector<std::string>& next_protocols) :
+ m_version(resumed_session.version()),
+ m_session_id(client_hello.session_id()),
+ m_random(make_hello_random(rng, policy)),
+ m_ciphersuite(resumed_session.ciphersuite_code()),
+ m_comp_method(resumed_session.compression_method())
+ {
+ /*
+ * 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_hello.secure_renegotiation())
+ m_extensions.add(new Renegotiation_Extension(reneg_info));
+
+ if(client_hello.supports_session_ticket() && offer_session_ticket)
m_extensions.add(new Session_Ticket());
+ if(size_t max_fragment_size = resumed_session.fragment_size())
+ m_extensions.add(new Maximum_Fragment_Length(max_fragment_size));
+
+ if(policy.negotiate_heartbeat_support() && client_hello.supports_heartbeats())
+ m_extensions.add(new Heartbeat_Support_Indicator(true));
+
+ if(client_hello.next_protocol_notification())
+ m_extensions.add(new Next_Protocol_Notification(next_protocols));
+
hash.update(io.send(*this));
}