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

randombit / botan / 21848380424

10 Feb 2026 01:47AM UTC coverage: 91.634% (+1.6%) from 90.069%
21848380424

push

github

web-flow
Merge pull request #5296 from randombit/jack/tls-header-patrol

Various changes to reduce header dependencies in TLS

104002 of 113497 relevant lines covered (91.63%)

11230277.53 hits per line

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

94.5
/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_12.h>
13

14
#include <botan/tls_callbacks.h>
15
#include <botan/tls_ciphersuite.h>
16
#include <botan/tls_exceptn.h>
17
#include <botan/tls_extensions.h>
18
#include <botan/tls_policy.h>
19
#include <botan/tls_session.h>
20
#include <botan/tls_session_manager.h>
21
#include <botan/internal/ct_utils.h>
22
#include <botan/internal/stl_util.h>
23
#include <botan/internal/tls_handshake_hash.h>
24
#include <botan/internal/tls_handshake_io.h>
25
#include <botan/internal/tls_reader.h>
26

27
#ifdef BOTAN_HAS_TLS_13
28
   #include <botan/tls_messages_13.h>
29
#endif
30

31
#include <array>
32

33
namespace Botan::TLS {
34

35
namespace {
36

37
const uint64_t DOWNGRADE_TLS11 = 0x444F574E47524400;
38
const uint64_t DOWNGRADE_TLS12 = 0x444F574E47524401;
39

40
// SHA-256("HelloRetryRequest")
41
const std::array<uint8_t, 32> HELLO_RETRY_REQUEST_MARKER = {
42
   0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
43
   0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C};
44

45
bool random_signals_hello_retry_request(const std::vector<uint8_t>& random) {
3,563✔
46
   return CT::is_equal(random.data(), HELLO_RETRY_REQUEST_MARKER.data(), HELLO_RETRY_REQUEST_MARKER.size()).as_bool();
3,563✔
47
}
48

49
std::vector<uint8_t> make_server_hello_random(RandomNumberGenerator& rng,
1,117✔
50
                                              Protocol_Version offered_version,
51
                                              Callbacks& cb,
52
                                              const Policy& policy) {
53
   BOTAN_UNUSED(offered_version);
1,117✔
54
   auto random = make_hello_random(rng, cb, policy);
1,117✔
55

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

71
   return random;
1,117✔
72
}
×
73

74
}  // namespace
75

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

91
         TLS_Data_Reader reader("ServerHello", buf);
3,563✔
92

93
         const uint8_t major_version = reader.get_byte();
3,563✔
94
         const uint8_t minor_version = reader.get_byte();
3,563✔
95

96
         m_legacy_version = Protocol_Version(major_version, minor_version);
3,563✔
97

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

105
         m_session_id = Session_ID(reader.get_range<uint8_t>(1, 0, 32));
3,563✔
106
         m_ciphersuite = reader.get_uint16_t();
3,554✔
107
         m_comp_method = reader.get_byte();
3,552✔
108

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

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

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

146
      Protocol_Version legacy_version() const { return m_legacy_version; }
2,131✔
147

148
      const Session_ID& session_id() const { return m_session_id; }
6,912✔
149

150
      const std::vector<uint8_t>& random() const { return m_random; }
2,010✔
151

152
      uint16_t ciphersuite() const { return m_ciphersuite; }
2,228✔
153

154
      uint8_t comp_method() const { return m_comp_method; }
1,397✔
155

156
      bool is_hello_retry_request() const { return m_is_hello_retry_request; }
1,076✔
157

158
      const Extensions& extensions() const { return m_extensions; }
4,449✔
159

160
      Extensions& extensions() { return m_extensions; }
39,553✔
161

162
   private:
163
      Protocol_Version m_legacy_version;
164
      Session_ID m_session_id;
165
      std::vector<uint8_t> m_random;
166
      bool m_is_hello_retry_request;
167
      uint16_t m_ciphersuite;
168
      uint8_t m_comp_method;
169

170
      Extensions m_extensions;
171
};
172

173
Server_Hello::Server_Hello(std::unique_ptr<Server_Hello_Internal> data) : m_data(std::move(data)) {}
4,814✔
174

175
Server_Hello::Server_Hello(Server_Hello&&) noexcept = default;
11,596✔
176
Server_Hello& Server_Hello::operator=(Server_Hello&&) noexcept = default;
1✔
177

178
Server_Hello::~Server_Hello() = default;
16,397✔
179

