• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5230455705

10 Jun 2023 02:30PM UTC coverage: 91.715% (-0.03%) from 91.746%
5230455705

push

github

randombit
Merge GH #3584 Change clang-format AllowShortFunctionsOnASingleLine config from All to Inline

77182 of 84154 relevant lines covered (91.72%)

11975295.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.98
/src/lib/tls/msg_server_hello.cpp
1
/*
2
* TLS Server Hello and Server Hello Done
3
* (C) 2004-2011,2015,2016,2019 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
#include <botan/tls_messages.h>
13

14
#include <botan/mem_ops.h>
15
#include <botan/tls_callbacks.h>
16
#include <botan/tls_exceptn.h>
17
#include <botan/tls_extensions.h>
18
#include <botan/tls_session_manager.h>
19
#include <botan/internal/stl_util.h>
20
#include <botan/internal/tls_handshake_hash.h>
21
#include <botan/internal/tls_handshake_io.h>
22
#include <botan/internal/tls_reader.h>
23
#include <botan/internal/tls_session_key.h>
24

25
#include <array>
26

27
namespace Botan::TLS {
28

29
namespace {
30

31
const uint64_t DOWNGRADE_TLS11 = 0x444F574E47524400;
32
const uint64_t DOWNGRADE_TLS12 = 0x444F574E47524401;
33

34
// SHA-256("HelloRetryRequest")
35
const std::vector<uint8_t> HELLO_RETRY_REQUEST_MARKER = {
36
   0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
37
   0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C};
38

39
bool random_signals_hello_retry_request(const std::vector<uint8_t>& random) {
3,420✔
40
   return constant_time_compare(random.data(), HELLO_RETRY_REQUEST_MARKER.data(), HELLO_RETRY_REQUEST_MARKER.size());
6,840✔
41
}
42

43
std::vector<uint8_t> make_server_hello_random(RandomNumberGenerator& rng,
1,035✔
44
                                              Protocol_Version offered_version,
45
                                              Callbacks& cb,
46
                                              const Policy& policy) {
47
   BOTAN_UNUSED(offered_version);
1,035✔
48
   auto random = make_hello_random(rng, cb, policy);
1,035✔
49

50
   // RFC 8446 4.1.3
51
   //    TLS 1.3 has a downgrade protection mechanism embedded in the server's
52
   //    random value. TLS 1.3 servers which negotiate TLS 1.2 or below in
53
   //    response to a ClientHello MUST set the last 8 bytes of their Random
54
   //    value specially in their ServerHello.
55
   //
56
   //    If negotiating TLS 1.2, TLS 1.3 servers MUST set the last 8 bytes of
57
   //    their Random value to the bytes: [DOWNGRADE_TLS12]
58
   if(offered_version.is_pre_tls_13() && policy.allow_tls13()) {
1,035✔
59
      constexpr size_t downgrade_signal_length = sizeof(DOWNGRADE_TLS12);
450✔
60
      BOTAN_ASSERT_NOMSG(random.size() >= downgrade_signal_length);
450✔
61
      auto lastbytes = random.data() + random.size() - downgrade_signal_length;
450✔
62
      store_be(DOWNGRADE_TLS12, lastbytes);
450✔
63
   }
64

65
   return random;
1,035✔
66
}
×
67

68
}  // namespace
69

70
/**
71
* Version-agnostic internal server hello data container that allows
72
* parsing Server_Hello messages without prior knowledge of the contained
73
* protocol version.
74
*/
75
class Server_Hello_Internal {
76
   public:
77
      /**
78
       * Deserialize a Server Hello message
79
       */
80
      Server_Hello_Internal(const std::vector<uint8_t>& buf) {
3,426✔
81
         if(buf.size() < 38) {
3,426✔
82
            throw Decoding_Error("Server_Hello: Packet corrupted");
6✔
83
         }
84

85
         TLS_Data_Reader reader("ServerHello", buf);
3,420✔
86

87
         const uint8_t major_version = reader.get_byte();
3,420✔
88
         const uint8_t minor_version = reader.get_byte();
3,420✔
89

90
         m_legacy_version = Protocol_Version(major_version, minor_version);
3,420✔
91

92
         // RFC 8446 4.1.3
93
         //    Upon receiving a message with type server_hello, implementations MUST
94
         //    first examine the Random value and, if it matches this value, process
95
         //    it as described in Section 4.1.4 [Hello Retry Request]).
96
         m_random = reader.get_fixed<uint8_t>(32);
3,420✔
97
         m_is_hello_retry_request = random_signals_hello_retry_request(m_random);
3,420✔
98

99
         m_session_id = Session_ID(reader.get_range<uint8_t>(1, 0, 32));
3,420✔
100
         m_ciphersuite = reader.get_uint16_t();
3,411✔
101
         m_comp_method = reader.get_byte();
3,409✔
102

103
         // Note that this code path might parse a TLS 1.2 (or older) server hello message that
104
         // is nevertheless marked as being a 'hello retry request' (potentially maliciously).
105
         // Extension parsing will however not be affected by the associated flag.
106
         // Only after parsing the extensions will the upstream code be able to decide
107
         // whether we're dealing with TLS 1.3 or older.
108
         m_extensions.deserialize(
3,408✔
109
            reader,
110
            Connection_Side::Server,
111
            m_is_hello_retry_request ? Handshake_Type::HelloRetryRequest : Handshake_Type::ServerHello);
3,408✔
112
      }
3,575✔
113

114
      Server_Hello_Internal(Protocol_Version lv,
1,300✔
115
                            Session_ID sid,
116
                            std::vector<uint8_t> r,
117
                            const uint16_t cs,
118
                            const uint8_t cm,
119
                            bool is_hrr = false) :
1,300✔
120
            m_legacy_version(lv),
1,300✔
121
            m_session_id(std::move(sid)),
1,300✔
122
            m_random(std::move(r)),
1,300✔
123
            m_is_hello_retry_request(is_hrr),
1,300✔
124
            m_ciphersuite(cs),
1,300✔
125
            m_comp_method(cm) {}
1,300✔
126

127
      Protocol_Version version() const {
4,245✔
128
         // RFC 8446 4.2.1
129
         //    A server which negotiates a version of TLS prior to TLS 1.3 MUST set
130
         //    ServerHello.version and MUST NOT send the "supported_versions"
131
         //    extension.  A server which negotiates TLS 1.3 MUST respond by sending
132
         //    a "supported_versions" extension containing the selected version
133
         //    value (0x0304).
134
         //
135
         // Note: Here we just take a message parsing decision, further validation of
136
         //       the extension's contents is done later.
137
         return (extensions().has<Supported_Versions>()) ? Protocol_Version::TLS_V13 : m_legacy_version;
4,245✔
138
      }
139

140
      Protocol_Version legacy_version() const { return m_legacy_version; }
1,987✔
141

142
      const Session_ID& session_id() const { return m_session_id; }
5,611✔
143

144
      const std::vector<uint8_t>& random() const { return m_random; }
1,769✔
145

146
      uint16_t ciphersuite() const { return m_ciphersuite; }
2,085✔
147

148
      uint8_t comp_method() const { return m_comp_method; }
1,309✔
149

150
      bool is_hello_retry_request() const { return m_is_hello_retry_request; }
1,018✔
151

152
      const Extensions& extensions() const { return m_extensions; }
4,245✔
153

154
      Extensions& extensions() { return m_extensions; }
32,036✔
155

156
   private:
157
      Protocol_Version m_legacy_version;
158
      Session_ID m_session_id;
159
      std::vector<uint8_t> m_random;
160
      bool m_is_hello_retry_request;
161
      uint16_t m_ciphersuite;
162
      uint8_t m_comp_method;
163

164
      Extensions m_extensions;
165
};
166

