Coverage Report

Created: 2022-06-23 06:44

/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
*     2021 Elektrobit Automotive GmbH
7
*     2022 René Meusel, Hannes Rantzsch - neXenio GmbH
8
*
9
* Botan is released under the Simplified BSD License (see license.txt)
10
*/
11
12
13
#include <botan/tls_exceptn.h>
14
#include <botan/tls_messages.h>
15
#include <botan/tls_callbacks.h>
16
#include <botan/rng.h>
17
#include <botan/hash.h>
18
#include <botan/tls_version.h>
19
20
#include <botan/internal/stl_util.h>
21
#include <botan/internal/tls_reader.h>
22
#include <botan/internal/tls_session_key.h>
23
#include <botan/internal/tls_handshake_io.h>
24
#include <botan/internal/tls_handshake_hash.h>
25
26
#include <chrono>
27
28
namespace Botan::TLS {
29
30
enum
31
   {
32
   TLS_EMPTY_RENEGOTIATION_INFO_SCSV        = 0x00FF,
33
   };
34
35
std::vector<uint8_t> make_hello_random(RandomNumberGenerator& rng,
36
                                       Callbacks& cb,
37
                                       const Policy& policy)
38
41.0k
   {
39
41.0k
   std::vector<uint8_t> buf(32);
40
41.0k
   rng.randomize(buf.data(), buf.size());
41
42
41.0k
   if(policy.hash_hello_random())
43
41.0k
      {
44
41.0k
      auto sha256 = HashFunction::create_or_throw("SHA-256");
45
41.0k
      sha256->update(buf);
46
41.0k
      sha256->final(buf);
47
41.0k
      }
48
49
41.0k
   if(policy.include_time_in_hello_random())
50
41.0k
      {
51
41.0k
      const uint32_t time32 = static_cast<uint32_t>(
52
41.0k
                                 std::chrono::system_clock::to_time_t(cb.tls_current_timestamp()));
53
54
41.0k
      store_be(time32, buf.data());
55
41.0k
      }
56
57
41.0k
   return buf;
58
41.0k
   }
59
60
/*
61
* Read a counterparty client hello
62
*/
63
Client_Hello::Client_Hello(const std::vector<uint8_t>& buf)
64
22.8k
   {
65
22.8k
   if(buf.size() < 41)
66
38
      { throw Decoding_Error("Client_Hello: Packet corrupted"); }
67
68
22.7k
   TLS_Data_Reader reader("ClientHello", buf);
69
70
22.7k
   const uint8_t major_version = reader.get_byte();
71
22.7k
   const uint8_t minor_version = reader.get_byte();
72
73
22.7k
   m_legacy_version = Protocol_Version(major_version, minor_version);
74
22.7k
   m_random = reader.get_fixed<uint8_t>(32);
75
22.7k
   m_session_id = reader.get_range<uint8_t>(1, 0, 32);
76
77
22.7k
   if(m_legacy_version.is_datagram_protocol())
78
1.36k
      {
79
1.36k
      auto sha256 = HashFunction::create_or_throw("SHA-256");
80
1.36k
      sha256->update(reader.get_data_read_so_far());
81
82
1.36k
      m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
83
84
1.36k
      sha256->update(reader.get_remaining());
85
1.36k
      m_cookie_input_bits.resize(sha256->output_length());
86
1.36k
      sha256->final(m_cookie_input_bits.data());
87
1.36k
      }
88
89
22.7k
   m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
90
91
22.7k
   m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
92
93
22.7k
   m_extensions.deserialize(reader, Connection_Side::CLIENT, type());
94
95
22.7k
   if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
96
11.3k
      {
97
11.3k
      if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
98
93
         {
99
93
         if(!reneg->renegotiation_info().empty())
100
5
            throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
101
5
                                "Client sent renegotiation SCSV and non-empty extension");
102
93
         }
103
11.2k
      else
104
11.2k
         {
105
         // add fake extension
106
11.2k
         m_extensions.add(new Renegotiation_Extension());
107
11.2k
         }
108
11.3k
      }
109
22.7k
   }
110
111
Handshake_Type Client_Hello::type() const
112
25.3k
   {
113
25.3k
   return CLIENT_HELLO;
114
25.3k
   }
115
116
Protocol_Version Client_Hello::legacy_version() const
117
21.1k
   {
118
21.1k
   return m_legacy_version;
119
21.1k
   }
120
121
const std::vector<uint8_t>& Client_Hello::random() const
122
26.2k
   {
123
26.2k
   return m_random;
124
26.2k
   }
