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

randombit / botan / 28278764342

26 Jun 2026 01:00PM UTC coverage: 89.352% (-0.002%) from 89.354%
28278764342

push

github

web-flow
Merge pull request #5700 from Rohde-Schwarz/chore/span_in_tls_msgs_and_exts

[std::span] For TLS message and extension parsing and usage

112053 of 125406 relevant lines covered (89.35%)

11047919.25 hits per line

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

92.26
/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/dns_name.h>
16
#include <botan/ipv4_address.h>
17
#include <botan/ipv6_address.h>
18
#include <botan/tls_exceptn.h>
19
#include <botan/tls_policy.h>
20
#include <botan/internal/fmt.h>
21
#include <botan/internal/parsing.h>
22
#include <botan/internal/stl_util.h>
23
#include <botan/internal/tls_reader.h>
24
#include <algorithm>
25
#include <unordered_set>
26

27
#if defined(BOTAN_HAS_TLS_13)
28
   #include <botan/tls_extensions_13.h>
29
#endif
30

31
#if defined(BOTAN_HAS_TLS_12)
32
   #include <botan/tls_extensions_12.h>
33
#endif
34

35
namespace Botan::TLS {
36

37
namespace {
38

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

50
      case Extension_Code::SupportedGroups:
3,226✔
51
         return std::make_unique<Supported_Groups>(reader, size);
3,226✔
52

53
      case Extension_Code::CertificateStatusRequest:
3,008✔
54
         return std::make_unique<Certificate_Status_Request>(reader, size, message_type, from);
3,008✔
55

56
      case Extension_Code::SignatureAlgorithms:
3,265✔
57
         return std::make_unique<Signature_Algorithms>(reader, size);
3,265✔
58

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

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

65
      case Extension_Code::ApplicationLayerProtocolNegotiation:
400✔
66
         return std::make_unique<Application_Layer_Protocol_Notification>(reader, size, from);
400✔
67

68
      case Extension_Code::ClientCertificateType:
60✔
69
         return std::make_unique<Client_Certificate_Type>(reader, size, from);
60✔
70

71
      case Extension_Code::ServerCertificateType:
92✔
72
         return std::make_unique<Server_Certificate_Type>(reader, size, from);
92✔
73

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

77
      case Extension_Code::SupportedVersions:
2,257✔
78
         return std::make_unique<Supported_Versions>(reader, size, from);
2,257✔
79

80
      case Extension_Code::Padding:
81
         break;  // RFC 7685, recognized but not implemented; falls through to Unknown_Extension
82

83
#if defined(BOTAN_HAS_TLS_12)
84
      case Extension_Code::EcPointFormats:
3,525✔
85
         return std::make_unique<Supported_Point_Formats>(reader, size);
3,525✔
86

87
      case Extension_Code::SafeRenegotiation:
6,598✔
88
         return std::make_unique<Renegotiation_Extension>(reader, size);
6,598✔
89

90
      case Extension_Code::ExtendedMasterSecret:
6,402✔
91
         return std::make_unique<Extended_Master_Secret>(reader, size);
6,402✔
92

93
      case Extension_Code::EncryptThenMac:
812✔
94
         return std::make_unique<Encrypt_then_MAC>(reader, size);
812✔
95

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

107
#if defined(BOTAN_HAS_TLS_13)
108
      case Extension_Code::PresharedKey:
379✔
109
         return std::make_unique<PSK>(reader, size, message_type);
379✔
110

111
      case Extension_Code::EarlyData:
5✔
112
         return std::make_unique<EarlyDataIndication>(reader, size, message_type);
5✔
113

114
      case Extension_Code::Cookie:
19✔
115
         return std::make_unique<Cookie>(reader, size);
19✔
116

117
      case Extension_Code::PskKeyExchangeModes:
1,410✔
118
         return std::make_unique<PSK_Key_Exchange_Modes>(reader, size);
1,410✔
119

120
      case Extension_Code::CertificateAuthorities:
7✔
121
         return std::make_unique<Certificate_Authorities>(reader, size);
7✔
122

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

136
   return std::make_unique<Unknown_Extension>(code, reader, size);
3,060✔
137
}
138

139
}  // namespace
140

141
Extensions::~Extensions() = default;
24,923✔
142

143
bool Extensions::has(Extension_Code type) const {
137,253✔
144
   return m_extensions.contains(type);
137,253✔
145
}
146

