Coverage Report

Created: 2021-06-10 10:30

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