167
Server_Hello::Server_Hello(std::unique_ptr<Server_Hello_Internal> data) : m_data(std::move(data)) {}
4,571✔
168

169
Server_Hello::Server_Hello(Server_Hello&&) noexcept = default;
10,903✔
170
Server_Hello& Server_Hello::operator=(Server_Hello&&) noexcept = default;
1✔
171

172
Server_Hello::~Server_Hello() = default;
15,461✔
173

174
/*
175
* Serialize a Server Hello message
176
*/
177
std::vector<uint8_t> Server_Hello::serialize() const {
1,309✔
178
   std::vector<uint8_t> buf;
1,309✔
179
   buf.reserve(1024);  // working around GCC warning
1,309✔
180

181
   buf.push_back(m_data->legacy_version().major_version());
1,309✔
182
   buf.push_back(m_data->legacy_version().minor_version());
1,309✔
183
   buf += m_data->random();
1,309✔
184

185
   append_tls_length_value(buf, m_data->session_id().get(), 1);
1,309✔
186

187
   buf.push_back(get_byte<0>(m_data->ciphersuite()));
1,309✔
188
   buf.push_back(get_byte<1>(m_data->ciphersuite()));
1,309✔
189

190
   buf.push_back(m_data->comp_method());
1,309✔
191

192
   buf += m_data->extensions().serialize(Connection_Side::Server);
1,309✔
193

194
   return buf;
1,309✔
195
}
×
196

197
Handshake_Type Server_Hello::type() const {
6,921✔
198
   return Handshake_Type::ServerHello;
6,921✔
199
}
200

201
Protocol_Version Server_Hello::legacy_version() const {
9,199✔
202
   return m_data->legacy_version();
9,199✔
203
}
204

205
const std::vector<uint8_t>& Server_Hello::random() const {
3,490✔
206
   return m_data->random();
3,490✔
207
}
208

