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

randombit / botan / 12468325145

23 Dec 2024 02:25PM UTC coverage: 91.249% (-1.2%) from 92.433%
12468325145

Pull #4475

github

web-flow
Merge 7f9570002 into 6471abdd1
Pull Request #4475: Add a compile-time `hex_decode_array()`

93396 of 102353 relevant lines covered (91.25%)

11367262.49 hits per line

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

94.46
/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/ct_utils.h>
20
#include <botan/internal/literals.h>
21
#include <botan/internal/stl_util.h>
22
#include <botan/internal/tls_handshake_hash.h>
23
#include <botan/internal/tls_handshake_io.h>
24
#include <botan/internal/tls_reader.h>
25
#include <botan/internal/tls_session_key.h>
26

27
#include <array>
28

29
namespace Botan::TLS {
30

31
namespace {
32

33
const uint64_t DOWNGRADE_TLS11 = 0x444F574E47524400;
34
const uint64_t DOWNGRADE_TLS12 = 0x444F574E47524401;
35

36
// SHA-256("HelloRetryRequest")
37
using namespace literals;
38
constexpr auto HELLO_RETRY_REQUEST_MARKER =
39
   "CF:21:AD:74:E5:9A:61:11:BE:1D:8C:02:1E:65:B8:91:C2:A2:11:16:7A:BB:8C:5E:07:9E:09:E2:C8:A8:33:9C"_hex;
40

41
bool random_signals_hello_retry_request(const std::vector<uint8_t>& random) {
3,554✔
42
   return CT::is_equal(random.data(), HELLO_RETRY_REQUEST_MARKER.data(), HELLO_RETRY_REQUEST_MARKER.size()).as_bool();
3,554✔
43
}
44

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

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

67
   return random;
1,121✔
68
}
×
69

70
}  // namespace
71

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

87
         TLS_Data_Reader reader("ServerHello", buf);
3,554✔
88

89
         const uint8_t major_version = reader.get_byte();
3,554✔
90
         const uint8_t minor_version = reader.get_byte();
3,554✔
91

92
         m_legacy_version = Protocol_Version(major_version, minor_version);
3,554✔
93

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

101
         m_session_id = Session_ID(reader.get_range<uint8_t>(1, 0, 32));
3,554✔
102
         m_ciphersuite = reader.get_uint16_t();
3,545✔
103
         m_comp_method = reader.get_byte();
3,543✔
104

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

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

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

142
      Protocol_Version legacy_version() const { return m_legacy_version; }
2,112✔
143

144
      const Session_ID& session_id() const { return m_session_id; }
5,830✔
145

146
      const std::vector<uint8_t>& random() const { return m_random; }
1,871✔
147

148
      uint16_t ciphersuite() const { return m_ciphersuite; }
2,209✔
149

150
      uint8_t comp_method() const { return m_comp_method; }
1,379✔
151

152
      bool is_hello_retry_request() const { return m_is_hello_retry_request; }
1,072✔
153

154
      const Extensions& extensions() const { return m_extensions; }
4,438✔
155

156
      Extensions& extensions() { return m_extensions; }
32,797✔
157

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

166
      Extensions m_extensions;
167
};
168

169
Server_Hello::Server_Hello(std::unique_ptr<Server_Hello_Internal> data) : m_data(std::move(data)) {}
4,790✔
170

171
Server_Hello::Server_Hello(Server_Hello&&) noexcept = default;
11,512✔
172
Server_Hello& Server_Hello::operator=(Server_Hello&&) noexcept = default;
1✔
173

174
Server_Hello::~Server_Hello() = default;
16,289✔
175

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

183
   buf.push_back(m_data->legacy_version().major_version());
1,379✔
184
   buf.push_back(m_data->legacy_version().minor_version());
1,379✔
185
   buf += m_data->random();
1,379✔
186

187
   append_tls_length_value(buf, m_data->session_id().get(), 1);
1,379✔
188

189
   buf.push_back(get_byte<0>(m_data->ciphersuite()));
1,379✔
190
   buf.push_back(get_byte<1>(m_data->ciphersuite()));
1,379✔
191

192
   buf.push_back(m_data->comp_method());
1,379✔
193

194
   buf += m_data->extensions().serialize(Connection_Side::Server);
1,379✔
195

196
   return buf;
1,379✔
197
}
×
198

199
Handshake_Type Server_Hello::type() const {
7,381✔
200
   return Handshake_Type::ServerHello;
7,381✔
201
}
202

