Botan  2.6.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/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  {
96  "Our policy accepts the version we are offering");
97 
98  /*
99  * Place all empty extensions in front to avoid a bug in some systems
100  * which reject hellos when the last extension in the list is empty.
101  */
102  m_extensions.add(new Extended_Master_Secret);
103  m_extensions.add(new Session_Ticket());
104 
105  if(policy.negotiate_encrypt_then_mac())
106  m_extensions.add(new Encrypt_then_MAC);
107 
108  m_extensions.add(new Renegotiation_Extension(reneg_info));
109  m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
110 
111  if(policy.support_cert_status_message())
112  m_extensions.add(new Certificate_Status_Request({}, {}));
113 
114  if(reneg_info.empty() && !next_protocols.empty())
116 
118  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
119 
120  if(m_version.is_datagram_protocol())
121  m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
122 
123 #if defined(BOTAN_HAS_SRP6)
124  m_extensions.add(new SRP_Identifier(client_settings.srp_identifier()));
125 #else
126  if(!client_settings.srp_identifier().empty())
127  {
128  throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled");
129  }
130 #endif
131 
132  std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
133 
134  if(supported_groups->ec_groups().size() > 0)
135  {
136  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
137  }
138 
139  m_extensions.add(supported_groups.release());
140 
141  cb.tls_modify_extensions(m_extensions, CLIENT);
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,
155  Callbacks& cb,
157  const std::vector<uint8_t>& reneg_info,
158  const Session& session,
159  const std::vector<std::string>& next_protocols) :
160  m_version(session.version()),
161  m_session_id(session.session_id()),
162  m_random(make_hello_random(rng, policy)),
163  m_suites(policy.ciphersuite_list(m_version, (session.srp_identifier() != ""))),
164  m_comp_methods(1)
165  {
166  if(!value_exists(m_suites, session.ciphersuite_code()))
167  m_suites.push_back(session.ciphersuite_code());
168 
169  /*
170  We always add the EMS extension, even if not used in the original session.
171  If the server understands it and follows the RFC it should reject our resume
172  attempt and upgrade us to a new session with the EMS protection.
173  */
174  m_extensions.add(new Extended_Master_Secret);
175 
176  m_extensions.add(new Renegotiation_Extension(reneg_info));
177  m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
178  m_extensions.add(new Session_Ticket(session.session_ticket()));
179 
180  std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
181 
182  if(supported_groups->ec_groups().size() > 0)
183  {
184  m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
185  }
186 
187  m_extensions.add(supported_groups.release());
188 
189  if(session.supports_encrypt_then_mac())
190  m_extensions.add(new Encrypt_then_MAC);
191 
192 #if defined(BOTAN_HAS_SRP6)
193  m_extensions.add(new SRP_Identifier(session.srp_identifier()));
194 #else
195  if(!session.srp_identifier().empty())
196  {
197  throw Invalid_State("Attempting to resume SRP session but TLS-SRP support disabled");
198  }
199 #endif
200 
202  m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
203 
204  if(reneg_info.empty() && !next_protocols.empty())
206 
207  cb.tls_modify_extensions(m_extensions, CLIENT);
208 
209  hash.update(io.send(*this));
210  }
211 
213  {
214  if(!m_version.is_datagram_protocol())
215  throw Exception("Cannot use hello cookie with stream protocol");
216 
217  m_hello_cookie = hello_verify.cookie();
218  }
219 
220 /*
221 * Serialize a Client Hello message
222 */
223 std::vector<uint8_t> Client_Hello::serialize() const
224  {
225  std::vector<uint8_t> buf;
226 
227  buf.push_back(m_version.major_version());
228  buf.push_back(m_version.minor_version());
229  buf += m_random;
230 
231  append_tls_length_value(buf, m_session_id, 1);
232 
233  if(m_version.is_datagram_protocol())
234  append_tls_length_value(buf, m_hello_cookie, 1);
235 
236  append_tls_length_value(buf, m_suites, 2);
237  append_tls_length_value(buf, m_comp_methods, 1);
238 
239  /*
240  * May not want to send extensions at all in some cases. If so,
241  * should include SCSV value (if reneg info is empty, if not we are
242  * renegotiating with a modern server)
243  */
244 
245  buf += m_extensions.serialize();
246 
247  return buf;
248  }
249 
250 /*
251 * Read a counterparty client hello
252 */
253 Client_Hello::Client_Hello(const std::vector<uint8_t>& buf)
254  {
255  if(buf.size() < 41)
256  throw Decoding_Error("Client_Hello: Packet corrupted");
257 
258  TLS_Data_Reader reader("ClientHello", buf);
259 
260  const uint8_t major_version = reader.get_byte();
261  const uint8_t minor_version = reader.get_byte();
262 
263  m_version = Protocol_Version(major_version, minor_version);
264 
265  m_random = reader.get_fixed<uint8_t>(32);
266 
267  m_session_id = reader.get_range<uint8_t>(1, 0, 32);
268 
269  if(m_version.is_datagram_protocol())
270  m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
271 
272  m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
273 
274  m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
275 
276  m_extensions.deserialize(reader);
277 
278  if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
279  {
280  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
281  {
282  if(!reneg->renegotiation_info().empty())
284  "Client sent renegotiation SCSV and non-empty extension");
285  }
286  else
287  {
288  // add fake extension
289  m_extensions.add(new Renegotiation_Extension());
290  }
291  }
292 
293  // Parsing complete, now any additional decoding checks
294 
295  if(m_version.supports_negotiable_signature_algorithms() == false)
296  {
297  if(m_extensions.has<Signature_Algorithms>())
299  "Client sent signature_algorithms extension in version that doesn't support it");
300  }
301  }
302 
304  {
305  return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
306  }
307 
308 /*
309 * Check if we offered this ciphersuite
310 */
311 bool Client_Hello::offered_suite(uint16_t ciphersuite) const
312  {
313  for(size_t i = 0; i != m_suites.size(); ++i)
314  if(m_suites[i] == ciphersuite)
315  return true;
316  return false;
317  }
318 
319 std::vector<Signature_Scheme> Client_Hello::signature_schemes() const
320  {
321  std::vector<Signature_Scheme> schemes;
322 
323  if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
324  {
325  schemes = sigs->supported_schemes();
326  }
327 
328  return schemes;
329  }
330 
331 std::vector<Group_Params> Client_Hello::supported_ecc_curves() const
332  {
333  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
334  return groups->ec_groups();
335  return std::vector<Group_Params>();
336  }
337 
338 std::vector<Group_Params> Client_Hello::supported_dh_groups() const
339  {
340  if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
341  return groups->dh_groups();
342  return std::vector<Group_Params>();
343  }
344 
346  {
347  if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
348  {
349  return ecc_formats->prefers_compressed();
350  }
351  return false;
352  }
353 
354 std::string Client_Hello::sni_hostname() const
355  {
356  if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
357  return sni->host_name();
358  return "";
359  }
360 
361 #if defined(BOTAN_HAS_SRP6)
362 std::string Client_Hello::srp_identifier() const
363  {
364  if(SRP_Identifier* srp = m_extensions.get<SRP_Identifier>())
365  return srp->identifier();
366  return "";
367  }
368 #endif
369 
371  {
372  return m_extensions.has<Renegotiation_Extension>();
373  }
374 
375 std::vector<uint8_t> Client_Hello::renegotiation_info() const
376  {
377  if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
378  return reneg->renegotiation_info();
379  return std::vector<uint8_t>();
380  }
381 
383  {
384  return m_extensions.has<Session_Ticket>();
385  }
386 
387 std::vector<uint8_t> Client_Hello::session_ticket() const
388  {
389  if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
390  return ticket->contents();
391  return std::vector<uint8_t>();
392  }
393 
395  {
396  return m_extensions.has<Application_Layer_Protocol_Notification>();
397  }
398 
400  {
401  return m_extensions.has<Extended_Master_Secret>();
402  }
403 
405  {
406  return m_extensions.has<Certificate_Status_Request>();
407  }
408 
410  {
411  return m_extensions.has<Encrypt_then_MAC>();
412  }
413 
415  {
416  return m_extensions.has<Signature_Algorithms>();
417  }
418 
419 std::vector<std::string> Client_Hello::next_protocols() const
420  {
421  if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
422  return alpn->protocols();
423  return std::vector<std::string>();
424  }
425 
426 std::vector<uint16_t> Client_Hello::srtp_profiles() const
427  {
428  if(SRTP_Protection_Profiles* srtp = m_extensions.get<SRTP_Protection_Profiles>())
429  return srtp->profiles();
430  return std::vector<uint16_t>();
431  }
432 
433 
434 }
435 
436 }
std::vector< uint8_t > serialize() const
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: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
void add(Extension *extn)
virtual bool negotiate_encrypt_then_mac() const
Definition: tls_policy.cpp:326
void update_hello_cookie(const Hello_Verify_Request &hello_verify)
virtual bool include_time_in_hello_random() const
Definition: tls_policy.cpp:323
virtual std::vector< uint16_t > srtp_profiles() const
Definition: tls_policy.cpp:339
virtual bool use_ecc_point_compression() const
Definition: tls_policy.cpp:125
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
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:30
virtual std::vector< Group_Params > key_exchange_groups() const
Definition: tls_policy.cpp:160
Hello_Request(Handshake_IO &io)
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:267
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:327
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:77
virtual bool acceptable_protocol_version(Protocol_Version version) const
Definition: tls_policy.cpp:272
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
virtual std::vector< Signature_Scheme > allowed_signature_schemes() const
Definition: tls_policy.cpp:22
std::vector< uint8_t > cookie() const
Definition: tls_messages.h:56
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