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

randombit / botan / 21943010187

12 Feb 2026 10:33AM UTC coverage: 90.061% (-0.006%) from 90.067%
21943010187

Pull #5318

github

web-flow
Merge 005a803db into f97d7db3f
Pull Request #5318: Allow disabling TLS 1.2 at Build Time

102245 of 113528 relevant lines covered (90.06%)

11733046.67 hits per line

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

89.67
/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

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

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

30
namespace Botan::TLS {
31

32
namespace {
33

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

45
      case Extension_Code::SupportedGroups:
2,909✔
46
         return std::make_unique<Supported_Groups>(reader, size);
2,909✔
47

48
      case Extension_Code::CertificateStatusRequest:
2,673✔
49
         return std::make_unique<Certificate_Status_Request>(reader, size, message_type, from);
2,673✔
50

51
      case Extension_Code::SignatureAlgorithms:
2,934✔
52
         return std::make_unique<Signature_Algorithms>(reader, size);
2,934✔
53

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

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

60
      case Extension_Code::ApplicationLayerProtocolNegotiation:
407✔
61
         return std::make_unique<Application_Layer_Protocol_Notification>(reader, size, from);
407✔
62

63
      case Extension_Code::ClientCertificateType:
2✔
64
         return std::make_unique<Client_Certificate_Type>(reader, size, from);
2✔
65

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

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

72
      case Extension_Code::SupportedVersions:
1,825✔
73
         return std::make_unique<Supported_Versions>(reader, size, from);
1,825✔
74

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

79
      case Extension_Code::SafeRenegotiation:
5,691✔
80
         return std::make_unique<Renegotiation_Extension>(reader, size);
5,691✔
81

82
      case Extension_Code::ExtendedMasterSecret:
5,515✔
83
         return std::make_unique<Extended_Master_Secret>(reader, size);
5,515✔
84

85
      case Extension_Code::EncryptThenMac:
814✔
86
         return std::make_unique<Encrypt_then_MAC>(reader, size);
814✔
87

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

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

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

106
      case Extension_Code::Cookie:
10✔
107
         return std::make_unique<Cookie>(reader, size);
10✔
108

109
      case Extension_Code::PskKeyExchangeModes:
1,072✔
110
         return std::make_unique<PSK_Key_Exchange_Modes>(reader, size);
1,072✔
111

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

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

128
   return std::make_unique<Unknown_Extension>(code, reader, size);
2,708✔
129
}
130

131
}  // namespace
132

133
Extensions::~Extensions() = default;
22,766✔
134

135
Extension* Extensions::get(Extension_Code type) const {
221,149✔
136
   const auto i =
221,149✔
137
      std::find_if(m_extensions.cbegin(), m_extensions.cend(), [type](const auto& ext) { return ext->type() == type; });
1,132,038✔
138

139
   return (i != m_extensions.end()) ? i->get() : nullptr;
221,149✔
140
}
141

142
void Extensions::add(std::unique_ptr<Extension> extn) {
84,935✔
143
   if(has(extn->type())) {
84,935✔
144
      throw Invalid_Argument("cannot add the same extension twice: " +
×
145
                             std::to_string(static_cast<uint16_t>(extn->type())));
×
146
   }
147

148
   m_extensions.emplace_back(extn.release());
84,935✔
149
}
84,935✔
150

