Coverage Report

Created: 2021-02-21 07:20

/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
49.5k
   {
36
49.5k
   std::vector<uint8_t> buf(32);
37
49.5k
   rng.randomize(buf.data(), buf.size());
38
39
49.5k
   std::unique_ptr<HashFunction> sha256 = HashFunction::create_or_throw("SHA-256");
40
49.5k
   sha256->update(buf);
41
49.5k
   sha256->final(buf);
42
43
49.5k
   if(policy.include_time_in_hello_random())
44
49.5k
      {
45
49.5k
      const uint32_t time32 = static_cast<uint32_t>(
46
49.5k
         std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
47
48
49.5k
      store_be(time32, buf.data());
49
49.5k
      }
50
51
49.5k
   return buf;
52
49.5k
   }
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)),
93
   m_comp_methods(1)
94
6.31k
   {
95
6.31k
   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.31k
   m_extensions.add(new Extended_Master_Secret);
104
6.31k
   m_extensions.add(new Session_Ticket());
105
106
6.31k
   if(policy.negotiate_encrypt_then_mac())
107
6.31k
      m_extensions.add(new Encrypt_then_MAC);
108
109
6.31k
   m_extensions.add(new Renegotiation_Extension(reneg_info));
110
111
6.31k
   m_extensions.add(new Supported_Versions(m_version, policy));
112
113
6.31k
   if(client_settings.hostname() != "")
114
6.31k
      m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
115
116
6.31k
   if(policy.support_cert_status_message())
117
6.31k
      m_extensions.add(new Certificate_Status_Request({}, {}));
118
119
6.31k
   if(reneg_info.empty() && !next_protocols.empty())
120
0
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
121
122
6.31k
   if(m_version.supports_negotiable_signature_algorithms())
123
6.31k
      m_extensions.add(new Signature_Algorithms(policy.acceptable_signature_schemes()));
124
125
6.31k
   if(m_version.is_datagram_protocol())
126
0
      m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
127
128
6.31k
   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
129
130
6.31k
   if(supported_groups->ec_groups().size() > 0)
131
6.31k
      {
132
6.31k
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
133
6.31k
      }
134
135
6.31k
   m_extensions.add(supported_groups.release());
136
137
6.31k
   cb.tls_modify_extensions(m_extensions, CLIENT);
138
139
6.31k
   if(policy.send_fallback_scsv(client_settings.protocol_version()))
140
0
      m_suites.push_back(TLS_FALLBACK_SCSV);
141
142
6.31k
   hash.update(io.send(*this));
143
6.31k
   }
144
145
/*
146
* Create a new Client Hello message (session resumption case)
147
*/
148
Client_Hello::Client_Hello(Handshake_IO& io,
149
                           Handshake_Hash& hash,
150
                           const Policy& policy,
151
                           Callbacks& cb,
152
                           RandomNumberGenerator& rng,
153
                           const std::vector<uint8_t>& reneg_info,
154
                           const Session& session,
155
                           const std::vector<std::string>& next_protocols) :
156
   m_version(session.version()),
157
   m_session_id(session.session_id()),
158
   m_random(make_hello_random(rng, policy)),
159
   m_suites(policy.ciphersuite_list(m_version)),
160
   m_comp_methods(1)
161
0
   {
162
0
   if(!policy.acceptable_protocol_version(m_version))
163
0
      throw Internal_Error("Offering " + m_version.to_string() +
164
0
                           " but our own policy does not accept it");
165
166
0
   if(!value_exists(m_suites, session.ciphersuite_code()))
167
0
      m_suites.push_back(session.ciphersuite_code());
168
169
   /*
170
   We always add the EMS extension, even if not used in the original session.
171
   If the server understands it and follows the RFC it should reject our resume
172
   attempt and upgrade us to a new session with the EMS protection.
173
   */
174
0
   m_extensions.add(new Extended_Master_Secret);
175
176
0
   m_extensions.add(new Renegotiation_Extension(reneg_info));
177
0
   m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
178
0
   m_extensions.add(new Session_Ticket(session.session_ticket()));
179
180
0
   if(policy.support_cert_status_message())
181
0
      m_extensions.add(new Certificate_Status_Request({}, {}));
182
183
0
   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
184
185
0
   if(supported_groups->ec_groups().size() > 0)
186
0
      {
187
0
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
188
0
      }
189
190
0
   m_extensions.add(supported_groups.release());
191
192
0
   if(session.supports_encrypt_then_mac())
193
0
      m_extensions.add(new Encrypt_then_MAC);
194
195
0
   if(m_version.supports_negotiable_signature_algorithms())
196
0
      m_extensions.add(new Signature_Algorithms(policy.acceptable_signature_schemes()));
197
198
0
   if(reneg_info.empty() && !next_protocols.empty())
199
0
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
200
201
0
   cb.tls_modify_extensions(m_extensions, CLIENT);
202
203
0
   hash.update(io.send(*this));
204
0
   }