209
uint8_t Server_Hello::compression_method() const {
5,120✔
210
   return m_data->comp_method();
5,120✔
211
}
212

213
const Session_ID& Server_Hello::session_id() const {
5,611✔
214
   return m_data->session_id();
5,611✔
215
}
216

217
uint16_t Server_Hello::ciphersuite() const {
12,044✔
218
   return m_data->ciphersuite();
12,044✔
219
}
220

221
std::set<Extension_Code> Server_Hello::extension_types() const {
1,107✔
222
   return m_data->extensions().extension_types();
1,107✔
223
}
224

225
const Extensions& Server_Hello::extensions() const {
7,351✔
226
   return m_data->extensions();
7,351✔
227
}
228

229
// New session case
230
Server_Hello_12::Server_Hello_12(Handshake_IO& io,
678✔
231
                                 Handshake_Hash& hash,
232
                                 const Policy& policy,
233
                                 Callbacks& cb,
234
                                 RandomNumberGenerator& rng,
235
                                 const std::vector<uint8_t>& reneg_info,
236
                                 const Client_Hello_12& client_hello,
237
                                 const Server_Hello_12::Settings& server_settings,
238
                                 std::string_view next_protocol) :
678✔
239
      Server_Hello(std::make_unique<Server_Hello_Internal>(
678✔
240
         server_settings.protocol_version(),
1,356✔
241
         server_settings.session_id(),
678✔
242
         make_server_hello_random(rng, server_settings.protocol_version(), cb, policy),
678✔
243
         server_settings.ciphersuite(),
678✔
244
         uint8_t(0))) {
1,356✔
245
   if(client_hello.supports_extended_master_secret()) {
678✔
246
      m_data->extensions().add(new Extended_Master_Secret);
673✔
247
   }
248

249
   // Sending the extension back does not commit us to sending a stapled response
250
   if(client_hello.supports_cert_status_message() && policy.support_cert_status_message()) {
678✔
251
      m_data->extensions().add(new Certificate_Status_Request);
190✔
252
   }
253

254
   if(!next_protocol.empty() && client_hello.supports_alpn()) {
678✔
255
      m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocol));
119✔
256
   }
257

258
   const auto c = Ciphersuite::by_id(m_data->ciphersuite());
678✔
259

260
   if(c && c->cbc_ciphersuite() && client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) {
678✔
261
      m_data->extensions().add(new Encrypt_then_MAC);
13✔
262
   }
263

264
   if(c && c->ecc_ciphersuite() && client_hello.extension_types().contains(Extension_Code::EcPointFormats)) {
1,840✔
265
      m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
580✔
266
   }
267

268
   if(client_hello.secure_renegotiation()) {
678✔
269
      m_data->extensions().add(new Renegotiation_Extension(reneg_info));
675✔
270
   }
271

272
   if(client_hello.supports_session_ticket() && server_settings.offer_session_ticket()) {
678✔
273
      m_data->extensions().add(new Session_Ticket_Extension());
489✔
274
   }
275

276
   if(m_data->legacy_version().is_datagram_protocol()) {
678✔
277
      const std::vector<uint16_t> server_srtp = policy.srtp_profiles();
266✔
278
      const std::vector<uint16_t> client_srtp = client_hello.srtp_profiles();
266✔
279

280
      if(!server_srtp.empty() && !client_srtp.empty()) {
266✔
281
         uint16_t shared = 0;
282
         // always using server preferences for now
283
         for(auto s_srtp : server_srtp) {
6✔
284
            for(auto c_srtp : client_srtp) {
16✔
285
               if(shared == 0 && s_srtp == c_srtp) {
12✔
286
                  shared = s_srtp;
1✔
287
               }
288
            }
289
         }
290

291
         if(shared) {
2✔
292
            m_data->extensions().add(new SRTP_Protection_Profiles(shared));
1✔
293
         }
294
      }
295
   }
268✔
296

297
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
678✔
298

299
   hash.update(io.send(*this));
1,356✔
300
}
678✔
301

302
// Resuming
303
Server_Hello_12::Server_Hello_12(Handshake_IO& io,
230✔
304
                                 Handshake_Hash& hash,
305
                                 const Policy& policy,
306
                                 Callbacks& cb,
307
                                 RandomNumberGenerator& rng,
308
                                 const std::vector<uint8_t>& reneg_info,
309
                                 const Client_Hello_12& client_hello,
310
                                 const Session& resumed_session,
311
                                 bool offer_session_ticket,
312
                                 std::string_view next_protocol) :