151
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
7,973✔
152
   if(reader.has_remaining()) {
7,973✔
153
      const uint16_t all_extn_size = reader.get_uint16_t();
7,968✔
154

155
      if(reader.remaining_bytes() != all_extn_size) {
7,968✔
156
         throw Decoding_Error("Bad extension size");
118✔
157
      }
158

159
      while(reader.has_remaining()) {
47,292✔
160
         const uint16_t extension_code = reader.get_uint16_t();
39,497✔
161
         const uint16_t extension_size = reader.get_uint16_t();
39,496✔
162

163
         const auto type = static_cast<Extension_Code>(extension_code);
39,496✔
164

165
         if(this->has(type)) {
39,496✔
166
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
13✔
167
         }
168

169
         // TODO offer a function on reader that returns a byte range as a reference
170
         // to avoid this copy of the extension data
171
         const std::vector<uint8_t> extn_data = reader.get_fixed<uint8_t>(extension_size);
39,483✔
172
         TLS_Data_Reader extn_reader("Extension", extn_data);
39,475✔
173
         this->add(make_extension(extn_reader, type, from, message_type));
39,475✔
174
         extn_reader.assert_done();
39,442✔
175
      }
39,442✔
176
   }
177
}
7,800✔
178

179
bool Extensions::contains_other_than(const std::set<Extension_Code>& allowed_extensions,
3,437✔
180
                                     const bool allow_unknown_extensions) const {
181
   const auto found = extension_types();
3,437✔
182

183
   std::vector<Extension_Code> diff;
3,437✔
184
   std::set_difference(
3,437✔
185
      found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
186

187
   if(allow_unknown_extensions) {
3,437✔
188
      // Go through the found unexpected extensions whether any of those
189
      // is known to this TLS implementation.
190
      const auto itr = std::find_if(diff.cbegin(), diff.cend(), [this](const auto ext_type) {
1,523✔
191
         const auto ext = get(ext_type);
10✔
192
         return ext && ext->is_implemented();
10✔
193
      });
194

195
      // ... if yes, `contains_other_than` is true
196
      return itr != diff.cend();
1,523✔
197
   }
198

199
   return !diff.empty();
1,914✔
200
}
3,437✔
201

202
std::unique_ptr<Extension> Extensions::take(Extension_Code type) {
520✔
203
   const auto i =
520✔
204
      std::find_if(m_extensions.begin(), m_extensions.end(), [type](const auto& ext) { return ext->type() == type; });
3,191✔
205

206
   std::unique_ptr<Extension> result;
520✔
207
   if(i != m_extensions.end()) {
520✔
208
      std::swap(result, *i);
251✔
209
      m_extensions.erase(i);
251✔
210
   }
211

212
   return result;
520✔
213
}
214

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

218
   for(const auto& extn : m_extensions) {
59,035✔
219
      if(extn->empty()) {
52,495✔
220
         continue;
3,120✔
221
      }
222

223
      const uint16_t extn_code = static_cast<uint16_t>(extn->type());
49,375✔
224

225
      const std::vector<uint8_t> extn_val = extn->serialize(whoami);
49,375✔
226

227
      buf.push_back(get_byte<0>(extn_code));
49,375✔
228
      buf.push_back(get_byte<1>(extn_code));
49,375✔
229

230
      buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
49,375✔
231
      buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
49,375✔
232

233
      buf += extn_val;
49,375✔
234
   }
49,375✔
235

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

238
   buf[0] = get_byte<0>(extn_size);
6,540✔
239
   buf[1] = get_byte<1>(extn_size);
6,540✔
240

241
   // avoid sending a completely empty extensions block
242
   if(buf.size() == 2) {
6,540✔
243
      return std::vector<uint8_t>();
304✔
244
   }
245

246
   return buf;
6,236✔
247
}
6,540✔
248

249
std::set<Extension_Code> Extensions::extension_types() const {
10,357✔
250
   std::set<Extension_Code> offers;
10,357✔
251
   std::transform(
10,357✔
252
      m_extensions.cbegin(), m_extensions.cend(), std::inserter(offers, offers.begin()), [](const auto& ext) {
58,633✔
253
         return ext->type();
58,633✔
254
      });
255
   return offers;
10,357✔
256
}
×
257

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

261
std::vector<uint8_t> Unknown_Extension::serialize(Connection_Side /*whoami*/) const {
2✔
262
   return m_value;
2✔
263
}
264

