Coverage Report

Created: 2021-05-04 09:02

/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
46.7k
   {
35
46.7k
   std::vector<uint8_t> buf(32);
36
46.7k
   rng.randomize(buf.data(), buf.size());
37
38
46.7k
   auto sha256 = HashFunction::create_or_throw("SHA-256");
39
46.7k
   sha256->update(buf);
40
46.7k
   sha256->final(buf);
41
42
46.7k
   if(policy.include_time_in_hello_random())
43
46.7k
      {
44
46.7k
      const uint32_t time32 = static_cast<uint32_t>(
45
46.7k
         std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
46
47
46.7k
      store_be(time32, buf.data());
48
46.7k
      }
49
50
46.7k
   return buf;
51
46.7k
   }
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.05k
   {
94
2.05k
   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.05k
   m_extensions.add(new Extended_Master_Secret);
103
2.05k
   m_extensions.add(new Session_Ticket());
104
105
2.05k
   if(policy.negotiate_encrypt_then_mac())
106
2.05k
      m_extensions.add(new Encrypt_then_MAC);
107
108
2.05k
   m_extensions.add(new Renegotiation_Extension(reneg_info));
109
110
2.05k
   m_extensions.add(new Supported_Versions(m_version, policy));
111
112
2.05k
   if(client_settings.hostname() != "")
113
2.05k
      m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
114
115
2.05k
   if(policy.support_cert_status_message())
116
2.05k
      m_extensions.add(new Certificate_Status_Request({}, {}));
117
118
2.05k
   if(reneg_info.empty() && !next_protocols.empty())
119
0
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));
120
121
2.05k
   m_extensions.add(new Signature_Algorithms(policy.acceptable_signature_schemes()));
122
123
2.05k
   if(m_version.is_datagram_protocol())
124
0
      m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
125
126
2.05k
   auto supported_groups = std::make_unique<Supported_Groups>(policy.key_exchange_groups());
127
128
2.05k
   if(supported_groups->ec_groups().size() > 0)
129
2.05k
      {
130
2.05k
      m_extensions.add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
131
2.05k
      }
132
133
2.05k
   m_extensions.add(supported_groups.release());
134
135
2.05k
   cb.tls_modify_extensions(m_extensions, CLIENT);
136
137
2.05k
   hash.update(io.send(*this));
138
2.05k
   }
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.05k
   {
213
2.05k
   std::vector<uint8_t> buf;
214
215
2.05k
   buf.push_back(m_version.major_version());
216
2.05k
   buf.push_back(m_version.minor_version());
217
2.05k
   buf += m_random;
218
219
2.05k
   append_tls_length_value(buf, m_session_id, 1);
220
221
2.05k
   if(m_version.is_datagram_protocol())
222
0
      append_tls_length_value(buf, m_hello_cookie, 1);
223
224
2.05k
   append_tls_length_value(buf, m_suites, 2);
225
2.05k
   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.05k
   buf += m_extensions.serialize(Connection_Side::CLIENT);
234
235
2.05k
   return buf;
236
2.05k
   }
237
238
std::vector<uint8_t> Client_Hello::cookie_input_data() const
239
10.6k
   {
240
10.6k
   if(m_cookie_input_bits.empty())
241
0
      throw Invalid_State("Client_Hello::cookie_input_data called but was not computed");
242
243
10.6k
   return m_cookie_input_bits;
244
10.6k
   }