230✔
313
      Server_Hello(std::make_unique<Server_Hello_Internal>(resumed_session.version(),
460✔
314
                                                           client_hello.session_id(),
230✔
315
                                                           make_hello_random(rng, cb, policy),
230✔
316
                                                           resumed_session.ciphersuite_code(),
460✔
317
                                                           uint8_t(0))) {
460✔
318
   if(client_hello.supports_extended_master_secret()) {
230✔
319
      m_data->extensions().add(new Extended_Master_Secret);
229✔
320
   }
321

322
   if(!next_protocol.empty() && client_hello.supports_alpn()) {
230✔
323
      m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocol));
17✔
324
   }
325

326
   if(client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) {
230✔
327
      Ciphersuite c = resumed_session.ciphersuite();
3✔
328
      if(c.cbc_ciphersuite()) {
3✔
329
         m_data->extensions().add(new Encrypt_then_MAC);
3✔
330
      }
331
   }
332

333
   if(resumed_session.ciphersuite().ecc_ciphersuite() &&
230✔
334
      client_hello.extension_types().contains(Extension_Code::EcPointFormats)) {
646✔
335
      m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
208✔
336
   }
337

338
   if(client_hello.secure_renegotiation()) {
230✔
339
      m_data->extensions().add(new Renegotiation_Extension(reneg_info));
230✔
340
   }
341

342
   if(client_hello.supports_session_ticket() && offer_session_ticket) {
230✔
343
      m_data->extensions().add(new Session_Ticket_Extension());
1✔
344
   }
345

346
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
230✔
347

348
   hash.update(io.send(*this));
460✔
349
}
230✔
350

351
Server_Hello_12::Server_Hello_12(const std::vector<uint8_t>& buf) :
2,440✔
352
      Server_Hello_12(std::make_unique<Server_Hello_Internal>(buf)) {}
2,440✔
353

354
Server_Hello_12::Server_Hello_12(std::unique_ptr<Server_Hello_Internal> data) : Server_Hello(std::move(data)) {
2,762✔
355
   if(!m_data->version().is_pre_tls_13()) {
5,524✔
356
      throw TLS_Exception(Alert::ProtocolVersion, "Expected server hello of (D)TLS 1.2 or lower");
×
357
   }
358
}
2,762✔
359

360
Protocol_Version Server_Hello_12::selected_version() const {
458✔
361
   return legacy_version();
458✔
362
}
363

364
bool Server_Hello_12::secure_renegotiation() const {
2,082✔
365
   return m_data->extensions().has<Renegotiation_Extension>();
2,082✔
366
}
367

368
std::vector<uint8_t> Server_Hello_12::renegotiation_info() const {
1,998✔
369
   if(Renegotiation_Extension* reneg = m_data->extensions().get<Renegotiation_Extension>()) {
1,998✔
370
      return reneg->renegotiation_info();
1,998✔
371
   }
372
   return std::vector<uint8_t>();
×
373
}
374

375
bool Server_Hello_12::supports_extended_master_secret() const {
3,795✔
376
   return m_data->extensions().has<Extended_Master_Secret>();
3,795✔
377
}
378

379
bool Server_Hello_12::supports_encrypt_then_mac() const {
5,959✔
380
   return m_data->extensions().has<Encrypt_then_MAC>();
5,959✔
381
}
382

383
bool Server_Hello_12::supports_certificate_status_message() const {
1,510✔
384
   return m_data->extensions().has<Certificate_Status_Request>();
1,510✔
385
}
386

387
bool Server_Hello_12::supports_session_ticket() const {
2,511✔
388
   return m_data->extensions().has<Session_Ticket_Extension>();
2,511✔
389
}
390

391
uint16_t Server_Hello_12::srtp_profile() const {
2,599✔
392
   if(auto srtp = m_data->extensions().get<SRTP_Protection_Profiles>()) {
2,599✔
393
      auto prof = srtp->profiles();
4✔
394
      if(prof.size() != 1 || prof[0] == 0) {
4✔
395
         throw Decoding_Error("Server sent malformed DTLS-SRTP extension");
×
396
      }
397
      return prof[0];
4✔
398
   }
4✔
399

400
   return 0;
401
}
402

403
std::string Server_Hello_12::next_protocol() const {
1,099✔
404
   if(auto alpn = m_data->extensions().get<Application_Layer_Protocol_Notification>()) {
1,099✔
405
      return alpn->single_protocol();
137✔
406
   }
407
   return "";
962✔
408
}
409

410
bool Server_Hello_12::prefers_compressed_ec_points() const {
12✔
411
   if(auto ecc_formats = m_data->extensions().get<Supported_Point_Formats>()) {
12✔
412
      return ecc_formats->prefers_compressed();
9✔
413
   }
414
   return false;
415
}
416

417
std::optional<Protocol_Version> Server_Hello_12::random_signals_downgrade() const {
460✔
418
   const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
460✔
419
   if(last8 == DOWNGRADE_TLS11) {
460✔
420
      return Protocol_Version::TLS_V11;
×
421
   }
422
   if(last8 == DOWNGRADE_TLS12) {
460✔
423
      return Protocol_Version::TLS_V12;
1✔
424
   }
425

426
   return std::nullopt;
459✔
427
}
428