265
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, uint16_t extension_size) {
2,829✔
266
   /*
267
   * This is used by the server to confirm that it knew the name
268
   */
269
   if(extension_size == 0) {
2,829✔
270
      return;
271
   }
272

273
   uint16_t name_bytes = reader.get_uint16_t();
2,794✔
274

275
   if(name_bytes + 2 != extension_size) {
2,794✔
276
      throw Decoding_Error("Bad encoding of SNI extension");
×
277
   }
278

279
   while(name_bytes > 0) {
5,588✔
280
      const uint8_t name_type = reader.get_byte();
2,794✔
281
      name_bytes--;
2,794✔
282

283
      if(name_type == 0) {
2,794✔
284
         // DNS
285
         m_sni_host_name = reader.get_string(2, 1, 65535);
2,794✔
286
         name_bytes -= static_cast<uint16_t>(2 + m_sni_host_name.size());
2,794✔
287
      } else {
288
         // some other unknown name type, which we will ignore
289
         reader.discard_next(name_bytes);
×
290
         name_bytes = 0;
×
291
      }
292
   }
293
}
×
294

295
std::vector<uint8_t> Server_Name_Indicator::serialize(Connection_Side whoami) const {
4,656✔
296
   // RFC 6066
297
   //    [...] the server SHALL include an extension of type "server_name" in
298
   //    the (extended) server hello. The "extension_data" field of this
299
   //    extension SHALL be empty.
300
   if(whoami == Connection_Side::Server) {
4,656✔
301
      return {};
366✔
302
   }
303

304
   std::vector<uint8_t> buf;
4,290✔
305

306
   const size_t name_len = m_sni_host_name.size();
4,290✔
307

308
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,290✔
309
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,290✔
310
   buf.push_back(0);  // DNS
4,290✔
311

312
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,290✔
313
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,290✔
314

315
   buf += as_span_of_bytes(m_sni_host_name);
4,290✔
316

317
   return buf;
4,290✔
318
}
4,290✔
319

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

323
   if(hostname.empty()) {
3,684✔
324
      return false;
325
   }
326

327
   if(string_to_ipv4(hostname).has_value()) {
3,637✔
328
      return false;
329
   }
330

331
   // IPv6? Anyway ':' is not valid in DNS
332
   if(hostname.find(':') != std::string_view::npos) {
3,637✔
333
      return false;
334
   }
335

336
   return true;
337
}
338

339
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
407✔
340
                                                                                 uint16_t extension_size,
341
                                                                                 Connection_Side from) {
407✔
342
   if(extension_size == 0) {
407✔
343
      return;  // empty extension
344
   }
345

346
   const uint16_t name_bytes = reader.get_uint16_t();
407✔
347

348
   size_t bytes_remaining = extension_size - 2;
407✔
349

350
   if(name_bytes != bytes_remaining) {
407✔
351
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
×
352
   }
353

354
   while(bytes_remaining > 0) {
1,085✔
355
      const std::string p = reader.get_string(1, 0, 255);
685✔
356

357
      if(bytes_remaining < p.size() + 1) {
685✔
358
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
359
      }
360

361
      if(p.empty()) {
685✔
362
         throw Decoding_Error("Empty ALPN protocol not allowed");
7✔
363
      }
364

365
      bytes_remaining -= (p.size() + 1);
678✔
366

367
      m_protocols.push_back(p);
678✔
368
   }
685✔
369

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

381
std::string Application_Layer_Protocol_Notification::single_protocol() const {
148✔
382
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
148✔
383
   return m_protocols.front();
148✔
384
}
385

386
std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const {
365✔
387
   std::vector<uint8_t> buf(2);
365✔
388

389
   for(auto&& proto : m_protocols) {
958✔
390
      if(proto.length() >= 256) {
593✔
391
         throw TLS_Exception(Alert::InternalError, "ALPN name too long");
×
392
      }
393
      if(!proto.empty()) {
593✔
394
         append_tls_length_value(buf, proto, 1);
1,186✔
395
      }
396
   }
397

398
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
365✔
399
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
365✔
400

401
   return buf;
365✔
402
}
×
403

404
Certificate_Type_Base::Certificate_Type_Base(std::vector<Certificate_Type> supported_cert_types) :
1,976✔
405
      m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
1,976✔
406
   BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
1,976✔
407
}
1,976✔
408