147
Extension* Extensions::get(Extension_Code type) const {
127,981✔
148
   const auto i = m_extensions.find(type);
127,981✔
149

150
   if(i == m_extensions.end()) {
127,981✔
151
      return nullptr;
152
   } else {
153
      return i->second.get();
86,124✔
154
   }
155
}
156

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

163
   m_extension_codes.push_back(type);
91,606✔
164
   m_extensions.emplace(type, std::move(extn));
91,606✔
165
}
91,606✔
166

167
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
9,350✔
168
   if(reader.has_remaining()) {
9,350✔
169
      const uint16_t all_extn_size = reader.get_uint16_t();
9,344✔
170

171
      if(reader.remaining_bytes() != all_extn_size) {
9,343✔
172
         throw Decoding_Error("Bad extension size");
131✔
173
      }
174

175
      while(reader.has_remaining()) {
54,766✔
176
         const uint16_t extension_code = reader.get_uint16_t();
45,648✔
177
         const uint16_t extension_size = reader.get_uint16_t();
45,648✔
178

179
         const auto type = static_cast<Extension_Code>(extension_code);
45,647✔
180

181
         if(this->has(type)) {
45,647✔
182
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
19✔
183
         }
184

185
         // TODO offer a function on reader that returns a byte range as a reference
186
         // to avoid this copy of the extension data
187
         const std::vector<uint8_t> extn_data = reader.get_fixed<uint8_t>(extension_size);
45,628✔
188
         m_raw_extension_data[type] = extn_data;
45,620✔
189
         TLS_Data_Reader extn_reader("Extension", extn_data);
45,620✔
190
         this->add(make_extension(extn_reader, type, from, message_type));
45,620✔
191
         extn_reader.assert_done();
45,554✔
192
      }
45,554✔
193
   }
194
}
9,124✔
195

196
bool Extensions::contains_other_than(const std::set<Extension_Code>& allowed_extensions,
4,135✔
197
                                     const bool allow_unknown_extensions) const {
198
   const auto found = extension_types();
4,135✔
199

200
   std::vector<Extension_Code> diff;
4,135✔
201
   std::set_difference(
4,135✔
202
      found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
203

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

212
      // ... if yes, `contains_other_than` is true
213
      return itr != diff.cend();
1,858✔
214
   }
215

216
   return !diff.empty();
2,277✔
217
}
4,135✔
218