429
/*
430
* Create a new Server Hello Done message
431
*/
432
Server_Hello_Done::Server_Hello_Done(Handshake_IO& io, Handshake_Hash& hash) {
660✔
433
   hash.update(io.send(*this));
1,320✔
434
}
660✔
435

436
/*
437
* Deserialize a Server Hello Done message
438
*/
439
Server_Hello_Done::Server_Hello_Done(const std::vector<uint8_t>& buf) {
776✔
440
   if(!buf.empty()) {
776✔
441
      throw Decoding_Error("Server_Hello_Done: Must be empty, and is not");
2✔
442
   }
443
}
774✔
444

445
/*
446
* Serialize a Server Hello Done message
447
*/
448
std::vector<uint8_t> Server_Hello_Done::serialize() const {
660✔
449
   return std::vector<uint8_t>();
660✔
450
}
451

452
#if defined(BOTAN_HAS_TLS_13)
453

454
const Server_Hello_13::Server_Hello_Tag Server_Hello_13::as_server_hello;
455
const Server_Hello_13::Hello_Retry_Request_Tag Server_Hello_13::as_hello_retry_request;
456
const Server_Hello_13::Hello_Retry_Request_Creation_Tag Server_Hello_13::as_new_hello_retry_request;
457

458
std::variant<Hello_Retry_Request, Server_Hello_13> Server_Hello_13::create(const Client_Hello_13& ch,
412✔
459
                                                                           bool hello_retry_request_allowed,
460
                                                                           Session_Manager& session_mgr,
461
                                                                           RandomNumberGenerator& rng,
462
                                                                           const Policy& policy,
463
                                                                           Callbacks& cb) {
464
   const auto& exts = ch.extensions();
412✔
465

466
   // RFC 8446 4.2.9
467
   //    [With PSK with (EC)DHE key establishment], the client and server MUST
468
   //    supply "key_share" values [...].
469
   //
470
   // Note: We currently do not support PSK without (EC)DHE, hence, we can
471
   //       assume that those extensions are available.
472
   BOTAN_ASSERT_NOMSG(exts.has<Supported_Groups>() && exts.has<Key_Share>());
824✔
473
   const auto& supported_by_client = exts.get<Supported_Groups>()->groups();
412✔
474
   const auto& offered_by_client = exts.get<Key_Share>()->offered_groups();
412✔
475
   const auto selected_group = policy.choose_key_exchange_group(supported_by_client, offered_by_client);
412✔
476

477
   // RFC 8446 4.1.1
478
   //    If there is no overlap between the received "supported_groups" and the
479
   //    groups supported by the server, then the server MUST abort the
480
   //    handshake with a "handshake_failure" or an "insufficient_security" alert.
481
   if(selected_group == Named_Group::NONE) {
412✔
482
      throw TLS_Exception(Alert::HandshakeFailure, "Client did not offer any acceptable group");
×
483
   }
484

485
   if(!value_exists(offered_by_client, selected_group)) {
412✔
486
      // RFC 8446 4.1.4
487
      //    If a client receives a second HelloRetryRequest in the same
488
      //    connection (i.e., where the ClientHello was itself in response to a
489
      //    HelloRetryRequest), it MUST abort the handshake with an
490
      //    "unexpected_message" alert.
491
      BOTAN_STATE_CHECK(hello_retry_request_allowed);
35✔
492
      return Hello_Retry_Request(ch, selected_group, policy, cb);
70✔
493
   } else {
494
      return Server_Hello_13(ch, selected_group, session_mgr, rng, cb, policy);
734✔
495
   }
496
}
392✔
497

498
std::variant<Hello_Retry_Request, Server_Hello_13, Server_Hello_12> Server_Hello_13::parse(
986✔
499
   const std::vector<uint8_t>& buf) {
500
   auto data = std::make_unique<Server_Hello_Internal>(buf);
986✔
501
   const auto version = data->version();
974✔
502

503
   // server hello that appears to be pre-TLS 1.3, takes precedence over...
504
   if(version.is_pre_tls_13()) {
974✔
505
      return Server_Hello_12(std::move(data));
930✔
506
   }
507

508
   // ... the TLS 1.3 "special case" aka. Hello_Retry_Request
509
   if(version == Protocol_Version::TLS_V13) {
509✔
510
      if(data->is_hello_retry_request()) {
509✔
511
         return Hello_Retry_Request(std::move(data));
81✔
512
      }
513

514
      return Server_Hello_13(std::move(data));
926✔
515
   }
516

517
   throw TLS_Exception(Alert::ProtocolVersion, "unexpected server hello version: " + version.to_string());
×
518
}
974✔
519