205
206
void Client_Hello::update_hello_cookie(const Hello_Verify_Request& hello_verify)
207
0
   {
208
0
   if(!m_version.is_datagram_protocol())
209
0
      throw Invalid_State("Cannot use hello cookie with stream protocol");
210
211
0
   m_hello_cookie = hello_verify.cookie();
212
0
   }
213
214
/*
215
* Serialize a Client Hello message
216
*/
217
std::vector<uint8_t> Client_Hello::serialize() const
218
6.31k
   {
219
6.31k
   std::vector<uint8_t> buf;
220
221
6.31k
   buf.push_back(m_version.major_version());
222
6.31k
   buf.push_back(m_version.minor_version());
223
6.31k
   buf += m_random;
224
225
6.31k
   append_tls_length_value(buf, m_session_id, 1);
226
227
6.31k
   if(m_version.is_datagram_protocol())
228
0
      append_tls_length_value(buf, m_hello_cookie, 1);
229
230
6.31k
   append_tls_length_value(buf, m_suites, 2);
231
6.31k
   append_tls_length_value(buf, m_comp_methods, 1);
232
233
   /*
234
   * May not want to send extensions at all in some cases. If so,
235
   * should include SCSV value (if reneg info is empty, if not we are
236
   * renegotiating with a modern server)
237
   */
238
239
6.31k
   buf += m_extensions.serialize(Connection_Side::CLIENT);
240
241
6.31k
   return buf;
242
6.31k
   }
243
244
std::vector<uint8_t> Client_Hello::cookie_input_data() const
245
8.34k
   {
246
8.34k
   if(m_cookie_input_bits.empty())
247
0
      throw Invalid_State("Client_Hello::cookie_input_data called but was not computed");
248
249
8.34k
   return m_cookie_input_bits;
250
8.34k
   }
251
252
/*
253
* Read a counterparty client hello
254
*/
255
Client_Hello::Client_Hello(const std::vector<uint8_t>& buf)
256
32.2k
   {
257
32.2k
   if(buf.size() < 41)
258
62
      throw Decoding_Error("Client_Hello: Packet corrupted");
259
260
32.2k
   TLS_Data_Reader reader("ClientHello", buf);
261
262
32.2k
   const uint8_t major_version = reader.get_byte();
263
32.2k
   const uint8_t minor_version = reader.get_byte();
264
265
32.2k
   m_version = Protocol_Version(major_version, minor_version);
266
32.2k
   m_random = reader.get_fixed<uint8_t>(32);
267
32.2k
   m_session_id = reader.get_range<uint8_t>(1, 0, 32);
268
269
32.2k
   if(m_version.is_datagram_protocol())
270
8.78k
      {
271
8.78k
      auto sha256 = HashFunction::create_or_throw("SHA-256");
272
8.78k
      sha256->update(reader.get_data_read_so_far());
273
274
8.78k
      m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
275
276
8.78k
      sha256->update(reader.get_remaining());
277
8.78k
      m_cookie_input_bits.resize(sha256->output_length());
278
8.78k
      sha256->final(m_cookie_input_bits.data());
279
8.78k
      }
280
281
32.2k
   m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
282
283
32.2k
   m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
284
285
32.2k
   m_extensions.deserialize(reader, Connection_Side::CLIENT);
286
287
32.2k
   if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
288
13.7k
      {
289
13.7k
      if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
290
260
         {
291
260
         if(!reneg->renegotiation_info().empty())
292
2
            throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
293
2
                                "Client sent renegotiation SCSV and non-empty extension");
294
13.5k
         }
295
13.5k
      else
296
13.5k
         {
297
         // add fake extension
298
13.5k
         m_extensions.add(new Renegotiation_Extension());
299
13.5k
         }
300
13.7k
      }
301
32.2k
   }
302
303
bool Client_Hello::sent_fallback_scsv() const
304
30.3k
   {
305
30.3k
   return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
306
30.3k
   }
