Botan  2.4.0
Crypto and TLS for C++11
msg_client_hello.cpp
Go to the documentation of this file.
1 /*
2 * TLS Hello Request and Client Hello Messages
3 * (C) 2004-2011,2015,2016 Jack Lloyd
4 * 2016 Matthias Gierlings
5 * 2017 Harry Reimann, Rohde & Schwarz Cybersecurity
6 *
7 * Botan is released under the Simplified BSD License (see license.txt)
8 */
9 
10 #include <botan/tls_messages.h>
11 #include <botan/tls_alert.h>
12 #include <botan/tls_exceptn.h>
13 #include <botan/rng.h>
14 #include <botan/hash.h>
15 
16 #include <botan/internal/tls_reader.h>
17 #include <botan/internal/tls_session_key.h>
18 #include <botan/internal/tls_handshake_io.h>
19 #include <botan/internal/tls_handshake_hash.h>
20 #include <botan/internal/stl_util.h>
21 #include <chrono>
22 
23 namespace Botan {
24 
25 namespace TLS {
26 
27 enum {
30 };
31 
32 std::vector<uint8_t> make_hello_random(RandomNumberGenerator& rng,
33  const Policy& policy)
34  {
35  std::vector<uint8_t> buf(32);
36  rng.randomize(buf.data(), buf.size());
37 
38  std::unique_ptr<HashFunction> sha256 = HashFunction::create_or_throw("SHA-256");
39  sha256->update(buf);
40  sha256->final(buf);
41 
42  if(policy.include_time_in_hello_random())
43  {
44  const uint32_t time32 = static_cast<uint32_t>(
45  std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
46 
47  store_be(time32, buf.data());
48  }
49 
50  return buf;
51  }
52 
53 /*
54 * Create a new Hello Request message
55 */
57  {
58  io.send(*this);
59  }
60 
61 /*
62 * Deserialize a Hello Request message
63 */
64 Hello_Request::Hello_Request(const std::vector<uint8_t>& buf)
65  {
66  if(buf.size())
67  throw Decoding_Error("Bad Hello_Request, has non-zero size");
68  }
69 
70 /*
71 * Serialize a Hello Request message
72 */
73 std::vector<uint8_t> Hello_Request::serialize() const
74  {
75  return std::vector<uint8_t>();
76  }
77 
78 /*
79 * Create a new Client Hello message
80 */
83  const Policy& policy,
85  const std::vector<uint8_t>& reneg_info,
86  const Client_Hello::Settings& client_settings,
87  const std::vector<std::string>& next_protocols) :
88  m_version(client_settings.protocol_version()),
89  m_random(make_hello_random(rng, policy)),
90  m_suites(policy.ciphersuite_list(m_version, !client_settings.srp_identifier().empty())),
91  m_comp_methods(policy.compression())
92  {
94  "Our policy accepts the version we are offering");
95 
96  /*
97  * Place all empty extensions in front to avoid a bug in some systems
98  * which reject hellos when the last extension in the list is empty.
99  */
100  m_extensions.add(new Extended_Master_Secret);
101  m_extensions.add(new Session_Ticket());
102 
103  if(policy.negotiate_encrypt_then_mac())
104  m_extensions.add(new Encrypt_then_MAC);
105 
106  m_extensions.add(new Renegotiation_Extension(reneg_info));
107  m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
108 
109  if(policy.support_cert_status_message())
110  m_extensions.add(new Certificate_Status_Request({}, {}));
111 
112  if(reneg_info.empty() && !next_protocols.empty())
113  m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
114 
116  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
117  policy.allowed_signature_methods()));
118 
119  if(m_version.is_datagram_protocol())
120  m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
121 
122 #if defined(BOTAN_HAS_SRP6)
123  m_extensions.add(new SRP_Identifier(client_settings.srp_identifier()));
124 #else
125  if(!client_settings.srp_identifier().empty())
126  {
127  throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled");
128  }
129 #endif
130 
131  Supported_Groups* supported_groups = new Supported_Groups(policy.allowed_groups());
132  m_extensions.add(supported_groups);
133 
134  if(!supported_groups->curves().empty())
135  {
136  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
137  }
138 
140  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
141  policy.allowed_signature_methods()));
142 
143  if(policy.send_fallback_scsv(client_settings.protocol_version()))
144  m_suites.push_back(TLS_FALLBACK_SCSV);
145 
146  hash.update(io.send(*this));
147  }
148 
149 /*
150 * Create a new Client Hello message (session resumption case)
151 */
154  const Policy& policy,
156  const std::vector<uint8_t>& reneg_info,
157  const Session& session,
158  const std::vector<std::string>& next_protocols) :
159  m_version(session.version()),
160  m_session_id(session.session_id()),
161  m_random(make_hello_random(rng, policy)),
162  m_suites(policy.ciphersuite_list(m_version, (session.srp_identifier() != ""))),
163  m_comp_methods(policy.compression())
164  {
165  if(!value_exists(m_suites, session.ciphersuite_code()))
166  m_suites.push_back(session.ciphersuite_code());
167 
168  if(!value_exists(m_comp_methods, session.compression_method()))
169  m_comp_methods.push_back(session.compression_method());
170 
171  /*
172  We always add the EMS extension, even if not used in the original session.
173  If the server understands it and follows the RFC it should reject our resume
174  attempt and upgrade us to a new session with the EMS protection.
175  */
176  m_extensions.add(new Extended_Master_Secret);
177 
178  m_extensions.add(new Renegotiation_Extension(reneg_info));
179  m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
180  m_extensions.add(new Session_Ticket(session.session_ticket()));
181  m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves()));
182 
183  if(!policy.allowed_ecc_curves().empty())
184  {
185  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
186  }
187 
188  if(session.supports_encrypt_then_mac())
189  m_extensions.add(new Encrypt_then_MAC);
190 
191 #if defined(BOTAN_HAS_SRP6)
192  m_extensions.add(new SRP_Identifier(session.srp_identifier()));
193 #else
194  if(!session.srp_identifier().empty())
195  {
196  throw Invalid_State("Attempting to resume SRP session but TLS-SRP support disabled");
197  }
198 #endif
199 
201  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
202  policy.allowed_signature_methods()));
203 
204  if(reneg_info.empty() && !next_protocols.empty())
205  m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
206 
207  hash.update(io.send(*this));
208  }
209 
211  {
212  if(!m_version.is_datagram_protocol())
213  throw Exception("Cannot use hello cookie with stream protocol");
214 
215  m_hello_cookie = hello_verify.cookie();
216  }
217 
218 /*
219 * Serialize a Client Hello message
220 */
221 std::vector<uint8_t> Client_Hello::serialize() const
222  {
223  std::vector<uint8_t> buf;
224 
225  buf.push_back(m_version.major_version());
226  buf.push_back(m_version.minor_version());
227  buf += m_random;
228 
229  append_tls_length_value(buf, m_session_id, 1);
230 
231  if(m_version.is_datagram_protocol())
232  append_tls_length_value(buf, m_hello_cookie, 1);
233 
234  append_tls_length_value(buf, m_suites, 2);
235  append_tls_length_value(buf, m_comp_methods, 1);
236 
237  /*
238  * May not want to send extensions at all in some cases. If so,
239  * should include SCSV value (if reneg info is empty, if not we are
240  * renegotiating with a modern server)
241  */
242 
243  buf += m_extensions.serialize();
244 
245  return buf;
246  }
247 
248 /*
249 * Read a counterparty client hello
250 */
251 Client_Hello::Client_Hello(const std::vector<uint8_t>& buf)
252  {
253  if(buf.size() < 41)
254  throw Decoding_Error("Client_Hello: Packet corrupted");
255 
256  TLS_Data_Reader reader("ClientHello", buf);
257 
258  const uint8_t major_version = reader.get_byte();
259  const uint8_t minor_version = reader.get_byte();
260 
261  m_version = Protocol_Version(major_version, minor_version);
262 
263  m_random = reader.get_fixed<uint8_t>(32);
264 
265  m_session_id = reader.get_range<uint8_t>(1, 0, 32);
266 
267  if(m_version.is_datagram_protocol())
268  m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
269 
270  m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
271 
272  m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
273 
274  m_extensions.deserialize(reader);
275 
276  if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
277  {
278  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
279  {
280  if(!reneg->renegotiation_info().empty())
282  "Client sent renegotiation SCSV and non-empty extension");
283  }
284  else
285  {
286  // add fake extension
287  m_extensions.add(new Renegotiation_Extension());
288  }
289  }
290 
291  // Parsing complete, now any additional decoding checks
292 
293  if(m_version.supports_negotiable_signature_algorithms() == false)
294  {
295  if(m_extensions.has<Signature_Algorithms>())
297  "Client sent signature_algorithms extension in version that doesn't support it");
298  }
299  }
300 
302  {
303  return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
304  }
305 
306 /*
307 * Check if we offered this ciphersuite
308 */
309 bool Client_Hello::offered_suite(uint16_t ciphersuite) const
310  {
311  for(size_t i = 0; i != m_suites.size(); ++i)
312  if(m_suites[i] == ciphersuite)
313  return true;
314  return false;
315  }
316 
317 std::vector<std::pair<std::string, std::string>> Client_Hello::supported_algos() const
318  {
319  if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
320  return sigs->supported_signature_algorthms();
321  return std::vector<std::pair<std::string, std::string>>();
322  }
323 
324 std::set<std::string> Client_Hello::supported_sig_algos() const
325  {
326  std::set<std::string> sig;
327  for(auto&& hash_and_sig : supported_algos())
328  sig.insert(hash_and_sig.second);
329  return sig;
330  }
331 
332 std::vector<std::string> Client_Hello::supported_ecc_curves() const
333  {
334  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
335  return groups->curves();
336  return std::vector<std::string>();
337  }
338 
339 std::vector<std::string> Client_Hello::supported_dh_groups() const
340  {
341  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
342  return groups->dh_groups();
343  return std::vector<std::string>();
344  }
345 
347  {
348  if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
349  {
350  return ecc_formats->prefers_compressed();
351  }
352  return false;
353  }
354 
355 std::string Client_Hello::sni_hostname() const
356  {
357  if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
358  return sni->host_name();
359  return "";
360  }
361 
362 #if defined(BOTAN_HAS_SRP6)
363 std::string Client_Hello::srp_identifier() const
364  {
365  if(SRP_Identifier* srp = m_extensions.get<SRP_Identifier>())
366  return srp->identifier();
367  return "";
368  }
369 #endif
370 
372  {
373  return m_extensions.has<Renegotiation_Extension>();
374  }
375 
376 std::vector<uint8_t> Client_Hello::renegotiation_info() const
377  {
378  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
379  return reneg->renegotiation_info();
380  return std::vector<uint8_t>();
381  }
382 
384  {
385  return m_extensions.has<Session_Ticket>();
386  }
387 
388 std::vector<uint8_t> Client_Hello::session_ticket() const
389  {
390  if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
391  return ticket->contents();
392  return std::vector<uint8_t>();
393  }
394 
396  {
397  return m_extensions.has<Application_Layer_Protocol_Notification>();
398  }
399 
401  {
402  return m_extensions.has<Extended_Master_Secret>();
403  }
404 
406  {
407  return m_extensions.has<Certificate_Status_Request>();
408  }
409 
411  {
412  return m_extensions.has<Encrypt_then_MAC>();
413  }
414 
416  {
417  return m_extensions.has<Signature_Algorithms>();
418  }
419 
420 std::vector<std::string> Client_Hello::next_protocols() const
421  {
422  if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
423  return alpn->protocols();
424  return std::vector<std::string>();
425  }
426 
427 std::vector<uint16_t> Client_Hello::srtp_profiles() const
428  {
429  if(SRTP_Protection_Profiles* srtp = m_extensions.get<SRTP_Protection_Profiles>())
430  return srtp->profiles();
431  return std::vector<uint16_t>();
432  }
433 
434 
435 }
436 
437 }
std::vector< uint8_t > serialize() const
Client_Hello(Handshake_IO &io, Handshake_Hash &hash, const Policy &policy, RandomNumberGenerator &rng, const std::vector< uint8_t > &reneg_info, const Client_Hello::Settings &client_settings, const std::vector< std::string > &next_protocols)
const Protocol_Version protocol_version() const
Definition: tls_messages.h:81
std::vector< T > get_fixed(size_t size)
Definition: tls_reader.h:126
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=0
uint16_t ciphersuite_code() const
Definition: tls_session.h:125
bool prefers_compressed_ec_points() const
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:345
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:434
std::vector< uint8_t > session_ticket() const
uint8_t minor_version() const
Definition: tls_version.h:82
virtual void randomize(uint8_t output[], size_t length)=0
bool supports_encrypt_then_mac() const
std::vector< uint8_t > renegotiation_info() const
Protocol_Version version() const
Definition: tls_messages.h:93
void add(Extension *extn)
uint8_t compression_method() const
Definition: tls_session.h:135
virtual bool negotiate_encrypt_then_mac() const
Definition: tls_policy.cpp:344
void update_hello_cookie(const Hello_Verify_Request &hello_verify)
const std::vector< uint8_t > & session_id() const
Definition: tls_messages.h:97
virtual bool include_time_in_hello_random() const
Definition: tls_policy.cpp:341
virtual std::vector< uint16_t > srtp_profiles() const
Definition: tls_policy.cpp:357
virtual bool use_ecc_point_compression() const
Definition: tls_policy.cpp:131
const std::vector< std::string > & curves() const
std::string hostname() const
const std::string & hostname() const
Definition: tls_messages.h:82
virtual std::vector< std::string > allowed_signature_hashes() const
Definition: tls_policy.cpp:48
const Server_Information & server_info() const
Definition: tls_session.h:190
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
Supported_Groups Supported_Elliptic_Curves
std::vector< std::string > supported_dh_groups() const
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:29
Hello_Request(Handshake_IO &io)
std::vector< std::string > supported_ecc_curves() const
std::vector< T > get_range_vector(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition: tls_reader.h:105
std::vector< T > get_range(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition: tls_reader.h:94
void update(const uint8_t in[], size_t length)
virtual bool send_fallback_scsv(Protocol_Version version) const
Definition: tls_policy.cpp:286
std::set< std::string > supported_sig_algos() const
virtual std::vector< std::string > allowed_groups() const
Definition: tls_policy.cpp:172
const std::vector< uint8_t > & session_ticket() const
Definition: tls_session.h:185
std::vector< std::string > next_protocols() const
bool offered_suite(uint16_t ciphersuite) const
const std::string & srp_identifier() const
Definition: tls_messages.h:83
Definition: alg_id.cpp:13
virtual bool support_cert_status_message() const
Definition: tls_policy.cpp:345
virtual std::vector< std::string > allowed_ecc_curves() const
Definition: tls_policy.cpp:107
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, const Policy &policy)
std::vector< std::pair< std::string, std::string > > supported_algos() const
bool supports_encrypt_then_mac() const
Definition: tls_session.h:165
bool value_exists(const std::vector< T > &vec, const T &val)
Definition: stl_util.h:86
bool sent_signature_algorithms() const
bool supports_cert_status_message() const
uint8_t major_version() const
Definition: tls_version.h:77
virtual std::vector< std::string > allowed_signature_methods() const
Definition: tls_policy.cpp:87
virtual bool acceptable_protocol_version(Protocol_Version version) const
Definition: tls_policy.cpp:291
std::vector< uint16_t > srtp_profiles() const
void deserialize(TLS_Data_Reader &reader)
std::string sni_hostname() const
bool supports_extended_master_secret() const
MechanismType hash
std::vector< uint8_t > cookie() const
Definition: tls_messages.h:54
const std::string & srp_identifier() const
Definition: tls_session.h:146
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition: tls_reader.h:185