180
/*
181
* Serialize a Server Hello message
182
*/
183
std::vector<uint8_t> Server_Hello::serialize() const {
1,397✔
184
   std::vector<uint8_t> buf;
1,397✔
185
   buf.reserve(1024);  // working around GCC warning
1,397✔
186

187
   buf.push_back(m_data->legacy_version().major_version());
1,397✔
188
   buf.push_back(m_data->legacy_version().minor_version());
1,397✔
189
   buf += m_data->random();
1,397✔
190

191
   append_tls_length_value(buf, m_data->session_id().get(), 1);
1,397✔
192

193
   buf.push_back(get_byte<0>(m_data->ciphersuite()));
1,397✔
194
   buf.push_back(get_byte<1>(m_data->ciphersuite()));
1,397✔
195

196
   buf.push_back(m_data->comp_method());
1,397✔
197

198
   buf += m_data->extensions().serialize(Connection_Side::Server);
1,397✔
199

200
   return buf;
1,397✔
201
}
×
202

203
Handshake_Type Server_Hello::type() const {
7,382✔
204
   return Handshake_Type::ServerHello;
7,382✔
205
}
206

207
Protocol_Version Server_Hello::legacy_version() const {
13,963✔
208
   return m_data->legacy_version();
13,963✔
209
}
210

211
const std::vector<uint8_t>& Server_Hello::random() const {
3,830✔
212
   return m_data->random();
3,830✔
213
}
214

215
uint8_t Server_Hello::compression_method() const {
6,512✔
216
   return m_data->comp_method();
6,512✔
217
}
218

219
const Session_ID& Server_Hello::session_id() const {
6,912✔
220
   return m_data->session_id();
6,912✔
221
}
222

223
uint16_t Server_Hello::ciphersuite() const {
14,942✔
224
   return m_data->ciphersuite();
14,942✔
225
}
226

227
std::set<Extension_Code> Server_Hello::extension_types() const {
2,319✔
228
   return m_data->extensions().extension_types();
2,319✔
229
}
230

231
const Extensions& Server_Hello::extensions() const {
8,177✔
232
   return m_data->extensions();
8,177✔
233
}
234

235
// New session case
236
Server_Hello_12::Server_Hello_12(Handshake_IO& io,
734✔
237
                                 Handshake_Hash& hash,
238
                                 const Policy& policy,
239
                                 Callbacks& cb,
240
                                 RandomNumberGenerator& rng,
241
                                 const std::vector<uint8_t>& reneg_info,
242
                                 const Client_Hello_12& client_hello,
243
                                 const Server_Hello_12::Settings& server_settings,
244
                                 std::string_view next_protocol) :
734✔
245
      Server_Hello(std::make_unique<Server_Hello_Internal>(
734✔
246
         server_settings.protocol_version(),
734✔
247
         server_settings.session_id(),
734✔
248
         make_server_hello_random(rng, server_settings.protocol_version(), cb, policy),
1,468✔
249
         server_settings.ciphersuite(),
734✔
250
         uint8_t(0))) {
1,468✔
251
   // NOLINTBEGIN(*-owning-memory)
252
   if(client_hello.supports_extended_master_secret()) {
734✔
253
      m_data->extensions().add(new Extended_Master_Secret);
729✔
254
   }
255

256
   // Sending the extension back does not commit us to sending a stapled response
257
   if(client_hello.supports_cert_status_message() && policy.support_cert_status_message()) {
734✔
258
      m_data->extensions().add(new Certificate_Status_Request);
200✔
259
   }
260

261
   if(!next_protocol.empty() && client_hello.supports_alpn()) {
734✔
262
      m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocol));
120✔
263
   }
264

265
   const auto c = Ciphersuite::by_id(m_data->ciphersuite());
734✔
266

267
   if(c && c->cbc_ciphersuite() && client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) {
734✔
268
      m_data->extensions().add(new Encrypt_then_MAC);
11✔
269
   }
270

271
   if(c && c->ecc_ciphersuite() && client_hello.extension_types().contains(Extension_Code::EcPointFormats)) {
2,104✔
272
      m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
635✔
273
   }
274

275
   if(client_hello.secure_renegotiation()) {
734✔
276
      m_data->extensions().add(new Renegotiation_Extension(reneg_info));
731✔
277
   }
278