307
308
/*
309
* Check if we offered this ciphersuite
310
*/
311
bool Client_Hello::offered_suite(uint16_t ciphersuite) const
312
65.8k
   {
313
383k
   for(size_t i = 0; i != m_suites.size(); ++i)
314
336k
      if(m_suites[i] == ciphersuite)
315
18.9k
         return true;
316
46.8k
   return false;
317
65.8k
   }
318
319
std::vector<Signature_Scheme> Client_Hello::signature_schemes() const
320
353
   {
321
353
   std::vector<Signature_Scheme> schemes;
322
323
353
   if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
324
317
      {
325
317
      schemes = sigs->supported_schemes();
326
317
      }
327
328
353
   return schemes;
329
353
   }
330
331
std::vector<Group_Params> Client_Hello::supported_ecc_curves() const
332
42.8k
   {
333
42.8k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
334
42.3k
      return groups->ec_groups();
335
515
   return std::vector<Group_Params>();
336
515
   }
337
338
std::vector<Group_Params> Client_Hello::supported_dh_groups() const
339
0
   {
340
0
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
341
0
      return groups->dh_groups();
342
0
   return std::vector<Group_Params>();
343
0
   }
344
345
bool Client_Hello::prefers_compressed_ec_points() const
346
20.3k
   {
347
20.3k
   if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
348
8.95k
      {
349
8.95k
      return ecc_formats->prefers_compressed();
350
8.95k
      }
351
11.3k
   return false;
352
11.3k
   }
353
354
std::string Client_Hello::sni_hostname() const
355
53.3k
   {
356
53.3k
   if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
357
3.08k
      return sni->host_name();
358
50.2k
   return "";
359
50.2k
   }
360
361
bool Client_Hello::secure_renegotiation() const
362
49.8k
   {
363
49.8k
   return m_extensions.has<Renegotiation_Extension>();
364
49.8k
   }
365
366
std::vector<uint8_t> Client_Hello::renegotiation_info() const
367
19.7k
   {
368
19.7k
   if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
369
19.7k
      return reneg->renegotiation_info();
370
0
   return std::vector<uint8_t>();
371
0
   }
372
373
std::vector<Protocol_Version> Client_Hello::supported_versions() const
374
30.3k
   {
375
30.3k
   if(Supported_Versions* versions = m_extensions.get<Supported_Versions>())
376
1.49k
      return versions->versions();
377
28.8k
   return {};
378
28.8k
   }
379
380
bool Client_Hello::supports_session_ticket() const
381
21.6k
   {
382
21.6k
   return m_extensions.has<Session_Ticket>();
383
21.6k
   }
384
385
std::vector<uint8_t> Client_Hello::session_ticket() const
386
21.9k
   {
387
21.9k
   if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
388
2.07k
      return ticket->contents();
389
19.8k
   return std::vector<uint8_t>();
390
19.8k
   }
391
392
bool Client_Hello::supports_alpn() const
393
33.6k
   {
394
33.6k
   return m_extensions.has<Application_Layer_Protocol_Notification>();
395
33.6k
   }
396
397
bool Client_Hello::supports_extended_master_secret() const
398
21.6k
   {
399
21.6k
   return m_extensions.has<Extended_Master_Secret>();
400
21.6k
   }
401
402
bool Client_Hello::supports_cert_status_message() const
403
21.7k
   {
404
21.7k
   return m_extensions.has<Certificate_Status_Request>();
405
21.7k
   }
406
407
bool Client_Hello::supports_encrypt_then_mac() const
408
15.2k
   {
409
15.2k
   return m_extensions.has<Encrypt_then_MAC>();
410
15.2k
   }
411
412
bool Client_Hello::sent_signature_algorithms() const
413
0
   {
414
0
   return m_extensions.has<Signature_Algorithms>();
415
0
   }
416
417
std::vector<std::string> Client_Hello::next_protocols() const
418
11.8k
   {
419
11.8k
   if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
420
11.8k
      return alpn->protocols();
421
0
   return std::vector<std::string>();
422
0
   }
423
424
std::vector<uint16_t> Client_Hello::srtp_profiles() const
425
0
   {
426
0
   if(SRTP_Protection_Profiles* srtp = m_extensions.get<SRTP_Protection_Profiles>())
427
0
      return srtp->profiles();
428
0
   return std::vector<uint16_t>();
429
0
   }
430
431
432
}
433
434
}