203
Protocol_Version Server_Hello::legacy_version() const {
9,677✔
204
   return m_data->legacy_version();
9,677✔
205
}
206

207
const std::vector<uint8_t>& Server_Hello::random() const {
3,649✔
208
   return m_data->random();
3,649✔
209
}
210

211
uint8_t Server_Hello::compression_method() const {
5,306✔
212
   return m_data->comp_method();
5,306✔
213
}
214

215
const Session_ID& Server_Hello::session_id() const {
5,830✔
216
   return m_data->session_id();
5,830✔
217
}
218

219
uint16_t Server_Hello::ciphersuite() const {
12,603✔
220
   return m_data->ciphersuite();
12,603✔
221
}
222

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

227
const Extensions& Server_Hello::extensions() const {
7,167✔
228
   return m_data->extensions();
7,167✔
229
}
230

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

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

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

260
   const auto c = Ciphersuite::by_id(m_data->ciphersuite());
733✔
261

262
   if(c && c->cbc_ciphersuite() && client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) {
733✔
263
      m_data->extensions().add(new Encrypt_then_MAC);
14✔
264
   }
265

266
   if(c && c->ecc_ciphersuite() && client_hello.extension_types().contains(Extension_Code::EcPointFormats)) {
2,102✔
267
      m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
635✔
268
   }
269

270
   if(client_hello.secure_renegotiation()) {
733✔
271
      m_data->extensions().add(new Renegotiation_Extension(reneg_info));
730✔
272
   }
273

274
   if(client_hello.supports_session_ticket() && server_settings.offer_session_ticket()) {
733✔
275
      m_data->extensions().add(new Session_Ticket_Extension());
543✔
276
   }
277

278
   if(m_data->legacy_version().is_datagram_protocol()) {
733✔
279
      const std::vector<uint16_t> server_srtp = policy.srtp_profiles();
290✔
280
      const std::vector<uint16_t> client_srtp = client_hello.srtp_profiles();
290✔
281

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

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

299
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
733✔
300

301
   hash.update(io.send(*this));
1,466✔
302
}
733✔
303

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

324
   if(!next_protocol.empty() && client_hello.supports_alpn()) {
228✔
325
      m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocol));
13✔
326
   }
327

328
   if(client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) {
228✔
329
      Ciphersuite c = resumed_session.ciphersuite();
2✔
330
      if(c.cbc_ciphersuite()) {
2✔
331
         m_data->extensions().add(new Encrypt_then_MAC);
2✔
332
      }
333
   }
334

335
   if(resumed_session.ciphersuite().ecc_ciphersuite() &&
228✔
336
      client_hello.extension_types().contains(Extension_Code::EcPointFormats)) {
644✔
337
      m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
208✔
338
   }
339

340
   if(client_hello.secure_renegotiation()) {
228✔
341
      m_data->extensions().add(new Renegotiation_Extension(reneg_info));
228✔
342
   }
343

344
   if(client_hello.supports_session_ticket() && offer_session_ticket) {
228✔
345
      m_data->extensions().add(new Session_Ticket_Extension());
1✔
346
   }
347

348
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
228✔
349

350
   hash.update(io.send(*this));
456✔
351
}
228✔
352

353
Server_Hello_12::Server_Hello_12(const std::vector<uint8_t>& buf) :
2,515✔
354
      Server_Hello_12(std::make_unique<Server_Hello_Internal>(buf)) {}
2,515✔
355

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

362
Protocol_Version Server_Hello_12::selected_version() const {
490✔
363
   return legacy_version();
490✔
364
}
365

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

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

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

381
bool Server_Hello_12::supports_encrypt_then_mac() const {
6,154✔
382
   return m_data->extensions().has<Encrypt_then_MAC>();
6,154✔
383
}
384

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

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

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

402
   return 0;
403
}
404

405
std::string Server_Hello_12::next_protocol() const {
1,174✔
406
   if(auto alpn = m_data->extensions().get<Application_Layer_Protocol_Notification>()) {
1,174✔
407
      return alpn->single_protocol();
133✔
408
   }
409
   return "";
1,041✔
410
}
411

412
bool Server_Hello_12::prefers_compressed_ec_points() const {
13✔
413
   if(auto ecc_formats = m_data->extensions().get<Supported_Point_Formats>()) {
13✔
414
      return ecc_formats->prefers_compressed();
10✔
415
   }
416
   return false;
417
}
418

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

428
   return std::nullopt;
491✔
429
}
430

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

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

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