279
   if(client_hello.supports_session_ticket() && server_settings.offer_session_ticket()) {
734✔
280
      m_data->extensions().add(new Session_Ticket_Extension());
543✔
281
   }
282

283
   if(m_data->legacy_version().is_datagram_protocol()) {
734✔
284
      const std::vector<uint16_t> server_srtp = policy.srtp_profiles();
289✔
285
      const std::vector<uint16_t> client_srtp = client_hello.srtp_profiles();
289✔
286

287
      if(!server_srtp.empty() && !client_srtp.empty()) {
289✔
288
         uint16_t shared = 0;
289
         // always using server preferences for now
290
         for(auto s_srtp : server_srtp) {
6✔
291
            for(auto c_srtp : client_srtp) {
16✔
292
               if(shared == 0 && s_srtp == c_srtp) {
12✔
293
                  shared = s_srtp;
1✔
294
               }
295
            }
296
         }
297

298
         if(shared != 0) {
2✔
299
            m_data->extensions().add(new SRTP_Protection_Profiles(shared));
1✔
300
         }
301
      }
302
   }
291✔
303
   // NOLINTEND(*-owning-memory)
304

305
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
734✔
306

307
   hash.update(io.send(*this));
1,468✔
308
}
734✔
309

310
// Resuming
311
Server_Hello_12::Server_Hello_12(Handshake_IO& io,
234✔
312
                                 Handshake_Hash& hash,
313
                                 const Policy& policy,
314
                                 Callbacks& cb,
315
                                 RandomNumberGenerator& rng,
316
                                 const std::vector<uint8_t>& reneg_info,
317
                                 const Client_Hello_12& client_hello,
318
                                 const Session& resumed_session,
319
                                 bool offer_session_ticket,
320
                                 std::string_view next_protocol) :
234✔
321
      Server_Hello(std::make_unique<Server_Hello_Internal>(resumed_session.version(),
468✔
322
                                                           client_hello.session_id(),
234✔
323
                                                           make_hello_random(rng, cb, policy),
468✔
324
                                                           resumed_session.ciphersuite_code(),
468✔
325
                                                           uint8_t(0))) {
468✔
326
   // NOLINTBEGIN(*-owning-memory)
327
   if(client_hello.supports_extended_master_secret()) {
234✔
328
      m_data->extensions().add(new Extended_Master_Secret);
233✔
329
   }
330

331
   if(!next_protocol.empty() && client_hello.supports_alpn()) {
234✔
332
      m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocol));
19✔
333
   }
334

335
   if(client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) {
234✔
336
      const Ciphersuite c = resumed_session.ciphersuite();
5✔
337
      if(c.cbc_ciphersuite()) {
5✔
338
         m_data->extensions().add(new Encrypt_then_MAC);
5✔
339
      }
340
   }
341

342
   if(resumed_session.ciphersuite().ecc_ciphersuite() &&
234✔
343
      client_hello.extension_types().contains(Extension_Code::EcPointFormats)) {
648✔
344
      m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
207✔
345
   }
346

347
   if(client_hello.secure_renegotiation()) {
234✔
348
      m_data->extensions().add(new Renegotiation_Extension(reneg_info));
234✔
349
   }
350

351
   if(client_hello.supports_session_ticket() && offer_session_ticket) {
234✔
352
      m_data->extensions().add(new Session_Ticket_Extension());
1✔
353
   }
354
   // NOLINTEND(*-owning-memory)
355

356
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
234✔
357

358
   hash.update(io.send(*this));
468✔
359
}
234✔
360

361
Server_Hello_12::Server_Hello_12(const std::vector<uint8_t>& buf) :
2,522✔
362
      Server_Hello_12(std::make_unique<Server_Hello_Internal>(buf)) {}
2,522✔
363

364
Server_Hello_12::Server_Hello_12(std::unique_ptr<Server_Hello_Internal> data) : Server_Hello(std::move(data)) {
2,876✔
365
   if(!m_data->version().is_pre_tls_13()) {
5,752✔
366
      throw TLS_Exception(Alert::ProtocolVersion, "Expected server hello of (D)TLS 1.2 or lower");
×
367
   }
368
}
2,876✔
369

370
Protocol_Version Server_Hello_12::selected_version() const {
490✔
371
   return legacy_version();
490✔
372
}
373

374
bool Server_Hello_12::secure_renegotiation() const {
3,206✔
375
   return m_data->extensions().has<Renegotiation_Extension>();
3,206✔
376
}
377