219
bool Extensions::remove_extension(Extension_Code type) {
133✔
220
   auto i = m_extensions.find(type);
133✔
221

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

232
std::vector<uint8_t> Extensions::serialize(Connection_Side whoami) const {
7,282✔
233
   std::vector<uint8_t> buf(2);  // 2 bytes for length field
7,282✔
234

235
   // Serialize in the order extensions were added, which matters for TLS 1.3
236
   for(const auto extn_type : m_extension_codes) {
61,247✔
237
      const auto& extn = m_extensions.at(extn_type);
53,965✔
238

239
      if(extn->empty()) {
53,965✔
240
         continue;
1,005✔
241
      }
242

243
      const uint16_t extn_code = static_cast<uint16_t>(extn_type);
52,960✔
244

245
      const std::vector<uint8_t> extn_val = extn->serialize(whoami);
52,960✔
246

247
      // Each extension carries a uint16 length prefix.
248
      BOTAN_ASSERT_NOMSG(extn_val.size() <= 0xFFFF);
52,960✔
249

250
      buf.push_back(get_byte<0>(extn_code));
52,960✔
251
      buf.push_back(get_byte<1>(extn_code));
52,960✔
252

253
      buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
52,960✔
254
      buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
52,960✔
255

256
      buf += extn_val;
52,960✔
257
   }
52,960✔
258

259
   // The outer extensions block is itself uint16-length-prefixed.
260
   BOTAN_ASSERT_NOMSG(buf.size() - 2 <= 0xFFFF);
7,282✔
261
   const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
7,282✔
262

263
   buf[0] = get_byte<0>(extn_size);
7,282✔
264
   buf[1] = get_byte<1>(extn_size);
7,282✔
265

266
   // avoid sending a completely empty extensions block
267
   if(buf.size() == 2) {
7,282✔
268
      return std::vector<uint8_t>();
375✔
269
   }
270

271
   return buf;
6,907✔
272
}
7,282✔
273

274
std::set<Extension_Code> Extensions::extension_types() const {
12,567✔
275
   std::set<Extension_Code> offers;
12,567✔
276
   for(const auto& [extn_type, extn] : m_extensions) {
80,487✔
277
      // Consistent with serialize(): empty extensions are not placed on
278
      // the wire so they must not appear in the "offered" set either.
279
      if(!extn->empty()) {
67,920✔
280
         offers.insert(extn_type);
67,136✔
281
      }
282
   }
283
   return offers;
12,567✔
284
}
×
285

286
void Extensions::reorder(std::span<const Extension_Code> order) {
50✔
287
   const std::set<Extension_Code> in_order(order.begin(), order.end());
50✔
288

289
   std::vector<Extension_Code> new_codes;
50✔
290
   new_codes.reserve(m_extension_codes.size());
50✔
291

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

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

310
   m_extension_codes = std::move(new_codes);
50✔
311
}
50✔
312

313
Unknown_Extension::Unknown_Extension(Extension_Code type, TLS_Data_Reader& reader, uint16_t extension_size) :
3,060✔
314
      m_type(type), m_value(reader.get_fixed<uint8_t>(extension_size)) {}
3,060✔
315

316
std::vector<uint8_t> Unknown_Extension::serialize(Connection_Side /*whoami*/) const {
2✔
317
   return m_value;
2✔
318
}
319

320
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
3,153✔
321
   /*
322
   RFC 6066 Section 3
323

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

342
      const uint16_t name_bytes = reader.get_uint16_t();
3,114✔
343

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

351
      BOTAN_ASSERT_NOMSG(reader.remaining_bytes() == name_bytes);
3,111✔
352

353
      while(reader.has_remaining()) {
6,222✔
354
         const uint8_t name_type = reader.get_byte();
3,111✔
355

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

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

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

389
   std::vector<uint8_t> buf;
4,571✔
390

391
   const size_t name_len = m_sni_host_name.size();
4,571✔
392

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

398
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,571✔
399
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,571✔
400
   buf.push_back(0);  // DNS
4,571✔
401

402
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,571✔
403
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,571✔
404

405
   buf += as_span_of_bytes(m_sni_host_name);
4,571✔
406

407
   return buf;
4,571✔
408
}
4,571✔
409

410
bool Server_Name_Indicator::hostname_acceptable_for_sni(std::string_view hostname) {
3,853✔
411
   // Avoid sending an IPv4/IPv6 address in SNI as this is prohibited
412

413
   if(hostname.empty() || hostname.size() > 255) {
3,853✔
414
      return false;
415
   }
416

417
   if(auto ipv4 = IPv4Address::from_string(hostname)) {
3,806✔
418
      return false;
×
419
   }
420

421
   if(auto ipv6 = IPv6Address::from_string(hostname)) {
3,806✔
422
      return false;
×
423
   }
424

425
   if(auto dns = DNSName::from_string(hostname)) {
3,806✔
426
      return true;
427
   } else {
428
      return false;
×
429
   }
3,806✔
430
}
431

432
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(std::string_view protocol) {
144✔
433
   BOTAN_ARG_CHECK(!protocol.empty(), "ALPN protocol name must not be empty");
144✔
434
   BOTAN_ARG_CHECK(protocol.size() < 256, "ALPN protocol name too long");
144✔
435
   m_protocols.emplace_back(protocol);
144✔
436
}
144✔
437

438
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(std::vector<std::string> protocols) :
146✔
439
      m_protocols(std::move(protocols)) {
146✔
440
   for(const auto& protocol : m_protocols) {
442✔
441
      BOTAN_ARG_CHECK(!protocol.empty(), "ALPN protocol name must not be empty");
296✔
442
      BOTAN_ARG_CHECK(protocol.size() < 256, "ALPN protocol name too long");
296✔
443
   }
444
}
146✔
445

446
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
406✔
447
                                                                                 uint16_t extension_size,
448
                                                                                 Connection_Side from) {
406✔
449
   if(extension_size < 2) {
406✔
450
      throw Decoding_Error("ALPN extension cannot be empty");
1✔
451
   }
452

453
   const uint16_t name_bytes = reader.get_uint16_t();
405✔
454

455
   size_t bytes_remaining = extension_size - 2;
405✔
456

457
   if(name_bytes != bytes_remaining) {
405✔
458
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
3✔
459
   }
460

461
   // RFC 7301 3.1: ProtocolName protocol_name_list<2..2^16-1>
462
   if(name_bytes == 0) {
402✔
463
      throw Decoding_Error("Empty ALPN protocol_name_list not allowed");
1✔
464
   }
465

466
   while(bytes_remaining > 0) {
1,067✔
467
      const std::string p = reader.get_string(1, 0, 255);
674✔
468

469
      if(bytes_remaining < p.size() + 1) {
674✔
470
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
471
      }
472

473
      if(p.empty()) {
674✔
474
         throw Decoding_Error("Empty ALPN protocol not allowed");
8✔
475
      }
476

477
      bytes_remaining -= (p.size() + 1);
666✔
478

479
      m_protocols.push_back(p);
666✔
480
   }
674✔
481

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

493
std::string Application_Layer_Protocol_Notification::single_protocol() const {
285✔
494
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
285✔
495
   return m_protocols.front();
285✔
496
}
497

498
std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const {
357✔
499
   std::vector<uint8_t> buf(2);
357✔
500

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

510
   // RFC 7301 3.1: ProtocolName protocol_name_list<2..2^16-1>;
511
   BOTAN_ASSERT_NOMSG(buf.size() - 2 <= 0xFFFF);
357✔
512
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
357✔
513
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
357✔
514

515
   return buf;
357✔
516
}
×
517

518
Certificate_Type_Base::Certificate_Type_Base(std::vector<Certificate_Type> supported_cert_types) :
140✔
519
      m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
140✔
520
   BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
140✔
521
}
140✔
522

523
Client_Certificate_Type::Client_Certificate_Type(const Client_Certificate_Type& cct, const Policy& policy) :
28✔
524
      Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
28✔
525

526
Server_Certificate_Type::Server_Certificate_Type(const Server_Certificate_Type& sct, const Policy& policy) :
73✔
527
      Certificate_Type_Base(sct, policy.accepted_server_certificate_types()) {}
73✔
528

529
Certificate_Type_Base::Certificate_Type_Base(const Certificate_Type_Base& certificate_type_from_client,
101✔
530
                                             std::span<const Certificate_Type> server_preference) :
101✔
531
      m_from(Connection_Side::Server) {
101✔
532
   // RFC 7250 4.2
533
   //    The server_certificate_type extension in the client hello indicates the
534
   //    types of certificates the client is able to process when provided by
535
   //    the server in a subsequent certificate payload. [...] With the
536
   //    server_certificate_type extension in the server hello, the TLS server
537
   //    indicates the certificate type carried in the Certificate payload.
538
   for(const auto server_supported_cert_type : server_preference) {
127✔
539
      if(value_exists(certificate_type_from_client.m_certificate_types, server_supported_cert_type)) {
246✔
540
         m_certificate_types.push_back(server_supported_cert_type);
97✔
541
         return;
97✔
542
      }
543
   }
544

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

553
Certificate_Type_Base::Certificate_Type_Base(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) :
152✔
554
      m_from(from) {
152✔
555
   if(extension_size == 0) {
152✔
556
      throw Decoding_Error("Certificate type extension cannot be empty");
×
557
   }
558

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

584
std::vector<uint8_t> Certificate_Type_Base::serialize(Connection_Side whoami) const {
164✔
585
   std::vector<uint8_t> result;
164✔
586
   if(whoami == Connection_Side::Client) {
164✔
587
      std::vector<uint8_t> type_bytes;
63✔
588
      std::transform(
63✔
589
         m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
590
            return static_cast<uint8_t>(type);
591
         });
592
      append_tls_length_value(result, type_bytes, 1);
126✔
593
   } else {
63✔
594
      BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
101✔
595
      result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
101✔
596
   }
597
   return result;
164✔
598
}
×
599

600
void Certificate_Type_Base::validate_selection(const Certificate_Type_Base& from_server) const {
26✔
601
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Client);
26✔
602
   BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
26✔
603

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

615
Certificate_Type Certificate_Type_Base::selected_certificate_type() const {
113✔
616
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Server);
113✔
617
   BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
113✔
618
   return m_certificate_types.front();
113✔
619
}
620

621
Supported_Groups::Supported_Groups(std::vector<Group_Params> groups) : m_groups(std::move(groups)) {}
4,359✔
622

623
const std::vector<Group_Params>& Supported_Groups::groups() const {
1,263✔
624
   return m_groups;
1,263✔
625
}
626

627
std::vector<Group_Params> Supported_Groups::ec_groups() const {
5,949✔
628
   std::vector<Group_Params> ec;
5,949✔
629
   for(auto g : m_groups) {
77,403✔
630
      if(g.is_pure_ecc_group()) {
142,908✔
631
         ec.push_back(g);
55,098✔
632
      }
633
   }
634
   return ec;
5,949✔
635
}
×
636

637
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,579✔
638
   std::vector<Group_Params> dh;
1,579✔
639
   for(auto g : m_groups) {
13,764✔
640
      if(g.is_in_ffdhe_range()) {
16,394✔
641
         dh.push_back(g);
565✔
642
      }
643
   }
644
   return dh;
1,579✔
645
}
×
646

647
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
5,144✔
648
   std::vector<uint8_t> buf(2);
5,144✔
649

650
   for(auto g : m_groups) {
75,167✔
651
      const uint16_t id = g.wire_code();
70,023✔
652

653
      if(id > 0) {
70,023✔
654
         buf.push_back(get_byte<0>(id));
70,023✔
655
         buf.push_back(get_byte<1>(id));
70,023✔
656
      }
657
   }
658

659
   // RFC 8446 4.2.7: NamedGroup named_group_list<2..2^16-1>;
660
   BOTAN_ASSERT_NOMSG(buf.size() - 2 <= 0xFFFF);
5,144✔
661
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
5,144✔
662
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
5,144✔
663

664
   return buf;
5,144✔
665
}
×
666

667
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
3,232✔
668
   const uint16_t len = reader.get_uint16_t();
3,232✔
669

670
   if(len + 2 != extension_size) {
3,232✔
671
      throw Decoding_Error("Inconsistent length field in supported groups list");
6✔
672
   }
673

674
   // RFC 8446 4.2.7: NamedGroup named_group_list<2..2^16-1>;
675
   if(len == 0) {
3,226✔
676
      throw Decoding_Error("Empty supported groups list");
1✔
677
   }
678

679
   if(len % 2 == 1) {
3,225✔
680
      throw Decoding_Error("Supported groups list of strange size");
1✔
681
   }
682

683
   const size_t elems = len / 2;
3,224✔
684

685
   std::unordered_set<uint16_t> seen;
3,224✔
686
   for(size_t i = 0; i != elems; ++i) {
30,562✔
687
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
27,338✔
688
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
689
      if(seen.insert(group.wire_code()).second) {
27,338✔
690
         m_groups.push_back(group);
27,338✔
691
      }
692
   }
693
}
3,232✔
694

695
namespace {
696

697
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
5,061✔
698
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
5,061✔
699

700
   std::vector<uint8_t> buf;
5,061✔
701

702
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
5,061✔
703

704
   buf.push_back(get_byte<0>(len));
5,061✔
705
   buf.push_back(get_byte<1>(len));
5,061✔
706

707
   for(const Signature_Scheme scheme : schemes) {
49,716✔
708
      buf.push_back(get_byte<0>(scheme.wire_code()));
44,655✔
709
      buf.push_back(get_byte<1>(scheme.wire_code()));
44,655✔
710
   }
711

712
   return buf;
5,061✔
713
}
×
714

715
std::vector<Signature_Scheme> parse_signature_algorithms(TLS_Data_Reader& reader, uint16_t extension_size) {
3,270✔
716
   uint16_t len = reader.get_uint16_t();
3,270✔
717

718
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
3,268✔
719
      throw Decoding_Error("Bad encoding on signature algorithms extension");
4✔
720
   }
721

722
   std::vector<Signature_Scheme> schemes;
3,264✔
723
   schemes.reserve(len / 2);
3,264✔
724
   while(len > 0) {
34,544✔
725
      schemes.emplace_back(reader.get_uint16_t());
31,280✔
726
      len -= 2;
31,280✔
727
   }
728

729
   return schemes;
3,264✔
730
}
×
731

732
}  // namespace
733

734
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
5,059✔
735
   return serialize_signature_algorithms(m_schemes);
5,059✔
736
}
737

738
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
3,265✔
739
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
3,265✔
740

741
std::vector<uint8_t> Signature_Algorithms_Cert::serialize(Connection_Side /*whoami*/) const {
2✔
742
   return serialize_signature_algorithms(m_schemes);
2✔
743
}
744

