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

randombit / botan / 24648292556

19 Apr 2026 10:53PM UTC coverage: 89.474% (+0.03%) from 89.442%
24648292556

push

github

web-flow
Merge pull request #5536 from randombit/jack/x509-misc

Various PKIX optimizations and bug fixes

106453 of 118977 relevant lines covered (89.47%)

11452293.24 hits per line

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

90.24
/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/tls_exceptn.h>
16
#include <botan/tls_policy.h>
17
#include <botan/internal/fmt.h>
18
#include <botan/internal/parsing.h>
19
#include <botan/internal/stl_util.h>
20
#include <botan/internal/tls_reader.h>
21
#include <algorithm>
22
#include <unordered_set>
23

24
#if defined(BOTAN_HAS_TLS_13)
25
   #include <botan/tls_extensions_13.h>
26
#endif
27

28
#if defined(BOTAN_HAS_TLS_12)
29
   #include <botan/tls_extensions_12.h>
30
#endif
31

32
namespace Botan::TLS {
33

34
namespace {
35

36
std::unique_ptr<Extension> make_extension(TLS_Data_Reader& reader,
43,870✔
37
                                          Extension_Code code,
38
                                          const Connection_Side from,
39
                                          const Handshake_Type message_type) {
40
   // This cast is safe because we read exactly a 16 bit length field for
41
   // the extension in Extensions::deserialize
42
   const uint16_t size = static_cast<uint16_t>(reader.remaining_bytes());
43,870✔
43
   switch(code) {
43,870✔
44
      case Extension_Code::ServerNameIndication:
3,030✔
45
         return std::make_unique<Server_Name_Indicator>(reader, size, from);
3,030✔
46

47
      case Extension_Code::SupportedGroups:
3,109✔
48
         return std::make_unique<Supported_Groups>(reader, size);
3,109✔
49

50
      case Extension_Code::CertificateStatusRequest:
2,887✔
51
         return std::make_unique<Certificate_Status_Request>(reader, size, message_type, from);
2,887✔
52

53
      case Extension_Code::SignatureAlgorithms:
3,137✔
54
         return std::make_unique<Signature_Algorithms>(reader, size);
3,137✔
55

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

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

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

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

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

71
      case Extension_Code::RecordSizeLimit:
45✔
72
         return std::make_unique<Record_Size_Limit>(reader, size, from);
45✔
73

74
      case Extension_Code::SupportedVersions:
2,097✔
75
         return std::make_unique<Supported_Versions>(reader, size, from);
2,097✔
76

77
#if defined(BOTAN_HAS_TLS_12)
78
      case Extension_Code::EcPointFormats:
3,402✔
79
         return std::make_unique<Supported_Point_Formats>(reader, size);
3,402✔
80

81
      case Extension_Code::SafeRenegotiation:
6,476✔
82
         return std::make_unique<Renegotiation_Extension>(reader, size);
6,476✔
83

84
      case Extension_Code::ExtendedMasterSecret:
6,280✔
85
         return std::make_unique<Extended_Master_Secret>(reader, size);
6,280✔
86

87
      case Extension_Code::EncryptThenMac:
819✔
88
         return std::make_unique<Encrypt_then_MAC>(reader, size);
819✔
89

90
      case Extension_Code::SessionTicket:
5,728✔
91
         return std::make_unique<Session_Ticket_Extension>(reader, size);
5,728✔
92
#else
93
      case Extension_Code::EcPointFormats:
94
      case Extension_Code::SafeRenegotiation:
95
      case Extension_Code::ExtendedMasterSecret:
96
      case Extension_Code::EncryptThenMac:
97
      case Extension_Code::SessionTicket:
98
         break;  // considered as 'unknown extension'
99
#endif
100

101
#if defined(BOTAN_HAS_TLS_13)
102
      case Extension_Code::PresharedKey:
302✔
103
         return std::make_unique<PSK>(reader, size, message_type);
302✔
104

105
      case Extension_Code::EarlyData:
5✔
106
         return std::make_unique<EarlyDataIndication>(reader, size, message_type);
5✔
107

108
      case Extension_Code::Cookie:
19✔
109
         return std::make_unique<Cookie>(reader, size);
19✔
110

111
      case Extension_Code::PskKeyExchangeModes:
1,289✔
112
         return std::make_unique<PSK_Key_Exchange_Modes>(reader, size);
1,289✔
113

114
      case Extension_Code::CertificateAuthorities:
3✔
115
         return std::make_unique<Certificate_Authorities>(reader, size);
3✔
116

117
      case Extension_Code::KeyShare:
1,872✔
118
         return std::make_unique<Key_Share>(reader, size, message_type);
1,872✔
119
#else
120
      case Extension_Code::PresharedKey:
121
      case Extension_Code::EarlyData:
122
      case Extension_Code::Cookie:
123
      case Extension_Code::PskKeyExchangeModes:
124
      case Extension_Code::CertificateAuthorities:
125
      case Extension_Code::KeyShare:
126
         break;  // considered as 'unknown extension'
127
#endif
128
   }
129

130
   return std::make_unique<Unknown_Extension>(code, reader, size);
2,942✔
131
}
132

133
}  // namespace
134

135
Extensions::~Extensions() = default;
25,146✔
136

137
bool Extensions::has(Extension_Code type) const {
132,763✔
138
   return m_extensions.contains(type);
132,763✔
139
}
140

141
Extension* Extensions::get(Extension_Code type) const {
109,689✔
142
   const auto i = m_extensions.find(type);
109,689✔
143

144
   if(i == m_extensions.end()) {
109,689✔
145
      return nullptr;
146
   } else {
147
      return i->second.get();
69,900✔
148
   }
149
}
150

151
void Extensions::add(std::unique_ptr<Extension> extn) {
88,866✔
152
   const auto type = extn->type();
88,866✔
153
   if(has(type)) {
88,866✔
154
      throw Invalid_Argument("cannot add the same extension twice: " + std::to_string(static_cast<uint16_t>(type)));
×
155
   }
156

157
   m_extension_codes.push_back(type);
88,866✔
158
   m_extensions.emplace(type, std::move(extn));
88,866✔
159
}
88,866✔
160

161
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
9,020✔
162
   if(reader.has_remaining()) {
9,020✔
163
      const uint16_t all_extn_size = reader.get_uint16_t();
9,014✔
164

165
      if(reader.remaining_bytes() != all_extn_size) {
9,013✔
166
         throw Decoding_Error("Bad extension size");
130✔
167
      }
168

169
      while(reader.has_remaining()) {
52,705✔
170
         const uint16_t extension_code = reader.get_uint16_t();
43,899✔
171
         const uint16_t extension_size = reader.get_uint16_t();
43,898✔
172

173
         const auto type = static_cast<Extension_Code>(extension_code);
43,897✔
174

175
         if(this->has(type)) {
43,897✔
176
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
19✔
177
         }
178

179
         // TODO offer a function on reader that returns a byte range as a reference
180
         // to avoid this copy of the extension data
181
         const std::vector<uint8_t> extn_data = reader.get_fixed<uint8_t>(extension_size);
43,878✔
182
         m_raw_extension_data[type] = extn_data;
43,870✔
183
         TLS_Data_Reader extn_reader("Extension", extn_data);
43,870✔
184
         this->add(make_extension(extn_reader, type, from, message_type));
43,870✔
185
         extn_reader.assert_done();
43,822✔
186
      }
43,822✔
187
   }
188
}
8,812✔
189

