Coverage Report

Created: 2020-02-14 15:38

/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
52.6k
   {
36
52.6k
   std::vector<uint8_t> buf(32);
37
52.6k
   rng.randomize(buf.data(), buf.size());
38
52.6k
39
52.6k
   std::unique_ptr<HashFunction> sha256 = HashFunction::create_or_throw("SHA-256");
40
52.6k
   sha256->update(buf);
41
52.6k
   sha256->final(buf);
42
52.6k
43
52.6k
   if(policy.include_time_in_hello_random())
44
52.6k
      {
45
52.6k
      const uint32_t time32 = static_cast<uint32_t>(
46
52.6k
         std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
47
52.6k
48
52.6k
      store_be(time32, buf.data());
49
52.6k
      }
50
52.6k
51
52.6k
   return buf;
52
52.6k
   }
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.89k
   {
95
5.89k
   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.89k
99
5.89k
   /*
100
5.89k
   * Place all empty extensions in front to avoid a bug in some systems
101
5.89k
   * which reject hellos when the last extension in the list is empty.
102
5.89k
   */
103
5.89k
   m_extensions.add(new Extended_Master_Secret);
104
5.89k
   m_extensions.add(new Session_Ticket());
105
5.89k
106
5.89k
   if(policy.negotiate_encrypt_then_mac())
107
5.89k
      m_extensions.add(new Encrypt_then_MAC);
108
5.89k
109
5.89k
   m_extensions.add(new Renegotiation_Extension(reneg_info));
110
5.89k
111
5.89k
   m_extensions.add(new Supported_Versions(m_version, policy));
112
5.89k
113
5.89k
   if(client_settings.hostname() != "")
114
5.89k
      m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
115
5.89k
116
5.89k
   if(policy.support_cert_status_message())
117
5.89k
      m_extensions.add(new Certificate_Status_Request({}, {}));
118
5.89k
119
5.89k
   if(reneg_info.empty() && !next_protocols.empty())
120
0
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
121
5.89k
122
5.89k
   if(m_version.supports_negotiable_signature_algorithms())
123
5.89k
      m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes()));
124
5.89k
125
5.89k
   if(m_version.is_datagram_protocol())
126
0
      m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
127
5.89k
128
5.89k
#if defined(BOTAN_HAS_SRP6)
129
5.89k
   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
5.89k
   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
138
5.89k
139
5.89k
   if(supported_groups->ec_groups().size() > 0)
140
5.89k
      {
141
5.89k
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
142
5.89k
      }
143
5.89k
144
5.89k
   m_extensions.add(supported_groups.release());
145
5.89k
146
5.89k
   cb.tls_modify_extensions(m_extensions, CLIENT);
147
5.89k
148
5.89k
   if(policy.send_fallback_scsv(client_settings.protocol_version()))
149
0
      m_suites.push_back(TLS_FALLBACK_SCSV);
150
5.89k
151
5.89k
   hash.update(io.send(*this));
152
5.89k
   }
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
0
   /*
179
0
   We always add the EMS extension, even if not used in the original session.
180
0
   If the server understands it and follows the RFC it should reject our resume
181
0
   attempt and upgrade us to a new session with the EMS protection.
182
0
   */
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
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.89k
   {
237
5.89k
   std::vector<uint8_t> buf;
238
5.89k
239
5.89k
   buf.push_back(m_version.major_version());
240
5.89k
   buf.push_back(m_version.minor_version());
241
5.89k
   buf += m_random;
242
5.89k
243
5.89k
   append_tls_length_value(buf, m_session_id, 1);
244
5.89k
245
5.89k
   if(m_version.is_datagram_protocol())
246
0
      append_tls_length_value(buf, m_hello_cookie, 1);
247
5.89k
248
5.89k
   append_tls_length_value(buf, m_suites, 2);
249
5.89k
   append_tls_length_value(buf, m_comp_methods, 1);
250
5.89k
251
5.89k
   /*
252
5.89k
   * May not want to send extensions at all in some cases. If so,
253
5.89k
   * should include SCSV value (if reneg info is empty, if not we are
254
5.89k
   * renegotiating with a modern server)
255
5.89k
   */
256
5.89k
257
5.89k
   buf += m_extensions.serialize(Connection_Side::CLIENT);
258
5.89k
259
5.89k
   return buf;
260
5.89k
   }
261
262
std::vector<uint8_t> Client_Hello::cookie_input_data() const
263
6.65k
   {
264
6.65k
   std::vector<uint8_t> buf;
265
6.65k
266
6.65k
   buf.push_back(m_version.major_version());
267
6.65k
   buf.push_back(m_version.minor_version());
268
6.65k
   buf += m_random;
269
6.65k
270
6.65k
   append_tls_length_value(buf, m_session_id, 1);
271
6.65k
272
6.65k
   append_tls_length_value(buf, m_suites, 2);
273
6.65k
   append_tls_length_value(buf, m_comp_methods, 1);
274
6.65k
275
6.65k
   // Here we don't serialize the extensions since the client extensions
276
6.65k
   // may contain values we don't know how to serialize back.
277
6.65k
278
6.65k
   return buf;
279
6.65k
   }