378
std::vector<uint8_t> Server_Hello_12::renegotiation_info() const {
3,113✔
379
   if(const Renegotiation_Extension* reneg = m_data->extensions().get<Renegotiation_Extension>()) {
3,113✔
380
      return reneg->renegotiation_info();
3,113✔
381
   }
382
   return std::vector<uint8_t>();
×
383
}
384

385
bool Server_Hello_12::supports_extended_master_secret() const {
3,958✔
386
   return m_data->extensions().has<Extended_Master_Secret>();
3,958✔
387
}
388

389
bool Server_Hello_12::supports_encrypt_then_mac() const {
6,885✔
390
   return m_data->extensions().has<Encrypt_then_MAC>();
6,885✔
391
}
392

393
bool Server_Hello_12::supports_certificate_status_message() const {
1,925✔
394
   return m_data->extensions().has<Certificate_Status_Request>();
1,925✔
395
}
396

397
bool Server_Hello_12::supports_session_ticket() const {
2,615✔
398
   return m_data->extensions().has<Session_Ticket_Extension>();
2,615✔
399
}
400

401
uint16_t Server_Hello_12::srtp_profile() const {
3,715✔
402
   if(auto* srtp = m_data->extensions().get<SRTP_Protection_Profiles>()) {
3,715✔
403
      auto prof = srtp->profiles();
4✔
404
      if(prof.size() != 1 || prof[0] == 0) {
4✔
405
         throw Decoding_Error("Server sent malformed DTLS-SRTP extension");
×
406
      }
407
      return prof[0];
4✔
408
   }
4✔
409

410
   return 0;
411
}
412

413
std::string Server_Hello_12::next_protocol() const {
2,163✔
414
   if(auto* alpn = m_data->extensions().get<Application_Layer_Protocol_Notification>()) {
2,163✔
415
      return alpn->single_protocol();
140✔
416
   }
417
   return "";
2,023✔
418
}
419

420
bool Server_Hello_12::prefers_compressed_ec_points() const {
25✔
421
   if(auto* ecc_formats = m_data->extensions().get<Supported_Point_Formats>()) {
25✔
422
      return ecc_formats->prefers_compressed();
13✔
423
   }
424
   return false;
425
}
426

427
std::optional<Protocol_Version> Server_Hello_12::random_signals_downgrade() const {
613✔
428
   const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
613✔
429
   if(last8 == DOWNGRADE_TLS11) {
613✔
430
      return Protocol_Version::TLS_V11;
×
431
   }
432
   if(last8 == DOWNGRADE_TLS12) {
613✔
433
      return Protocol_Version::TLS_V12;
1✔
434
   }
435

436
   return std::nullopt;
612✔
437
}
438

439
/*
440
* Create a new Server Hello Done message
441
*/
442
Server_Hello_Done::Server_Hello_Done(Handshake_IO& io, Handshake_Hash& hash) {
708✔
443
   hash.update(io.send(*this));
1,416✔
444
}
708✔
445

446
/*
447
* Deserialize a Server Hello Done message
448
*/
449
Server_Hello_Done::Server_Hello_Done(const std::vector<uint8_t>& buf) {
855✔
450
   if(!buf.empty()) {
855✔
451
      throw Decoding_Error("Server_Hello_Done: Must be empty, and is not");
2✔
452
   }
453
}
853✔
454

455
/*
456
* Serialize a Server Hello Done message
457
*/
458
std::vector<uint8_t> Server_Hello_Done::serialize() const {
708✔
459
   return std::vector<uint8_t>();
708✔
460
}
461

462
#if defined(BOTAN_HAS_TLS_13)
463

464
const Server_Hello_13::Server_Hello_Tag Server_Hello_13::as_server_hello;
465
const Server_Hello_13::Hello_Retry_Request_Tag Server_Hello_13::as_hello_retry_request;
466
const Server_Hello_13::Hello_Retry_Request_Creation_Tag Server_Hello_13::as_new_hello_retry_request;
467