190
bool Extensions::contains_other_than(const std::set<Extension_Code>& allowed_extensions,
3,811✔
191
                                     const bool allow_unknown_extensions) const {
192
   const auto found = extension_types();
3,811✔
193

194
   std::vector<Extension_Code> diff;
3,811✔
195
   std::set_difference(
3,811✔
196
      found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
197

198
   if(allow_unknown_extensions) {
3,811✔
199
      // Go through the found unexpected extensions whether any of those
200
      // is known to this TLS implementation.
201
      const auto itr = std::find_if(diff.cbegin(), diff.cend(), [this](const auto ext_type) {
1,705✔
202
         const auto ext = get(ext_type);
22✔
203
         return ext && ext->is_implemented();
22✔
204
      });
205

206
      // ... if yes, `contains_other_than` is true
207
      return itr != diff.cend();
1,705✔
208
   }
209

210
   return !diff.empty();
2,106✔
211
}
3,811✔
212

213
bool Extensions::remove_extension(Extension_Code type) {
137✔
214
   auto i = m_extensions.find(type);
137✔
215

216
   if(i == m_extensions.end()) {
137✔
217
      return false;
218
   } else {
219
      m_extensions.erase(i);
137✔
220
      std::erase(m_extension_codes, type);
137✔
221
      m_raw_extension_data.erase(type);
137✔
222
      return true;
137✔
223
   }
224
}
225

226
std::vector<uint8_t> Extensions::serialize(Connection_Side whoami) const {
6,904✔
227
   std::vector<uint8_t> buf(2);  // 2 bytes for length field
6,904✔
228

229
   // Serialize in the order extensions were added, which matters for TLS 1.3
230
   for(const auto extn_type : m_extension_codes) {
59,693✔
231
      const auto& extn = m_extensions.at(extn_type);
52,789✔
232

233
      if(extn->empty()) {
52,789✔
234
         continue;
953✔
235
      }
236

237
      const uint16_t extn_code = static_cast<uint16_t>(extn_type);
51,836✔
238

239
      const std::vector<uint8_t> extn_val = extn->serialize(whoami);
51,836✔
240

241
      buf.push_back(get_byte<0>(extn_code));
51,836✔
242
      buf.push_back(get_byte<1>(extn_code));
51,836✔
243

244
      buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
51,836✔
245
      buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
51,836✔
246

247
      buf += extn_val;
51,836✔
248
   }
51,836✔
249

250
   const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
6,904✔
251

252
   buf[0] = get_byte<0>(extn_size);
6,904✔
253
   buf[1] = get_byte<1>(extn_size);
6,904✔
254

255
   // avoid sending a completely empty extensions block
256
   if(buf.size() == 2) {
6,904✔
257
      return std::vector<uint8_t>();
310✔
258
   }
259

260
   return buf;
6,594✔
261
}
6,904✔
262

263
std::set<Extension_Code> Extensions::extension_types() const {
12,120✔
264
   std::set<Extension_Code> offers;
12,120✔
265
   for(const auto& [extn_type, extn] : m_extensions) {
78,778✔
266
      // Consistent with serialize(): empty extensions are not placed on
267
      // the wire so they must not appear in the "offered" set either.
268
      if(!extn->empty()) {
66,658✔
269
         offers.insert(extn_type);
65,982✔
270
      }
271
   }
272
   return offers;
12,120✔
273
}
×
274

275
void Extensions::reorder(const std::vector<Extension_Code>& order) {
50✔
276
   const std::set<Extension_Code> in_order(order.begin(), order.end());
50✔
277

278
   std::vector<Extension_Code> new_codes;
50✔
279
   new_codes.reserve(m_extension_codes.size());
50✔
280

281
   // First: extensions not mentioned in the order (preserving their relative order)
282
   for(auto code : m_extension_codes) {
426✔
283
      if(!in_order.contains(code)) {
752✔
284
         new_codes.push_back(code);
242✔
285
      }
286
   }
287

288
   // Then: extensions in the specified order
289
   for(auto code : order) {
323✔
290
      if(m_extensions.contains(code)) {
546✔
291
         new_codes.push_back(code);
134✔
292
      }
293
   }
294

295
   m_extension_codes = std::move(new_codes);
50✔
296
}
50✔
297

298
Unknown_Extension::Unknown_Extension(Extension_Code type, TLS_Data_Reader& reader, uint16_t extension_size) :
2,942✔
299
      m_type(type), m_value(reader.get_fixed<uint8_t>(extension_size)) {}
2,942✔
300

301
std::vector<uint8_t> Unknown_Extension::serialize(Connection_Side /*whoami*/) const {
2✔
302
   return m_value;
2✔
303
}
304

305
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
3,030✔
306
   /*
307
   RFC 6066 Section 3
308

309
      A server that receives a client hello containing the "server_name"
310
      extension MAY use the information contained in the extension to guide
311
      its selection of an appropriate certificate to return to the client,
312
      and/or other aspects of security policy.  In this event, the server
313
      SHALL include an extension of type "server_name" in the (extended)
314
      server hello.  The "extension_data" field of this extension SHALL be
315
      empty.
316
   */
317
   if(from == Connection_Side::Server) {
3,030✔
318
      if(extension_size != 0) {
36✔
319
         throw TLS_Exception(Alert::IllegalParameter, "Server sent non-empty SNI extension");
×
320
      }
321
   } else {
322
      // Clients are required to send at least one name in the SNI
323
      if(extension_size == 0) {
2,994✔
324
         throw TLS_Exception(Alert::IllegalParameter, "Client sent empty SNI extension");
×
325
      }
326

327
      const uint16_t name_bytes = reader.get_uint16_t();
2,994✔
328

329
      if(name_bytes + 2 != extension_size || name_bytes < 3) {
2,994✔
330
         throw Decoding_Error("Bad encoding of SNI extension");
×
331
      }
332

333
      BOTAN_ASSERT_NOMSG(reader.remaining_bytes() == name_bytes);
2,994✔
334

335
      while(reader.has_remaining()) {
5,988✔
336
         const uint8_t name_type = reader.get_byte();
2,994✔
337

338
         if(name_type == 0) {
2,994✔
339
            /*
340
            RFC 6066 Section 3
341
               The ServerNameList MUST NOT contain more than one name of the same name_type.
342
            */
343
            if(!m_sni_host_name.empty()) {
2,994✔
344
               throw Decoding_Error("TLS ServerNameIndicator contains more than one host_name");
×
345
            }
346
            m_sni_host_name = reader.get_string(2, 1, 65535);
2,994✔
347
         } else {
348
            /*
349
            Unknown name type - skip its length-prefixed value and continue
350

351
            RFC 6066 Section 3
352
               For backward compatibility, all future data structures associated
353
               with new NameTypes MUST begin with a 16-bit length field.
354
            */
355
            const uint16_t unknown_name_len = reader.get_uint16_t();
×
356
            reader.discard_next(unknown_name_len);
×
357
         }
358
      }
359
   }
360
}
3,030✔
361