454
#if defined(BOTAN_HAS_TLS_13)
455

456
const Server_Hello_13::Server_Hello_Tag Server_Hello_13::as_server_hello;
457
const Server_Hello_13::Hello_Retry_Request_Tag Server_Hello_13::as_hello_retry_request;
458
const Server_Hello_13::Hello_Retry_Request_Creation_Tag Server_Hello_13::as_new_hello_retry_request;
459

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

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

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

488
   // RFC 8446 4.2.8:
489
   //    Servers MUST NOT send a KeyShareEntry for any group not indicated in the
490
   //    client's "supported_groups" extension [...]
491
   if(!value_exists(supported_by_client, selected_group)) {
424✔
492
      throw TLS_Exception(Alert::InternalError, "Application selected a group that is not supported by the client");
×
493
   }
494

495
   // RFC 8446 4.1.4
496
   //    The server will send this message in response to a ClientHello
497
   //    message if it is able to find an acceptable set of parameters but the
498
   //    ClientHello does not contain sufficient information to proceed with
499
   //    the handshake.
500
   //
501
   // In this case, the Client Hello did not contain a key share offer for
502
   // the group selected by the application.
503
   if(!value_exists(offered_by_client, selected_group)) {
424✔
504
      // RFC 8446 4.1.4
505
      //    If a client receives a second HelloRetryRequest in the same
506
      //    connection (i.e., where the ClientHello was itself in response to a
507
      //    HelloRetryRequest), it MUST abort the handshake with an
508
      //    "unexpected_message" alert.
509
      BOTAN_STATE_CHECK(hello_retry_request_allowed);
36✔
510
      return Hello_Retry_Request(ch, selected_group, policy, cb);
72✔
511
   } else {
512
      return Server_Hello_13(ch, selected_group, session_mgr, credentials_mgr, rng, cb, policy);
757✔
513
   }
514
}
405✔
515

516
std::variant<Hello_Retry_Request, Server_Hello_13, Server_Hello_12> Server_Hello_13::parse(
1,045✔
517
   const std::vector<uint8_t>& buf) {
518
   auto data = std::make_unique<Server_Hello_Internal>(buf);
1,045✔
519
   const auto version = data->version();
1,033✔
520

521
   // server hello that appears to be pre-TLS 1.3, takes precedence over...
522
   if(version.is_pre_tls_13()) {
1,033✔
523
      return Server_Hello_12(std::move(data));
994✔
524
   }
525

526
   // ... the TLS 1.3 "special case" aka. Hello_Retry_Request
527
   if(version == Protocol_Version::TLS_V13) {
536✔
528
      if(data->is_hello_retry_request()) {
536✔
529
         return Hello_Retry_Request(std::move(data));
119✔
530
      }
531

532
      return Server_Hello_13(std::move(data));
942✔
533
   }
534

535
   throw TLS_Exception(Alert::ProtocolVersion, "unexpected server hello version: " + version.to_string());
×
536
}
1,033✔
537

538
/**
539
 * Validation that applies to both Server Hello and Hello Retry Request
540
 */
541
void Server_Hello_13::basic_validation() const {
536✔
542
   BOTAN_ASSERT_NOMSG(m_data->version() == Protocol_Version::TLS_V13);
1,072✔
543

544
   // Note: checks that cannot be performed without contextual information
545
   //       are done in the specific TLS client implementation.
546
   // Note: The Supported_Version extension makes sure internally that
547
   //       exactly one entry is provided.
548

549
   // Note: Hello Retry Request basic validation is equivalent with the
550
   //       basic validations required for Server Hello
551
   //
552
   // RFC 8446 4.1.4
553
   //    Upon receipt of a HelloRetryRequest, the client MUST check the
554
   //    legacy_version, [...], and legacy_compression_method as specified in
555
   //    Section 4.1.3 and then process the extensions, starting with determining
556
   //    the version using "supported_versions".
557

558
   // RFC 8446 4.1.3
559
   //    In TLS 1.3, [...] the legacy_version field MUST be set to 0x0303
560
   if(legacy_version() != Protocol_Version::TLS_V12) {
536✔
561
      throw TLS_Exception(Alert::ProtocolVersion,
2✔
562
                          "legacy_version '" + legacy_version().to_string() + "' is not allowed");
6✔
563
   }
564

565
   // RFC 8446 4.1.3
566
   //    legacy_compression_method:  A single byte which MUST have the value 0.
567
   if(compression_method() != 0x00) {
534✔
568
      throw TLS_Exception(Alert::DecodeError, "compression is not supported in TLS 1.3");
2✔
569
   }
570

571
   // RFC 8446 4.1.3
572
   //    All TLS 1.3 ServerHello messages MUST contain the "supported_versions" extension.
573
   if(!extensions().has<Supported_Versions>()) {
532✔
574
      throw TLS_Exception(Alert::MissingExtension, "server hello did not contain 'supported version' extension");
×
575
   }
576

577
   // RFC 8446 4.2.1
578
   //    A server which negotiates TLS 1.3 MUST respond by sending
579
   //    a "supported_versions" extension containing the selected version
580
   //    value (0x0304).
581
   if(selected_version() != Protocol_Version::TLS_V13) {
532✔
582
      throw TLS_Exception(Alert::IllegalParameter, "TLS 1.3 Server Hello selected a different version");
1✔
583
   }
584
}
531✔
585