745
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
5✔
746
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
5✔
747

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

761
   if(m_pp.size() * 2 + mki.size() + 3 != extension_size) {
9✔
762
      throw Decoding_Error("Bad encoding for SRTP protection extension");
×
763
   }
764

765
   if(!mki.empty()) {
9✔
766
      throw Decoding_Error("Unhandled non-empty MKI for SRTP protection extension");
×
767
   }
768
}
10✔
769

770
std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const {
5✔
771
   std::vector<uint8_t> buf;
5✔
772

773
   const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2);
5✔
774
   buf.push_back(get_byte<0>(pp_len));
5✔
775
   buf.push_back(get_byte<1>(pp_len));
5✔
776

777
   for(const uint16_t pp : m_pp) {
12✔
778
      buf.push_back(get_byte<0>(pp));
7✔
779
      buf.push_back(get_byte<1>(pp));
7✔
780
   }
781

782
   buf.push_back(0);  // srtp_mki, always empty here
5✔
783

784
   return buf;
5✔
785
}
×
786

787
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,862✔
788
   std::vector<uint8_t> buf;
4,862✔
789

790
   if(whoami == Connection_Side::Server) {
4,862✔
791
      BOTAN_ASSERT_NOMSG(m_versions.size() == 1);
581✔
792
      buf.push_back(m_versions[0].major_version());
581✔
793
      buf.push_back(m_versions[0].minor_version());
581✔
794
   } else {
795
      // RFC 8446 4.2.1: ProtocolVersion versions<2..254>; - up to 127 entries.
796
      BOTAN_ASSERT_NOMSG(!m_versions.empty());
4,281✔
797
      BOTAN_ASSERT_NOMSG(m_versions.size() <= 127);
4,281✔
798
      const uint8_t len = static_cast<uint8_t>(m_versions.size() * 2);
4,281✔
799

800
      buf.push_back(len);
4,281✔
801

802
      for(const Protocol_Version version : m_versions) {
9,787✔
803
         buf.push_back(version.major_version());
5,506✔
804
         buf.push_back(version.minor_version());
5,506✔
805
      }
806
   }
