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

randombit / botan / 21756362022

06 Feb 2026 03:40PM UTC coverage: 90.069% (-0.004%) from 90.073%
21756362022

Pull #5293

github

web-flow
Merge 5018e3dec into 8ea0ca252
Pull Request #5293: Refactor: Disentangle Client_Hello implementations

102251 of 113525 relevant lines covered (90.07%)

11438009.49 hits per line

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

89.3
/src/lib/tls/tls_extensions.cpp
1
/*
2
* TLS Extensions
3
* (C) 2011,2012,2015,2016 Jack Lloyd
4
*     2016 Juraj Somorovsky
5
*     2021 Elektrobit Automotive GmbH
6
*     2022 René Meusel, Hannes Rantzsch - neXenio GmbH
7
*     2023 Mateusz Berezecki
8
*     2023 Fabian Albert, René Meusel - Rohde & Schwarz Cybersecurity
9
*
10
* Botan is released under the Simplified BSD License (see license.txt)
11
*/
12

13
#include <botan/tls_extensions.h>
14

15
#include <botan/ber_dec.h>
16
#include <botan/der_enc.h>
17
#include <botan/tls_exceptn.h>
18
#include <botan/tls_policy.h>
19
#include <botan/internal/mem_utils.h>
20
#include <botan/internal/parsing.h>
21
#include <botan/internal/stl_util.h>
22
#include <botan/internal/tls_reader.h>
23

24
#include <algorithm>
25
#include <iterator>
26

27
namespace Botan::TLS {
28

29
namespace {
30

31
std::unique_ptr<Extension> make_extension(TLS_Data_Reader& reader,
39,469✔
32
                                          Extension_Code code,
33
                                          const Connection_Side from,
34
                                          const Handshake_Type message_type) {
35
   // This cast is safe because we read exactly a 16 bit length field for
36
   // the extension in Extensions::deserialize
37
   const uint16_t size = static_cast<uint16_t>(reader.remaining_bytes());
39,469✔
38
   switch(code) {
39,469✔
39
      case Extension_Code::ServerNameIndication:
2,829✔
40
         return std::make_unique<Server_Name_Indicator>(reader, size);
2,829✔
41

42
      case Extension_Code::SupportedGroups:
2,909✔
43
         return std::make_unique<Supported_Groups>(reader, size);
2,909✔
44

45
      case Extension_Code::CertificateStatusRequest:
2,672✔
46
         return std::make_unique<Certificate_Status_Request>(reader, size, message_type, from);
2,672✔
47

48
      case Extension_Code::EcPointFormats:
3,200✔
49
         return std::make_unique<Supported_Point_Formats>(reader, size);
3,200✔
50

51
      case Extension_Code::SafeRenegotiation:
5,691✔
52
         return std::make_unique<Renegotiation_Extension>(reader, size);
5,691✔
53

54
      case Extension_Code::SignatureAlgorithms:
2,934✔
55
         return std::make_unique<Signature_Algorithms>(reader, size);
2,934✔
56

57
      case Extension_Code::CertSignatureAlgorithms:
×
58
         return std::make_unique<Signature_Algorithms_Cert>(reader, size);
×
59

60
      case Extension_Code::UseSrtp:
10✔
61
         return std::make_unique<SRTP_Protection_Profiles>(reader, size);
10✔
62

63
      case Extension_Code::ApplicationLayerProtocolNegotiation:
407✔
64
         return std::make_unique<Application_Layer_Protocol_Notification>(reader, size, from);
407✔
65

66
      case Extension_Code::ClientCertificateType:
2✔
67
         return std::make_unique<Client_Certificate_Type>(reader, size, from);
2✔
68

69
      case Extension_Code::ServerCertificateType:
2✔
70
         return std::make_unique<Server_Certificate_Type>(reader, size, from);
2✔
71

72
      case Extension_Code::ExtendedMasterSecret:
5,515✔
73
         return std::make_unique<Extended_Master_Secret>(reader, size);
5,515✔
74

75
      case Extension_Code::RecordSizeLimit:
45✔
76
         return std::make_unique<Record_Size_Limit>(reader, size, from);
45✔
77

78
      case Extension_Code::EncryptThenMac:
811✔
79
         return std::make_unique<Encrypt_then_MAC>(reader, size);
811✔
80

81
      case Extension_Code::SessionTicket:
4,979✔
82
         return std::make_unique<Session_Ticket_Extension>(reader, size);
4,979✔
83

84
      case Extension_Code::SupportedVersions:
1,824✔
85
         return std::make_unique<Supported_Versions>(reader, size, from);
1,824✔
86

87
#if defined(BOTAN_HAS_TLS_13)
88
      case Extension_Code::PresharedKey:
232✔
89
         return std::make_unique<PSK>(reader, size, message_type);
232✔
90

91
      case Extension_Code::EarlyData:
5✔
92
         return std::make_unique<EarlyDataIndication>(reader, size, message_type);
5✔
93

94
      case Extension_Code::Cookie:
10✔
95
         return std::make_unique<Cookie>(reader, size);
10✔
96

97
      case Extension_Code::PskKeyExchangeModes:
1,072✔
98
         return std::make_unique<PSK_Key_Exchange_Modes>(reader, size);
1,072✔
99

100
      case Extension_Code::CertificateAuthorities:
3✔
101
         return std::make_unique<Certificate_Authorities>(reader, size);
3✔
102

103
      case Extension_Code::KeyShare:
1,609✔
104
         return std::make_unique<Key_Share>(reader, size, message_type);
1,609✔
105
#endif
106
   }
107

108
   return std::make_unique<Unknown_Extension>(code, reader, size);
2,708✔
109
}
110

111
}  // namespace
112

113
Extensions::~Extensions() = default;
22,766✔
114

115
Extension* Extensions::get(Extension_Code type) const {
221,145✔
116
   const auto i =
221,145✔
117
      std::find_if(m_extensions.cbegin(), m_extensions.cend(), [type](const auto& ext) { return ext->type() == type; });
1,131,918✔
118

119
   return (i != m_extensions.end()) ? i->get() : nullptr;
221,145✔
120
}
121

122
void Extensions::add(std::unique_ptr<Extension> extn) {
84,930✔
123
   if(has(extn->type())) {
84,930✔
124
      throw Invalid_Argument("cannot add the same extension twice: " +
×
125
                             std::to_string(static_cast<uint16_t>(extn->type())));
×
126
   }
127

128
   m_extensions.emplace_back(extn.release());
84,930✔
129
}
84,930✔
130

131
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
7,973✔
132
   if(reader.has_remaining()) {
7,973✔
133
      const uint16_t all_extn_size = reader.get_uint16_t();
7,968✔
134

135
      if(reader.remaining_bytes() != all_extn_size) {
7,968✔
136
         throw Decoding_Error("Bad extension size");
118✔
137
      }
138

139
      while(reader.has_remaining()) {
47,286✔
140
         const uint16_t extension_code = reader.get_uint16_t();
39,491✔
141
         const uint16_t extension_size = reader.get_uint16_t();
39,490✔
142

143
         const auto type = static_cast<Extension_Code>(extension_code);
39,490✔
144

145
         if(this->has(type)) {
39,490✔
146
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
13✔
147
         }
148

149
         // TODO offer a function on reader that returns a byte range as a reference
150
         // to avoid this copy of the extension data
151
         const std::vector<uint8_t> extn_data = reader.get_fixed<uint8_t>(extension_size);
39,477✔
152
         TLS_Data_Reader extn_reader("Extension", extn_data);
39,469✔
153
         this->add(make_extension(extn_reader, type, from, message_type));
39,469✔
154
         extn_reader.assert_done();
39,436✔
155
      }
39,436✔
156
   }
157
}
7,800✔
158

