Coverage Report

Created: 2020-06-30 13:58

/src/botan/src/lib/tls/msg_client_hello.cpp
Line
Count
Source (jump to first uncovered line)
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 {
29
   TLS_EMPTY_RENEGOTIATION_INFO_SCSV        = 0x00FF,
30
   TLS_FALLBACK_SCSV                        = 0x5600
31
};
32
33
std::vector<uint8_t> make_hello_random(RandomNumberGenerator& rng,
34
                                       const Policy& policy)
35
54.6k
   {
36
54.6k
   std::vector<uint8_t> buf(32);
37
54.6k
   rng.randomize(buf.data(), buf.size());
38
54.6k
39
54.6k
   std::unique_ptr<HashFunction> sha256 = HashFunction::create_or_throw("SHA-256");
40
54.6k
   sha256->update(buf);
41
54.6k
   sha256->final(buf);
42
54.6k
43
54.6k
   if(policy.include_time_in_hello_random())
44
54.6k
      {
45
54.6k
      const uint32_t time32 = static_cast<uint32_t>(
46
54.6k
         std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
47
54.6k
48
54.6k
      store_be(time32, buf.data());
49
54.6k
      }
50
54.6k
51
54.6k
   return buf;
52
54.6k
   }
53
54
/*
55
* Create a new Hello Request message
56
*/
57
Hello_Request::Hello_Request(Handshake_IO& io)
58
0
   {
59
0
   io.send(*this);
60
0
   }
61
62
/*
63
* Deserialize a Hello Request message
64
*/
65
Hello_Request::Hello_Request(const std::vector<uint8_t>& buf)
66
0
   {
67
0
   if(buf.size())
68
0
      throw Decoding_Error("Bad Hello_Request, has non-zero size");
69
0
   }
70
71
/*
72
* Serialize a Hello Request message
73
*/
74
std::vector<uint8_t> Hello_Request::serialize() const
75
0
   {
76
0
   return std::vector<uint8_t>();
77
0
   }
78
79
/*
80
* Create a new Client Hello message
81
*/
82
Client_Hello::Client_Hello(Handshake_IO& io,
83
                           Handshake_Hash& hash,
84
                           const Policy& policy,
85
                           Callbacks& cb,
86
                           RandomNumberGenerator& rng,
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
5.71k
   {
95
5.71k
   if(!policy.acceptable_protocol_version(m_version))
96
0
      throw Internal_Error("Offering " + m_version.to_string() +
97
0
                           " but our own policy does not accept it");
98
5.71k
99
5.71k
   /*
100
5.71k
   * Place all empty extensions in front to avoid a bug in some systems
101
5.71k
   * which reject hellos when the last extension in the list is empty.
102
5.71k
   */
103
5.71k
   m_extensions.add(new Extended_Master_Secret);
104
5.71k
   m_extensions.add(new Session_Ticket());
105
5.71k
106
5.71k
   if(policy.negotiate_encrypt_then_mac())
107
5.71k
      m_extensions.add(new Encrypt_then_MAC);
108
5.71k
109
5.71k
   m_extensions.add(new Renegotiation_Extension(reneg_info));
110
5.71k
111
5.71k
   m_extensions.add(new Supported_Versions(m_version, policy));
112
5.71k
113
5.71k
   if(client_settings.hostname() != "")
114
5.71k
      m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
115
5.71k
116
5.71k
   if(policy.support_cert_status_message())
117
5.71k
      m_extensions.add(new Certificate_Status_Request({}, {}));
118
5.71k
119
5.71k
   if(reneg_info.empty() && !next_protocols.empty())
120
0
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
121
5.71k
122
5.71k
   if(m_version.supports_negotiable_signature_algorithms())
123
5.71k
      m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
124
5.71k
125
5.71k
   if(m_version.is_datagram_protocol())
126
0
      m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
127
5.71k
128
5.71k
#if defined(BOTAN_HAS_SRP6)
129
5.71k
   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
5.71k
   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
138
5.71k
139
5.71k
   if(supported_groups->ec_groups().size() > 0)
140
5.71k
      {
141
5.71k
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
142
5.71k
      }
143
5.71k
144
5.71k
   m_extensions.add(supported_groups.release());
145
5.71k
146
5.71k
   cb.tls_modify_extensions(m_extensions, CLIENT);
147
5.71k
148
5.71k
   if(policy.send_fallback_scsv(client_settings.protocol_version()))
149
0
      m_suites.push_back(TLS_FALLBACK_SCSV);
150
5.71k
151
5.71k
   hash.update(io.send(*this));
152
5.71k
   }
153
154
/*
155
* Create a new Client Hello message (session resumption case)
156
*/
157
Client_Hello::Client_Hello(Handshake_IO& io,
158
                           Handshake_Hash& hash,
159
                           const Policy& policy,
160
                           Callbacks& cb,
161
                           RandomNumberGenerator& rng,
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
0
   {
171
0
   if(!policy.acceptable_protocol_version(m_version))
172
0
      throw Internal_Error("Offering " + m_version.to_string() +
173
0
                           " but our own policy does not accept it");
174
0
175
0
   if(!value_exists(m_suites, session.ciphersuite_code()))
176
0
      m_suites.push_back(session.ciphersuite_code());
177
0
178
0
   /*
179
0
   We always add the EMS extension, even if not used in the original session.
180
0
   If the server understands it and follows the RFC it should reject our resume
181
0
   attempt and upgrade us to a new session with the EMS protection.
182
0
   */
183
0
   m_extensions.add(new Extended_Master_Secret);
184
0
185
0
   m_extensions.add(new Renegotiation_Extension(reneg_info));
186
0
   m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
187
0
   m_extensions.add(new Session_Ticket(session.session_ticket()));
188
0
189
0
   if(policy.support_cert_status_message())
190
0
      m_extensions.add(new Certificate_Status_Request({}, {}));
191
0
192
0
   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
193
0
194
0
   if(supported_groups->ec_groups().size() > 0)
195
0
      {
196
0
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
197
0
      }
198
0
199
0
   m_extensions.add(supported_groups.release());
200
0
201
0
   if(session.supports_encrypt_then_mac())
202
0
      m_extensions.add(new Encrypt_then_MAC);
203
0
204
0
#if defined(BOTAN_HAS_SRP6)
205
0
   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
213
0
   if(m_version.supports_negotiable_signature_algorithms())
214
0
      m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
215
0
216
0
   if(reneg_info.empty() && !next_protocols.empty())
217
0
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
218
0
219
0
   cb.tls_modify_extensions(m_extensions, CLIENT);
220
0
221
0
   hash.update(io.send(*this));
222
0
   }
223
224
void Client_Hello::update_hello_cookie(const Hello_Verify_Request& hello_verify)
225
0
   {
226
0
   if(!m_version.is_datagram_protocol())
227
0
      throw Invalid_State("Cannot use hello cookie with stream protocol");
228
0
229
0
   m_hello_cookie = hello_verify.cookie();
230
0
   }
231
232
/*
233
* Serialize a Client Hello message
234
*/
235
std::vector<uint8_t> Client_Hello::serialize() const
236
5.71k
   {
237
5.71k
   std::vector<uint8_t> buf;
238
5.71k
239
5.71k
   buf.push_back(m_version.major_version());
240
5.71k
   buf.push_back(m_version.minor_version());
241
5.71k
   buf += m_random;
242
5.71k
243
5.71k
   append_tls_length_value(buf, m_session_id, 1);
244
5.71k
245
5.71k
   if(m_version.is_datagram_protocol())
246
0
      append_tls_length_value(buf, m_hello_cookie, 1);
247
5.71k
248
5.71k
   append_tls_length_value(buf, m_suites, 2);
249
5.71k
   append_tls_length_value(buf, m_comp_methods, 1);
250
5.71k
251
5.71k
   /*
252
5.71k
   * May not want to send extensions at all in some cases. If so,
253
5.71k
   * should include SCSV value (if reneg info is empty, if not we are
254
5.71k
   * renegotiating with a modern server)
255
5.71k
   */
256
5.71k
257
5.71k
   buf += m_extensions.serialize(Connection_Side::CLIENT);
258
5.71k
259
5.71k
   return buf;
260
5.71k
   }
261
262
std::vector<uint8_t> Client_Hello::cookie_input_data() const
263
6.67k
   {
264
6.67k
   std::vector<uint8_t> buf;
265
6.67k
266
6.67k
   buf.push_back(m_version.major_version());
267
6.67k
   buf.push_back(m_version.minor_version());
268
6.67k
   buf += m_random;
269
6.67k
270
6.67k
   append_tls_length_value(buf, m_session_id, 1);
271
6.67k
272
6.67k
   append_tls_length_value(buf, m_suites, 2);
273
6.67k
   append_tls_length_value(buf, m_comp_methods, 1);
274
6.67k
275
6.67k
   // Here we don't serialize the extensions since the client extensions
276
6.67k
   // may contain values we don't know how to serialize back.
277
6.67k
278
6.67k
   return buf;
279
6.67k
   }
280
281
/*
282
* Read a counterparty client hello
283
*/
284
Client_Hello::Client_Hello(const std::vector<uint8_t>& buf)
285
33.3k
   {
286
33.3k
   if(buf.size() < 41)
287
88
      throw Decoding_Error("Client_Hello: Packet corrupted");
288
33.2k
289
33.2k
   TLS_Data_Reader reader("ClientHello", buf);
290
33.2k
291
33.2k
   const uint8_t major_version = reader.get_byte();
292
33.2k
   const uint8_t minor_version = reader.get_byte();
293
33.2k
294
33.2k
   m_version = Protocol_Version(major_version, minor_version);
295
33.2k
296
33.2k
   m_random = reader.get_fixed<uint8_t>(32);
297
33.2k
298
33.2k
   m_session_id = reader.get_range<uint8_t>(1, 0, 32);
299
33.2k
300
33.2k
   if(m_version.is_datagram_protocol())
301
6.99k
      m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
302
33.2k
303
33.2k
   m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
304
33.2k
305
33.2k
   m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
306
33.2k
307
33.2k
   m_extensions.deserialize(reader, Connection_Side::CLIENT);
308
33.2k
309
33.2k
   if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
310
4.60k
      {
311
4.60k
      if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
312
29
         {
313
29
         if(!reneg->renegotiation_info().empty())
314
2
            throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
315
2
                                "Client sent renegotiation SCSV and non-empty extension");
316
4.57k
         }
317
4.57k
      else
318
4.57k
         {
319
4.57k
         // add fake extension
320
4.57k
         m_extensions.add(new Renegotiation_Extension());
321
4.57k
         }
322
4.60k
      }
323
33.2k
   }
324
325
bool Client_Hello::sent_fallback_scsv() const
326
31.4k
   {
327
31.4k
   return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
328
31.4k
   }
329
330
/*
331
* Check if we offered this ciphersuite
332
*/
333
bool Client_Hello::offered_suite(uint16_t ciphersuite) const
334
67.6k
   {
335
584k
   for(size_t i = 0; i != m_suites.size(); ++i)
336
526k
      if(m_suites[i] == ciphersuite)
337
9.15k
         return true;
338
67.6k
   return false;
339
67.6k
   }
340
341
std::vector<Signature_Scheme> Client_Hello::signature_schemes() const
342
467
   {
343
467
   std::vector<Signature_Scheme> schemes;
344
467
345
467
   if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
346
428
      {
347
428
      schemes = sigs->supported_schemes();
348
428
      }
349
467
350
467
   return schemes;
351
467
   }
352
353
std::vector<Group_Params> Client_Hello::supported_ecc_curves() const
354
42.9k
   {
355
42.9k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
356
38.5k
      return groups->ec_groups();
357
4.43k
   return std::vector<Group_Params>();
358
4.43k
   }
359
360
std::vector<Group_Params> Client_Hello::supported_dh_groups() const
361
5.63k
   {
362
5.63k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
363
1.83k
      return groups->dh_groups();
364
3.80k
   return std::vector<Group_Params>();
365
3.80k
   }
366
367
bool Client_Hello::prefers_compressed_ec_points() const
368
17.8k
   {
369
17.8k
   if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
370
752
      {
371
752
      return ecc_formats->prefers_compressed();
372
752
      }
373
17.0k
   return false;
374
17.0k
   }
375
376
std::string Client_Hello::sni_hostname() const
377
88.7k
   {
378
88.7k
   if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
379
20.7k
      return sni->host_name();
380
67.9k
   return "";
381
67.9k
   }
382
383
#if defined(BOTAN_HAS_SRP6)
384
std::string Client_Hello::srp_identifier() const
385
0
   {
386
0
   if(SRP_Identifier* srp = m_extensions.get<SRP_Identifier>())
387
0
      return srp->identifier();
388
0
   return "";
389
0
   }
390
#endif
391
392
bool Client_Hello::secure_renegotiation() const
393
54.9k
   {
394
54.9k
   return m_extensions.has<Renegotiation_Extension>();
395
54.9k
   }
396
397
std::vector<uint8_t> Client_Hello::renegotiation_info() const
398
11.4k
   {
399
11.4k
   if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
400
11.4k
      return reneg->renegotiation_info();
401
0
   return std::vector<uint8_t>();
402
0
   }
403
404
std::vector<Protocol_Version> Client_Hello::supported_versions() const
405
31.4k
   {
406
31.4k
   if(Supported_Versions* versions = m_extensions.get<Supported_Versions>())
407
10
      return versions->versions();
408
31.4k
   return {};
409
31.4k
   }
410
411
bool Client_Hello::supports_session_ticket() const
412
24.4k
   {
413
24.4k
   return m_extensions.has<Session_Ticket>();
414
24.4k
   }
415
416
std::vector<uint8_t> Client_Hello::session_ticket() const
417
24.8k
   {
418
24.8k
   if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
419
1.12k
      return ticket->contents();
420
23.7k
   return std::vector<uint8_t>();
421
23.7k
   }
422
423
bool Client_Hello::supports_alpn() const
424
30.6k
   {
425
30.6k
   return m_extensions.has<Application_Layer_Protocol_Notification>();
426
30.6k
   }
427
428
bool Client_Hello::supports_extended_master_secret() const
429
24.4k
   {
430
24.4k
   return m_extensions.has<Extended_Master_Secret>();
431
24.4k
   }
432
433
bool Client_Hello::supports_cert_status_message() const
434
24.6k
   {
435
24.6k
   return m_extensions.has<Certificate_Status_Request>();
436
24.6k
   }
437
438
bool Client_Hello::supports_encrypt_then_mac() const
439
14.4k
   {
440
14.4k
   return m_extensions.has<Encrypt_then_MAC>();
441
14.4k
   }
442
443
bool Client_Hello::sent_signature_algorithms() const
444
0
   {
445
0
   return m_extensions.has<Signature_Algorithms>();
446
0
   }
447
448
std::vector<std::string> Client_Hello::next_protocols() const
449
5.93k
   {
450
5.93k
   if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
451
5.93k
      return alpn->protocols();
452
0
   return std::vector<std::string>();
453
0
   }
454
455
std::vector<uint16_t> Client_Hello::srtp_profiles() const
456
0
   {
457
0
   if(SRTP_Protection_Profiles* srtp = m_extensions.get<SRTP_Protection_Profiles>())
458
0
      return srtp->profiles();
459
0
   return std::vector<uint16_t>();
460
0
   }
461
462
463
}
464
465
}