280
281
/*
282
* Read a counterparty client hello
283
*/
284
Client_Hello::Client_Hello(const std::vector<uint8_t>& buf)
285
32.2k
   {
286
32.2k
   if(buf.size() < 41)
287
75
      throw Decoding_Error("Client_Hello: Packet corrupted");
288
32.2k
289
32.2k
   TLS_Data_Reader reader("ClientHello", buf);
290
32.2k
291
32.2k
   const uint8_t major_version = reader.get_byte();
292
32.2k
   const uint8_t minor_version = reader.get_byte();
293
32.2k
294
32.2k
   m_version = Protocol_Version(major_version, minor_version);
295
32.2k
296
32.2k
   m_random = reader.get_fixed<uint8_t>(32);
297
32.2k
298
32.2k
   m_session_id = reader.get_range<uint8_t>(1, 0, 32);
299
32.2k
300
32.2k
   if(m_version.is_datagram_protocol())
301
6.97k
      m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
302
32.2k
303
32.2k
   m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
304
32.2k
305
32.2k
   m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
306
32.2k
307
32.2k
   m_extensions.deserialize(reader, Connection_Side::CLIENT);
308
32.2k
309
32.2k
   if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
310
2.52k
      {
311
2.52k
      if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
312
22
         {
313
22
         if(!reneg->renegotiation_info().empty())
314
2
            throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
315
2
                                "Client sent renegotiation SCSV and non-empty extension");
316
2.50k
         }
317
2.50k
      else
318
2.50k
         {
319
2.50k
         // add fake extension
320
2.50k
         m_extensions.add(new Renegotiation_Extension());
321
2.50k
         }
322
2.52k
      }
323
32.2k
   }
324
325
bool Client_Hello::sent_fallback_scsv() const
326
30.3k
   {
327
30.3k
   return offered_suite(static_cast<uint16_t>(TLS_FALLBACK_SCSV));
328
30.3k
   }
329
330
/*
331
* Check if we offered this ciphersuite
332
*/
333
bool Client_Hello::offered_suite(uint16_t ciphersuite) const
334
65.5k
   {
335
587k
   for(size_t i = 0; i != m_suites.size(); ++i)
336
529k
      if(m_suites[i] == ciphersuite)
337
7.17k
         return true;
338
65.5k
   return false;
339
65.5k
   }
340
341
std::vector<Signature_Scheme> Client_Hello::signature_schemes() const
342
445
   {
343
445
   std::vector<Signature_Scheme> schemes;
344
445
345
445
   if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
346
407
      {
347
407
      schemes = sigs->supported_schemes();
348
407
      }
349
445
350
445
   return schemes;
351
445
   }
352
353
std::vector<Group_Params> Client_Hello::supported_ecc_curves() const
354
39.8k
   {
355
39.8k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
356
34.8k
      return groups->ec_groups();
357
5.01k
   return std::vector<Group_Params>();
358
5.01k
   }
359
360
std::vector<Group_Params> Client_Hello::supported_dh_groups() const
361
6.59k
   {
362
6.59k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
363
2.22k
      return groups->dh_groups();
364
4.37k
   return std::vector<Group_Params>();
365
4.37k
   }
366
367
bool Client_Hello::prefers_compressed_ec_points() const
368
15.7k
   {
369
15.7k
   if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
370
552
      {
371
552
      return ecc_formats->prefers_compressed();
372
552
      }
373
15.2k
   return false;
374
15.2k
   }
375
376
std::string Client_Hello::sni_hostname() const
377
85.4k
   {
378
85.4k
   if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
379
18.5k
      return sni->host_name();
380
66.9k
   return "";
381
66.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
52.9k
   {
394
52.9k
   return m_extensions.has<Renegotiation_Extension>();
395
52.9k
   }
396
397
std::vector<uint8_t> Client_Hello::renegotiation_info() const
398
9.88k
   {
399
9.88k
   if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
400
9.88k
      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
30.3k
   {
406
30.3k
   if(Supported_Versions* versions = m_extensions.get<Supported_Versions>())
407
9
      return versions->versions();
408
30.3k
   return {};
409
30.3k
   }
410
411
bool Client_Hello::supports_session_ticket() const
412
23.3k
   {
413
23.3k
   return m_extensions.has<Session_Ticket>();
414
23.3k
   }
415
416
std::vector<uint8_t> Client_Hello::session_ticket() const
417
23.7k
   {
418
23.7k
   if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
419
825
      return ticket->contents();
420
22.9k
   return std::vector<uint8_t>();
421
22.9k
   }
422
423
bool Client_Hello::supports_alpn() const
424
26.9k
   {
425
26.9k
   return m_extensions.has<Application_Layer_Protocol_Notification>();
426
26.9k
   }
427
428
bool Client_Hello::supports_extended_master_secret() const
429
23.3k
   {
430
23.3k
   return m_extensions.has<Extended_Master_Secret>();
431
23.3k
   }
432
433
bool Client_Hello::supports_cert_status_message() const
434
23.5k
   {
435
23.5k
   return m_extensions.has<Certificate_Status_Request>();
436
23.5k
   }
437
438
bool Client_Hello::supports_encrypt_then_mac() const
439
12.6k
   {
440
12.6k
   return m_extensions.has<Encrypt_then_MAC>();
441
12.6k
   }
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
3.32k
   {
450
3.32k
   if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
451
3.32k
      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
}