409
Client_Certificate_Type::Client_Certificate_Type(const Client_Certificate_Type& cct, const Policy& policy) :
1✔
410
      Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
1✔
411

412
Server_Certificate_Type::Server_Certificate_Type(const Server_Certificate_Type& sct, const Policy& policy) :
1✔
413
      Certificate_Type_Base(sct, policy.accepted_server_certificate_types()) {}
1✔
414

415
Certificate_Type_Base::Certificate_Type_Base(const Certificate_Type_Base& certificate_type_from_client,
2✔
416
                                             const std::vector<Certificate_Type>& server_preference) :
2✔
417
      m_from(Connection_Side::Server) {
2✔
418
   // RFC 7250 4.2
419
   //    The server_certificate_type extension in the client hello indicates the
420
   //    types of certificates the client is able to process when provided by
421
   //    the server in a subsequent certificate payload. [...] With the
422
   //    server_certificate_type extension in the server hello, the TLS server
423
   //    indicates the certificate type carried in the Certificate payload.
424
   for(const auto server_supported_cert_type : server_preference) {
2✔
425
      if(value_exists(certificate_type_from_client.m_certificate_types, server_supported_cert_type)) {
4✔
426
         m_certificate_types.push_back(server_supported_cert_type);
2✔
427
         return;
2✔
428
      }
429
   }
430

431
   // RFC 7250 4.2 (2.)
432
   //    The server supports the extension defined in this document, but
433
   //    it does not have any certificate type in common with the client.
434
   //    Then, the server terminates the session with a fatal alert of
435
   //    type "unsupported_certificate".
436
   throw TLS_Exception(Alert::UnsupportedCertificate, "Failed to agree on certificate_type");
×
437
}
×
438

439
Certificate_Type_Base::Certificate_Type_Base(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) :
4✔
440
      m_from(from) {
4✔
441
   if(extension_size == 0) {
4✔
442
      throw Decoding_Error("Certificate type extension cannot be empty");
×
443
   }
444

445
   if(from == Connection_Side::Client) {
4✔
446
      const auto type_bytes = reader.get_tls_length_value(1);
2✔
447
      if(static_cast<size_t>(extension_size) != type_bytes.size() + 1) {
2✔
448
         throw Decoding_Error("certificate type extension had inconsistent length");
×
449
      }
450
      std::transform(
2✔
451
         type_bytes.begin(), type_bytes.end(), std::back_inserter(m_certificate_types), [](const auto type_byte) {
2✔
452
            return static_cast<Certificate_Type>(type_byte);
453
         });
454
   } else {
2✔
455
      // RFC 7250 4.2
456
      //    Note that only a single value is permitted in the
457
      //    server_certificate_type extension when carried in the server hello.
458
      if(extension_size != 1) {
2✔
459
         throw Decoding_Error("Server's certificate type extension must be of length 1");
×
460
      }
461
      const auto type_byte = reader.get_byte();
2✔
462
      m_certificate_types.push_back(static_cast<Certificate_Type>(type_byte));
2✔
463
   }
464
}
4✔
465

466
std::vector<uint8_t> Certificate_Type_Base::serialize(Connection_Side whoami) const {
12✔
467
   std::vector<uint8_t> result;
12✔
468
   if(whoami == Connection_Side::Client) {
12✔
469
      std::vector<uint8_t> type_bytes;
6✔
470
      std::transform(
6✔
471
         m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
472
            return static_cast<uint8_t>(type);
473
         });
474
      append_tls_length_value(result, type_bytes, 1);
12✔
475
   } else {
6✔
476
      BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
6✔
477
      result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
6✔
478
   }