159
bool Extensions::contains_other_than(const std::set<Extension_Code>& allowed_extensions,
3,437✔
160
                                     const bool allow_unknown_extensions) const {
161
   const auto found = extension_types();
3,437✔
162

163
   std::vector<Extension_Code> diff;
3,437✔
164
   std::set_difference(
3,437✔
165
      found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
166

167
   if(allow_unknown_extensions) {
3,437✔
168
      // Go through the found unexpected extensions whether any of those
169
      // is known to this TLS implementation.
170
      const auto itr = std::find_if(diff.cbegin(), diff.cend(), [this](const auto ext_type) {
1,523✔
171
         const auto ext = get(ext_type);
10✔
172
         return ext && ext->is_implemented();
10✔
173
      });
174

175
      // ... if yes, `contains_other_than` is true
176
      return itr != diff.cend();
1,523✔
177
   }
178

179
   return !diff.empty();
1,914✔
180
}
3,437✔
181

182
std::unique_ptr<Extension> Extensions::take(Extension_Code type) {
520✔
183
   const auto i =
520✔
184
      std::find_if(m_extensions.begin(), m_extensions.end(), [type](const auto& ext) { return ext->type() == type; });
3,186✔
185

186
   std::unique_ptr<Extension> result;
520✔
187
   if(i != m_extensions.end()) {
520✔
188
      std::swap(result, *i);
251✔
189
      m_extensions.erase(i);
251✔
190
   }
191

192
   return result;
520✔
193
}
194

195
std::vector<uint8_t> Extensions::serialize(Connection_Side whoami) const {
6,540✔
196
   std::vector<uint8_t> buf(2);  // 2 bytes for length field
6,540✔
197

198
   for(const auto& extn : m_extensions) {
59,029✔
199
      if(extn->empty()) {
52,489✔
200
         continue;
3,120✔
201
      }
202

203
      const uint16_t extn_code = static_cast<uint16_t>(extn->type());
49,369✔
204

205
      const std::vector<uint8_t> extn_val = extn->serialize(whoami);
49,369✔
206

207
      buf.push_back(get_byte<0>(extn_code));
49,369✔
208
      buf.push_back(get_byte<1>(extn_code));
49,369✔
209

210
      buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
49,369✔
211
      buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
49,369✔
212

213
      buf += extn_val;
49,369✔
214
   }
49,369✔
215

216
   const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
6,540✔
217

218
   buf[0] = get_byte<0>(extn_size);
6,540✔
219
   buf[1] = get_byte<1>(extn_size);
6,540✔
220

221
   // avoid sending a completely empty extensions block
222
   if(buf.size() == 2) {
6,540✔
223
      return std::vector<uint8_t>();
304✔
224
   }
225

226
   return buf;
6,236✔
227
}
6,540✔
228

229
std::set<Extension_Code> Extensions::extension_types() const {
10,357✔
230
   std::set<Extension_Code> offers;
10,357✔
231
   std::transform(
10,357✔
232
      m_extensions.cbegin(), m_extensions.cend(), std::inserter(offers, offers.begin()), [](const auto& ext) {
58,628✔
233
         return ext->type();
58,628✔
234
      });
235
   return offers;
10,357✔
236
}
×
237

238
Unknown_Extension::Unknown_Extension(Extension_Code type, TLS_Data_Reader& reader, uint16_t extension_size) :
2,708✔
239
      m_type(type), m_value(reader.get_fixed<uint8_t>(extension_size)) {}
2,708✔
240

241
std::vector<uint8_t> Unknown_Extension::serialize(Connection_Side /*whoami*/) const {
2✔
242
   return m_value;
2✔
243
}
244

245
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, uint16_t extension_size) {
2,829✔
246
   /*
247
   * This is used by the server to confirm that it knew the name
248
   */
249
   if(extension_size == 0) {
2,829✔
250
      return;
251
   }
252

253
   uint16_t name_bytes = reader.get_uint16_t();
2,794✔
254

255
   if(name_bytes + 2 != extension_size) {
2,794✔
256
      throw Decoding_Error("Bad encoding of SNI extension");
×
257
   }
258

259
   while(name_bytes > 0) {
5,588✔
260
      const uint8_t name_type = reader.get_byte();
2,794✔
261
      name_bytes--;
2,794✔
262

263
      if(name_type == 0) {
2,794✔
264
         // DNS
265
         m_sni_host_name = reader.get_string(2, 1, 65535);
2,794✔
266
         name_bytes -= static_cast<uint16_t>(2 + m_sni_host_name.size());
2,794✔
267
      } else {
268
         // some other unknown name type, which we will ignore
269
         reader.discard_next(name_bytes);
×
270
         name_bytes = 0;
×
271
      }
272
   }
273
}
×
274