125
126
const std::vector<uint8_t>& Client_Hello::session_id() const
127
19.9k
   {
128
19.9k
   return m_session_id;
129
19.9k
   }
130
131
const std::vector<uint8_t>& Client_Hello::compression_methods() const
132
21.1k
   {
133
21.1k
   return m_comp_methods;
134
21.1k
   }
135
136
const std::vector<uint16_t>& Client_Hello::ciphersuites() const
137
19.9k
   {
138
19.9k
   return m_suites;
139
19.9k
   }
140
141
std::set<Handshake_Extension_Type> Client_Hello::extension_types() const
142
19.0k
   {
143
19.0k
   return m_extensions.extension_types();
144
19.0k
   }
145
146
const Extensions& Client_Hello::extensions() const
147
19.9k
   {
148
19.9k
   return m_extensions;
149
19.9k
   }
150
151
void Client_Hello_12::update_hello_cookie(const Hello_Verify_Request& hello_verify)
152
0
   {
153
0
   if(!m_legacy_version.is_datagram_protocol())
154
0
      { throw Invalid_State("Cannot use hello cookie with stream protocol"); }
155
156
0
   m_hello_cookie = hello_verify.cookie();
157
0
   }
158
159
/*
160
* Serialize a Client Hello message
161
*/
162
std::vector<uint8_t> Client_Hello::serialize() const
163
1.42k
   {
164
1.42k
   std::vector<uint8_t> buf;
165
166
1.42k
   buf.push_back(m_legacy_version.major_version());
167
1.42k
   buf.push_back(m_legacy_version.minor_version());
168
1.42k
   buf += m_random;
169
170
1.42k
   append_tls_length_value(buf, m_session_id, 1);
171
172
1.42k
   if(m_legacy_version.is_datagram_protocol())
173
0
      { append_tls_length_value(buf, m_hello_cookie, 1); }
174
175
1.42k
   append_tls_length_value(buf, m_suites, 2);
176
1.42k
   append_tls_length_value(buf, m_comp_methods, 1);
177
178
   /*
179
   * May not want to send extensions at all in some cases. If so,
180
   * should include SCSV value (if reneg info is empty, if not we are
181
   * renegotiating with a modern server)
182
   */
183
184
1.42k
   buf += m_extensions.serialize(Connection_Side::CLIENT);
185
186
1.42k
   return buf;
187
1.42k
   }
188
189
std::vector<uint8_t> Client_Hello::cookie_input_data() const
190
1.17k
   {
191
1.17k
   if(m_cookie_input_bits.empty())
192
0
      { throw Invalid_State("Client_Hello::cookie_input_data called but was not computed"); }
193
194
1.17k
   return m_cookie_input_bits;
195
1.17k
   }
196
197
/*
198
* Check if we offered this ciphersuite
199
*/
200
bool Client_Hello::offered_suite(uint16_t ciphersuite) const
201
21.4k
   {
202
21.4k
   return std::find(m_suites.cbegin(), m_suites.cend(), ciphersuite) != m_suites.cend();
203
21.4k
   }
204
205
std::vector<Signature_Scheme> Client_Hello::signature_schemes() const
206
92
   {
207
92
   std::vector<Signature_Scheme> schemes;
208
209
92
   if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
210
69
      {
211
69
      schemes = sigs->supported_schemes();
212
69
      }
213
214
92
   return schemes;
215
92
   }
216
217
std::vector<Group_Params> Client_Hello::supported_ecc_curves() const
218
39.0k
   {
219
39.0k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
220
38.3k
      { return groups->ec_groups(); }
221
647
   return std::vector<Group_Params>();
222
39.0k
   }
223
224
std::vector<Group_Params> Client_Hello::supported_dh_groups() const
225
0
   {
226
0
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
227
0
      { return groups->dh_groups(); }
228
0
   return std::vector<Group_Params>();
229
0
   }
230
231
bool Client_Hello_12::prefers_compressed_ec_points() const
232
18.2k
   {
233
18.2k
   if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
234
3.50k
      {
235
3.50k
      return ecc_formats->prefers_compressed();
236
3.50k
      }
237
14.7k
   return false;
238
18.2k
   }
239
240
std::string Client_Hello::sni_hostname() const
241
54.0k
   {
242
54.0k
   if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
243
6.43k
      { return sni->host_name(); }
244
47.6k
   return "";
245
54.0k
   }