807

808
   return buf;
4,862✔
809
}
×
810

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

827
#if defined(BOTAN_HAS_TLS_12)
828
   if(offer.is_datagram_protocol()) {
3,615✔
829
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
431✔
830
         m_versions.push_back(Protocol_Version::DTLS_V12);
431✔
831
      }
832
   } else {
833
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
4,282✔
834
         m_versions.push_back(Protocol_Version::TLS_V12);
3,114✔
835
      }
836
   }
837
#endif
838

839
   // if no versions are supported, the input variables are not used
840
   BOTAN_UNUSED(offer, policy);
3,615✔
841
}
3,615✔
842

843
Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
2,259✔
844
   if(from == Connection_Side::Server) {
2,259✔
845
      if(extension_size != 2) {
643✔
846
         throw Decoding_Error("Server sent invalid supported_versions extension");
1✔
847
      }
848
      m_versions.push_back(Protocol_Version(reader.get_uint16_t()));
642✔
849
   } else {
850
      auto versions = reader.get_range<uint16_t>(1, 1, 127);
1,616✔
851

852
      for(auto v : versions) {
5,754✔
853
         m_versions.push_back(Protocol_Version(v));
4,138✔
854
      }
855

856
      if(extension_size != 1 + 2 * versions.size()) {
1,616✔
857
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
858
      }
859
   }