275
std::vector<uint8_t> Server_Name_Indicator::serialize(Connection_Side whoami) const {
4,656✔
276
   // RFC 6066
277
   //    [...] the server SHALL include an extension of type "server_name" in
278
   //    the (extended) server hello. The "extension_data" field of this
279
   //    extension SHALL be empty.
280
   if(whoami == Connection_Side::Server) {
4,656✔
281
      return {};
366✔
282
   }
283

284
   std::vector<uint8_t> buf;
4,290✔
285

286
   const size_t name_len = m_sni_host_name.size();
4,290✔
287

288
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,290✔
289
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,290✔
290
   buf.push_back(0);  // DNS
4,290✔
291

292
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,290✔
293
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,290✔
294

295
   buf += as_span_of_bytes(m_sni_host_name);
4,290✔
296

297
   return buf;
4,290✔
298
}
4,290✔
299

300
bool Server_Name_Indicator::hostname_acceptable_for_sni(std::string_view hostname) {
3,684✔
301
   // Avoid sending an IPv4/IPv6 address in SNI as this is prohibited
302

303
   if(hostname.empty()) {
3,684✔
304
      return false;
305
   }
306

307
   if(string_to_ipv4(hostname).has_value()) {
3,637✔
308
      return false;
309
   }
310

311
   // IPv6? Anyway ':' is not valid in DNS
312
   if(hostname.find(':') != std::string_view::npos) {
3,637✔
313
      return false;
314
   }
315

316
   return true;
317
}
318

319
Renegotiation_Extension::Renegotiation_Extension(TLS_Data_Reader& reader, uint16_t extension_size) :
5,691✔
320
      m_reneg_data(reader.get_range<uint8_t>(1, 0, 255)) {
5,691✔
321
   if(m_reneg_data.size() + 1 != extension_size) {
5,689✔
322
      throw Decoding_Error("Bad encoding for secure renegotiation extn");
1✔
323
   }
324
}
5,689✔
325

326
std::vector<uint8_t> Renegotiation_Extension::serialize(Connection_Side /*whoami*/) const {
5,268✔
327
   std::vector<uint8_t> buf;
5,268✔
328
   append_tls_length_value(buf, m_reneg_data, 1);
5,268✔
329
   return buf;
5,268✔
330
}
×
331

332
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
407✔
333
                                                                                 uint16_t extension_size,
334
                                                                                 Connection_Side from) {
407✔
335
   if(extension_size == 0) {
407✔
336
      return;  // empty extension
337
   }
338

339
   const uint16_t name_bytes = reader.get_uint16_t();
407✔
340

341
   size_t bytes_remaining = extension_size - 2;
407✔
342

343
   if(name_bytes != bytes_remaining) {
407✔
344
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
×
345
   }
346

347
   while(bytes_remaining > 0) {
1,085✔
348
      const std::string p = reader.get_string(1, 0, 255);
685✔
349

350
      if(bytes_remaining < p.size() + 1) {
685✔
351
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
352
      }
353

354
      if(p.empty()) {
685✔
355
         throw Decoding_Error("Empty ALPN protocol not allowed");
7✔
356
      }
357

358
      bytes_remaining -= (p.size() + 1);
678✔
359

360
      m_protocols.push_back(p);
678✔
361
   }
685✔
362

363
   // RFC 7301 3.1
364
   //    The "extension_data" field of the [...] extension is structured the
365
   //    same as described above for the client "extension_data", except that
366
   //    the "ProtocolNameList" MUST contain exactly one "ProtocolName".
367
   if(from == Connection_Side::Server && m_protocols.size() != 1) {
400✔
368
      throw TLS_Exception(
×
369
         Alert::DecodeError,
370
         "Server sent " + std::to_string(m_protocols.size()) + " protocols in ALPN extension response");
×
371
   }
372
}
7✔
373