468
std::variant<Hello_Retry_Request, Server_Hello_13> Server_Hello_13::create(const Client_Hello_13& ch,
432✔
469
                                                                           bool hello_retry_request_allowed,
470
                                                                           Session_Manager& session_mgr,
471
                                                                           Credentials_Manager& credentials_mgr,
472
                                                                           RandomNumberGenerator& rng,
473
                                                                           const Policy& policy,
474
                                                                           Callbacks& cb) {
475
   const auto& exts = ch.extensions();
432✔
476

477
   // RFC 8446 4.2.9
478
   //    [With PSK with (EC)DHE key establishment], the client and server MUST
479
   //    supply "key_share" values [...].
480
   //
481
   // Note: We currently do not support PSK without (EC)DHE, hence, we can
482
   //       assume that those extensions are available.
483
   BOTAN_ASSERT_NOMSG(exts.has<Supported_Groups>() && exts.has<Key_Share>());
864✔
484
   const auto& supported_by_client = exts.get<Supported_Groups>()->groups();
432✔
485
   const auto& offered_by_client = exts.get<Key_Share>()->offered_groups();
432✔
486
   const auto selected_group = policy.choose_key_exchange_group(supported_by_client, offered_by_client);
432✔
487

488
   // RFC 8446 4.1.1
489
   //    If there is no overlap between the received "supported_groups" and the
490
   //    groups supported by the server, then the server MUST abort the
491
   //    handshake with a "handshake_failure" or an "insufficient_security" alert.
492
   if(selected_group == Named_Group::NONE) {
432✔
493
      throw TLS_Exception(Alert::HandshakeFailure, "Client did not offer any acceptable group");
×
494
   }
495

496
   // RFC 8446 4.2.8:
497
   //    Servers MUST NOT send a KeyShareEntry for any group not indicated in the
498
   //    client's "supported_groups" extension [...]
499
   if(!value_exists(supported_by_client, selected_group)) {
864✔
500
      throw TLS_Exception(Alert::InternalError, "Application selected a group that is not supported by the client");
×
501
   }
502

503
   // RFC 8446 4.1.4
504
   //    The server will send this message in response to a ClientHello
505
   //    message if it is able to find an acceptable set of parameters but the
506
   //    ClientHello does not contain sufficient information to proceed with
507
   //    the handshake.
508
   //
509
   // In this case, the Client Hello did not contain a key share offer for
510
   // the group selected by the application.
511
   if(!value_exists(offered_by_client, selected_group)) {
864✔
512
      // RFC 8446 4.1.4
513
      //    If a client receives a second HelloRetryRequest in the same
514
      //    connection (i.e., where the ClientHello was itself in response to a
515
      //    HelloRetryRequest), it MUST abort the handshake with an
516
      //    "unexpected_message" alert.
517
      BOTAN_STATE_CHECK(hello_retry_request_allowed);
49✔
518
      return Hello_Retry_Request(ch, selected_group, policy, cb);
98✔
519
   } else {
520
      return Server_Hello_13(ch, selected_group, session_mgr, credentials_mgr, rng, cb, policy);
750✔
521
   }
522
}
416✔
523

524
std::variant<Hello_Retry_Request, Server_Hello_13, Server_Hello_12> Server_Hello_13::parse(
1,047✔
525
   const std::vector<uint8_t>& buf) {
526
   auto data = std::make_unique<Server_Hello_Internal>(buf);
1,047✔
527
   const auto version = data->version();
1,035✔
528

529
   // server hello that appears to be pre-TLS 1.3, takes precedence over...
530
   if(version.is_pre_tls_13()) {
1,035✔
531
      return Server_Hello_12(std::move(data));
994✔
532
   }
533

534
   // ... the TLS 1.3 "special case" aka. Hello_Retry_Request
535
   if(version == Protocol_Version::TLS_V13) {
538✔
536
      if(data->is_hello_retry_request()) {
538✔
537
         return Hello_Retry_Request(std::move(data));
135✔
538
      }
539

540
      return Server_Hello_13(std::move(data));
930✔
541
   }
542

543
   throw TLS_Exception(Alert::ProtocolVersion, "unexpected server hello version: " + version.to_string());
×
544
}
1,035✔
545

546
/**
547
 * Validation that applies to both Server Hello and Hello Retry Request
548
 */