479
   return result;
12✔
480
}
×
481

482
void Certificate_Type_Base::validate_selection(const Certificate_Type_Base& from_server) const {
2✔
483
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Client);
2✔
484
   BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
2✔
485

486
   // RFC 7250 4.2
487
   //    The value conveyed in the [client_]certificate_type extension MUST be
488
   //    selected from one of the values provided in the [client_]certificate_type
489
   //    extension sent in the client hello.
490
   if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
4✔
491
      throw TLS_Exception(Alert::IllegalParameter,
×
492
                          Botan::fmt("Selected certificate type was not offered: {}",
×
493
                                     certificate_type_to_string(from_server.selected_certificate_type())));
×
494
   }
495
}
2✔
496

497
Certificate_Type Certificate_Type_Base::selected_certificate_type() const {
6✔
498
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Server);
6✔
499
   BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
6✔
500
   return m_certificate_types.front();
6✔
501
}
502

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

505
const std::vector<Group_Params>& Supported_Groups::groups() const {
948✔
506
   return m_groups;
948✔
507
}
508

509
std::vector<Group_Params> Supported_Groups::ec_groups() const {
5,024✔
510
   std::vector<Group_Params> ec;
5,024✔
511
   for(auto g : m_groups) {
52,100✔
512
      if(g.is_pure_ecc_group()) {
94,152✔
513
         ec.push_back(g);
34,689✔
514
      }
515
   }
516
   return ec;
5,024✔
517
}
×
518

519
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,511✔
520
   std::vector<Group_Params> dh;
1,511✔
521
   for(auto g : m_groups) {
11,116✔
522
      if(g.is_in_ffdhe_range()) {
12,447✔
523
         dh.push_back(g);
550✔
524
      }
525
   }
526
   return dh;
1,511✔
527
}
×
528

529
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,724✔
530
   std::vector<uint8_t> buf(2);
4,724✔
531

532
   for(auto g : m_groups) {
54,923✔
533
      const uint16_t id = g.wire_code();
50,199✔
534

535
      if(id > 0) {
50,199✔
536
         buf.push_back(get_byte<0>(id));
50,199✔
537
         buf.push_back(get_byte<1>(id));
50,199✔
538
      }
539
   }
540

541
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,724✔
542
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,724✔
543

544
   return buf;
4,724✔
545
}
×
546

547
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
2,911✔
548
   const uint16_t len = reader.get_uint16_t();
2,911✔
549

550
   if(len + 2 != extension_size) {
2,911✔
551
      throw Decoding_Error("Inconsistent length field in supported groups list");
4✔
552
   }
553

554
   if(len % 2 == 1) {
2,907✔
555
      throw Decoding_Error("Supported groups list of strange size");
×
556
   }
557

558
   const size_t elems = len / 2;
2,907✔
559

560
   for(size_t i = 0; i != elems; ++i) {
23,913✔
561
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
21,006✔
562
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
563
      if(!value_exists(m_groups, group)) {
42,012✔
564
         m_groups.push_back(group);
21,006✔
565
      }
566
   }
567
}
2,911✔
568

569
namespace {
570

571
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
4,728✔
572
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
4,728✔
573

574
   std::vector<uint8_t> buf;
4,728✔
575

576
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,728✔
577

578
   buf.push_back(get_byte<0>(len));
4,728✔
579
   buf.push_back(get_byte<1>(len));
4,728✔
580

581
   for(const Signature_Scheme scheme : schemes) {
46,320✔
582
      buf.push_back(get_byte<0>(scheme.wire_code()));
41,592✔
583
      buf.push_back(get_byte<1>(scheme.wire_code()));
41,592✔
584
   }
585

586
   return buf;
4,728✔
587
}
×
588

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