374
std::string Application_Layer_Protocol_Notification::single_protocol() const {
148✔
375
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
148✔
376
   return m_protocols.front();
148✔
377
}
378

379
std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const {
365✔
380
   std::vector<uint8_t> buf(2);
365✔
381

382
   for(auto&& proto : m_protocols) {
958✔
383
      if(proto.length() >= 256) {
593✔
384
         throw TLS_Exception(Alert::InternalError, "ALPN name too long");
×
385
      }
386
      if(!proto.empty()) {
593✔
387
         append_tls_length_value(buf, proto, 1);
1,186✔
388
      }
389
   }
390

391
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
365✔
392
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
365✔
393

394
   return buf;
365✔
395
}
×
396

397
std::string certificate_type_to_string(Certificate_Type type) {
24✔
398
   switch(type) {
24✔
399
      case Certificate_Type::X509:
24✔
400
         return "X509";
24✔
401
      case Certificate_Type::RawPublicKey:
×
402
         return "RawPublicKey";
×
403
   }
404

405
   return "Unknown";
×
406
}
407

408
Certificate_Type certificate_type_from_string(const std::string& type_str) {
10✔
409
   if(type_str == "X509") {
10✔
410
      return Certificate_Type::X509;
411
   } else if(type_str == "RawPublicKey") {
4✔
412
      return Certificate_Type::RawPublicKey;
413
   } else {
414
      throw Decoding_Error("Unknown certificate type: " + type_str);
×
415
   }
416
}
417

418
Certificate_Type_Base::Certificate_Type_Base(std::vector<Certificate_Type> supported_cert_types) :
1,976✔
419
      m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
1,976✔
420
   BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
1,976✔
421
}
1,976✔
422

423
Client_Certificate_Type::Client_Certificate_Type(const Client_Certificate_Type& cct, const Policy& policy) :
1✔
424
      Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
1✔
425

426
Server_Certificate_Type::Server_Certificate_Type(const Server_Certificate_Type& sct, const Policy& policy) :
1✔
427
      Certificate_Type_Base(sct, policy.accepted_server_certificate_types()) {}
1✔
428

429
Certificate_Type_Base::Certificate_Type_Base(const Certificate_Type_Base& certificate_type_from_client,
2✔
430
                                             const std::vector<Certificate_Type>& server_preference) :
2✔
431
      m_from(Connection_Side::Server) {
2✔
432
   // RFC 7250 4.2
433
   //    The server_certificate_type extension in the client hello indicates the
434
   //    types of certificates the client is able to process when provided by
435
   //    the server in a subsequent certificate payload. [...] With the
436
   //    server_certificate_type extension in the server hello, the TLS server
437
   //    indicates the certificate type carried in the Certificate payload.
438
   for(const auto server_supported_cert_type : server_preference) {
2✔
439
      if(value_exists(certificate_type_from_client.m_certificate_types, server_supported_cert_type)) {
4✔
440
         m_certificate_types.push_back(server_supported_cert_type);
2✔
441
         return;
2✔
442
      }
443
   }
444

445
   // RFC 7250 4.2 (2.)
446
   //    The server supports the extension defined in this document, but
447
   //    it does not have any certificate type in common with the client.
448
   //    Then, the server terminates the session with a fatal alert of
449
   //    type "unsupported_certificate".
450
   throw TLS_Exception(Alert::UnsupportedCertificate, "Failed to agree on certificate_type");
×
451
}
×
452

453
Certificate_Type_Base::Certificate_Type_Base(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) :
4✔
454
      m_from(from) {
4✔
455
   if(extension_size == 0) {
4✔
456
      throw Decoding_Error("Certificate type extension cannot be empty");
×
457
   }
458

459
   if(from == Connection_Side::Client) {
4✔
460
      const auto type_bytes = reader.get_tls_length_value(1);
2✔
461
      if(static_cast<size_t>(extension_size) != type_bytes.size() + 1) {
2✔
462
         throw Decoding_Error("certificate type extension had inconsistent length");
×
463
      }
464
      std::transform(
2✔
465
         type_bytes.begin(), type_bytes.end(), std::back_inserter(m_certificate_types), [](const auto type_byte) {
2✔
466
            return static_cast<Certificate_Type>(type_byte);
467
         });
468
   } else {
2✔
469
      // RFC 7250 4.2
470
      //    Note that only a single value is permitted in the
471
      //    server_certificate_type extension when carried in the server hello.
472
      if(extension_size != 1) {
2✔
473
         throw Decoding_Error("Server's certificate type extension must be of length 1");
×
474
      }
475
      const auto type_byte = reader.get_byte();
2✔
476
      m_certificate_types.push_back(static_cast<Certificate_Type>(type_byte));
2✔
477
   }
478
}
4✔
479

480
std::vector<uint8_t> Certificate_Type_Base::serialize(Connection_Side whoami) const {
12✔
481
   std::vector<uint8_t> result;
12✔
482
   if(whoami == Connection_Side::Client) {
12✔
483
      std::vector<uint8_t> type_bytes;
6✔
484
      std::transform(
6✔
485
         m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
486
            return static_cast<uint8_t>(type);
487
         });
488
      append_tls_length_value(result, type_bytes, 1);
12✔
489
   } else {
6✔
490
      BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
6✔
491
      result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
6✔
492
   }
493
   return result;
12✔
494
}
×
495