246
247
bool Client_Hello_12::secure_renegotiation() const
248
41.1k
   {
249
41.1k
   return m_extensions.has<Renegotiation_Extension>();
250
41.1k
   }
251
252
std::vector<uint8_t> Client_Hello_12::renegotiation_info() const
253
12.5k
   {
254
12.5k
   if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
255
12.5k
      { return reneg->renegotiation_info(); }
256
0
   return std::vector<uint8_t>();
257
12.5k
   }
258
259
std::vector<Protocol_Version> Client_Hello::supported_versions() const
260
21.1k
   {
261
21.1k
   if(Supported_Versions* versions = m_extensions.get<Supported_Versions>())
262
20
      { return versions->versions(); }
263
21.1k
   return {};
264
21.1k
   }
265
266
bool Client_Hello_12::supports_session_ticket() const
267
19.7k
   {
268
19.7k
   return m_extensions.has<Session_Ticket>();
269
19.7k
   }
270
271
std::vector<uint8_t> Client_Hello_12::session_ticket() const
272
19.9k
   {
273
19.9k
   if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
274
6.68k
      { return ticket->contents(); }
275
13.2k
   return std::vector<uint8_t>();
276
19.9k
   }
277
278
bool Client_Hello::supports_alpn() const
279
23.3k
   {
280
23.3k
   return m_extensions.has<Application_Layer_Protocol_Notification>();
281
23.3k
   }
282
283
bool Client_Hello_12::supports_extended_master_secret() const
284
19.7k
   {
285
19.7k
   return m_extensions.has<Extended_Master_Secret>();
286
19.7k
   }
287
288
bool Client_Hello_12::supports_cert_status_message() const
289
19.8k
   {
290
19.8k
   return m_extensions.has<Certificate_Status_Request>();
291
19.8k
   }
292
293
bool Client_Hello_12::supports_encrypt_then_mac() const
294
15.3k
   {
295
15.3k
   return m_extensions.has<Encrypt_then_MAC>();
296
15.3k
   }
297
298
bool Client_Hello::sent_signature_algorithms() const
299
0
   {
300
0
   return m_extensions.has<Signature_Algorithms>();
301
0
   }
302
303
std::vector<std::string> Client_Hello::next_protocols() const
304
3.42k
   {
305
3.42k
   if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
306
3.42k
      { return alpn->protocols(); }
307
0
   return std::vector<std::string>();
308
3.42k
   }
309
310
std::vector<uint16_t> Client_Hello::srtp_profiles() const
311
0
   {
312
0
   if(SRTP_Protection_Profiles* srtp = m_extensions.get<SRTP_Protection_Profiles>())
313
0
      { return srtp->profiles(); }
314
0
   return std::vector<uint16_t>();
315
0
   }
316
317
const std::vector<uint8_t>& Client_Hello::cookie() const
318
1.17k
   {
319
1.17k
   return m_hello_cookie;
320
1.17k
   }
321
/*
322
* Create a new Hello Request message
323
*/
324
Hello_Request::Hello_Request(Handshake_IO& io)
325
0
   {
326
0
   io.send(*this);
327
0
   }
328
329
/*
330
* Deserialize a Hello Request message
331
*/
332
Hello_Request::Hello_Request(const std::vector<uint8_t>& buf)
333
0
   {
334
0
   if(!buf.empty())
335
0
      { throw Decoding_Error("Bad Hello_Request, has non-zero size"); }
336
0
   }
337
338
/*
339
* Serialize a Hello Request message
340
*/
341
std::vector<uint8_t> Hello_Request::serialize() const
342
0
   {
343
0
   return std::vector<uint8_t>();
344
0
   }
345
346
/*
347
* Create a new Client Hello message
348
*/
349
Client_Hello_12::Client_Hello_12(Handshake_IO& io,
350
                                 Handshake_Hash& hash,
351
                                 const Policy& policy,
352
                                 Callbacks& cb,
353
                                 RandomNumberGenerator& rng,
354
                                 const std::vector<uint8_t>& reneg_info,
355
                                 const Client_Hello_12::Settings& client_settings,
356
                                 const std::vector<std::string>& next_protocols)