362
std::vector<uint8_t> Server_Name_Indicator::serialize(Connection_Side whoami) const {
4,804✔
363
   // RFC 6066
364
   //    [...] the server SHALL include an extension of type "server_name" in
365
   //    the (extended) server hello. The "extension_data" field of this
366
   //    extension SHALL be empty.
367
   if(whoami == Connection_Side::Server) {
4,804✔
368
      return {};
300✔
369
   }
370

371
   std::vector<uint8_t> buf;
4,504✔
372

373
   const size_t name_len = m_sni_host_name.size();
4,504✔
374

375
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,504✔
376
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,504✔
377
   buf.push_back(0);  // DNS
4,504✔
378

379
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,504✔
380
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,504✔
381

382
   buf += as_span_of_bytes(m_sni_host_name);
4,504✔
383

384
   return buf;
4,504✔
385
}
4,504✔
386

387
bool Server_Name_Indicator::hostname_acceptable_for_sni(std::string_view hostname) {
3,805✔
388
   // Avoid sending an IPv4/IPv6 address in SNI as this is prohibited
389

390
   if(hostname.empty()) {
3,805✔
391
      return false;
392
   }
393

394
   if(string_to_ipv4(hostname).has_value()) {
3,758✔
395
      return false;
396
   }
397

398
   // IPv6? Anyway ':' is not valid in DNS
399
   if(hostname.find(':') != std::string_view::npos) {
3,758✔
400
      return false;
401
   }
402

403
   return true;
404
}
405