496
void Certificate_Type_Base::validate_selection(const Certificate_Type_Base& from_server) const {
2✔
497
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Client);
2✔
498
   BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
2✔
499

500
   // RFC 7250 4.2
501
   //    The value conveyed in the [client_]certificate_type extension MUST be
502
   //    selected from one of the values provided in the [client_]certificate_type
503
   //    extension sent in the client hello.
504
   if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
4✔
505
      throw TLS_Exception(Alert::IllegalParameter,
×
506
                          Botan::fmt("Selected certificate type was not offered: {}",
×
507
                                     certificate_type_to_string(from_server.selected_certificate_type())));
×
508
   }
509
}
2✔
510

511
Certificate_Type Certificate_Type_Base::selected_certificate_type() const {
6✔
512
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Server);
6✔
513
   BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
6✔
514
   return m_certificate_types.front();
6✔
515
}
516

517
Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) {}
4,047✔
518

519
const std::vector<Group_Params>& Supported_Groups::groups() const {
948✔
520
   return m_groups;
948✔
521
}
522

523
std::vector<Group_Params> Supported_Groups::ec_groups() const {
5,022✔
524
   std::vector<Group_Params> ec;
5,022✔
525
   for(auto g : m_groups) {
52,078✔
526
      if(g.is_pure_ecc_group()) {
94,112✔
527
         ec.push_back(g);
34,673✔
528
      }
529
   }
530
   return ec;
5,022✔
531
}
×
532

533
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,510✔
534
   std::vector<Group_Params> dh;
1,510✔
535
   for(auto g : m_groups) {
11,105✔
536
      if(g.is_in_ffdhe_range()) {
12,435✔
537
         dh.push_back(g);
548✔
538
      }
539
   }
540
   return dh;
1,510✔
541
}
×
542

543
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,724✔
544
   std::vector<uint8_t> buf(2);
4,724✔
545

546
   for(auto g : m_groups) {
54,923✔
547
      const uint16_t id = g.wire_code();
50,199✔
548

549
      if(id > 0) {
50,199✔
550
         buf.push_back(get_byte<0>(id));
50,199✔
551
         buf.push_back(get_byte<1>(id));
50,199✔
552
      }
553
   }
554

555
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,724✔
556
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,724✔
557

558
   return buf;
4,724✔
559
}
×
560

561
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
2,911✔
562
   const uint16_t len = reader.get_uint16_t();
2,911✔
563

564
   if(len + 2 != extension_size) {
2,911✔
565
      throw Decoding_Error("Inconsistent length field in supported groups list");
4✔
566
   }
567

568
   if(len % 2 == 1) {
2,907✔
569
      throw Decoding_Error("Supported groups list of strange size");
×
570
   }
571

572
   const size_t elems = len / 2;
2,907✔
573

574
   for(size_t i = 0; i != elems; ++i) {
23,913✔
575
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
21,006✔
576
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
577
      if(!value_exists(m_groups, group)) {
42,012✔
578
         m_groups.push_back(group);
21,006✔
579
      }
580
   }
581
}
2,911✔
582

583
std::vector<uint8_t> Supported_Point_Formats::serialize(Connection_Side /*whoami*/) const {
5,112✔
584
   // if this extension is sent, it MUST include uncompressed (RFC 4492, section 5.1)
585
   if(m_prefers_compressed) {
5,112✔
586
      return std::vector<uint8_t>{2, ANSIX962_COMPRESSED_PRIME, UNCOMPRESSED};
10✔
587
   } else {
588
      return std::vector<uint8_t>{1, UNCOMPRESSED};
5,102✔
589
   }
590
}
591

592
Supported_Point_Formats::Supported_Point_Formats(TLS_Data_Reader& reader, uint16_t extension_size) {
3,200✔
593
   const uint8_t len = reader.get_byte();
3,200✔
594

595
   if(len + 1 != extension_size) {
3,200✔
596
      throw Decoding_Error("Inconsistent length field in supported point formats list");
2✔
597
   }
598

599
   bool includes_uncompressed = false;
3,203✔
600
   for(size_t i = 0; i != len; ++i) {
3,203✔
601
      const uint8_t format = reader.get_byte();
3,202✔
602

603
      if(static_cast<ECPointFormat>(format) == UNCOMPRESSED) {
3,202✔
604
         m_prefers_compressed = false;
3,187✔
605
         reader.discard_next(len - i - 1);
3,187✔
606
         return;
3,187✔
607
      } else if(static_cast<ECPointFormat>(format) == ANSIX962_COMPRESSED_PRIME) {
15✔
608
         m_prefers_compressed = true;
10✔
609
         std::vector<uint8_t> remaining_formats = reader.get_fixed<uint8_t>(len - i - 1);
10✔
610
         includes_uncompressed =
10✔
611
            std::any_of(std::begin(remaining_formats), std::end(remaining_formats), [](uint8_t remaining_format) {
10✔
612
               return static_cast<ECPointFormat>(remaining_format) == UNCOMPRESSED;
613
            });
614
         break;
10✔
615
      }
10✔
616

617
      // ignore ANSIX962_COMPRESSED_CHAR2, we don't support these curves
618
   }
619

620
   // RFC 4492 5.1.:
621
   //   If the Supported Point Formats Extension is indeed sent, it MUST contain the value 0 (uncompressed)
622
   //   as one of the items in the list of point formats.
623
   // Note:
624
   //   RFC 8422 5.1.2. explicitly requires this check,
625
   //   but only if the Supported Groups extension was sent.
626
   if(!includes_uncompressed) {
11✔
627
      throw TLS_Exception(Alert::IllegalParameter,
1✔
628
                          "Supported Point Formats Extension must contain the uncompressed point format");
1✔
629
   }
630
}
631