520
/**
521
 * Validation that applies to both Server Hello and Hello Retry Request
522
 */
523
void Server_Hello_13::basic_validation() const {
509✔
524
   BOTAN_ASSERT_NOMSG(m_data->version() == Protocol_Version::TLS_V13);
1,018✔
525

526
   // Note: checks that cannot be performed without contextual information
527
   //       are done in the specific TLS client implementation.
528
   // Note: The Supported_Version extension makes sure internally that
529
   //       exactly one entry is provided.
530

531
   // Note: Hello Retry Request basic validation is equivalent with the
532
   //       basic validations required for Server Hello
533
   //
534
   // RFC 8446 4.1.4
535
   //    Upon receipt of a HelloRetryRequest, the client MUST check the
536
   //    legacy_version, [...], and legacy_compression_method as specified in
537
   //    Section 4.1.3 and then process the extensions, starting with determining
538
   //    the version using "supported_versions".
539

540
   // RFC 8446 4.1.3
541
   //    In TLS 1.3, [...] the legacy_version field MUST be set to 0x0303
542
   if(legacy_version() != Protocol_Version::TLS_V12) {
509✔
543
      throw TLS_Exception(Alert::ProtocolVersion,
2✔
544
                          "legacy_version '" + legacy_version().to_string() + "' is not allowed");
4✔
545
   }
546

547
   // RFC 8446 4.1.3
548
   //    legacy_compression_method:  A single byte which MUST have the value 0.
549
   if(compression_method() != 0x00) {
507✔
550
      throw TLS_Exception(Alert::DecodeError, "compression is not supported in TLS 1.3");
2✔
551
   }
552

553
   // RFC 8446 4.1.3
554
   //    All TLS 1.3 ServerHello messages MUST contain the "supported_versions" extension.
555
   if(!extensions().has<Supported_Versions>()) {
505✔
556
      throw TLS_Exception(Alert::MissingExtension, "server hello did not contain 'supported version' extension");
×
557
   }
558

559
   // RFC 8446 4.2.1
560
   //    A server which negotiates TLS 1.3 MUST respond by sending
561
   //    a "supported_versions" extension containing the selected version
562
   //    value (0x0304).
563
   if(selected_version() != Protocol_Version::TLS_V13) {
505✔
564
      throw TLS_Exception(Alert::IllegalParameter, "TLS 1.3 Server Hello selected a different version");
1✔
565
   }
566
}
504✔
567

568
Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Server_Hello_13::Server_Hello_Tag) :
467✔
569
      Server_Hello(std::move(data)) {
467✔
570
   BOTAN_ASSERT_NOMSG(!m_data->is_hello_retry_request());
467✔
571
   basic_validation();
467✔
572

573
   const auto& exts = extensions();
463✔
574

575
   // RFC 8446 4.1.3
576
   //    The ServerHello MUST only include extensions which are required to
577
   //    establish the cryptographic context and negotiate the protocol version.
578
   //    [...]
579
   //    Other extensions (see Section 4.2) are sent separately in the
580
   //    EncryptedExtensions message.
581
   //
582
   // Note that further validation dependent on the client hello is done in the
583
   // TLS client implementation.
584
   const std::set<Extension_Code> allowed = {
463✔
585
      Extension_Code::KeyShare,
586
      Extension_Code::SupportedVersions,
587
      Extension_Code::PresharedKey,
588
   };
463✔
589

590
   // As the ServerHello shall only contain essential extensions, we don't give
591
   // any slack for extensions not implemented by Botan here.
592
   if(exts.contains_other_than(allowed)) {
463✔
593
      throw TLS_Exception(Alert::UnsupportedExtension, "Server Hello contained an extension that is not allowed");
2✔
594
   }
595

596
   // RFC 8446 4.1.3
597
   //    Current ServerHello messages additionally contain
598
   //    either the "pre_shared_key" extension or the "key_share"
599
   //    extension, or both [...].
600
   if(!exts.has<Key_Share>() && !exts.has<PSK_Key_Exchange_Modes>()) {
463✔
601
      throw TLS_Exception(Alert::MissingExtension, "server hello must contain key exchange information");
2✔
602
   }
603
}
467✔
604

605
Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data,
42✔
606
                                 Server_Hello_13::Hello_Retry_Request_Tag) :