406
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
406✔
407
                                                                                 uint16_t extension_size,
408
                                                                                 Connection_Side from) {
406✔
409
   if(extension_size == 0) {
406✔
410
      throw Decoding_Error("ALPN extension cannot be empty");
×
411
   }
412

413
   const uint16_t name_bytes = reader.get_uint16_t();
406✔
414

415
   size_t bytes_remaining = extension_size - 2;
406✔
416

417
   if(name_bytes != bytes_remaining) {
406✔
418
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
2✔
419
   }
420

421
   while(bytes_remaining > 0) {
1,079✔
422
      const std::string p = reader.get_string(1, 0, 255);
682✔
423

424
      if(bytes_remaining < p.size() + 1) {
682✔
425
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
426
      }
427

428
      if(p.empty()) {
682✔
429
         throw Decoding_Error("Empty ALPN protocol not allowed");
7✔
430
      }
431

432
      bytes_remaining -= (p.size() + 1);
675✔
433

434
      m_protocols.push_back(p);
675✔
435
   }
682✔
436

437
   // RFC 7301 3.1
438
   //    The "extension_data" field of the [...] extension is structured the
439
   //    same as described above for the client "extension_data", except that
440
   //    the "ProtocolNameList" MUST contain exactly one "ProtocolName".
441
   if(from == Connection_Side::Server && m_protocols.size() != 1) {
397✔
442
      throw TLS_Exception(
×
443
         Alert::DecodeError,
444
         "Server sent " + std::to_string(m_protocols.size()) + " protocols in ALPN extension response");
×
445
   }
446
}
406✔
447