592
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
2,935✔
593
      throw Decoding_Error("Bad encoding on signature algorithms extension");
1✔
594
   }
595

596
   std::vector<Signature_Scheme> schemes;
2,934✔
597
   schemes.reserve(len / 2);
2,934✔
598
   while(len > 0) {
30,781✔
599
      schemes.emplace_back(reader.get_uint16_t());
27,847✔
600
      len -= 2;
27,847✔
601
   }
602

603
   return schemes;
2,934✔
604
}
×
605

606
}  // namespace
607

608
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
4,726✔
609
   return serialize_signature_algorithms(m_schemes);
4,726✔
610
}
611

612
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
2,934✔
613
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2,934✔
614

615
std::vector<uint8_t> Signature_Algorithms_Cert::serialize(Connection_Side /*whoami*/) const {
2✔
616
   return serialize_signature_algorithms(m_schemes);
2✔
617
}
618

619
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
2✔
620
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2✔
621

622
SRTP_Protection_Profiles::SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size) :
10✔
623
      m_pp(reader.get_range<uint16_t>(2, 0, 65535)) {
10✔
624
   const std::vector<uint8_t> mki = reader.get_range<uint8_t>(1, 0, 255);
9✔
625

626
   if(m_pp.size() * 2 + mki.size() + 3 != extension_size) {
9✔
627
      throw Decoding_Error("Bad encoding for SRTP protection extension");
×
628
   }
629

630
   if(!mki.empty()) {
9✔
631
      throw Decoding_Error("Unhandled non-empty MKI for SRTP protection extension");
×
632
   }
633
}
9✔
634

635
std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const {
5✔
636
   std::vector<uint8_t> buf;
5✔
637

638
   const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2);
5✔
639
   buf.push_back(get_byte<0>(pp_len));
5✔
640
   buf.push_back(get_byte<1>(pp_len));
5✔
641

642
   for(const uint16_t pp : m_pp) {
12✔
643
      buf.push_back(get_byte<0>(pp));
7✔
644
      buf.push_back(get_byte<1>(pp));
7✔
645
   }
646

647
   buf.push_back(0);  // srtp_mki, always empty here
5✔
648

649
   return buf;
5✔
650
}
×
651

652
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,482✔
653
   std::vector<uint8_t> buf;
4,482✔
654

655
   if(whoami == Connection_Side::Server) {
4,482✔
656
      BOTAN_ASSERT_NOMSG(m_versions.size() == 1);
429✔
657
      buf.push_back(m_versions[0].major_version());
429✔
658
      buf.push_back(m_versions[0].minor_version());
429✔
659
   } else {
660
      BOTAN_ASSERT_NOMSG(!m_versions.empty());
4,053✔
661
      const uint8_t len = static_cast<uint8_t>(m_versions.size() * 2);
4,053✔
662

663
      buf.push_back(len);
4,053✔
664

665
      for(const Protocol_Version version : m_versions) {
9,224✔
666
         buf.push_back(version.major_version());
5,171✔
667
         buf.push_back(version.minor_version());
5,171✔
668
      }
669
   }
670

671
   return buf;
4,482✔
672
}
×
673

674
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,472✔
675
   // RFC 8446 4.2.1
676
   //    The extension contains a list of supported versions in preference order,
677
   //    with the most preferred version first. Implementations [...] MUST send
678
   //    this extension in the ClientHello containing all versions of TLS which
679
   //    they are prepared to negotiate.
680
   //
681
   // We simply assume that we always want the newest available TLS version.
682
#if defined(BOTAN_HAS_TLS_13)
683
   if(!offer.is_datagram_protocol()) {
3,472✔
684
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,156✔
685
         m_versions.push_back(Protocol_Version::TLS_V13);
988✔
686
      }
687
   }
688
#endif
689

690
#if defined(BOTAN_HAS_TLS_12)
691
   if(offer.is_datagram_protocol()) {
3,472✔
692
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
400✔
693
         m_versions.push_back(Protocol_Version::DTLS_V12);
400✔
694
      }
