Coverage Report

Created: 2020-11-21 08:34

/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
57.3k
   {
36
57.3k
   std::vector<uint8_t> buf(32);
37
57.3k
   rng.randomize(buf.data(), buf.size());
38
39
57.3k
   std::unique_ptr<HashFunction> sha256 = HashFunction::create_or_throw("SHA-256");
40
57.3k
   sha256->update(buf);
41
57.3k
   sha256->final(buf);
42
43
57.3k
   if(policy.include_time_in_hello_random())
44
57.3k
      {
45
57.3k
      const uint32_t time32 = static_cast<uint32_t>(
46
57.3k
         std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
47
48
57.3k
      store_be(time32, buf.data());
49
57.3k
      }
50
51
57.3k
   return buf;
52
57.3k
   }
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
6.01k
   {
95
6.01k
   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
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
6.01k
   m_extensions.add(new Extended_Master_Secret);
104
6.01k
   m_extensions.add(new Session_Ticket());
105
106
6.01k
   if(policy.negotiate_encrypt_then_mac())
107
6.01k
      m_extensions.add(new Encrypt_then_MAC);
108
109
6.01k
   m_extensions.add(new Renegotiation_Extension(reneg_info));
110
111
6.01k
   m_extensions.add(new Supported_Versions(m_version, policy));
112
113
6.01k
   if(client_settings.hostname() != "")
114
6.01k
      m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
115
116
6.01k
   if(policy.support_cert_status_message())
117
6.01k
      m_extensions.add(new Certificate_Status_Request({}, {}));
118
119
6.01k
   if(reneg_info.empty() && !next_protocols.empty())
120
0
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
121
122
6.01k
   if(m_version.supports_negotiable_signature_algorithms())
123
6.01k
      m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
124
125
6.01k
   if(m_version.is_datagram_protocol())
126
0
      m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
127
128
6.01k
#if defined(BOTAN_HAS_SRP6)
129
6.01k
   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
6.01k
   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
138
139
6.01k
   if(supported_groups->ec_groups().size() > 0)
140
6.01k
      {
141
6.01k
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
142
6.01k
      }
143
144
6.01k
   m_extensions.add(supported_groups.release());
145
146
6.01k
   cb.tls_modify_extensions(m_extensions, CLIENT);
147
148
6.01k
   if(policy.send_fallback_scsv(client_settings.protocol_version()))
149
0
      m_suites.push_back(TLS_FALLBACK_SCSV);
150
151
6.01k
   hash.update(io.send(*this));
152
6.01k
   }
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
175
0
   if(!value_exists(m_suites, session.ciphersuite_code()))
176
0
      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
0
   m_extensions.add(new Extended_Master_Secret);
184
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
189
0
   if(policy.support_cert_status_message())
190
0
      m_extensions.add(new Certificate_Status_Request({}, {}));
191
192
0
   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
193
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
199
0
   m_extensions.add(supported_groups.release());
200
201
0
   if(session.supports_encrypt_then_mac())
202
0
      m_extensions.add(new Encrypt_then_MAC);
203
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
216
0
   if(reneg_info.empty() && !next_protocols.empty())
217
0
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
218
219
0
   cb.tls_modify_extensions(m_extensions, CLIENT);
220
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
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
6.01k
   {
237
6.01k
   std::vector<uint8_t> buf;
238
239
6.01k
   buf.push_back(m_version.major_version());
240
6.01k
   buf.push_back(m_version.minor_version());
241
6.01k
   buf += m_random;
242
243
6.01k
   append_tls_length_value(buf, m_session_id, 1);
244
245
6.01k
   if(m_version.is_datagram_protocol())
246
0
      append_tls_length_value(buf, m_hello_cookie, 1);
247
248
6.01k
   append_tls_length_value(buf, m_suites, 2);
249
6.01k
   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
6.01k
   buf += m_extensions.serialize(Connection_Side::CLIENT);
258
259
6.01k
   return buf;
260
6.01k
   }
261
262
std::vector<uint8_t> Client_Hello::cookie_input_data() const
263
6.67k
   {
264
6.67k
   std::vector<uint8_t> buf;
265
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
270
6.67k
   append_tls_length_value(buf, m_session_id, 1);
271
272
6.67k
   append_tls_length_value(buf, m_suites, 2);
273
6.67k
   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
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
34.6k
   {
286
34.6k
   if(buf.size() < 41)
287
85
      throw Decoding_Error("Client_Hello: Packet corrupted");
288
289
34.5k
   TLS_Data_Reader reader("ClientHello", buf);
290
291
34.5k
   const uint8_t major_version = reader.get_byte();
292
34.5k
   const uint8_t minor_version = reader.get_byte();
293
294
34.5k
   m_version = Protocol_Version(major_version, minor_version);
295
296
34.5k
   m_random = reader.get_fixed<uint8_t>(32);
297
298
34.5k
   m_session_id = reader.get_range<uint8_t>(1, 0, 32);
299
300
34.5k
   if(m_version.is_datagram_protocol())
301
6.96k
      m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
302
303
34.5k
   m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
304
305
34.5k
   m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
306
307
34.5k
   m_extensions.deserialize(reader, Connection_Side::CLIENT);
308
309
34.5k
   if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
310
5.83k
      {
311
5.83k
      if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
312
45
         {
313
45
         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.79k
         }
317
5.79k
      else
318
5.79k
         {
319
         // add fake extension
320
5.79k
         m_extensions.add(new Renegotiation_Extension());
321
5.79k
         }
322
5.83k
      }
323
34.5k
   }
324
325
bool Client_Hello::sent_fallback_scsv() const
326
32.6k
   {
327
32.6k
   return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
328
32.6k
   }
329
330
/*
331
* Check if we offered this ciphersuite
332
*/
333
bool Client_Hello::offered_suite(uint16_t ciphersuite) const
334
70.2k
   {
335
601k
   for(size_t i = 0; i != m_suites.size(); ++i)
336
541k
      if(m_suites[i] == ciphersuite)
337
10.6k
         return true;
338
59.6k
   return false;
339
70.2k
   }
340
341
std::vector<Signature_Scheme> Client_Hello::signature_schemes() const
342
356
   {
343
356
   std::vector<Signature_Scheme> schemes;
344
345
356
   if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
346
319
      {
347
319
      schemes = sigs->supported_schemes();
348
319
      }
349
350
356
   return schemes;
351
356
   }
352
353
std::vector<Group_Params> Client_Hello::supported_ecc_curves() const
354
44.4k
   {
355
44.4k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
356
39.4k
      return groups->ec_groups();
357
5.00k
   return std::vector<Group_Params>();
358
5.00k
   }
359
360
std::vector<Group_Params> Client_Hello::supported_dh_groups() const
361
6.30k
   {
362
6.30k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
363
2.16k
      return groups->dh_groups();
364
4.13k
   return std::vector<Group_Params>();
365
4.13k
   }
366
367
bool Client_Hello::prefers_compressed_ec_points() const
368
18.0k
   {
369
18.0k
   if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
370
867
      {
371
867
      return ecc_formats->prefers_compressed();
372
867
      }
373
17.1k
   return false;
374
17.1k
   }
375
376
std::string Client_Hello::sni_hostname() const
377
92.3k
   {
378
92.3k
   if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
379
23.4k
      return sni->host_name();
380
68.9k
   return "";
381
68.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
57.6k
   {
394
57.6k
   return m_extensions.has<Renegotiation_Extension>();
395
57.6k
   }
396
397
std::vector<uint8_t> Client_Hello::renegotiation_info() const
398
12.8k
   {
399
12.8k
   if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
400
12.8k
      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.6k
   {
406
32.6k
   if(Supported_Versions* versions = m_extensions.get<Supported_Versions>())
407
11
      return versions->versions();
408
32.6k
   return {};
409
32.6k
   }
410
411
bool Client_Hello::supports_session_ticket() const
412
25.6k
   {
413
25.6k
   return m_extensions.has<Session_Ticket>();
414
25.6k
   }
415
416
std::vector<uint8_t> Client_Hello::session_ticket() const
417
26.0k
   {
418
26.0k
   if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
419
1.75k
      return ticket->contents();
420
24.2k
   return std::vector<uint8_t>();
421
24.2k
   }
422
423
bool Client_Hello::supports_alpn() const
424
33.5k
   {
425
33.5k
   return m_extensions.has<Application_Layer_Protocol_Notification>();
426
33.5k
   }
427
428
bool Client_Hello::supports_extended_master_secret() const
429
25.6k
   {
430
25.6k
   return m_extensions.has<Extended_Master_Secret>();
431
25.6k
   }
432
433
bool Client_Hello::supports_cert_status_message() const
434
25.8k
   {
435
25.8k
   return m_extensions.has<Certificate_Status_Request>();
436
25.8k
   }
437
438
bool Client_Hello::supports_encrypt_then_mac() const
439
17.1k
   {
440
17.1k
   return m_extensions.has<Encrypt_then_MAC>();
441
17.1k
   }
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.65k
   {
450
7.65k
   if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
451
7.65k
      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
}