549
void Server_Hello_13::basic_validation() const {
538✔
550
   BOTAN_ASSERT_NOMSG(m_data->version() == Protocol_Version::TLS_V13);
1,076✔
551

552
   // Note: checks that cannot be performed without contextual information
553
   //       are done in the specific TLS client implementation.
554
   // Note: The Supported_Version extension makes sure internally that
555
   //       exactly one entry is provided.
556

557
   // Note: Hello Retry Request basic validation is equivalent with the
558
   //       basic validations required for Server Hello
559
   //
560
   // RFC 8446 4.1.4
561
   //    Upon receipt of a HelloRetryRequest, the client MUST check the
562
   //    legacy_version, [...], and legacy_compression_method as specified in
563
   //    Section 4.1.3 and then process the extensions, starting with determining
564
   //    the version using "supported_versions".
565

566
   // RFC 8446 4.1.3
567
   //    In TLS 1.3, [...] the legacy_version field MUST be set to 0x0303
568
   if(legacy_version() != Protocol_Version::TLS_V12) {
538✔
569
      throw TLS_Exception(Alert::ProtocolVersion,
2✔
570
                          "legacy_version '" + legacy_version().to_string() + "' is not allowed");
6✔
571
   }
572

573
   // RFC 8446 4.1.3
574
   //    legacy_compression_method:  A single byte which MUST have the value 0.
575
   if(compression_method() != 0x00) {
536✔
576
      throw TLS_Exception(Alert::DecodeError, "compression is not supported in TLS 1.3");
2✔
577
   }
578

579
   // RFC 8446 4.1.3
580
   //    All TLS 1.3 ServerHello messages MUST contain the "supported_versions" extension.
581
   if(!extensions().has<Supported_Versions>()) {
534✔
582
      throw TLS_Exception(Alert::MissingExtension, "server hello did not contain 'supported version' extension");
×
583
   }
584

585
   // RFC 8446 4.2.1
586
   //    A server which negotiates TLS 1.3 MUST respond by sending
587
   //    a "supported_versions" extension containing the selected version
588
   //    value (0x0304).
589
   if(selected_version() != Protocol_Version::TLS_V13) {
534✔
590
      throw TLS_Exception(Alert::IllegalParameter, "TLS 1.3 Server Hello selected a different version");
1✔
591
   }
592
}
533✔
593

594
Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data,
469✔
595
                                 Server_Hello_13::Server_Hello_Tag /*tag*/) :
469✔
596
      Server_Hello(std::move(data)) {
469✔
597
   BOTAN_ASSERT_NOMSG(!m_data->is_hello_retry_request());
469✔
598
   basic_validation();
469✔
599

600
   const auto& exts = extensions();
465✔
601

602
   // RFC 8446 4.1.3
603
   //    The ServerHello MUST only include extensions which are required to
604
   //    establish the cryptographic context and negotiate the protocol version.
605
   //    [...]
606
   //    Other extensions (see Section 4.2) are sent separately in the
607
   //    EncryptedExtensions message.
608
   //
609
   // Note that further validation dependent on the client hello is done in the
610
   // TLS client implementation.
611
   const std::set<Extension_Code> allowed = {
465✔
612
      Extension_Code::KeyShare,
613
      Extension_Code::SupportedVersions,
614
      Extension_Code::PresharedKey,
615
   };
465✔
616

617
   // As the ServerHello shall only contain essential extensions, we don't give
618
   // any slack for extensions not implemented by Botan here.
619
   if(exts.contains_other_than(allowed)) {
465✔
620
      throw TLS_Exception(Alert::UnsupportedExtension, "Server Hello contained an extension that is not allowed");
2✔
621
   }
622

623
   // RFC 8446 4.1.3
624
   //    Current ServerHello messages additionally contain
625
   //    either the "pre_shared_key" extension or the "key_share"
626
   //    extension, or both [...].
627
   if(!exts.has<Key_Share>() && !exts.has<PSK_Key_Exchange_Modes>()) {
465✔
628
      throw TLS_Exception(Alert::MissingExtension, "server hello must contain key exchange information");
2✔
629
   }
630
}
469✔
631

632
Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data,
69✔
633
                                 Server_Hello_13::Hello_Retry_Request_Tag /*tag*/) :