695
   } else {
696
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
4,060✔
697
         m_versions.push_back(Protocol_Version::TLS_V12);
3,043✔
698
      }
699
   }
700
#endif
701

702
   // if no versions are supported, the input variables are not used
703
   BOTAN_UNUSED(offer, policy);
3,472✔
704
}
3,472✔
705

706
Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
1,827✔
707
   if(from == Connection_Side::Server) {
1,827✔
708
      if(extension_size != 2) {
541✔
709
         throw Decoding_Error("Server sent invalid supported_versions extension");
×
710
      }
711
      m_versions.push_back(Protocol_Version(reader.get_uint16_t()));
541✔
712
   } else {
713
      auto versions = reader.get_range<uint16_t>(1, 1, 127);
1,286✔
714

715
      for(auto v : versions) {
4,561✔
716
         m_versions.push_back(Protocol_Version(v));
3,275✔
717
      }
718

719
      if(extension_size != 1 + 2 * versions.size()) {
1,286✔
720
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
721
      }
722
   }
1,286✔
723
}
1,827✔
724

725
bool Supported_Versions::supports(Protocol_Version version) const {
1,485✔
726
   for(auto v : m_versions) {
1,996✔
727
      if(version == v) {
1,977✔
728
         return true;
1,485✔
729
      }
730
   }
731
   return false;
732
}
733

734
Record_Size_Limit::Record_Size_Limit(const uint16_t limit) : m_limit(limit) {
16✔
735
   BOTAN_ASSERT(limit >= 64, "RFC 8449 does not allow record size limits smaller than 64 bytes");
16✔
736
   BOTAN_ASSERT(limit <= MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */,
16✔
737
                "RFC 8449 does not allow record size limits larger than 2^14+1");
738
}
16✔
739

740
Record_Size_Limit::Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
45✔
741
   if(extension_size != 2) {
45✔
742
      throw TLS_Exception(Alert::DecodeError, "invalid record_size_limit extension");
×
743
   }
744

745
   m_limit = reader.get_uint16_t();
45✔
746

747
   // RFC 8449 4.
748
   //    This value is the length of the plaintext of a protected record.
749
   //    The value includes the content type and padding added in TLS 1.3 (that
750
   //    is, the complete length of TLSInnerPlaintext).
751
   //
752
   //    A server MUST NOT enforce this restriction; a client might advertise
753
   //    a higher limit that is enabled by an extension or version the server
754
   //    does not understand. A client MAY abort the handshake with an
755
   //    "illegal_parameter" alert.
756
   //
757
   // Note: We are currently supporting this extension in TLS 1.3 only, hence
758
   //       we check for the TLS 1.3 limit. The TLS 1.2 limit would not include
759
   //       the "content type byte" and hence be one byte less!
760
   if(m_limit > MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */ && from == Connection_Side::Server) {
45✔
761
      throw TLS_Exception(Alert::IllegalParameter,
×
762
                          "Server requested a record size limit larger than the protocol's maximum");
×
763
   }
764

765
   // RFC 8449 4.
766
   //    Endpoints MUST NOT send a "record_size_limit" extension with a value
767
   //    smaller than 64.  An endpoint MUST treat receipt of a smaller value
768
   //    as a fatal error and generate an "illegal_parameter" alert.
769
   if(m_limit < 64) {
45✔
770
      throw TLS_Exception(Alert::IllegalParameter, "Received a record size limit smaller than 64 bytes");
×
771
   }
772
}
45✔
773

774
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side /*whoami*/) const {
53✔
775
   std::vector<uint8_t> buf;
53✔
776

777
   buf.push_back(get_byte<0>(m_limit));
53✔
778
   buf.push_back(get_byte<1>(m_limit));
53✔
779

780
   return buf;
53✔
781
}
×
782

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