Coverage Report

Created: 2022-05-14 06:06

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