69✔
634
      Server_Hello(std::move(data)) {
69✔
635
   BOTAN_ASSERT_NOMSG(m_data->is_hello_retry_request());
69✔
636
   basic_validation();
69✔
637

638
   const auto& exts = extensions();
68✔
639

640
   // RFC 8446 4.1.4
641
   //     The HelloRetryRequest extensions defined in this specification are:
642
   //     -  supported_versions (see Section 4.2.1)
643
   //     -  cookie (see Section 4.2.2)
644
   //     -  key_share (see Section 4.2.8)
645
   const std::set<Extension_Code> allowed = {
68✔
646
      Extension_Code::Cookie,
647
      Extension_Code::SupportedVersions,
648
      Extension_Code::KeyShare,
649
   };
68✔
650

651
   // As the Hello Retry Request shall only contain essential extensions, we
652
   // don't give any slack for extensions not implemented by Botan here.
653
   if(exts.contains_other_than(allowed)) {
68✔
654
      throw TLS_Exception(Alert::UnsupportedExtension,
1✔
655
                          "Hello Retry Request contained an extension that is not allowed");
1✔
656
   }
657

658
   // RFC 8446 4.1.4
659
   //    Clients MUST abort the handshake with an "illegal_parameter" alert if
660
   //    the HelloRetryRequest would not result in any change in the ClientHello.
661
   if(!exts.has<Key_Share>() && !exts.has<Cookie>()) {
69✔
662
      throw TLS_Exception(Alert::IllegalParameter, "Hello Retry Request does not request any changes to Client Hello");
1✔
663
   }
664
}
69✔
665

666
Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data,
49✔
667
                                 Hello_Retry_Request_Creation_Tag /*tag*/) :
49✔
668
      Server_Hello(std::move(data)) {}
49✔
669

670
namespace {
671

672
uint16_t choose_ciphersuite(const Client_Hello_13& ch, const Policy& policy) {
432✔
673
   auto pref_list = ch.ciphersuites();
432✔
674
   // TODO: DTLS might need to make this version dynamic
675
   auto other_list = policy.ciphersuite_list(Protocol_Version::TLS_V13);
432✔
676

677
   if(policy.server_uses_own_ciphersuite_preferences()) {
432✔
678
      std::swap(pref_list, other_list);
432✔
679
   }
680

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

708
   // RFC 8446 4.1.1
709
   //     If the server is unable to negotiate a supported set of parameters
710
   //     [...], it MUST abort the handshake with either a "handshake_failure"
711
   //     or "insufficient_security" fatal alert [...].
712
   throw TLS_Exception(Alert::HandshakeFailure, "Can't agree on a ciphersuite with client");
×
713
}
864✔
714
}  // namespace
715

716
Server_Hello_13::Server_Hello_13(const Client_Hello_13& ch,
383✔
717
                                 std::optional<Named_Group> key_exchange_group,
718
                                 Session_Manager& session_mgr,
719
                                 Credentials_Manager& credentials_mgr,
720
                                 RandomNumberGenerator& rng,
721
                                 Callbacks& cb,
722
                                 const Policy& policy) :
383✔
723
      Server_Hello(std::make_unique<Server_Hello_Internal>(
766✔
724
         Protocol_Version::TLS_V12,
725
         ch.session_id(),
383✔
726
         make_server_hello_random(rng, Protocol_Version::TLS_V13, cb, policy),
766✔
727
         choose_ciphersuite(ch, policy),
383✔
728
         uint8_t(0) /* compression method */
766✔
729
         )) {
766✔
730
   // RFC 8446 4.2.1
731
   //    A server which negotiates TLS 1.3 MUST respond by sending a
732
   //    "supported_versions" extension containing the selected version
733
   //    value (0x0304). It MUST set the ServerHello.legacy_version field to
734
   //     0x0303 (TLS 1.2).
735
   //
736
   // Note that the legacy version (TLS 1.2) is set in this constructor's
737
   // initializer list, accordingly.
738
   m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13));  // NOLINT(*-owning-memory)
383✔
739

740
   if(key_exchange_group.has_value()) {
383✔
741
      BOTAN_ASSERT_NOMSG(ch.extensions().has<Key_Share>());
383✔
742
      m_data->extensions().add(Key_Share::create_as_encapsulation(
1,133✔
743
         key_exchange_group.value(), *ch.extensions().get<Key_Share>(), policy, cb, rng));
383✔
744
   }
745

746
   const auto& ch_exts = ch.extensions();
367✔
747