632
namespace {
633

634
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
4,729✔
635
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
4,729✔
636

637
   std::vector<uint8_t> buf;
4,729✔
638

639
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,729✔
640

641
   buf.push_back(get_byte<0>(len));
4,729✔
642
   buf.push_back(get_byte<1>(len));
4,729✔
643

644
   for(const Signature_Scheme scheme : schemes) {
46,330✔
645
      buf.push_back(get_byte<0>(scheme.wire_code()));
41,601✔
646
      buf.push_back(get_byte<1>(scheme.wire_code()));
41,601✔
647
   }
648

649
   return buf;
4,729✔
650
}
×
651

652
std::vector<Signature_Scheme> parse_signature_algorithms(TLS_Data_Reader& reader, uint16_t extension_size) {
2,936✔
653
   uint16_t len = reader.get_uint16_t();
2,936✔
654

655
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
2,935✔
656
      throw Decoding_Error("Bad encoding on signature algorithms extension");
1✔
657
   }
658

659
   std::vector<Signature_Scheme> schemes;
2,934✔
660
   schemes.reserve(len / 2);
2,934✔
661
   while(len > 0) {
30,781✔
662
      schemes.emplace_back(reader.get_uint16_t());
27,847✔
663
      len -= 2;
27,847✔
664
   }
665

666
   return schemes;
2,934✔
667
}
×
668

669
}  // namespace
670

671
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
4,727✔
672
   return serialize_signature_algorithms(m_schemes);
4,727✔
673
}
674

675
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
2,934✔
676
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2,934✔
677

678
std::vector<uint8_t> Signature_Algorithms_Cert::serialize(Connection_Side /*whoami*/) const {
2✔
679
   return serialize_signature_algorithms(m_schemes);
2✔
680
}
681

682
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
2✔
683
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2✔
684

685
Session_Ticket_Extension::Session_Ticket_Extension(TLS_Data_Reader& reader, uint16_t extension_size) :
4,979✔
686
      m_ticket(Session_Ticket(reader.get_elem<uint8_t, std::vector<uint8_t>>(extension_size))) {}
4,979✔
687

688
SRTP_Protection_Profiles::SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size) :
10✔
689
      m_pp(reader.get_range<uint16_t>(2, 0, 65535)) {
10✔
690
   const std::vector<uint8_t> mki = reader.get_range<uint8_t>(1, 0, 255);
9✔
691

692
   if(m_pp.size() * 2 + mki.size() + 3 != extension_size) {
9✔
693
      throw Decoding_Error("Bad encoding for SRTP protection extension");
×
694
   }
695

696
   if(!mki.empty()) {
9✔
697
      throw Decoding_Error("Unhandled non-empty MKI for SRTP protection extension");
×
698
   }
699
}
9✔
700

701
std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const {
5✔
702
   std::vector<uint8_t> buf;
5✔
703

704
   const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2);
5✔
705
   buf.push_back(get_byte<0>(pp_len));
5✔
706
   buf.push_back(get_byte<1>(pp_len));
5✔
707

708
   for(const uint16_t pp : m_pp) {
12✔
709
      buf.push_back(get_byte<0>(pp));
7✔
710
      buf.push_back(get_byte<1>(pp));
7✔
711
   }
712

713
   buf.push_back(0);  // srtp_mki, always empty here
5✔
714

715
   return buf;
5✔
716
}
×
717

718
Extended_Master_Secret::Extended_Master_Secret(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
5,515✔
719
   if(extension_size != 0) {
5,515✔
720
      throw Decoding_Error("Invalid extended_master_secret extension");
2✔
721
   }
722
}
5,513✔
723

724
std::vector<uint8_t> Extended_Master_Secret::serialize(Connection_Side /*whoami*/) const {
5,242✔
725
   return std::vector<uint8_t>();
5,242✔
726
}
727

728
Encrypt_then_MAC::Encrypt_then_MAC(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
811✔
729
   if(extension_size != 0) {
811✔
730
      throw Decoding_Error("Invalid encrypt_then_mac extension");
×
731
   }
732
}
811✔
733

734
std::vector<uint8_t> Encrypt_then_MAC::serialize(Connection_Side /*whoami*/) const {
3,979✔
735
   return std::vector<uint8_t>();
3,979✔
736
}
737

738
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,481✔
739
   std::vector<uint8_t> buf;
4,481✔
740

741
   if(whoami == Connection_Side::Server) {
4,481✔
742
      BOTAN_ASSERT_NOMSG(m_versions.size() == 1);
429✔
743
      buf.push_back(m_versions[0].major_version());
429✔
744
      buf.push_back(m_versions[0].minor_version());
429✔
745
   } else {
746
      BOTAN_ASSERT_NOMSG(!m_versions.empty());
4,052✔
747
      const uint8_t len = static_cast<uint8_t>(m_versions.size() * 2);
4,052✔
748

749
      buf.push_back(len);
4,052✔
750

751
      for(const Protocol_Version version : m_versions) {
9,222✔
752
         buf.push_back(version.major_version());
5,170✔
753
         buf.push_back(version.minor_version());
5,170✔
754
      }
755
   }
