Botan  2.12.1
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/tls_callbacks.h>
14 #include <botan/rng.h>
15 #include <botan/hash.h>
16 
17 #include <botan/internal/tls_reader.h>
18 #include <botan/internal/tls_session_key.h>
19 #include <botan/internal/tls_handshake_io.h>
20 #include <botan/internal/tls_handshake_hash.h>
21 #include <botan/internal/stl_util.h>
22 #include <chrono>
23 
24 namespace Botan {
25 
26 namespace TLS {
27 
28 enum {
31 };
32 
33 std::vector<uint8_t> make_hello_random(RandomNumberGenerator& rng,
34  const Policy& policy)
35  {
36  std::vector<uint8_t> buf(32);
37  rng.randomize(buf.data(), buf.size());
38 
39  std::unique_ptr<HashFunction> sha256 = HashFunction::create_or_throw("SHA-256");
40  sha256->update(buf);
41  sha256->final(buf);
42 
43  if(policy.include_time_in_hello_random())
44  {
45  const uint32_t time32 = static_cast<uint32_t>(
46  std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
47 
48  store_be(time32, buf.data());
49  }
50 
51  return buf;
52  }
53 
54 /*
55 * Create a new Hello Request message
56 */
58  {
59  io.send(*this);
60  }
61 
62 /*
63 * Deserialize a Hello Request message
64 */
65 Hello_Request::Hello_Request(const std::vector<uint8_t>& buf)
66  {
67  if(buf.size())
68  throw Decoding_Error("Bad Hello_Request, has non-zero size");
69  }
70 
71 /*
72 * Serialize a Hello Request message
73 */
74 std::vector<uint8_t> Hello_Request::serialize() const
75  {
76  return std::vector<uint8_t>();
77  }
78 
79 /*
80 * Create a new Client Hello message
81 */
84  const Policy& policy,
85  Callbacks& cb,
87  const std::vector<uint8_t>& reneg_info,
88  const Client_Hello::Settings& client_settings,
89  const std::vector<std::string>& next_protocols) :
90  m_version(client_settings.protocol_version()),
91  m_random(make_hello_random(rng, policy)),
92  m_suites(policy.ciphersuite_list(m_version, !client_settings.srp_identifier().empty())),
93  m_comp_methods(1)
94  {
95  if(!policy.acceptable_protocol_version(m_version))
96  throw Internal_Error("Offering " + m_version.to_string() +
97  " but our own policy does not accept it");
98 
99  /*
100  * Place all empty extensions in front to avoid a bug in some systems
101  * which reject hellos when the last extension in the list is empty.
102  */
103  m_extensions.add(new Extended_Master_Secret);
104  m_extensions.add(new Session_Ticket());
105 
106  if(policy.negotiate_encrypt_then_mac())
107  m_extensions.add(new Encrypt_then_MAC);
108 
109  m_extensions.add(new Renegotiation_Extension(reneg_info));
110 
111  m_extensions.add(new Supported_Versions(m_version, policy));
112 
113  if(client_settings.hostname() != "")
114  m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
115 
116  if(policy.support_cert_status_message())
117  m_extensions.add(new Certificate_Status_Request({}, {}));
118 
119  if(reneg_info.empty() && !next_protocols.empty())
121 
123  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
124 
125  if(m_version.is_datagram_protocol())
126  m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
127 
128 #if defined(BOTAN_HAS_SRP6)
129  m_extensions.add(new SRP_Identifier(client_settings.srp_identifier()));
130 #else
131  if(!client_settings.srp_identifier().empty())
132  {
133  throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled");
134  }
135 #endif
136 
137  std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
138 
139  if(supported_groups->ec_groups().size() > 0)
140  {
141  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
142  }
143 
144  m_extensions.add(supported_groups.release());
145 
146  cb.tls_modify_extensions(m_extensions, CLIENT);
147 
148  if(policy.send_fallback_scsv(client_settings.protocol_version()))
149  m_suites.push_back(TLS_FALLBACK_SCSV);
150 
151  hash.update(io.send(*this));
152  }
153 
154 /*
155 * Create a new Client Hello message (session resumption case)
156 */
159  const Policy& policy,
160  Callbacks& cb,
162  const std::vector<uint8_t>& reneg_info,
163  const Session& session,
164  const std::vector<std::string>& next_protocols) :
165  m_version(session.version()),
166  m_session_id(session.session_id()),
167  m_random(make_hello_random(rng, policy)),
168  m_suites(policy.ciphersuite_list(m_version, (session.srp_identifier() != ""))),
169  m_comp_methods(1)
170  {
171  if(!policy.acceptable_protocol_version(m_version))
172  throw Internal_Error("Offering " + m_version.to_string() +
173  " but our own policy does not accept it");
174 
175  if(!value_exists(m_suites, session.ciphersuite_code()))
176  m_suites.push_back(session.ciphersuite_code());
177 
178  /*
179  We always add the EMS extension, even if not used in the original session.
180  If the server understands it and follows the RFC it should reject our resume
181  attempt and upgrade us to a new session with the EMS protection.
182  */
183  m_extensions.add(new Extended_Master_Secret);
184 
185  m_extensions.add(new Renegotiation_Extension(reneg_info));
186  m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
187  m_extensions.add(new Session_Ticket(session.session_ticket()));
188 
189  if(policy.support_cert_status_message())
190  m_extensions.add(new Certificate_Status_Request({}, {}));
191 
192  std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
193 
194  if(supported_groups->ec_groups().size() > 0)
195  {
196  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
197  }
198 
199  m_extensions.add(supported_groups.release());
200 
201  if(session.supports_encrypt_then_mac())
202  m_extensions.add(new Encrypt_then_MAC);
203 
204 #if defined(BOTAN_HAS_SRP6)
205  m_extensions.add(new SRP_Identifier(session.srp_identifier()));
206 #else
207  if(!session.srp_identifier().empty())
208  {
209  throw Invalid_State("Attempting to resume SRP session but TLS-SRP support disabled");
210  }
211 #endif
212 
214  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
215 
216  if(reneg_info.empty() && !next_protocols.empty())
218 
219  cb.tls_modify_extensions(m_extensions, CLIENT);
220 
221  hash.update(io.send(*this));
222  }
223 
225  {
226  if(!m_version.is_datagram_protocol())
227  throw Invalid_State("Cannot use hello cookie with stream protocol");
228 
229  m_hello_cookie = hello_verify.cookie();
230  }
231 
232 /*
233 * Serialize a Client Hello message
234 */
235 std::vector<uint8_t> Client_Hello::serialize() const
236  {
237  std::vector<uint8_t> buf;
238 
239  buf.push_back(m_version.major_version());
240  buf.push_back(m_version.minor_version());
241  buf += m_random;
242 
243  append_tls_length_value(buf, m_session_id, 1);
244 
245  if(m_version.is_datagram_protocol())
246  append_tls_length_value(buf, m_hello_cookie, 1);
247 
248  append_tls_length_value(buf, m_suites, 2);
249  append_tls_length_value(buf, m_comp_methods, 1);
250 
251  /*
252  * May not want to send extensions at all in some cases. If so,
253  * should include SCSV value (if reneg info is empty, if not we are
254  * renegotiating with a modern server)
255  */
256 
257  buf += m_extensions.serialize(Connection_Side::CLIENT);
258 
259  return buf;
260  }
261 
262 std::vector<uint8_t> Client_Hello::cookie_input_data() const
263  {
264  std::vector<uint8_t> buf;
265 
266  buf.push_back(m_version.major_version());
267  buf.push_back(m_version.minor_version());
268  buf += m_random;
269 
270  append_tls_length_value(buf, m_session_id, 1);
271 
272  append_tls_length_value(buf, m_suites, 2);
273  append_tls_length_value(buf, m_comp_methods, 1);
274 
275  // Here we don't serialize the extensions since the client extensions
276  // may contain values we don't know how to serialize back.
277 
278  return buf;
279  }
280 
281 /*
282 * Read a counterparty client hello
283 */
284 Client_Hello::Client_Hello(const std::vector<uint8_t>& buf)
285  {
286  if(buf.size() < 41)
287  throw Decoding_Error("Client_Hello: Packet corrupted");
288 
289  TLS_Data_Reader reader("ClientHello", buf);
290 
291  const uint8_t major_version = reader.get_byte();
292  const uint8_t minor_version = reader.get_byte();
293 
294  m_version = Protocol_Version(major_version, minor_version);
295 
296  m_random = reader.get_fixed<uint8_t>(32);
297 
298  m_session_id = reader.get_range<uint8_t>(1, 0, 32);
299 
300  if(m_version.is_datagram_protocol())
301  m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
302 
303  m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
304 
305  m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
306 
307  m_extensions.deserialize(reader, Connection_Side::CLIENT);
308 
309  if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
310  {
311  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
312  {
313  if(!reneg->renegotiation_info().empty())
315  "Client sent renegotiation SCSV and non-empty extension");
316  }
317  else
318  {
319  // add fake extension
320  m_extensions.add(new Renegotiation_Extension());
321  }
322  }
323  }
324 
326  {
327  return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
328  }
329 
330 /*
331 * Check if we offered this ciphersuite
332 */
333 bool Client_Hello::offered_suite(uint16_t ciphersuite) const
334  {
335  for(size_t i = 0; i != m_suites.size(); ++i)
336  if(m_suites[i] == ciphersuite)
337  return true;
338  return false;
339  }
340 
341 std::vector<Signature_Scheme> Client_Hello::signature_schemes() const
342  {
343  std::vector<Signature_Scheme> schemes;
344 
345  if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
346  {
347  schemes = sigs->supported_schemes();
348  }
349 
350  return schemes;
351  }
352 
353 std::vector<Group_Params> Client_Hello::supported_ecc_curves() const
354  {
355  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
356  return groups->ec_groups();
357  return std::vector<Group_Params>();
358  }
359 
360 std::vector<Group_Params> Client_Hello::supported_dh_groups() const
361  {
362  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
363  return groups->dh_groups();
364  return std::vector<Group_Params>();
365  }
366 
368  {
369  if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
370  {
371  return ecc_formats->prefers_compressed();
372  }
373  return false;
374  }
375 
376 std::string Client_Hello::sni_hostname() const
377  {
378  if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
379  return sni->host_name();
380  return "";
381  }
382 
383 #if defined(BOTAN_HAS_SRP6)
384 std::string Client_Hello::srp_identifier() const
385  {
386  if(SRP_Identifier* srp = m_extensions.get<SRP_Identifier>())
387  return srp->identifier();
388  return "";
389  }
390 #endif
391 
393  {
394  return m_extensions.has<Renegotiation_Extension>();
395  }
396 
397 std::vector<uint8_t> Client_Hello::renegotiation_info() const
398  {
399  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
400  return reneg->renegotiation_info();
401  return std::vector<uint8_t>();
402  }
403 
404 std::vector<Protocol_Version> Client_Hello::supported_versions() const
405  {
406  if(Supported_Versions* versions = m_extensions.get<Supported_Versions>())
407  return versions->versions();
408  return {};
409  }
410 
412  {
413  return m_extensions.has<Session_Ticket>();
414  }
415 
416 std::vector<uint8_t> Client_Hello::session_ticket() const
417  {
418  if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
419  return ticket->contents();
420  return std::vector<uint8_t>();
421  }
422 
424  {
425  return m_extensions.has<Application_Layer_Protocol_Notification>();
426  }
427 
429  {
430  return m_extensions.has<Extended_Master_Secret>();
431  }
432 
434  {
435  return m_extensions.has<Certificate_Status_Request>();
436  }
437 
439  {
440  return m_extensions.has<Encrypt_then_MAC>();
441  }
442 
444  {
445  return m_extensions.has<Signature_Algorithms>();
446  }
447 
448 std::vector<std::string> Client_Hello::next_protocols() const
449  {
450  if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
451  return alpn->protocols();
452  return std::vector<std::string>();
453  }
454 
455 std::vector<uint16_t> Client_Hello::srtp_profiles() const
456  {
457  if(SRTP_Protection_Profiles* srtp = m_extensions.get<SRTP_Protection_Profiles>())
458  return srtp->profiles();
459  return std::vector<uint16_t>();
460  }
461 
462 
463 }
464 
465 }
const Protocol_Version protocol_version() const
Definition: tls_messages.h:83
std::vector< T > get_fixed(size_t size)
Definition: tls_reader.h:126
virtual std::vector< uint8_t > send(const Handshake_Message &msg)=0
Client_Hello(Handshake_IO &io, Handshake_Hash &hash, const Policy &policy, Callbacks &cb, RandomNumberGenerator &rng, const std::vector< uint8_t > &reneg_info, const Client_Hello::Settings &client_settings, const std::vector< std::string > &next_protocols)
uint16_t ciphersuite_code() const
Definition: tls_session.h:123
bool prefers_compressed_ec_points() const
std::vector< Group_Params > supported_dh_groups() const
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:344
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:438
std::vector< uint8_t > session_ticket() const
uint8_t minor_version() const
Definition: tls_version.h:84
virtual void randomize(uint8_t output[], size_t length)=0
bool supports_encrypt_then_mac() const
std::vector< uint8_t > serialize(Connection_Side whoami) const
std::vector< uint8_t > renegotiation_info() const
void add(Extension *extn)
virtual bool negotiate_encrypt_then_mac() const
Definition: tls_policy.cpp:332
void update_hello_cookie(const Hello_Verify_Request &hello_verify)
virtual bool include_time_in_hello_random() const
Definition: tls_policy.cpp:329
virtual std::vector< uint16_t > srtp_profiles() const
Definition: tls_policy.cpp:353
virtual bool use_ecc_point_compression() const
Definition: tls_policy.cpp:127
std::string hostname() const
const std::string & hostname() const
Definition: tls_messages.h:84
const Server_Information & server_info() const
Definition: tls_session.h:183
void deserialize(TLS_Data_Reader &reader, Connection_Side from)
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
std::string to_string() const
Definition: tls_version.cpp:15
virtual std::vector< Group_Params > key_exchange_groups() const
Definition: tls_policy.cpp:162
std::vector< uint8_t > cookie_input_data() const
Hello_Request(Handshake_IO &io)
const std::vector< uint8_t > & cookie() const
Definition: tls_messages.h:56
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
std::vector< Signature_Scheme > signature_schemes() const
virtual bool send_fallback_scsv(Protocol_Version version) const
Definition: tls_policy.cpp:273
const std::vector< uint8_t > & session_ticket() const
Definition: tls_session.h:178
std::vector< std::string > next_protocols() const
bool offered_suite(uint16_t ciphersuite) const
const std::string & srp_identifier() const
Definition: tls_messages.h:85
Definition: alg_id.cpp:13
virtual bool support_cert_status_message() const
Definition: tls_policy.cpp:333
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, const Policy &policy)
virtual void tls_modify_extensions(Extensions &extn, Connection_Side which_side)
bool supports_encrypt_then_mac() const
Definition: tls_session.h:158
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:79
std::vector< Protocol_Version > supported_versions() const
virtual bool acceptable_protocol_version(Protocol_Version version) const
Definition: tls_policy.cpp:278
std::vector< uint16_t > srtp_profiles() const
std::string sni_hostname() const
bool supports_extended_master_secret() const
MechanismType hash
virtual std::vector< Signature_Scheme > allowed_signature_schemes() const
Definition: tls_policy.cpp:22
std::vector< Group_Params > supported_ecc_curves() const
const std::string & srp_identifier() const
Definition: tls_session.h:139
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