245
246
/*
247
* Read a counterparty client hello
248
*/
249
Client_Hello::Client_Hello(const std::vector<uint8_t>& buf)
250
35.4k
   {
251
35.4k
   if(buf.size() < 41)
252
82
      throw Decoding_Error("Client_Hello: Packet corrupted");
253
254
35.3k
   TLS_Data_Reader reader("ClientHello", buf);
255
256
35.3k
   const uint8_t major_version = reader.get_byte();
257
35.3k
   const uint8_t minor_version = reader.get_byte();
258
259
35.3k
   m_version = Protocol_Version(major_version, minor_version);
260
35.3k
   m_random = reader.get_fixed<uint8_t>(32);
261
35.3k
   m_session_id = reader.get_range<uint8_t>(1, 0, 32);
262
263
35.3k
   if(m_version.is_datagram_protocol())
264
11.1k
      {
265
11.1k
      auto sha256 = HashFunction::create_or_throw("SHA-256");
266
11.1k
      sha256->update(reader.get_data_read_so_far());
267
268
11.1k
      m_hello_cookie = reader.get_range<uint8_t>(1, 0, 255);
269
270
11.1k
      sha256->update(reader.get_remaining());
271
11.1k
      m_cookie_input_bits.resize(sha256->output_length());
272
11.1k
      sha256->final(m_cookie_input_bits.data());
273
11.1k
      }
274
275
35.3k
   m_suites = reader.get_range_vector<uint16_t>(2, 1, 32767);
276
277
35.3k
   m_comp_methods = reader.get_range_vector<uint8_t>(1, 1, 255);
278
279
35.3k
   m_extensions.deserialize(reader, Connection_Side::CLIENT);
280
281
35.3k
   if(offered_suite(static_cast<uint16_t>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
282
14.9k
      {
283
14.9k
      if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
284
224
         {
285
224
         if(!reneg->renegotiation_info().empty())
286
2
            throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
287
2
                                "Client sent renegotiation SCSV and non-empty extension");
288
14.7k
         }
289
14.7k
      else
290
14.7k
         {
291
         // add fake extension
292
14.7k
         m_extensions.add(new Renegotiation_Extension());
293
14.7k
         }
294
14.9k
      }
295
35.3k
   }
296
297
/*
298
* Check if we offered this ciphersuite
299
*/
300
bool Client_Hello::offered_suite(uint16_t ciphersuite) const
301
33.7k
   {
302
83.0k
   for(size_t i = 0; i != m_suites.size(); ++i)
303
64.2k
      if(m_suites[i] == ciphersuite)
304
14.9k
         return true;
305
18.8k
   return false;
306
33.7k
   }
307
308
std::vector<Signature_Scheme> Client_Hello::signature_schemes() const
309
122
   {
310
122
   std::vector<Signature_Scheme> schemes;
311
312
122
   if(Signature_Algorithms* sigs = m_extensions.get<Signature_Algorithms>())
313
79
      {
314
79
      schemes = sigs->supported_schemes();
315
79
      }
316
317
122
   return schemes;
318
122
   }
319
320
std::vector<Group_Params> Client_Hello::supported_ecc_curves() const
321
44.2k
   {
322
44.2k
   if(Supported_Groups* groups = m_extensions.get<Supported_Groups>())
323
43.6k
      return groups->ec_groups();
324
628
   return std::vector<Group_Params>();
325
628
   }
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.0k
   {
336
21.0k
   if(Supported_Point_Formats* ecc_formats = m_extensions.get<Supported_Point_Formats>())
337
10.6k
      {
338
10.6k
      return ecc_formats->prefers_compressed();
339
10.6k
      }
340
10.4k
   return false;
341
10.4k
   }
342
343
std::string Client_Hello::sni_hostname() const
344
56.3k
   {
345
56.3k
   if(Server_Name_Indicator* sni = m_extensions.get<Server_Name_Indicator>())
346
3.80k
      return sni->host_name();
347
52.5k
   return "";
348
52.5k
   }
349
350
bool Client_Hello::secure_renegotiation() const
351
47.0k
   {
352
47.0k
   return m_extensions.has<Renegotiation_Extension>();
353
47.0k
   }
354
355
std::vector<uint8_t> Client_Hello::renegotiation_info() const
356
15.8k
   {
357
15.8k
   if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
358
15.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
33.4k
   {
364
33.4k
   if(Supported_Versions* versions = m_extensions.get<Supported_Versions>())
365
1.03k
      return versions->versions();
366
32.3k
   return {};
367
32.3k
   }
368
369
bool Client_Hello::supports_session_ticket() const
370
22.3k
   {
371
22.3k
   return m_extensions.has<Session_Ticket>();
372
22.3k
   }
373
374
std::vector<uint8_t> Client_Hello::session_ticket() const
375
22.6k
   {
376
22.6k
   if(Session_Ticket* ticket = m_extensions.get<Session_Ticket>())
377
3.04k
      return ticket->contents();
378
19.6k
   return std::vector<uint8_t>();
379
19.6k
   }
380
381
bool Client_Hello::supports_alpn() const
382
33.8k
   {
383
33.8k
   return m_extensions.has<Application_Layer_Protocol_Notification>();
384
33.8k
   }
385
386
bool Client_Hello::supports_extended_master_secret() const
387
22.3k
   {
388
22.3k
   return m_extensions.has<Extended_Master_Secret>();
389
22.3k
   }
390
391
bool Client_Hello::supports_cert_status_message() const
392
22.5k
   {
393
22.5k
   return m_extensions.has<Certificate_Status_Request>();
394
22.5k
   }
395
396
bool Client_Hello::supports_encrypt_then_mac() const
397
15.8k
   {
398
15.8k
   return m_extensions.has<Encrypt_then_MAC>();
399
15.8k
   }
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
11.2k
   {
408
11.2k
   if(auto alpn = m_extensions.get<Application_Layer_Protocol_Notification>())
409
11.2k
      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
}