756

757
   return buf;
4,481✔
758
}
×
759

760
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,471✔
761
   if(offer.is_datagram_protocol()) {
3,471✔
762
#if defined(BOTAN_HAS_TLS_12)
763
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
400✔
764
         m_versions.push_back(Protocol_Version::DTLS_V12);
400✔
765
      }
766
#endif
767
   } else {
768
#if defined(BOTAN_HAS_TLS_13)
769
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,154✔
770
         m_versions.push_back(Protocol_Version::TLS_V13);
988✔
771
      }
772
#endif
773
#if defined(BOTAN_HAS_TLS_12)
774
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
4,059✔
775
         m_versions.push_back(Protocol_Version::TLS_V12);
3,042✔
776
      }
777
#endif
778
   }
779
}
3,471✔
780

781
Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
1,826✔
782
   if(from == Connection_Side::Server) {
1,826✔
783
      if(extension_size != 2) {
541✔
784
         throw Decoding_Error("Server sent invalid supported_versions extension");
×
785
      }
786
      m_versions.push_back(Protocol_Version(reader.get_uint16_t()));
541✔
787
   } else {
788
      auto versions = reader.get_range<uint16_t>(1, 1, 127);
1,285✔
789

790
      for(auto v : versions) {
4,559✔
791
         m_versions.push_back(Protocol_Version(v));
3,274✔
792
      }
793

794
      if(extension_size != 1 + 2 * versions.size()) {
1,285✔
795
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
796
      }
797
   }
1,285✔
798
}
1,826✔
799

800
bool Supported_Versions::supports(Protocol_Version version) const {
1,485✔
801
   for(auto v : m_versions) {
1,996✔
802
      if(version == v) {
1,977✔
803
         return true;
1,485✔
804
      }
805
   }
806
   return false;
807
}
808

809
Record_Size_Limit::Record_Size_Limit(const uint16_t limit) : m_limit(limit) {
16✔
810
   BOTAN_ASSERT(limit >= 64, "RFC 8449 does not allow record size limits smaller than 64 bytes");
16✔
811
   BOTAN_ASSERT(limit <= MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */,
16✔
812
                "RFC 8449 does not allow record size limits larger than 2^14+1");
813
}
16✔
814

815
Record_Size_Limit::Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
45✔
816
   if(extension_size != 2) {
45✔
817
      throw TLS_Exception(Alert::DecodeError, "invalid record_size_limit extension");
×
818
   }
819

820
   m_limit = reader.get_uint16_t();
45✔
821

822
   // RFC 8449 4.
823
   //    This value is the length of the plaintext of a protected record.
824
   //    The value includes the content type and padding added in TLS 1.3 (that
825
   //    is, the complete length of TLSInnerPlaintext).
826
   //
827
   //    A server MUST NOT enforce this restriction; a client might advertise
828
   //    a higher limit that is enabled by an extension or version the server
829
   //    does not understand. A client MAY abort the handshake with an
830
   //    "illegal_parameter" alert.
831
   //
832
   // Note: We are currently supporting this extension in TLS 1.3 only, hence
833
   //       we check for the TLS 1.3 limit. The TLS 1.2 limit would not include
834
   //       the "content type byte" and hence be one byte less!
835
   if(m_limit > MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */ && from == Connection_Side::Server) {
45✔
836
      throw TLS_Exception(Alert::IllegalParameter,
×
837
                          "Server requested a record size limit larger than the protocol's maximum");
×
838
   }
839

840
   // RFC 8449 4.
841
   //    Endpoints MUST NOT send a "record_size_limit" extension with a value
842
   //    smaller than 64.  An endpoint MUST treat receipt of a smaller value
843
   //    as a fatal error and generate an "illegal_parameter" alert.
844
   if(m_limit < 64) {
45✔
845
      throw TLS_Exception(Alert::IllegalParameter, "Received a record size limit smaller than 64 bytes");
×
846
   }
847
}
45✔
848

849
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side /*whoami*/) const {
53✔
850
   std::vector<uint8_t> buf;
53✔
851

852
   buf.push_back(get_byte<0>(m_limit));
53✔
853
   buf.push_back(get_byte<1>(m_limit));
53✔
854

855
   return buf;
53✔
856
}
×
857

858
#if defined(BOTAN_HAS_TLS_13)
859
Cookie::Cookie(const std::vector<uint8_t>& cookie) : m_cookie(cookie) {}
4✔
860

861
Cookie::Cookie(TLS_Data_Reader& reader, uint16_t extension_size) {
12✔
862
   if(extension_size == 0) {
12✔
863
      return;
864
   }
865

866
   const uint16_t len = reader.get_uint16_t();
12✔
867

868
   if(len == 0) {
12✔
869
      // Based on RFC 8446 4.2.2, len of the Cookie buffer must be at least 1
870
      throw Decoding_Error("Cookie length must be at least 1 byte");
1✔
871
   }
872

873
   if(len > reader.remaining_bytes()) {
11✔
874
      throw Decoding_Error("Not enough bytes in the buffer to decode Cookie");
×
875
   }
876

877
   for(size_t i = 0; i < len; ++i) {
719✔
878
      m_cookie.push_back(reader.get_byte());
708✔
879
   }
880
}
1✔
881

