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

randombit / botan / 25139258422

29 Apr 2026 08:02PM UTC coverage: 89.37% (-0.02%) from 89.385%
25139258422

push

github

web-flow
Merge pull request #5550 from randombit/jack/tls-misc

TLS conformance, hardening, and performance fixes

107055 of 119789 relevant lines covered (89.37%)

11415549.66 hits per line

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

91.07
/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,804✔
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,804✔
43
   switch(code) {
43,804✔
44
      case Extension_Code::ServerNameIndication:
3,024✔
45
         return std::make_unique<Server_Name_Indicator>(reader, size, from);
3,024✔
46

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

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

53
      case Extension_Code::SignatureAlgorithms:
3,131✔
54
         return std::make_unique<Signature_Algorithms>(reader, size);
3,131✔
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:
400✔
63
         return std::make_unique<Application_Layer_Protocol_Notification>(reader, size, from);
400✔
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,091✔
75
         return std::make_unique<Supported_Versions>(reader, size, from);
2,091✔
76

77
      case Extension_Code::Padding:
78
         break;  // RFC 7685, recognized but not implemented; falls through to Unknown_Extension
79

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

84
      case Extension_Code::SafeRenegotiation:
6,470✔
85
         return std::make_unique<Renegotiation_Extension>(reader, size);
6,470✔
86

87
      case Extension_Code::ExtendedMasterSecret:
6,274✔
88
         return std::make_unique<Extended_Master_Secret>(reader, size);
6,274✔
89

90
      case Extension_Code::EncryptThenMac:
811✔
91
         return std::make_unique<Encrypt_then_MAC>(reader, size);
811✔
92

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

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

108
      case Extension_Code::EarlyData:
5✔
109
         return std::make_unique<EarlyDataIndication>(reader, size, message_type);
5✔
110

111
      case Extension_Code::Cookie:
19✔
112
         return std::make_unique<Cookie>(reader, size);
19✔
113

114
      case Extension_Code::PskKeyExchangeModes:
1,289✔
115
         return std::make_unique<PSK_Key_Exchange_Modes>(reader, size);
1,289✔
116

117
      case Extension_Code::CertificateAuthorities:
3✔
118
         return std::make_unique<Certificate_Authorities>(reader, size);
3✔
119

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

133
   return std::make_unique<Unknown_Extension>(code, reader, size);
2,936✔
134
}
135

136
}  // namespace
137

138
Extensions::~Extensions() = default;
25,137✔
139

140
bool Extensions::has(Extension_Code type) const {
132,591✔
141
   return m_extensions.contains(type);
132,591✔
142
}
143

144
Extension* Extensions::get(Extension_Code type) const {
115,416✔
145
   const auto i = m_extensions.find(type);
115,416✔
146

147
   if(i == m_extensions.end()) {
115,416✔
148
      return nullptr;
149
   } else {
150
      return i->second.get();
75,054✔
151
   }
152
}
153

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

160
   m_extension_codes.push_back(type);
88,760✔
161
   m_extensions.emplace(type, std::move(extn));
88,760✔
162
}
88,760✔
163