586
Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Server_Hello_13::Server_Hello_Tag) :
475✔
587
      Server_Hello(std::move(data)) {
475✔
588
   BOTAN_ASSERT_NOMSG(!m_data->is_hello_retry_request());
475✔
589
   basic_validation();
475✔
590

591
   const auto& exts = extensions();
471✔
592

593
   // RFC 8446 4.1.3
594
   //    The ServerHello MUST only include extensions which are required to
595
   //    establish the cryptographic context and negotiate the protocol version.
596
   //    [...]
597
   //    Other extensions (see Section 4.2) are sent separately in the
598
   //    EncryptedExtensions message.
599
   //
600
   // Note that further validation dependent on the client hello is done in the
601
   // TLS client implementation.
602
   const std::set<Extension_Code> allowed = {
471✔
603
      Extension_Code::KeyShare,
604
      Extension_Code::SupportedVersions,
605
      Extension_Code::PresharedKey,
606
   };
471✔
607

608
   // As the ServerHello shall only contain essential extensions, we don't give
609
   // any slack for extensions not implemented by Botan here.
610
   if(exts.contains_other_than(allowed)) {
471✔
611
      throw TLS_Exception(Alert::UnsupportedExtension, "Server Hello contained an extension that is not allowed");
2✔
612
   }
613

614
   // RFC 8446 4.1.3
615
   //    Current ServerHello messages additionally contain
616
   //    either the "pre_shared_key" extension or the "key_share"
617
   //    extension, or both [...].
618
   if(!exts.has<Key_Share>() && !exts.has<PSK_Key_Exchange_Modes>()) {
471✔
619
      throw TLS_Exception(Alert::MissingExtension, "server hello must contain key exchange information");
2✔
620
   }
621
}
475✔
622

623
Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data,
61✔
624
                                 Server_Hello_13::Hello_Retry_Request_Tag) :
61✔
625
      Server_Hello(std::move(data)) {
61✔
626
   BOTAN_ASSERT_NOMSG(m_data->is_hello_retry_request());
61✔
627
   basic_validation();
61✔
628

629
   const auto& exts = extensions();
60✔
630

631
   // RFC 8446 4.1.4
632
   //     The HelloRetryRequest extensions defined in this specification are:
633
   //     -  supported_versions (see Section 4.2.1)
634
   //     -  cookie (see Section 4.2.2)
635
   //     -  key_share (see Section 4.2.8)
636
   const std::set<Extension_Code> allowed = {
60✔
637
      Extension_Code::Cookie,
638
      Extension_Code::SupportedVersions,
639
      Extension_Code::KeyShare,
640
   };
60✔
641

642
   // As the Hello Retry Request shall only contain essential extensions, we
643
   // don't give any slack for extensions not implemented by Botan here.
644
   if(exts.contains_other_than(allowed)) {
60✔
645
      throw TLS_Exception(Alert::UnsupportedExtension,
1✔
646
                          "Hello Retry Request contained an extension that is not allowed");
1✔
647
   }
648

649
   // RFC 8446 4.1.4
650
   //    Clients MUST abort the handshake with an "illegal_parameter" alert if
651
   //    the HelloRetryRequest would not result in any change in the ClientHello.
652
   if(!exts.has<Key_Share>() && !exts.has<Cookie>()) {
61✔
653
      throw TLS_Exception(Alert::IllegalParameter, "Hello Retry Request does not request any changes to Client Hello");
1✔
654
   }
655
}
61✔
656

657
Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Hello_Retry_Request_Creation_Tag) :
36✔
658
      Server_Hello(std::move(data)) {}