448
std::string Application_Layer_Protocol_Notification::single_protocol() const {
285✔
449
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
285✔
450
   return m_protocols.front();
285✔
451
}
452

453
std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const {
363✔
454
   std::vector<uint8_t> buf(2);
363✔
455

456
   for(auto&& proto : m_protocols) {
951✔
457
      if(proto.length() >= 256) {
588✔
458
         throw TLS_Exception(Alert::InternalError, "ALPN name too long");
×
459
      }
460
      if(!proto.empty()) {
588✔
461
         append_tls_length_value(buf, proto, 1);
1,176✔
462
      }
463
   }
464

465
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
363✔
466
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
363✔
467

468
   return buf;
363✔
469
}
×
470

471
Certificate_Type_Base::Certificate_Type_Base(std::vector<Certificate_Type> supported_cert_types) :
64✔
472
      m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
64✔
473
   BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
64✔
474
}
64✔
475

476
Client_Certificate_Type::Client_Certificate_Type(const Client_Certificate_Type& cct, const Policy& policy) :
9✔
477
      Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
9✔
478

479
Server_Certificate_Type::Server_Certificate_Type(const Server_Certificate_Type& sct, const Policy& policy) :
1✔
480
      Certificate_Type_Base(sct, policy.accepted_server_certificate_types()) {}
1✔
481

482
Certificate_Type_Base::Certificate_Type_Base(const Certificate_Type_Base& certificate_type_from_client,
10✔
483
                                             const std::vector<Certificate_Type>& server_preference) :
10✔
484
      m_from(Connection_Side::Server) {
10✔
485
   // RFC 7250 4.2
486
   //    The server_certificate_type extension in the client hello indicates the
487
   //    types of certificates the client is able to process when provided by
488
   //    the server in a subsequent certificate payload. [...] With the
489
   //    server_certificate_type extension in the server hello, the TLS server
490
   //    indicates the certificate type carried in the Certificate payload.
491
   for(const auto server_supported_cert_type : server_preference) {
11✔
492
      if(value_exists(certificate_type_from_client.m_certificate_types, server_supported_cert_type)) {
22✔
493
         m_certificate_types.push_back(server_supported_cert_type);
10✔
494
         return;
10✔
495
      }
496
   }
497

498
   // RFC 7250 4.2 (2.)
499
   //    The server supports the extension defined in this document, but
500
   //    it does not have any certificate type in common with the client.
501
   //    Then, the server terminates the session with a fatal alert of
502
   //    type "unsupported_certificate".
503
   throw TLS_Exception(Alert::UnsupportedCertificate, "Failed to agree on certificate_type");
×
504
}
×
505

506
Certificate_Type_Base::Certificate_Type_Base(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) :
12✔
507
      m_from(from) {
12✔
508
   if(extension_size == 0) {
12✔
509
      throw Decoding_Error("Certificate type extension cannot be empty");
×
510
   }
511

512
   if(from == Connection_Side::Client) {
12✔
513
      const auto type_bytes = reader.get_tls_length_value(1);
10✔
514
      if(static_cast<size_t>(extension_size) != type_bytes.size() + 1) {
10✔
515
         throw Decoding_Error("certificate type extension had inconsistent length");
×
516
      }
517
      std::transform(
10✔
518
         type_bytes.begin(), type_bytes.end(), std::back_inserter(m_certificate_types), [](const auto type_byte) {
10✔
519
            return static_cast<Certificate_Type>(type_byte);
520
         });
521
   } else {
10✔
522
      // RFC 7250 4.2
523
      //    Note that only a single value is permitted in the
524
      //    server_certificate_type extension when carried in the server hello.
525
      if(extension_size != 1) {
2✔
526
         throw Decoding_Error("Server's certificate type extension must be of length 1");
×
527
      }
528
      const auto type_byte = reader.get_byte();
2✔
529
      m_certificate_types.push_back(static_cast<Certificate_Type>(type_byte));
2✔
530
   }
531
}
12✔
532

533
std::vector<uint8_t> Certificate_Type_Base::serialize(Connection_Side whoami) const {
23✔
534
   std::vector<uint8_t> result;
23✔
535
   if(whoami == Connection_Side::Client) {
23✔
536
      std::vector<uint8_t> type_bytes;
9✔
537
      std::transform(
9✔
538
         m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
539
            return static_cast<uint8_t>(type);
540
         });
541
      append_tls_length_value(result, type_bytes, 1);
18✔
542
   } else {
9✔
543
      BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
14✔
544
      result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
14✔
545
   }
546
   return result;
23✔
547
}
×
548

549
void Certificate_Type_Base::validate_selection(const Certificate_Type_Base& from_server) const {
2✔
550
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Client);
2✔
551
   BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
2✔
552

553
   // RFC 7250 4.2
554
   //    The value conveyed in the [client_]certificate_type extension MUST be
555
   //    selected from one of the values provided in the [client_]certificate_type
556
   //    extension sent in the client hello.
557
   if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
4✔
558
      throw TLS_Exception(Alert::IllegalParameter,
×
559
                          Botan::fmt("Selected certificate type was not offered: {}",
×
560
                                     certificate_type_to_string(from_server.selected_certificate_type())));
×
561
   }
562
}
2✔
563

564
Certificate_Type Certificate_Type_Base::selected_certificate_type() const {
14✔
565
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Server);
14✔
566
   BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
14✔
567
   return m_certificate_types.front();
14✔
568
}
569

570
Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) {}
4,195✔
571

572
const std::vector<Group_Params>& Supported_Groups::groups() const {
1,031✔
573
   return m_groups;
1,031✔
574
}
575

576
std::vector<Group_Params> Supported_Groups::ec_groups() const {
5,213✔
577
   std::vector<Group_Params> ec;
5,213✔
578
   for(auto g : m_groups) {
54,943✔
579
      if(g.is_pure_ecc_group()) {
99,460✔
580
         ec.push_back(g);
35,747✔
581
      }
582
   }
583
   return ec;
5,213✔
584
}
×
585

586
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,580✔
587
   std::vector<Group_Params> dh;
1,580✔
588
   for(auto g : m_groups) {
12,842✔
589
      if(g.is_in_ffdhe_range()) {
15,455✔
590
         dh.push_back(g);
547✔
591
      }
592
   }
593
   return dh;
1,580✔
594
}
×
595

596
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,965✔
597
   std::vector<uint8_t> buf(2);
4,965✔
598

599
   for(auto g : m_groups) {
57,757✔
600
      const uint16_t id = g.wire_code();
52,792✔
601

602
      if(id > 0) {
52,792✔
603
         buf.push_back(get_byte<0>(id));
52,792✔
604
         buf.push_back(get_byte<1>(id));
52,792✔
605
      }
606
   }
607

608
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,965✔
609
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,965✔
610

611
   return buf;
4,965✔
612
}
×
613

614
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
3,111✔
615
   const uint16_t len = reader.get_uint16_t();
3,111✔
616

617
   if(len + 2 != extension_size) {
3,111✔
618
      throw Decoding_Error("Inconsistent length field in supported groups list");
4✔
619
   }
620

621
   if(len % 2 == 1) {
3,107✔
622
      throw Decoding_Error("Supported groups list of strange size");
×
623
   }
624

625
   const size_t elems = len / 2;
3,107✔
626

627
   std::unordered_set<uint16_t> seen;
3,107✔
628
   for(size_t i = 0; i != elems; ++i) {
27,481✔
629
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
24,374✔
630
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
631
      if(seen.insert(group.wire_code()).second) {
24,374✔
632
         m_groups.push_back(group);
24,374✔
633
      }
634
   }
635
}
3,111✔
636

637
namespace {
638

639
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
4,965✔
640
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
4,965✔
641

642
   std::vector<uint8_t> buf;
4,965✔
643

644
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,965✔
645

646
   buf.push_back(get_byte<0>(len));
4,965✔
647
   buf.push_back(get_byte<1>(len));
4,965✔
648

649
   for(const Signature_Scheme scheme : schemes) {
48,762✔
650
      buf.push_back(get_byte<0>(scheme.wire_code()));
43,797✔
651
      buf.push_back(get_byte<1>(scheme.wire_code()));
43,797✔
652
   }
653

654
   return buf;
4,965✔
655
}
×
656

657
std::vector<Signature_Scheme> parse_signature_algorithms(TLS_Data_Reader& reader, uint16_t extension_size) {
3,139✔
658
   uint16_t len = reader.get_uint16_t();
3,139✔
659

660
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
3,137✔
661
      throw Decoding_Error("Bad encoding on signature algorithms extension");
1✔
662
   }
663

664
   std::vector<Signature_Scheme> schemes;
3,136✔
665
   schemes.reserve(len / 2);
3,136✔
666
   while(len > 0) {
33,047✔
667
      schemes.emplace_back(reader.get_uint16_t());
29,911✔
668
      len -= 2;
29,911✔
669
   }
670

671
   return schemes;
3,136✔
672
}
×
673

674
}  // namespace
675

676
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
4,963✔
677
   return serialize_signature_algorithms(m_schemes);
4,963✔
678
}
679

680
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
3,137✔
681
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
3,137✔
682

683
std::vector<uint8_t> Signature_Algorithms_Cert::serialize(Connection_Side /*whoami*/) const {
2✔
684
   return serialize_signature_algorithms(m_schemes);
2✔
685
}
686

687
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
2✔
688
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2✔
689

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

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

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

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

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

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

715
   buf.push_back(0);  // srtp_mki, always empty here
5✔
716

717
   return buf;
5✔
718
}
×
719

720
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,680✔
721
   std::vector<uint8_t> buf;
4,680✔
722

723
   if(whoami == Connection_Side::Server) {
4,680✔
724
      BOTAN_ASSERT_NOMSG(m_versions.size() == 1);
465✔
725
      buf.push_back(m_versions[0].major_version());
465✔
726
      buf.push_back(m_versions[0].minor_version());
465✔
727
   } else {
728
      BOTAN_ASSERT_NOMSG(!m_versions.empty());
4,215✔
729
      const uint8_t len = static_cast<uint8_t>(m_versions.size() * 2);
4,215✔
730

731
      buf.push_back(len);
4,215✔
732

733
      for(const Protocol_Version version : m_versions) {
9,642✔
734
         buf.push_back(version.major_version());
5,427✔
735
         buf.push_back(version.minor_version());
5,427✔
736
      }
737
   }
738

739
   return buf;
4,680✔
740
}
×
741

742
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,567✔
743
   // RFC 8446 4.2.1
744
   //    The extension contains a list of supported versions in preference order,
745
   //    with the most preferred version first. Implementations [...] MUST send
746
   //    this extension in the ClientHello containing all versions of TLS which
747
   //    they are prepared to negotiate.
748
   //
749
   // We simply assume that we always want the newest available TLS version.
750
#if defined(BOTAN_HAS_TLS_13)
751
   if(!offer.is_datagram_protocol()) {
3,567✔
752
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,220✔
753
         m_versions.push_back(Protocol_Version::TLS_V13);
1,050✔
754
      }
755
   }
756
#endif
757

758
#if defined(BOTAN_HAS_TLS_12)
759
   if(offer.is_datagram_protocol()) {
3,567✔
760
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
432✔
761
         m_versions.push_back(Protocol_Version::DTLS_V12);
432✔
762
      }
763
   } else {
764
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
4,185✔
765
         m_versions.push_back(Protocol_Version::TLS_V12);
3,103✔
766
      }
767
   }
768
#endif
769

770
   // if no versions are supported, the input variables are not used
771
   BOTAN_UNUSED(offer, policy);
3,567✔
772
}
3,567✔
773

774
Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
2,099✔
775
   if(from == Connection_Side::Server) {
2,099✔
776
      if(extension_size != 2) {
598✔
777
         throw Decoding_Error("Server sent invalid supported_versions extension");
1✔
778
      }
779
      m_versions.push_back(Protocol_Version(reader.get_uint16_t()));
597✔
780
   } else {
781
      auto versions = reader.get_range<uint16_t>(1, 1, 127);
1,501✔
782

783
      for(auto v : versions) {
5,495✔
784
         m_versions.push_back(Protocol_Version(v));
3,994✔
785
      }
786

787
      if(extension_size != 1 + 2 * versions.size()) {
1,501✔
788
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
789
      }
790
   }
1,501✔
791
}
2,099✔
792

793
bool Supported_Versions::supports(Protocol_Version version) const {
1,589✔
794
   for(auto v : m_versions) {
2,100✔
795
      if(version == v) {
2,081✔
796
         return true;
1,589✔
797
      }
798
   }
799
   return false;
800
}
801

802
Record_Size_Limit::Record_Size_Limit(const uint16_t limit) : m_limit(limit) {
16✔
803
   BOTAN_ASSERT(limit >= 64, "RFC 8449 does not allow record size limits smaller than 64 bytes");
16✔
804
   BOTAN_ASSERT(limit <= MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */,
16✔
805
                "RFC 8449 does not allow record size limits larger than 2^14+1");
806
}
16✔
807

808
Record_Size_Limit::Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
45✔
809
   if(extension_size != 2) {
45✔
810
      throw TLS_Exception(Alert::DecodeError, "invalid record_size_limit extension");
×
811
   }
812

813
   m_limit = reader.get_uint16_t();
45✔
814

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

833
   // RFC 8449 4.
834
   //    Endpoints MUST NOT send a "record_size_limit" extension with a value
835
   //    smaller than 64.  An endpoint MUST treat receipt of a smaller value
836
   //    as a fatal error and generate an "illegal_parameter" alert.
837
   if(m_limit < 64) {
45✔
838
      throw TLS_Exception(Alert::IllegalParameter, "Received a record size limit smaller than 64 bytes");
×
839
   }
840
}
45✔
841

842
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side /*whoami*/) const {
53✔
843
   std::vector<uint8_t> buf;
53✔
844

845
   buf.push_back(get_byte<0>(m_limit));
53✔
846
   buf.push_back(get_byte<1>(m_limit));
53✔
847

848
   return buf;
53✔
849
}
×
850

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