882
std::vector<uint8_t> Cookie::serialize(Connection_Side /*whoami*/) const {
10✔
883
   std::vector<uint8_t> buf;
10✔
884

885
   const uint16_t len = static_cast<uint16_t>(m_cookie.size());
10✔
886

887
   buf.push_back(get_byte<0>(len));
10✔
888
   buf.push_back(get_byte<1>(len));
10✔
889

890
   for(const auto& cookie_byte : m_cookie) {
712✔
891
      buf.push_back(cookie_byte);
702✔
892
   }
893

894
   return buf;
10✔
895
}
×
896

897
std::vector<uint8_t> PSK_Key_Exchange_Modes::serialize(Connection_Side /*whoami*/) const {
1,184✔
898
   std::vector<uint8_t> buf;
1,184✔
899

900
   BOTAN_ASSERT_NOMSG(m_modes.size() < 256);
1,184✔
901
   buf.push_back(static_cast<uint8_t>(m_modes.size()));
1,184✔
902
   for(const auto& mode : m_modes) {
2,368✔
903
      buf.push_back(static_cast<uint8_t>(mode));
1,184✔
904
   }
905

906
   return buf;
1,184✔
907
}
×
908

909
PSK_Key_Exchange_Modes::PSK_Key_Exchange_Modes(TLS_Data_Reader& reader, uint16_t extension_size) {
1,072✔
910
   if(extension_size < 2) {
1,072✔
911
      throw Decoding_Error("Empty psk_key_exchange_modes extension is illegal");
×
912
   }
913

914
   const auto mode_count = reader.get_byte();
1,072✔
915
   for(uint16_t i = 0; i < mode_count; ++i) {
2,148✔
916
      const auto mode = static_cast<PSK_Key_Exchange_Mode>(reader.get_byte());
1,076✔
917
      if(mode == PSK_Key_Exchange_Mode::PSK_KE || mode == PSK_Key_Exchange_Mode::PSK_DHE_KE) {
1,076✔
918
         m_modes.push_back(mode);
1,070✔
919
      }
920
   }
921
}
1,072✔
922

923
std::vector<uint8_t> Certificate_Authorities::serialize(Connection_Side /*whoami*/) const {
81✔
924
   std::vector<uint8_t> out;
81✔
925
   std::vector<uint8_t> dn_list;
81✔
926

927
   for(const auto& dn : m_distinguished_names) {
162✔
928
      std::vector<uint8_t> encoded_dn;
81✔
929
      auto encoder = DER_Encoder(encoded_dn);
81✔
930
      dn.encode_into(encoder);
81✔
931
      append_tls_length_value(dn_list, encoded_dn, 2);
81✔
932
   }
162✔
933

934
   append_tls_length_value(out, dn_list, 2);
81✔
935

936
   return out;
81✔
937
}
81✔
938

939
Certificate_Authorities::Certificate_Authorities(TLS_Data_Reader& reader, uint16_t extension_size) {
3✔
940
   if(extension_size < 2) {
3✔
941
      throw Decoding_Error("Empty certificate_authorities extension is illegal");
×
942
   }
943

944
   const uint16_t purported_size = reader.get_uint16_t();
3✔
945

946
   if(reader.remaining_bytes() != purported_size) {
3✔
947
      throw Decoding_Error("Inconsistent length in certificate_authorities extension");
×
948
   }
949

950
   while(reader.has_remaining()) {
9✔
951
      std::vector<uint8_t> name_bits = reader.get_tls_length_value(2);
6✔
952

953
      BER_Decoder decoder(name_bits.data(), name_bits.size());
6✔
954
      m_distinguished_names.emplace_back();
6✔
955
      decoder.decode(m_distinguished_names.back());
6✔
956
   }
12✔
957
}
3✔
958

959
Certificate_Authorities::Certificate_Authorities(std::vector<X509_DN> acceptable_DNs) :
82✔
960
      m_distinguished_names(std::move(acceptable_DNs)) {}
82✔
961

962
std::vector<uint8_t> EarlyDataIndication::serialize(Connection_Side /*whoami*/) const {
8✔
963
   std::vector<uint8_t> result;
8✔
964
   if(m_max_early_data_size.has_value()) {
8✔
965
      const auto max_data = m_max_early_data_size.value();
2✔
966
      result.push_back(get_byte<0>(max_data));
2✔
967
      result.push_back(get_byte<1>(max_data));
2✔
968
      result.push_back(get_byte<2>(max_data));
2✔
969
      result.push_back(get_byte<3>(max_data));
2✔
970
   }
971
   return result;
8✔
972
}
×
973

974
EarlyDataIndication::EarlyDataIndication(TLS_Data_Reader& reader,
5✔
975
                                         uint16_t extension_size,
976
                                         Handshake_Type message_type) {
5✔
977
   if(message_type == Handshake_Type::NewSessionTicket) {
5✔
978
      if(extension_size != 4) {
1✔
979
         throw TLS_Exception(Alert::DecodeError,
×
980
                             "Received an early_data extension in a NewSessionTicket message "
981
                             "without maximum early data size indication");
×
982
      }
983

984
      m_max_early_data_size = reader.get_uint32_t();
1✔
985
   } else if(extension_size != 0) {
4✔
986
      throw TLS_Exception(Alert::DecodeError,
×
987
                          "Received an early_data extension containing an unexpected data "
988
                          "size indication");
×
989
   }
990
}
5✔
991

992
bool EarlyDataIndication::empty() const {
8✔
993
   // This extension may be empty by definition but still carry information
994
   return false;
8✔
995
}
996

997
#endif
998
}  // 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