36✔
659

660
namespace {
661

662
uint16_t choose_ciphersuite(const Client_Hello_13& ch, const Policy& policy) {
424✔
663
   auto pref_list = ch.ciphersuites();
424✔
664
   // TODO: DTLS might need to make this version dynamic
665
   auto other_list = policy.ciphersuite_list(Protocol_Version::TLS_V13);
424✔
666

667
   if(policy.server_uses_own_ciphersuite_preferences()) {
424✔
668
      std::swap(pref_list, other_list);
424✔
669
   }
670

671
   for(auto suite_id : pref_list) {
1,270✔
672
      // TODO: take potentially available PSKs into account to select a
673
      //       compatible ciphersuite.
674
      //
675
      // Assuming the client sent one or more PSKs, we would first need to find
676
      // the hash functions they are associated to. For session tickets, that
677
      // would mean decrypting the ticket and comparing the cipher suite used in
678
      // those tickets. For (currently not yet supported) pre-assigned PSKs, the
679
      // hash function needs to be specified along with them.
680
      //
681
      // Then we could refine the ciphersuite selection using the required hash
682
      // function for the PSK(s) we are wishing to use down the road.
683
      //
684
      // For now, we just negotiate the cipher suite blindly and hope for the
685
      // best. As long as PSKs are used for session resumption only, this has a
686
      // high chance of success. Previous handshakes with this client have very
687
      // likely selected the same ciphersuite anyway.
688
      //
689
      // See also RFC 8446 4.2.11
690
      //    When session resumption is the primary use case of PSKs, the most
691
      //    straightforward way to implement the PSK/cipher suite matching
692
      //    requirements is to negotiate the cipher suite first [...].
693
      if(value_exists(other_list, suite_id)) {
2,540✔
694
         return suite_id;
424✔
695
      }
696
   }
697

698
   // RFC 8446 4.1.1
699
   //     If the server is unable to negotiate a supported set of parameters
700
   //     [...], it MUST abort the handshake with either a "handshake_failure"
701
   //     or "insufficient_security" fatal alert [...].
702
   throw TLS_Exception(Alert::HandshakeFailure, "Can't agree on a ciphersuite with client");
×
703
}
848✔
704
}  // namespace
705

706
Server_Hello_13::Server_Hello_13(const Client_Hello_13& ch,
388✔
707
                                 std::optional<Named_Group> key_exchange_group,
708
                                 Session_Manager& session_mgr,
709
                                 Credentials_Manager& credentials_mgr,
710
                                 RandomNumberGenerator& rng,
711
                                 Callbacks& cb,
712
                                 const Policy& policy) :
388✔
713
      Server_Hello(std::make_unique<Server_Hello_Internal>(
776✔
714
         Protocol_Version::TLS_V12,
715
         ch.session_id(),
388✔
716
         make_server_hello_random(rng, Protocol_Version::TLS_V13, cb, policy),
388✔
717
         choose_ciphersuite(ch, policy),
388✔
718
         uint8_t(0) /* compression method */
776✔
719
         )) {
776✔
720
   // RFC 8446 4.2.1
721
   //    A server which negotiates TLS 1.3 MUST respond by sending a
722
   //    "supported_versions" extension containing the selected version
723
   //    value (0x0304). It MUST set the ServerHello.legacy_version field to
724
   //     0x0303 (TLS 1.2).
725
   //
726
   // Note that the legacy version (TLS 1.2) is set in this constructor's
727
   // initializer list, accordingly.
728
   m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13));
388✔
729

730
   if(key_exchange_group.has_value()) {
388✔
731
      BOTAN_ASSERT_NOMSG(ch.extensions().has<Key_Share>());
388✔
732
      m_data->extensions().add(Key_Share::create_as_encapsulation(
1,145✔
733
         key_exchange_group.value(), *ch.extensions().get<Key_Share>(), policy, cb, rng));
388✔
734
   }
735

736
   auto& ch_exts = ch.extensions();
369✔
737