748
   if(ch_exts.has<PSK>()) {
367✔
749
      const auto cs = Ciphersuite::by_id(m_data->ciphersuite());
97✔
750
      BOTAN_ASSERT_NOMSG(cs);
97✔
751

752
      // RFC 8446 4.2.9
753
      //    A client MUST provide a "psk_key_exchange_modes" extension if it
754
      //    offers a "pre_shared_key" extension.
755
      //
756
      // Note: Client_Hello_13 constructor already performed a graceful check.
757
      auto* const psk_modes = ch_exts.get<PSK_Key_Exchange_Modes>();
97✔
758
      BOTAN_ASSERT_NONNULL(psk_modes);
97✔
759

760
      // TODO: also support PSK_Key_Exchange_Mode::PSK_KE
761
      //       (PSK-based handshake without an additional ephemeral key exchange)
762
      if(value_exists(psk_modes->modes(), PSK_Key_Exchange_Mode::PSK_DHE_KE)) {
194✔
763
         if(auto server_psk = ch_exts.get<PSK>()->select_offered_psk(
96✔
764
               ch.sni_hostname(), cs.value(), session_mgr, credentials_mgr, cb, policy)) {
192✔
765
            // RFC 8446 4.2.11
766
            //    In order to accept PSK key establishment, the server sends a
767
            //    "pre_shared_key" extension indicating the selected identity.
768
            m_data->extensions().add(std::move(server_psk));
188✔
769
         }
96✔
770
      }
771
   }
772

773
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
367✔
774
}
383✔
775

776
std::optional<Protocol_Version> Server_Hello_13::random_signals_downgrade() const {
×
777
   const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
×
778
   if(last8 == DOWNGRADE_TLS11) {
×
779
      return Protocol_Version::TLS_V11;
×
780
   }
781
   if(last8 == DOWNGRADE_TLS12) {
×
782
      return Protocol_Version::TLS_V12;
×
783
   }
784

785
   return std::nullopt;
×
786
}
787

788
Protocol_Version Server_Hello_13::selected_version() const {
2,604✔
789
   auto* const versions_ext = m_data->extensions().get<Supported_Versions>();
2,604✔
790
   BOTAN_ASSERT_NOMSG(versions_ext);
2,604✔
791
   const auto& versions = versions_ext->versions();
2,604✔
792
   BOTAN_ASSERT_NOMSG(versions.size() == 1);
2,604✔
793
   return versions.front();
2,604✔
794
}
795

796
Hello_Retry_Request::Hello_Retry_Request(std::unique_ptr<Server_Hello_Internal> data) :
69✔
797
      Server_Hello_13(std::move(data), Server_Hello_13::as_hello_retry_request) {}
69✔
798

799
Hello_Retry_Request::Hello_Retry_Request(const Client_Hello_13& ch,
49✔
800
                                         Named_Group selected_group,
801
                                         const Policy& policy,
802
                                         Callbacks& cb) :
49✔
803
      Server_Hello_13(std::make_unique<Server_Hello_Internal>(
98✔
804
                         Protocol_Version::TLS_V12 /* legacy_version */,
805
                         ch.session_id(),
49✔
806
                         std::vector<uint8_t>(HELLO_RETRY_REQUEST_MARKER.begin(), HELLO_RETRY_REQUEST_MARKER.end()),
98✔
807
                         choose_ciphersuite(ch, policy),
49✔
808
                         uint8_t(0) /* compression method */,
98✔
809
                         true /* is Hello Retry Request */
98✔
810
                         ),
811
                      as_new_hello_retry_request) {
98✔
812
   // RFC 8446 4.1.4
813
   //     As with the ServerHello, a HelloRetryRequest MUST NOT contain any
814
   //     extensions that were not first offered by the client in its
815
   //     ClientHello, with the exception of optionally the "cookie" [...]
816
   //     extension.
817
   BOTAN_STATE_CHECK(ch.extensions().has<Supported_Groups>());
49✔
818
   BOTAN_STATE_CHECK(ch.extensions().has<Key_Share>());
49✔
819

820
   BOTAN_STATE_CHECK(!value_exists(ch.extensions().get<Key_Share>()->offered_groups(), selected_group));
114✔
821

822
   // RFC 8446 4.1.4
823
   //    The server's extensions MUST contain "supported_versions".
824
   //
825
   // RFC 8446 4.2.1
826
   //    A server which negotiates TLS 1.3 MUST respond by sending a
827
   //    "supported_versions" extension containing the selected version
828
   //    value (0x0304). It MUST set the ServerHello.legacy_version field to
829
   //    0x0303 (TLS 1.2).
830
   //
831
   // Note that the legacy version (TLS 1.2) is set in this constructor's
832
   // initializer list, accordingly.
833
   // NOLINTBEGIN(*-owning-memory)
834
   m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13));
49✔
835

836
   m_data->extensions().add(new Key_Share(selected_group));
49✔
837
   // NOLINTEND(*-owning-memory)
838

839
   cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
49✔
840
}
49✔
841

842
#endif  // BOTAN_HAS_TLS_13
843

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