164
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
9,014✔
165
   if(reader.has_remaining()) {
9,014✔
166
      const uint16_t all_extn_size = reader.get_uint16_t();
9,008✔
167

168
      if(reader.remaining_bytes() != all_extn_size) {
9,007✔
169
         throw Decoding_Error("Bad extension size");
130✔
170
      }
171

172
      while(reader.has_remaining()) {
52,630✔
173
         const uint16_t extension_code = reader.get_uint16_t();
43,832✔
174
         const uint16_t extension_size = reader.get_uint16_t();
43,832✔
175

176
         const auto type = static_cast<Extension_Code>(extension_code);
43,831✔
177

178
         if(this->has(type)) {
43,831✔
179
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
19✔
180
         }
181

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

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

197
   std::vector<Extension_Code> diff;
3,811✔
198
   std::set_difference(
3,811✔
199
      found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
200

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

209
      // ... if yes, `contains_other_than` is true
210
      return itr != diff.cend();
1,705✔
211
   }
212

213
   return !diff.empty();
2,106✔
214
}
3,811✔
215

216
bool Extensions::remove_extension(Extension_Code type) {
133✔
217
   auto i = m_extensions.find(type);
133✔
218

219
   if(i == m_extensions.end()) {
133✔
220
      return false;
221
   } else {
222
      m_extensions.erase(i);
133✔
223
      std::erase(m_extension_codes, type);
133✔
224
      m_raw_extension_data.erase(type);
133✔
225
      return true;
133✔
226
   }
227
}
228

229
std::vector<uint8_t> Extensions::serialize(Connection_Side whoami) const {
6,899✔
230
   std::vector<uint8_t> buf(2);  // 2 bytes for length field
6,899✔
231

232
   // Serialize in the order extensions were added, which matters for TLS 1.3
233
   for(const auto extn_type : m_extension_codes) {
59,626✔
234
      const auto& extn = m_extensions.at(extn_type);
52,727✔
235

236
      if(extn->empty()) {
52,727✔
237
         continue;
947✔
238
      }
239

240
      const uint16_t extn_code = static_cast<uint16_t>(extn_type);
51,780✔
241

242
      const std::vector<uint8_t> extn_val = extn->serialize(whoami);
51,780✔
243

244
      // Each extension carries a uint16 length prefix.
245
      BOTAN_ASSERT_NOMSG(extn_val.size() <= 0xFFFF);
51,780✔
246

247
      buf.push_back(get_byte<0>(extn_code));
51,780✔
248
      buf.push_back(get_byte<1>(extn_code));
51,780✔
249

250
      buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
51,780✔
251
      buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
51,780✔
252

253
      buf += extn_val;
51,780✔
254
   }
51,780✔
255

256
   // The outer extensions block is itself uint16-length-prefixed.
257
   BOTAN_ASSERT_NOMSG(buf.size() - 2 <= 0xFFFF);
6,899✔
258
   const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
6,899✔
259

260
   buf[0] = get_byte<0>(extn_size);
6,899✔
261
   buf[1] = get_byte<1>(extn_size);
6,899✔
262

263
   // avoid sending a completely empty extensions block
264
   if(buf.size() == 2) {
6,899✔
265
      return std::vector<uint8_t>();
310✔
266
   }
267

268
   return buf;
6,589✔
269
}
6,899✔
270

271
std::set<Extension_Code> Extensions::extension_types() const {
12,116✔
272
   std::set<Extension_Code> offers;
12,116✔
273
   for(const auto& [extn_type, extn] : m_extensions) {
78,748✔
274
      // Consistent with serialize(): empty extensions are not placed on
275
      // the wire so they must not appear in the "offered" set either.
276
      if(!extn->empty()) {
66,632✔
277
         offers.insert(extn_type);
65,957✔
278
      }
279
   }
280
   return offers;
12,116✔
281
}
×
282

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

286
   std::vector<Extension_Code> new_codes;
50✔
287
   new_codes.reserve(m_extension_codes.size());
50✔
288

289
   // First: extensions not mentioned in the order (preserving their relative order)
290
   for(auto code : m_extension_codes) {
426✔
291
      if(!in_order.contains(code)) {
752✔
292
         new_codes.push_back(code);
242✔
293
      }
294
   }
295

296
   // Then: extensions in the specified order. Deduplicate so a caller that
297
   // accidentally lists the same code twice doesn't cause it to be
298
   // serialized twice (which would also break peers that reject duplicate
299
   // extension codes per RFC 8446 4.2 / RFC 5246 7.4.1.4).
300
   std::unordered_set<Extension_Code> already_pushed;
50✔
301
   for(auto code : order) {
323✔
302
      if(m_extensions.contains(code) && already_pushed.insert(code).second) {
680✔
303
         new_codes.push_back(code);
134✔
304
      }
305
   }
306

307
   m_extension_codes = std::move(new_codes);
50✔
308
}
50✔
309

310
Unknown_Extension::Unknown_Extension(Extension_Code type, TLS_Data_Reader& reader, uint16_t extension_size) :
2,936✔
311
      m_type(type), m_value(reader.get_fixed<uint8_t>(extension_size)) {}
2,936✔
312

313
std::vector<uint8_t> Unknown_Extension::serialize(Connection_Side /*whoami*/) const {
2✔
314
   return m_value;
2✔
315
}
316