738
   if(ch_exts.has<PSK>()) {
369✔
739
      const auto cs = Ciphersuite::by_id(m_data->ciphersuite());
97✔
740
      BOTAN_ASSERT_NOMSG(cs);
97✔
741

742
      // RFC 8446 4.2.9
743
      //    A client MUST provide a "psk_key_exchange_modes" extension if it
744
      //    offers a "pre_shared_key" extension.
745
      //
746
      // Note: Client_Hello_13 constructor already performed a graceful check.
747
      const auto psk_modes = ch_exts.get<PSK_Key_Exchange_Modes>();
97✔
748
      BOTAN_ASSERT_NONNULL(psk_modes);
97✔
749

750
      // TODO: also support PSK_Key_Exchange_Mode::PSK_KE
751
      //       (PSK-based handshake without an additional ephemeral key exchange)
752
      if(value_exists(psk_modes->modes(), PSK_Key_Exchange_Mode::PSK_DHE_KE)) {
97✔
753
         if(auto server_psk = ch_exts.get<PSK>()->select_offered_psk(
96✔
754
               ch.sni_hostname(), cs.value(), session_mgr, credentials_mgr, cb, policy)) {
192✔
755
            // RFC 8446 4.2.11
756
            //    In order to accept PSK key establishment, the server sends a
757
            //    "pre_shared_key" extension indicating the selected identity.
758
            m_data->extensions().add(std::move(server_psk));
188✔
759
         }
96✔
760
      }
761
   }
762

763
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
369✔
764
}
388✔
765

766
std::optional<Protocol_Version> Server_Hello_13::random_signals_downgrade() const {
×
767
   const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
×
768
   if(last8 == DOWNGRADE_TLS11) {
×
769
      return Protocol_Version::TLS_V11;
×
770
   }
771
   if(last8 == DOWNGRADE_TLS12) {
×
772
      return Protocol_Version::TLS_V12;
×
773
   }
774

775
   return std::nullopt;
×
776
}
777

778
Protocol_Version Server_Hello_13::selected_version() const {
2,597✔
779
   const auto versions_ext = m_data->extensions().get<Supported_Versions>();
2,597✔
780
   BOTAN_ASSERT_NOMSG(versions_ext);
2,597✔
781
   const auto& versions = versions_ext->versions();
2,597✔
782
   BOTAN_ASSERT_NOMSG(versions.size() == 1);
2,597✔
783
   return versions.front();
2,597✔
784
}
785

786
Hello_Retry_Request::Hello_Retry_Request(std::unique_ptr<Server_Hello_Internal> data) :
61✔
787
      Server_Hello_13(std::move(data), Server_Hello_13::as_hello_retry_request) {}
61✔
788

789
Hello_Retry_Request::Hello_Retry_Request(const Client_Hello_13& ch,
36✔
790
                                         Named_Group selected_group,
791
                                         const Policy& policy,
792
                                         Callbacks& cb) :
36✔
793
      Server_Hello_13(std::make_unique<Server_Hello_Internal>(
72✔
794
                         Protocol_Version::TLS_V12 /* legacy_version */,
795
                         ch.session_id(),
36✔
796
                         std::vector(HELLO_RETRY_REQUEST_MARKER.begin(), HELLO_RETRY_REQUEST_MARKER.end()),
36✔
797
                         choose_ciphersuite(ch, policy),
36✔
798
                         uint8_t(0) /* compression method */,
72✔
799
                         true /* is Hello Retry Request */
72✔
800
                         ),
801
                      as_new_hello_retry_request) {
72✔
802
   // RFC 8446 4.1.4
803
   //     As with the ServerHello, a HelloRetryRequest MUST NOT contain any
804
   //     extensions that were not first offered by the client in its
805
   //     ClientHello, with the exception of optionally the "cookie" [...]
806
   //     extension.
807
   BOTAN_STATE_CHECK(ch.extensions().has<Supported_Groups>());
36✔
808
   BOTAN_STATE_CHECK(ch.extensions().has<Key_Share>());
36✔
809

810
   BOTAN_STATE_CHECK(!value_exists(ch.extensions().get<Key_Share>()->offered_groups(), selected_group));
75✔
811

812
   // RFC 8446 4.1.4
813
   //    The server's extensions MUST contain "supported_versions".
814
   //
815
   // RFC 8446 4.2.1
816
   //    A server which negotiates TLS 1.3 MUST respond by sending a
817
   //    "supported_versions" extension containing the selected version
818
   //    value (0x0304). It MUST set the ServerHello.legacy_version field to
819
   //    0x0303 (TLS 1.2).
820
   //
821
   // Note that the legacy version (TLS 1.2) is set in this constructor's
822
   // initializer list, accordingly.
823
   m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13));
36✔
824

825
   m_data->extensions().add(new Key_Share(selected_group));
36✔
826

827
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
36✔
828
}
36✔
829

830
#endif  // BOTAN_HAS_TLS_13
831

832
}  // 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

© 2026 Coveralls, Inc