1,616✔
860
}
2,259✔
861

862
bool Supported_Versions::supports(Protocol_Version version) const {
1,751✔
863
   for(auto v : m_versions) {
2,263✔
864
      if(version == v) {
2,244✔
865
         return true;
1,751✔
866
      }
867
   }
868
   return false;
869
}
870

871
Record_Size_Limit::Record_Size_Limit(const uint16_t limit) : m_limit(limit) {
16✔
872
   BOTAN_ARG_CHECK(limit >= 64, "RFC 8449 does not allow record size limits smaller than 64 bytes");
16✔
873
   BOTAN_ARG_CHECK(limit <= MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */,
16✔
874
                   "RFC 8449 does not allow record size limits larger than 2^14+1");
875
}
16✔
876

877
Record_Size_Limit::Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
45✔
878
   if(extension_size != 2) {
45✔
879
      throw TLS_Exception(Alert::DecodeError, "invalid record_size_limit extension");
×
880
   }
881

882
   m_limit = reader.get_uint16_t();
45✔
883

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

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

911
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side /*whoami*/) const {
53✔
912
   std::vector<uint8_t> buf;
53✔
913

914
   buf.push_back(get_byte<0>(m_limit));
53✔
915
   buf.push_back(get_byte<1>(m_limit));
53✔
916

917
   return buf;
53✔
918
}
×
919

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