357
1.42k
   {
358
1.42k
   m_legacy_version = client_settings.protocol_version();
359
1.42k
   m_random = make_hello_random(rng, cb, policy);
360
1.42k
   m_suites = policy.ciphersuite_list(client_settings.protocol_version());
361
362
1.42k
   if(!policy.acceptable_protocol_version(m_legacy_version))
363
0
      throw Internal_Error("Offering " + m_legacy_version.to_string() +
364
0
                           " but our own policy does not accept it");
365
366
   /*
367
   * Place all empty extensions in front to avoid a bug in some systems
368
   * which reject hellos when the last extension in the list is empty.
369
   */
370
371
   // EMS must always be used with TLS 1.2, regardless of the policy used.
372
1.42k
   m_extensions.add(new Extended_Master_Secret);
373
374
1.42k
   if(policy.negotiate_encrypt_then_mac())
375
1.42k
      { m_extensions.add(new Encrypt_then_MAC); }
376
377
1.42k
   m_extensions.add(new Session_Ticket());
378
379
1.42k
   m_extensions.add(new Renegotiation_Extension(reneg_info));
380
381
1.42k
   m_extensions.add(new Supported_Versions(m_legacy_version, policy));
382
383
1.42k
   if(!client_settings.hostname().empty())
384
1.42k
      { m_extensions.add(new Server_Name_Indicator(client_settings.hostname())); }
385
386
1.42k
   if(policy.support_cert_status_message())
387
1.42k
      m_extensions.add(new Certificate_Status_Request({}, {}));
388
389
1.42k
   auto supported_groups = std::make_unique<Supported_Groups>(policy.key_exchange_groups());
390
1.42k
   if(!supported_groups->ec_groups().empty())
391
1.42k
      {
392
1.42k
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
393
1.42k
      }
394
1.42k
   m_extensions.add(supported_groups.release());
395
396
1.42k
   m_extensions.add(new Signature_Algorithms(policy.acceptable_signature_schemes()));
397
398
1.42k
   if(reneg_info.empty() && !next_protocols.empty())
399
0
      { m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); }
400
401
1.42k
   if(m_legacy_version.is_datagram_protocol())
402
0
      { m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles())); }
403
404
1.42k
   cb.tls_modify_extensions(m_extensions, CLIENT);
405
406
1.42k
   hash.update(io.send(*this));
407
1.42k
   }
408
409
/*
410
* Create a new Client Hello message (session resumption case)
411
*/
412
Client_Hello_12::Client_Hello_12(Handshake_IO& io,
413
                                 Handshake_Hash& hash,
414
                                 const Policy& policy,
415
                                 Callbacks& cb,
416
                                 RandomNumberGenerator& rng,
417
                                 const std::vector<uint8_t>& reneg_info,
418
                                 const Session& session,
419
                                 const std::vector<std::string>& next_protocols)
420
0
   {
421
0
   m_legacy_version = session.version();
422
0
   m_random = make_hello_random(rng, cb, policy);
423
0
   m_session_id = session.session_id();
424
0
   m_suites = policy.ciphersuite_list(m_legacy_version);
425
426
0
   if(!policy.acceptable_protocol_version(session.version()))
427
0
      throw Internal_Error("Offering " + m_legacy_version.to_string() +
428
0
                           " but our own policy does not accept it");
429
430
0
   if(!value_exists(m_suites, session.ciphersuite_code()))
431
0
      { m_suites.push_back(session.ciphersuite_code()); }
432
433
   /*
434
   * As EMS must always be used with TLS 1.2, add it even if it wasn't used
435
   * in the original session. If the server understands it and follows the
436
   * RFC it should reject our resume attempt and upgrade us to a new session
437
   * with the EMS protection.
438
   */
439
0
   m_extensions.add(new Extended_Master_Secret);
440
441
0
   if(session.supports_encrypt_then_mac())
442
0
      { m_extensions.add(new Encrypt_then_MAC); }
443
444
0
   m_extensions.add(new Session_Ticket(session.session_ticket()));
445
446
0
   m_extensions.add(new Renegotiation_Extension(reneg_info));
447
448
0
   m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
449
450
0
   if(policy.support_cert_status_message())
451
0
      m_extensions.add(new Certificate_Status_Request({}, {}));
452
453
0
   auto supported_groups = std::make_unique<Supported_Groups>(policy.key_exchange_groups());
454
455
0
   if(!supported_groups->ec_groups().empty())
456
0
      {
457
0
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
458
0
      }
459
460
0
   m_extensions.add(supported_groups.release());
461
462
0
   m_extensions.add(new Signature_Algorithms(policy.acceptable_signature_schemes()));
463
464
0
   if(reneg_info.empty() && !next_protocols.empty())
465
0
      { m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols)); }
466
467
0
   cb.tls_modify_extensions(m_extensions, CLIENT);
468
469
0
   hash.update(io.send(*this));
470
0
   }
471
472
473
}