42✔
607
      Server_Hello(std::move(data)) {
42✔
608
   BOTAN_ASSERT_NOMSG(m_data->is_hello_retry_request());
42✔
609
   basic_validation();
42✔
610

611
   const auto& exts = extensions();
41✔
612

613
   // RFC 8446 4.1.4
614
   //     The HelloRetryRequest extensions defined in this specification are:
615
   //     -  supported_versions (see Section 4.2.1)
616
   //     -  cookie (see Section 4.2.2)
617
   //     -  key_share (see Section 4.2.8)
618
   const std::set<Extension_Code> allowed = {
41✔
619
      Extension_Code::Cookie,
620
      Extension_Code::SupportedVersions,
621
      Extension_Code::KeyShare,
622
   };
41✔
623

624
   // As the Hello Retry Request shall only contain essential extensions, we
625
   // don't give any slack for extensions not implemented by Botan here.
626
   if(exts.contains_other_than(allowed)) {
41✔
627
      throw TLS_Exception(Alert::UnsupportedExtension,
1✔
628
                          "Hello Retry Request contained an extension that is not allowed");
2✔
629
   }
630

631
   // RFC 8446 4.1.4
632
   //    Clients MUST abort the handshake with an "illegal_parameter" alert if
633
   //    the HelloRetryRequest would not result in any change in the ClientHello.
634
   if(!exts.has<Key_Share>() && !exts.has<Cookie>()) {
42✔
635
      throw TLS_Exception(Alert::IllegalParameter, "Hello Retry Request does not request any changes to Client Hello");
1✔
636
   }
637
}
42✔
638

639
Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Hello_Retry_Request_Creation_Tag) :
35✔
640
      Server_Hello(std::move(data)) {}
35✔
641

642
namespace {
643

644
uint16_t choose_ciphersuite(const Client_Hello_13& ch, const Policy& policy) {
412✔
645
   auto pref_list = ch.ciphersuites();
412✔
646
   // TODO: DTLS might need to make this version dynamic
647
   auto other_list = policy.ciphersuite_list(Protocol_Version::TLS_V13);
432✔
648

649
   if(policy.server_uses_own_ciphersuite_preferences()) {
412✔
650
      std::swap(pref_list, other_list);
412✔
651
   }
652

653
   for(auto suite_id : pref_list) {
1,282✔
654
      // TODO: take potentially available PSKs into account to select a
655
      //       compatible ciphersuite.
656
      //
657
      // Assuming the client sent one or more PSKs, we would first need to find
658
      // the hash functions they are associated to. For session tickets, that
659
      // would mean decrypting the ticket and comparing the cipher suite used in
660
      // those tickets. For (currently not yet supported) pre-assigned PSKs, the
661
      // hash function needs to be specified along with them.
662
      //
663
      // Then we could refine the ciphersuite selection using the required hash
664
      // function for the PSK(s) we are wishing to use down the road.
665
      //
666
      // For now, we just negotiate the cipher suite blindly and hope for the
667
      // best. As long as PSKs are used for session resumption only, this has a
668
      // high chance of success. Previous handshakes with this client have very
669
      // likely selected the same ciphersuite anyway.
670
      //
671
      // See also RFC 8446 4.2.11
672
      //    When session resumption is the primary use case of PSKs, the most
673
      //    straightforward way to implement the PSK/cipher suite matching
674
      //    requirements is to negotiate the cipher suite first [...].
675
      if(value_exists(other_list, suite_id)) {
2,524✔
676
         return suite_id;
392✔
677
      }
678
   }
679

680
   // RFC 8446 4.1.1
681
   //     If the server is unable to negotiate a supported set of parameters
682
   //     [...], it MUST abort the handshake with either a "handshake_failure"
683
   //     or "insufficient_security" fatal alert [...].
684
   throw TLS_Exception(Alert::HandshakeFailure, "Can't agree on a ciphersuite with client");
20✔
685
}
804✔
686
}  // namespace
687

688
Server_Hello_13::Server_Hello_13(const Client_Hello_13& ch,
377✔
689
                                 std::optional<Named_Group> key_exchange_group,
690
                                 Session_Manager& session_mgr,
691
                                 RandomNumberGenerator& rng,
692
                                 Callbacks& cb,
693
                                 const Policy& policy) :
377✔
694
      Server_Hello(std::make_unique<Server_Hello_Internal>(
714✔
695
         Protocol_Version::TLS_V12,
696
         ch.session_id(),
357✔
697
         make_server_hello_random(rng, Protocol_Version::TLS_V13, cb, policy),
357✔
698
         choose_ciphersuite(ch, policy),
357✔
699
         uint8_t(0) /* compression method */
734✔
700
         )) {
734✔
701
   // RFC 8446 4.2.1
702
   //    A server which negotiates TLS 1.3 MUST respond by sending a
703
   //    "supported_versions" extension containing the selected version
704
   //    value (0x0304). It MUST set the ServerHello.legacy_version field to
705
   //     0x0303 (TLS 1.2).
706
   //
707
   // Note that the legacy version (TLS 1.2) is set in this constructor's
708
   // initializer list, accordingly.
709
   m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13));
357✔
710

711
   if(key_exchange_group.has_value()) {
357✔
712
      m_data->extensions().add(new Key_Share(key_exchange_group.value(), cb, rng));
357✔
713
   }
714

715
   auto& ch_exts = ch.extensions();
357✔
716

