Coverage Report

Created: 2020-10-17 06:46

/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
56.8k
   {
36
56.8k
   std::vector<uint8_t> buf(32);
37
56.8k
   rng.randomize(buf.data(), buf.size());
38
56.8k
39
56.8k
   std::unique_ptr<HashFunction> sha256 = HashFunction::create_or_throw("SHA-256");
40
56.8k
   sha256->update(buf);
41
56.8k
   sha256->final(buf);
42
56.8k
43
56.8k
   if(policy.include_time_in_hello_random())
44
56.8k
      {
45
56.8k
      const uint32_t time32 = static_cast<uint32_t>(
46
56.8k
         std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
47
56.8k
48
56.8k
      store_be(time32, buf.data());
49
56.8k
      }
50
56.8k
51
56.8k
   return buf;
52
56.8k
   }
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.92k
   {
95
5.92k
   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.92k
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
5.92k
   m_extensions.add(new Extended_Master_Secret);
104
5.92k
   m_extensions.add(new Session_Ticket());
105
5.92k
106
5.92k
   if(policy.negotiate_encrypt_then_mac())
107
5.92k
      m_extensions.add(new Encrypt_then_MAC);
108
5.92k
109
5.92k
   m_extensions.add(new Renegotiation_Extension(reneg_info));
110
5.92k
111
5.92k
   m_extensions.add(new Supported_Versions(m_version, policy));
112
5.92k
113
5.92k
   if(client_settings.hostname() != "")
114
5.92k
      m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
115
5.92k
116
5.92k
   if(policy.support_cert_status_message())
117
5.92k
      m_extensions.add(new Certificate_Status_Request({}, {}));
118
5.92k
119
5.92k
   if(reneg_info.empty() && !next_protocols.empty())
120
0
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
121
5.92k
122
5.92k
   if(m_version.supports_negotiable_signature_algorithms())
123
5.92k
      m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
124
5.92k
125
5.92k
   if(m_version.is_datagram_protocol())
126
0
      m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
127
5.92k
128
5.92k
#if defined(BOTAN_HAS_SRP6)
129
5.92k
   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
5.92k
137
5.92k
   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
138
5.92k
139
5.92k
   if(supported_groups->ec_groups().size() > 0)
140
5.92k
      {
141
5.92k
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
142
5.92k
      }
143
5.92k
144
5.92k
   m_extensions.add(supported_groups.release());
145
5.92k
146
5.92k
   cb.tls_modify_extensions(m_extensions, CLIENT);
147
5.92k
148
5.92k
   if(policy.send_fallback_scsv(client_settings.protocol_version()))
149
0
      m_suites.push_back(TLS_FALLBACK_SCSV);
150
5.92k
151
5.92k
   hash.update(io.send(*this));
152
5.92k
   }
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
   /*
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
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
0
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.92k
   {
237
5.92k
   std::vector<uint8_t> buf;
238
5.92k
239
5.92k
   buf.push_back(m_version.major_version());
240
5.92k
   buf.push_back(m_version.minor_version());
241
5.92k
   buf += m_random;
242
5.92k
243
5.92k
   append_tls_length_value(buf, m_session_id, 1);
244
5.92k
245
5.92k
   if(m_version.is_datagram_protocol())
246
0
      append_tls_length_value(buf, m_hello_cookie, 1);
247
5.92k
248
5.92k
   append_tls_length_value(buf, m_suites, 2);
249
5.92k
   append_tls_length_value(buf, m_comp_methods, 1);
250
5.92k
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
5.92k
257
5.92k
   buf += m_extensions.serialize(Connection_Side::CLIENT);
258
5.92k
259
5.92k
   return buf;
260
5.92k
   }
261
262
std::vector<uint8_t> Client_Hello::cookie_input_data() const
263
6.66k
   {
264
6.66k
   std::vector<uint8_t> buf;
265
6.66k
266
6.66k
   buf.push_back(m_version.major_version());
267
6.66k
   buf.push_back(m_version.minor_version());
268
6.66k
   buf += m_random;
269
6.66k
270
6.66k
   append_tls_length_value(buf, m_session_id, 1);
271
6.66k
272
6.66k
   append_tls_length_value(buf, m_suites, 2);
273
6.66k
   append_tls_length_value(buf, m_comp_methods, 1);
274
6.66k
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
6.66k
278
6.66k
   return buf;
279
6.66k
   }
280
281
/*
282
* Read a counterparty client hello
283
*/
284
Client_Hello::Client_Hello(const std::vector<uint8_t>& buf)
285
34.3k
   {
286
34.3k
   if(buf.size() < 41)
287
91
      throw Decoding_Error("Client_Hello: Packet corrupted");
288
34.3k
289
34.3k
   TLS_Data_Reader reader("ClientHello", buf);
290
34.3k
291
34.3k
   const uint8_t major_version = reader.get_byte();
292
34.3k
   const uint8_t minor_version = reader.get_byte();
293
34.3k
294
34.3k
   m_version = Protocol_Version(major_version, minor_version);
295
34.3k
296
34.3k
   m_random = reader.get_fixed<uint8_t>(32);
297
34.3k
298
34.3k
   m_session_id = reader.get_range<uint8_t>(1, 0, 32);
299
34.3k
300
34.3k
   if(m_version.is_datagram_protocol())
301
6.99k
      m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
302
34.3k
303
34.3k
   m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
304
34.3k
305
34.3k
   m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
306
34.3k
307
34.3k
   m_extensions.deserialize(reader, Connection_Side::CLIENT);
308
34.3k
309
34.3k
   if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
310
5.93k
      {
311
5.93k
      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
5.90k
         }
317
5.90k
      else
318
5.90k
         {
319
         // add fake extension
320
5.90k
         m_extensions.add(new Renegotiation_Extension());
321
5.90k
         }
322
5.93k
      }
323
34.3k
   }
324
325
bool Client_Hello::sent_fallback_scsv() const
326
32.4k
   {
327
32.4k
   return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
328
32.4k
   }
329
330
/*
331
* Check if we offered this ciphersuite
332
*/
333
bool Client_Hello::offered_suite(uint16_t ciphersuite) const
334
69.7k
   {
335
594k
   for(size_t i = 0; i != m_suites.size(); ++i)
336
535k
      if(m_suites[i] == ciphersuite)
337
10.6k
         return true;
338
59.1k
   return false;
339
69.7k
   }
340
341
std::vector<Signature_Scheme> Client_Hello::signature_schemes() const
342
353
   {
343
353
   std::vector<Signature_Scheme> schemes;
344
353
345
353
   if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
346
312
      {
347
312
      schemes = sigs->supported_schemes();
348
312
      }
349
353
350
353
   return schemes;
351
353
   }
352
353
std::vector<Group_Params> Client_Hello::supported_ecc_curves() const
354
44.5k
   {
355
44.5k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
356
39.8k
      return groups->ec_groups();
357
4.70k
   return std::vector<Group_Params>();
358
4.70k
   }
359
360
std::vector<Group_Params> Client_Hello::supported_dh_groups() const
361
5.95k
   {
362
5.95k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
363
2.01k
      return groups->dh_groups();
364
3.93k
   return std::vector<Group_Params>();
365
3.93k
   }
366
367
bool Client_Hello::prefers_compressed_ec_points() const
368
18.2k
   {
369
18.2k
   if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
370
869
      {
371
869
      return ecc_formats->prefers_compressed();
372
869
      }
373
17.3k
   return false;
374
17.3k
   }
375
376
std::string Client_Hello::sni_hostname() const
377
91.5k
   {
378
91.5k
   if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
379
22.9k
      return sni->host_name();
380
68.5k
   return "";
381
68.5k
   }
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
57.1k
   {
394
57.1k
   return m_extensions.has<Renegotiation_Extension>();
395
57.1k
   }
396
397
std::vector<uint8_t> Client_Hello::renegotiation_info() const
398
13.2k
   {
399
13.2k
   if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
400
13.2k
      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
32.4k
   {
406
32.4k
   if(Supported_Versions* versions = m_extensions.get<Supported_Versions>())
407
12
      return versions->versions();
408
32.4k
   return {};
409
32.4k
   }
410
411
bool Client_Hello::supports_session_ticket() const
412
25.4k
   {
413
25.4k
   return m_extensions.has<Session_Ticket>();
414
25.4k
   }
415
416
std::vector<uint8_t> Client_Hello::session_ticket() const
417
25.8k
   {
418
25.8k
   if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
419
1.38k
      return ticket->contents();
420
24.4k
   return std::vector<uint8_t>();
421
24.4k
   }
422
423
bool Client_Hello::supports_alpn() const
424
33.1k
   {
425
33.1k
   return m_extensions.has<Application_Layer_Protocol_Notification>();
426
33.1k
   }
427
428
bool Client_Hello::supports_extended_master_secret() const
429
25.4k
   {
430
25.4k
   return m_extensions.has<Extended_Master_Secret>();
431
25.4k
   }
432
433
bool Client_Hello::supports_cert_status_message() const
434
25.6k
   {
435
25.6k
   return m_extensions.has<Certificate_Status_Request>();
436
25.6k
   }
437
438
bool Client_Hello::supports_encrypt_then_mac() const
439
16.3k
   {
440
16.3k
   return m_extensions.has<Encrypt_then_MAC>();
441
16.3k
   }
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
7.40k
   {
450
7.40k
   if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
451
7.40k
      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
}