317
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
3,024✔
318
   /*
319
   RFC 6066 Section 3
320

321
      A server that receives a client hello containing the "server_name"
322
      extension MAY use the information contained in the extension to guide
323
      its selection of an appropriate certificate to return to the client,
324
      and/or other aspects of security policy.  In this event, the server
325
      SHALL include an extension of type "server_name" in the (extended)
326
      server hello.  The "extension_data" field of this extension SHALL be
327
      empty.
328
   */
329
   if(from == Connection_Side::Server) {
3,024✔
330
      if(extension_size != 0) {
36✔
331
         throw TLS_Exception(Alert::IllegalParameter, "Server sent non-empty SNI extension");
×
332
      }
333
   } else {
334
      // Clients are required to send at least one name in the SNI
335
      if(extension_size == 0) {
2,988✔
336
         throw TLS_Exception(Alert::IllegalParameter, "Client sent empty SNI extension");
×
337
      }
338

339
      const uint16_t name_bytes = reader.get_uint16_t();
2,988✔
340

341
      // RFC 6066 3: a ServerName carrying a host_name (the only NameType
342
      // currently defined and the only one this implementation acts on)
343
      // requires at least 1 byte name_type + 2 byte length + 1 byte HostName.
344
      if(name_bytes + 2 != extension_size || name_bytes < 4) {
2,988✔
345
         throw Decoding_Error("Bad encoding of SNI extension");
×
346
      }
347

348
      BOTAN_ASSERT_NOMSG(reader.remaining_bytes() == name_bytes);
2,988✔
349

350
      while(reader.has_remaining()) {
5,976✔
351
         const uint8_t name_type = reader.get_byte();
2,988✔
352

353
         if(name_type == 0) {
2,988✔
354
            /*
355
            RFC 6066 Section 3
356
               The ServerNameList MUST NOT contain more than one name of the same name_type.
357
            */
358
            if(!m_sni_host_name.empty()) {
2,988✔
359
               throw Decoding_Error("TLS ServerNameIndicator contains more than one host_name");
×
360
            }
361
            m_sni_host_name = reader.get_string(2, 1, 65535);
2,988✔
362
         } else {
363
            /*
364
            Unknown name type - skip its length-prefixed value and continue
365

366
            RFC 6066 Section 3
367
               For backward compatibility, all future data structures associated
368
               with new NameTypes MUST begin with a 16-bit length field.
369
            */
370
            const uint16_t unknown_name_len = reader.get_uint16_t();
×
371
            reader.discard_next(unknown_name_len);
×
372
         }
373
      }
374
   }
375
}
3,024✔
376

377
std::vector<uint8_t> Server_Name_Indicator::serialize(Connection_Side whoami) const {
4,799✔
378
   // RFC 6066
379
   //    [...] the server SHALL include an extension of type "server_name" in
380
   //    the (extended) server hello. The "extension_data" field of this
381
   //    extension SHALL be empty.
382
   if(whoami == Connection_Side::Server) {
4,799✔
383
      return {};
300✔
384
   }
385

386
   std::vector<uint8_t> buf;
4,499✔
387

388
   const size_t name_len = m_sni_host_name.size();
4,499✔
389

390
   // RFC 6066 3: HostName<1..2^16-1>; the outer ServerNameList wraps a
391
   // 1-byte name_type and a 2-byte length so the whole entry must fit in
392
   // a uint16_t too.
393
   BOTAN_ASSERT_NOMSG(name_len + 3 <= 0xFFFF);
4,499✔
394

395
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,499✔
396
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,499✔
397
   buf.push_back(0);  // DNS
4,499✔
398

399
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,499✔
400
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,499✔
401

402
   buf += as_span_of_bytes(m_sni_host_name);
4,499✔
403

404
   return buf;
4,499✔
405
}
4,499✔
406

407
bool Server_Name_Indicator::hostname_acceptable_for_sni(std::string_view hostname) {
3,802✔
408
   // Avoid sending an IPv4/IPv6 address in SNI as this is prohibited
409

410
   if(hostname.empty()) {
3,802✔
411
      return false;
412
   }
413

414
   if(string_to_ipv4(hostname).has_value()) {
3,755✔
415
      return false;
416
   }
417

418
   // IPv6? Anyway ':' is not valid in DNS
419
   if(hostname.find(':') != std::string_view::npos) {
3,755✔
420
      return false;
421
   }
422

423
   return true;
424
}
425

426
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(std::string_view protocol) {
144✔
427
   BOTAN_ARG_CHECK(!protocol.empty(), "ALPN protocol name must not be empty");
144✔
428
   BOTAN_ARG_CHECK(protocol.size() < 256, "ALPN protocol name too long");
144✔
429
   m_protocols.emplace_back(protocol);
144✔
430
}
144✔
431

432
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(
146✔
433
   const std::vector<std::string>& protocols) :
146✔
434
      m_protocols(protocols) {
146✔
435
   for(const auto& protocol : protocols) {
442✔
436
      BOTAN_ARG_CHECK(!protocol.empty(), "ALPN protocol name must not be empty");
296✔
437
      BOTAN_ARG_CHECK(protocol.size() < 256, "ALPN protocol name too long");
296✔
438
   }
439
}
146✔
440

441
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
406✔
442
                                                                                 uint16_t extension_size,
443
                                                                                 Connection_Side from) {
406✔
444
   if(extension_size < 2) {
406✔
445
      throw Decoding_Error("ALPN extension cannot be empty");
1✔
446
   }
447

448
   const uint16_t name_bytes = reader.get_uint16_t();
405✔
449

450
   size_t bytes_remaining = extension_size - 2;
405✔
451

452
   if(name_bytes != bytes_remaining) {
405✔
453
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
3✔
454
   }
455

456
   // RFC 7301 3.1: ProtocolName protocol_name_list<2..2^16-1>
457
   if(name_bytes == 0) {
402✔
458
      throw Decoding_Error("Empty ALPN protocol_name_list not allowed");
1✔
459
   }
460

461
   while(bytes_remaining > 0) {
1,067✔
462
      const std::string p = reader.get_string(1, 0, 255);
674✔
463

464
      if(bytes_remaining < p.size() + 1) {
674✔
465
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
466
      }
467

468
      if(p.empty()) {
674✔
469
         throw Decoding_Error("Empty ALPN protocol not allowed");
8✔
470
      }
471

472
      bytes_remaining -= (p.size() + 1);
666✔
473

474
      m_protocols.push_back(p);
666✔
475
   }
674✔
476

477
   // RFC 7301 3.1
478
   //    The "extension_data" field of the [...] extension is structured the
479
   //    same as described above for the client "extension_data", except that
480
   //    the "ProtocolNameList" MUST contain exactly one "ProtocolName".
481
   if(from == Connection_Side::Server && m_protocols.size() != 1) {
393✔
482
      throw TLS_Exception(
×
483
         Alert::DecodeError,
484
         "Server sent " + std::to_string(m_protocols.size()) + " protocols in ALPN extension response");
×
485
   }
486
}
406✔
487

488
std::string Application_Layer_Protocol_Notification::single_protocol() const {
285✔
489
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
285✔
490
   return m_protocols.front();
285✔
491
}
492

493
std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const {
357✔
494
   std::vector<uint8_t> buf(2);
357✔
495

496
   for(auto&& proto : m_protocols) {
933✔
497
      if(proto.length() >= 256) {
576✔
498
         throw TLS_Exception(Alert::InternalError, "ALPN name too long");
×
499
      }
500
      if(!proto.empty()) {
576✔
501
         append_tls_length_value(buf, proto, 1);
1,152✔
502
      }
503
   }
504

505
   // RFC 7301 3.1: ProtocolName protocol_name_list<2..2^16-1>;
506
   BOTAN_ASSERT_NOMSG(buf.size() - 2 <= 0xFFFF);
357✔
507
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
357✔
508
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
357✔
509

510
   return buf;
357✔
511
}
×
512

513
Certificate_Type_Base::Certificate_Type_Base(std::vector<Certificate_Type> supported_cert_types) :
64✔
514
      m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
64✔
515
   BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
64✔
516
}
64✔
517

518
Client_Certificate_Type::Client_Certificate_Type(const Client_Certificate_Type& cct, const Policy& policy) :
9✔
519
      Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
9✔
520

521
Server_Certificate_Type::Server_Certificate_Type(const Server_Certificate_Type& sct, const Policy& policy) :
1✔
522
      Certificate_Type_Base(sct, policy.accepted_server_certificate_types()) {}
1✔
523

524
Certificate_Type_Base::Certificate_Type_Base(const Certificate_Type_Base& certificate_type_from_client,
10✔
525
                                             const std::vector<Certificate_Type>& server_preference) :
10✔
526
      m_from(Connection_Side::Server) {
10✔
527
   // RFC 7250 4.2
528
   //    The server_certificate_type extension in the client hello indicates the
529
   //    types of certificates the client is able to process when provided by
530
   //    the server in a subsequent certificate payload. [...] With the
531
   //    server_certificate_type extension in the server hello, the TLS server
532
   //    indicates the certificate type carried in the Certificate payload.
533
   for(const auto server_supported_cert_type : server_preference) {
11✔
534
      if(value_exists(certificate_type_from_client.m_certificate_types, server_supported_cert_type)) {
22✔
535
         m_certificate_types.push_back(server_supported_cert_type);
10✔
536
         return;
10✔
537
      }
538
   }
539

540
   // RFC 7250 4.2 (2.)
541
   //    The server supports the extension defined in this document, but
542
   //    it does not have any certificate type in common with the client.
543
   //    Then, the server terminates the session with a fatal alert of
544
   //    type "unsupported_certificate".
545
   throw TLS_Exception(Alert::UnsupportedCertificate, "Failed to agree on certificate_type");
×
546
}
×
547

548
Certificate_Type_Base::Certificate_Type_Base(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) :
12✔
549
      m_from(from) {
12✔
550
   if(extension_size == 0) {
12✔
551
      throw Decoding_Error("Certificate type extension cannot be empty");
×
552
   }
553

554
   if(from == Connection_Side::Client) {
12✔
555
      const auto type_bytes = reader.get_tls_length_value(1);
10✔
556
      if(static_cast<size_t>(extension_size) != type_bytes.size() + 1) {
10✔
557
         throw Decoding_Error("certificate type extension had inconsistent length");
×
558
      }
559
      // RFC 7250 4: {client,server}_certificate_types<1..2^8-1> so must be non-empty
560
      if(type_bytes.empty()) {
10✔
561
         throw Decoding_Error("Certificate type extension contains no types");
×
562
      }
563
      std::transform(
10✔
564
         type_bytes.begin(), type_bytes.end(), std::back_inserter(m_certificate_types), [](const auto type_byte) {
10✔
565
            return static_cast<Certificate_Type>(type_byte);
566
         });
567
   } else {
10✔
568
      // RFC 7250 4.2
569
      //    Note that only a single value is permitted in the
570
      //    server_certificate_type extension when carried in the server hello.
571
      if(extension_size != 1) {
2✔
572
         throw Decoding_Error("Server's certificate type extension must be of length 1");
×
573
      }
574
      const auto type_byte = reader.get_byte();
2✔
575
      m_certificate_types.push_back(static_cast<Certificate_Type>(type_byte));
2✔
576
   }
577
}
12✔
578

579
std::vector<uint8_t> Certificate_Type_Base::serialize(Connection_Side whoami) const {
23✔
580
   std::vector<uint8_t> result;
23✔
581
   if(whoami == Connection_Side::Client) {
23✔
582
      std::vector<uint8_t> type_bytes;
9✔
583
      std::transform(
9✔
584
         m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
585
            return static_cast<uint8_t>(type);
586
         });
587
      append_tls_length_value(result, type_bytes, 1);
18✔
588
   } else {
9✔
589
      BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
14✔
590
      result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
14✔
591
   }
592
   return result;
23✔
593
}
×
594

595
void Certificate_Type_Base::validate_selection(const Certificate_Type_Base& from_server) const {
2✔
596
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Client);
2✔
597
   BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
2✔
598

599
   // RFC 7250 4.2
600
   //    The value conveyed in the [client_]certificate_type extension MUST be
601
   //    selected from one of the values provided in the [client_]certificate_type
602
   //    extension sent in the client hello.
603
   if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
4✔
604
      throw TLS_Exception(Alert::IllegalParameter,
×
605
                          Botan::fmt("Selected certificate type was not offered: {}",
×
606
                                     certificate_type_to_string(from_server.selected_certificate_type())));
×
607
   }
608
}
2✔
609

610
Certificate_Type Certificate_Type_Base::selected_certificate_type() const {
14✔
611
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Server);
14✔
612
   BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
14✔
613
   return m_certificate_types.front();
14✔
614
}
615

616
Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) {}
4,192✔
617

618
const std::vector<Group_Params>& Supported_Groups::groups() const {
1,031✔
619
   return m_groups;
1,031✔
620
}
621

622
std::vector<Group_Params> Supported_Groups::ec_groups() const {
5,931✔
623
   std::vector<Group_Params> ec;
5,931✔
624
   for(auto g : m_groups) {
63,378✔
625
      if(g.is_pure_ecc_group()) {
114,894✔
626
         ec.push_back(g);
41,176✔
627
      }
628
   }
629
   return ec;
5,931✔
630
}
×
631

632
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,579✔
633
   std::vector<Group_Params> dh;
1,579✔
634
   for(auto g : m_groups) {
12,849✔
635
      if(g.is_in_ffdhe_range()) {
15,463✔
636
         dh.push_back(g);
555✔
637
      }
638
   }
639
   return dh;
1,579✔
640
}
×
641

642
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,960✔
643
   std::vector<uint8_t> buf(2);
4,960✔
644

645
   for(auto g : m_groups) {
57,756✔
646
      const uint16_t id = g.wire_code();
52,796✔
647

648
      if(id > 0) {
52,796✔
649
         buf.push_back(get_byte<0>(id));
52,796✔
650
         buf.push_back(get_byte<1>(id));
52,796✔
651
      }
652
   }
653

654
   // RFC 8446 4.2.7: NamedGroup named_group_list<2..2^16-1>;
655
   BOTAN_ASSERT_NOMSG(buf.size() - 2 <= 0xFFFF);
4,960✔
656
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,960✔
657
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,960✔
658

659
   return buf;
4,960✔
660
}
×
661

662
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
3,109✔
663
   const uint16_t len = reader.get_uint16_t();
3,109✔
664

665
   if(len + 2 != extension_size) {
3,109✔
666
      throw Decoding_Error("Inconsistent length field in supported groups list");
6✔
667
   }
668

669
   // RFC 8446 4.2.7: NamedGroup named_group_list<2..2^16-1>;
670
   if(len == 0) {
3,103✔
671
      throw Decoding_Error("Empty supported groups list");
1✔
672
   }
673

674
   if(len % 2 == 1) {
3,102✔
675
      throw Decoding_Error("Supported groups list of strange size");
1✔
676
   }
677

678
   const size_t elems = len / 2;
3,101✔
679

680
   std::unordered_set<uint16_t> seen;
3,101✔
681
   for(size_t i = 0; i != elems; ++i) {
27,469✔
682
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
24,368✔
683
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
684
      if(seen.insert(group.wire_code()).second) {
24,368✔
685
         m_groups.push_back(group);
24,368✔
686
      }
687
   }
688
}
3,109✔
689

690
namespace {
691

692
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
4,963✔
693
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
4,963✔
694

695
   std::vector<uint8_t> buf;
4,963✔
696

697
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,963✔
698

699
   buf.push_back(get_byte<0>(len));
4,963✔
700
   buf.push_back(get_byte<1>(len));
4,963✔
701

702
   for(const Signature_Scheme scheme : schemes) {
48,736✔
703
      buf.push_back(get_byte<0>(scheme.wire_code()));
43,773✔
704
      buf.push_back(get_byte<1>(scheme.wire_code()));
43,773✔
705
   }
706

707
   return buf;
4,963✔
708
}
×
709

710
std::vector<Signature_Scheme> parse_signature_algorithms(TLS_Data_Reader& reader, uint16_t extension_size) {
3,136✔
711
   uint16_t len = reader.get_uint16_t();
3,136✔
712

713
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
3,134✔
714
      throw Decoding_Error("Bad encoding on signature algorithms extension");
4✔
715
   }
716

717
   std::vector<Signature_Scheme> schemes;
3,130✔
718
   schemes.reserve(len / 2);
3,130✔
719
   while(len > 0) {
32,981✔
720
      schemes.emplace_back(reader.get_uint16_t());
29,851✔
721
      len -= 2;
29,851✔
722
   }
723

724
   return schemes;
3,130✔
725
}
×
726

727
}  // namespace
728

729
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
4,961✔
730
   return serialize_signature_algorithms(m_schemes);
4,961✔
731
}
732

733
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
3,131✔
734
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
3,131✔
735

736
std::vector<uint8_t> Signature_Algorithms_Cert::serialize(Connection_Side /*whoami*/) const {
2✔
737
   return serialize_signature_algorithms(m_schemes);
2✔
738
}
739

740
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
5✔
741
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
5✔
742

743
SRTP_Protection_Profiles::SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size) {
10✔
744
   // RFC 5764 4.1.1: UseSRTPData consists of
745
   //    SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
746
   //    opaque srtp_mki<0..255>;
747
   // for a wire size of 2 (profiles len) + 2*N + 1 (mki len) + mki_bytes,
748
   // with N >= 1.
749
   if(extension_size < 5) {
10✔
750
      throw Decoding_Error("Truncated SRTP protection extension");
1✔
751
   }
752
   const size_t max_profile_pairs = (static_cast<size_t>(extension_size) - 3) / 2;
9✔
753
   m_pp = reader.get_range<uint16_t>(2, 1, max_profile_pairs);
9✔
754
   const std::vector<uint8_t> mki = reader.get_range<uint8_t>(1, 0, 255);
9✔
755

756
   if(m_pp.size() * 2 + mki.size() + 3 != extension_size) {
9✔
757
      throw Decoding_Error("Bad encoding for SRTP protection extension");
×
758
   }
759

760
   if(!mki.empty()) {
9✔
761
      throw Decoding_Error("Unhandled non-empty MKI for SRTP protection extension");
×
762
   }
763
}
10✔
764

765
std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const {
5✔
766
   std::vector<uint8_t> buf;
5✔
767

768
   const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2);
5✔
769
   buf.push_back(get_byte<0>(pp_len));
5✔
770
   buf.push_back(get_byte<1>(pp_len));
5✔
771

772
   for(const uint16_t pp : m_pp) {
12✔
773
      buf.push_back(get_byte<0>(pp));
7✔
774
      buf.push_back(get_byte<1>(pp));
7✔
775
   }
776

777
   buf.push_back(0);  // srtp_mki, always empty here
5✔
778

779
   return buf;
5✔
780
}
×
781

782
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,675✔
783
   std::vector<uint8_t> buf;
4,675✔
784

785
   if(whoami == Connection_Side::Server) {
4,675✔
786
      BOTAN_ASSERT_NOMSG(m_versions.size() == 1);
465✔
787
      buf.push_back(m_versions[0].major_version());
465✔
788
      buf.push_back(m_versions[0].minor_version());
465✔
789
   } else {
790
      // RFC 8446 4.2.1: ProtocolVersion versions<2..254>; - up to 127 entries.
791
      BOTAN_ASSERT_NOMSG(!m_versions.empty());
4,210✔
792
      BOTAN_ASSERT_NOMSG(m_versions.size() <= 127);
4,210✔
793
      const uint8_t len = static_cast<uint8_t>(m_versions.size() * 2);
4,210✔
794

795
      buf.push_back(len);
4,210✔
796

797
      for(const Protocol_Version version : m_versions) {
9,632✔
798
         buf.push_back(version.major_version());
5,422✔
799
         buf.push_back(version.minor_version());
5,422✔
800
      }
801
   }
802

803
   return buf;
4,675✔
804
}
×
805

806
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,565✔
807
   // RFC 8446 4.2.1
808
   //    The extension contains a list of supported versions in preference order,
809
   //    with the most preferred version first. Implementations [...] MUST send
810
   //    this extension in the ClientHello containing all versions of TLS which
811
   //    they are prepared to negotiate.
812
   //
813
   // We simply assume that we always want the newest available TLS version.
814
#if defined(BOTAN_HAS_TLS_13)
815
   if(!offer.is_datagram_protocol()) {
3,565✔
816
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,222✔
817
         m_versions.push_back(Protocol_Version::TLS_V13);
1,050✔
818
      }
819
   }
820
#endif
821

822
#if defined(BOTAN_HAS_TLS_12)
823
   if(offer.is_datagram_protocol()) {
3,565✔
824
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
429✔
825
         m_versions.push_back(Protocol_Version::DTLS_V12);
429✔
826
      }
827
   } else {
828
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
4,186✔
829
         m_versions.push_back(Protocol_Version::TLS_V12);
3,104✔
830
      }
831
   }
832
#endif
833

834
   // if no versions are supported, the input variables are not used
835
   BOTAN_UNUSED(offer, policy);
3,565✔
836
}
3,565✔
837

838
Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
2,093✔
839
   if(from == Connection_Side::Server) {
2,093✔
840
      if(extension_size != 2) {
598✔
841
         throw Decoding_Error("Server sent invalid supported_versions extension");
1✔
842
      }
843
      m_versions.push_back(Protocol_Version(reader.get_uint16_t()));
597✔
844
   } else {
845
      auto versions = reader.get_range<uint16_t>(1, 1, 127);
1,495✔
846

847
      for(auto v : versions) {
5,483✔
848
         m_versions.push_back(Protocol_Version(v));
3,988✔
849
      }
850

851
      if(extension_size != 1 + 2 * versions.size()) {
1,495✔
852
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
853
      }
854
   }
1,495✔
855
}
2,093✔
856

857
bool Supported_Versions::supports(Protocol_Version version) const {
1,589✔
858
   for(auto v : m_versions) {
2,100✔
859
      if(version == v) {
2,081✔
860
         return true;
1,589✔
861
      }
862
   }
863
   return false;
864
}
865

866
Record_Size_Limit::Record_Size_Limit(const uint16_t limit) : m_limit(limit) {
16✔
867
   BOTAN_ASSERT(limit >= 64, "RFC 8449 does not allow record size limits smaller than 64 bytes");
16✔
868
   BOTAN_ASSERT(limit <= MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */,
16✔
869
                "RFC 8449 does not allow record size limits larger than 2^14+1");
870
}
16✔
871

872
Record_Size_Limit::Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
45✔
873
   if(extension_size != 2) {
45✔
874
      throw TLS_Exception(Alert::DecodeError, "invalid record_size_limit extension");
×
875
   }
876

877
   m_limit = reader.get_uint16_t();
45✔
878

879
   // RFC 8449 4.
880
   //    This value is the length of the plaintext of a protected record.
881
   //    The value includes the content type and padding added in TLS 1.3 (that
882
   //    is, the complete length of TLSInnerPlaintext).
883
   //
884
   //    A server MUST NOT enforce this restriction; a client might advertise
885
   //    a higher limit that is enabled by an extension or version the server
886
   //    does not understand. A client MAY abort the handshake with an
887
   //    "illegal_parameter" alert.
888
   //
889
   // Note: We are currently supporting this extension in TLS 1.3 only, hence
890
   //       we check for the TLS 1.3 limit. The TLS 1.2 limit would not include
891
   //       the "content type byte" and hence be one byte less!
892
   if(m_limit > MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */ && from == Connection_Side::Server) {
45✔
893
      throw TLS_Exception(Alert::IllegalParameter,
×
894
                          "Server requested a record size limit larger than the protocol's maximum");
×
895
   }
896

897
   // RFC 8449 4.
898
   //    Endpoints MUST NOT send a "record_size_limit" extension with a value
899
   //    smaller than 64.  An endpoint MUST treat receipt of a smaller value
900
   //    as a fatal error and generate an "illegal_parameter" alert.
901
   if(m_limit < 64) {
45✔
902
      throw TLS_Exception(Alert::IllegalParameter, "Received a record size limit smaller than 64 bytes");
×
903
   }
904
}
45✔
905

906
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side /*whoami*/) const {
53✔
907
   std::vector<uint8_t> buf;
53✔
908

909
   buf.push_back(get_byte<0>(m_limit));
53✔
910
   buf.push_back(get_byte<1>(m_limit));
53✔
911

912
   return buf;
53✔
913
}
×
914

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