717
   if(ch_exts.has<PSK>()) {
357✔
718
      const auto cs = Ciphersuite::by_id(m_data->ciphersuite());
98✔
719
      BOTAN_ASSERT_NOMSG(cs);
98✔
720

721
      // RFC 8446 4.2.9
722
      //    A client MUST provide a "psk_key_exchange_modes" extension if it
723
      //    offers a "pre_shared_key" extension.
724
      //
725
      // Note: Client_Hello_13 constructor already performed a graceful check.
726
      const auto psk_modes = ch_exts.get<PSK_Key_Exchange_Modes>();
98✔
727
      BOTAN_ASSERT_NONNULL(psk_modes);
98✔
728

729
      // TODO: also support PSK_Key_Exchange_Mode::PSK_KE
730
      //       (PSK-based handshake without an additional ephemeral key exchange)
731
      if(value_exists(psk_modes->modes(), PSK_Key_Exchange_Mode::PSK_DHE_KE)) {
98✔
732
         if(auto server_psk = ch_exts.get<PSK>()->select_offered_psk(cs.value(), session_mgr, cb, policy)) {
97✔
733
            // RFC 8446 4.2.11
734
            //    In order to accept PSK key establishment, the server sends a
735
            //    "pre_shared_key" extension indicating the selected identity.
736
            m_data->extensions().add(std::move(server_psk));
190✔
737
         }
97✔
738
      }
739
   }
740

741
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
357✔
742
}
357✔
743

744
std::optional<Protocol_Version> Server_Hello_13::random_signals_downgrade() const {
×
745
   const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
×
746
   if(last8 == DOWNGRADE_TLS11) {
×
747
      return Protocol_Version::TLS_V11;
×
748
   }
749
   if(last8 == DOWNGRADE_TLS12) {
×
750
      return Protocol_Version::TLS_V12;
×
751
   }
752

753
   return std::nullopt;
×
754
}
755

756
Protocol_Version Server_Hello_13::selected_version() const {
2,448✔
757
   const auto versions_ext = m_data->extensions().get<Supported_Versions>();
2,448✔
758
   BOTAN_ASSERT_NOMSG(versions_ext);
2,448✔
759
   const auto& versions = versions_ext->versions();
2,448✔
760
   BOTAN_ASSERT_NOMSG(versions.size() == 1);
2,448✔
761
   return versions.front();
2,448✔
762
}
763

764
Hello_Retry_Request::Hello_Retry_Request(std::unique_ptr<Server_Hello_Internal> data) :
42✔
765
      Server_Hello_13(std::move(data), Server_Hello_13::as_hello_retry_request) {}
42✔
766

767
Hello_Retry_Request::Hello_Retry_Request(const Client_Hello_13& ch,
35✔
768
                                         Named_Group selected_group,
769
                                         const Policy& policy,
770
                                         Callbacks& cb) :
35✔
771
      Server_Hello_13(std::make_unique<Server_Hello_Internal>(Protocol_Version::TLS_V12 /* legacy_version */,
70✔
772
                                                              ch.session_id(),
35✔
773
                                                              HELLO_RETRY_REQUEST_MARKER,
774
                                                              choose_ciphersuite(ch, policy),
35✔
775
                                                              uint8_t(0) /* compression method */,
70✔
776
                                                              true /* is Hello Retry Request */
70✔
777
                                                              ),
778
                      as_new_hello_retry_request) {
70✔
779
   // RFC 8446 4.1.4
780
   //     As with the ServerHello, a HelloRetryRequest MUST NOT contain any
781
   //     extensions that were not first offered by the client in its
782
   //     ClientHello, with the exception of optionally the "cookie" [...]
783
   //     extension.
784
   BOTAN_STATE_CHECK(ch.extensions().has<Supported_Groups>());
35✔
785
   BOTAN_STATE_CHECK(ch.extensions().has<Key_Share>());
35✔
786

787
   BOTAN_STATE_CHECK(!value_exists(ch.extensions().get<Key_Share>()->offered_groups(), selected_group));
72✔
788

789
   // RFC 8446 4.1.4
790
   //    The server's extensions MUST contain "supported_versions".
791
   //
792
   // RFC 8446 4.2.1
793
   //    A server which negotiates TLS 1.3 MUST respond by sending a
794
   //    "supported_versions" extension containing the selected version
795
   //    value (0x0304). It MUST set the ServerHello.legacy_version field to
796
   //    0x0303 (TLS 1.2).
797
   //
798
   // Note that the legacy version (TLS 1.2) is set in this constructor's
799
   // initializer list, accordingly.
800
   m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13));
35✔
801

802
   m_data->extensions().add(new Key_Share(selected_group));
35✔
803

804
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
35✔
805
}
35✔
806

807
#endif  // BOTAN_HAS_TLS_13
808

809
}  // namespace Botan::TLS
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc