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

randombit / botan / 16293079084

15 Jul 2025 12:20PM UTC coverage: 90.627% (+0.003%) from 90.624%
16293079084

push

github

web-flow
Merge pull request #4990 from randombit/jack/string-and-span

Improve string<->span conversions

99640 of 109945 relevant lines covered (90.63%)

12253617.72 hits per line

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

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

13
#include <botan/tls_extensions.h>
14

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

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

26
namespace Botan::TLS {
27

28
namespace {
29

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

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

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

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

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

53
      case Extension_Code::SignatureAlgorithms:
2,930✔
54
         return std::make_unique<Signature_Algorithms>(reader, size);
2,930✔
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:
401✔
63
         return std::make_unique<Application_Layer_Protocol_Notification>(reader, size, from);
401✔
64

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

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

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

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

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

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

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

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

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

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

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

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

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

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

110
}  // namespace
111

112
Extensions::~Extensions() = default;
22,753✔
113

114
Extension* Extensions::get(Extension_Code type) const {
219,830✔
115
   const auto i =
219,830✔
116
      std::find_if(m_extensions.cbegin(), m_extensions.cend(), [type](const auto& ext) { return ext->type() == type; });
1,128,888✔
117

118
   return (i != m_extensions.end()) ? i->get() : nullptr;
219,830✔
119
}
120

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

127
   m_extensions.emplace_back(extn.release());
84,818✔
128
}
84,818✔
129

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

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

138
      while(reader.has_remaining()) {
47,220✔
139
         const uint16_t extension_code = reader.get_uint16_t();
39,432✔
140
         const uint16_t extension_size = reader.get_uint16_t();
39,431✔
141

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

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

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

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

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

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

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

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

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

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

191
   return result;
514✔
192
}
193

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

197
   for(const auto& extn : m_extensions) {
58,973✔
198
      if(extn->empty()) {
52,439✔
199
         continue;
3,120✔
200
      }
201

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

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

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

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

212
      buf += extn_val;
49,319✔
213
   }
49,319✔
214

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

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

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

225
   return buf;
6,230✔
226
}
6,534✔
227

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

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

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

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

252
   uint16_t name_bytes = reader.get_uint16_t();
2,790✔
253

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

258
   while(name_bytes > 0) {
5,580✔
259
      uint8_t name_type = reader.get_byte();
2,790✔
260
      name_bytes--;
2,790✔
261

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

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

283
   std::vector<uint8_t> buf;
4,287✔
284

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

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

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

294
   buf += as_span_of_bytes(m_sni_host_name);
4,287✔
295

296
   return buf;
4,287✔
297
}
4,287✔
298

299
Renegotiation_Extension::Renegotiation_Extension(TLS_Data_Reader& reader, uint16_t extension_size) :
5,684✔
300
      m_reneg_data(reader.get_range<uint8_t>(1, 0, 255)) {
5,684✔
301
   if(m_reneg_data.size() + 1 != extension_size) {
5,682✔
302
      throw Decoding_Error("Bad encoding for secure renegotiation extn");
1✔
303
   }
304
}
5,682✔
305

306
std::vector<uint8_t> Renegotiation_Extension::serialize(Connection_Side /*whoami*/) const {
5,262✔
307
   std::vector<uint8_t> buf;
5,262✔
308
   append_tls_length_value(buf, m_reneg_data, 1);
5,262✔
309
   return buf;
5,262✔
310
}
×
311

312
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
401✔
313
                                                                                 uint16_t extension_size,
314
                                                                                 Connection_Side from) {
401✔
315
   if(extension_size == 0) {
401✔
316
      return;  // empty extension
317
   }
318

319
   const uint16_t name_bytes = reader.get_uint16_t();
401✔
320

321
   size_t bytes_remaining = extension_size - 2;
401✔
322

323
   if(name_bytes != bytes_remaining) {
401✔
324
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
×
325
   }
326

327
   while(bytes_remaining > 0) {
1,070✔
328
      const std::string p = reader.get_string(1, 0, 255);
676✔
329

330
      if(bytes_remaining < p.size() + 1) {
676✔
331
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
332
      }
333

334
      if(p.empty()) {
676✔
335
         throw Decoding_Error("Empty ALPN protocol not allowed");
7✔
336
      }
337

338
      bytes_remaining -= (p.size() + 1);
669✔
339

340
      m_protocols.push_back(p);
669✔
341
   }
676✔
342

343
   // RFC 7301 3.1
344
   //    The "extension_data" field of the [...] extension is structured the
345
   //    same as described above for the client "extension_data", except that
346
   //    the "ProtocolNameList" MUST contain exactly one "ProtocolName".
347
   if(from == Connection_Side::Server && m_protocols.size() != 1) {
394✔
348
      throw TLS_Exception(
×
349
         Alert::DecodeError,
350
         "Server sent " + std::to_string(m_protocols.size()) + " protocols in ALPN extension response");
×
351
   }
352
}
7✔
353

354
std::string Application_Layer_Protocol_Notification::single_protocol() const {
145✔
355
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
145✔
356
   return m_protocols.front();
145✔
357
}
358

359
std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const {
359✔
360
   std::vector<uint8_t> buf(2);
359✔
361

362
   for(auto&& proto : m_protocols) {
943✔
363
      if(proto.length() >= 256) {
584✔
364
         throw TLS_Exception(Alert::InternalError, "ALPN name too long");
×
365
      }
366
      if(!proto.empty()) {
584✔
367
         append_tls_length_value(buf, proto, 1);
1,168✔
368
      }
369
   }
370

371
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
359✔
372
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
359✔
373

374
   return buf;
359✔
375
}
×
376

377
std::string certificate_type_to_string(Certificate_Type type) {
24✔
378
   switch(type) {
24✔
379
      case Certificate_Type::X509:
24✔
380
         return "X509";
24✔
381
      case Certificate_Type::RawPublicKey:
×
382
         return "RawPublicKey";
×
383
   }
384

385
   return "Unknown";
×
386
}
387

388
Certificate_Type certificate_type_from_string(const std::string& type_str) {
10✔
389
   if(type_str == "X509") {
10✔
390
      return Certificate_Type::X509;
391
   } else if(type_str == "RawPublicKey") {
4✔
392
      return Certificate_Type::RawPublicKey;
393
   } else {
394
      throw Decoding_Error("Unknown certificate type: " + type_str);
×
395
   }
396
}
397

398
Certificate_Type_Base::Certificate_Type_Base(std::vector<Certificate_Type> supported_cert_types) :
1,976✔
399
      m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
1,976✔
400
   BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
1,976✔
401
}
1,976✔
402

403
Client_Certificate_Type::Client_Certificate_Type(const Client_Certificate_Type& cct, const Policy& policy) :
1✔
404
      Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
1✔
405

406
Server_Certificate_Type::Server_Certificate_Type(const Server_Certificate_Type& sct, const Policy& policy) :
1✔
407
      Certificate_Type_Base(sct, policy.accepted_server_certificate_types()) {}
1✔
408

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

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

433
Certificate_Type_Base::Certificate_Type_Base(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) :
4✔
434
      m_from(from) {
4✔
435
   if(extension_size == 0) {
4✔
436
      throw Decoding_Error("Certificate type extension cannot be empty");
×
437
   }
438

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

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

476
void Certificate_Type_Base::validate_selection(const Certificate_Type_Base& from_server) const {
2✔
477
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Client);
2✔
478
   BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
2✔
479

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

491
Certificate_Type Certificate_Type_Base::selected_certificate_type() const {
6✔
492
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Server);
6✔
493
   BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
6✔
494
   return m_certificate_types.front();
6✔
495
}
496

497
Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) {}
4,044✔
498

499
const std::vector<Group_Params>& Supported_Groups::groups() const {
948✔
500
   return m_groups;
948✔
501
}
502

503
std::vector<Group_Params> Supported_Groups::ec_groups() const {
5,015✔
504
   std::vector<Group_Params> ec;
5,015✔
505
   for(auto g : m_groups) {
52,082✔
506
      if(g.is_pure_ecc_group()) {
94,134✔
507
         ec.push_back(g);
34,680✔
508
      }
509
   }
510
   return ec;
5,015✔
511
}
×
512

513
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,506✔
514
   std::vector<Group_Params> dh;
1,506✔
515
   for(auto g : m_groups) {
11,115✔
516
      if(g.is_in_ffdhe_range()) {
12,453✔
517
         dh.push_back(g);
552✔
518
      }
519
   }
520
   return dh;
1,506✔
521
}
×
522

523
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,721✔
524
   std::vector<uint8_t> buf(2);
4,721✔
525

526
   for(auto g : m_groups) {
54,917✔
527
      const uint16_t id = g.wire_code();
50,196✔
528

529
      if(id > 0) {
50,196✔
530
         buf.push_back(get_byte<0>(id));
50,196✔
531
         buf.push_back(get_byte<1>(id));
50,196✔
532
      }
533
   }
534

535
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,721✔
536
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,721✔
537

538
   return buf;
4,721✔
539
}
×
540

541
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
2,907✔
542
   const uint16_t len = reader.get_uint16_t();
2,907✔
543

544
   if(len + 2 != extension_size) {
2,907✔
545
      throw Decoding_Error("Inconsistent length field in supported groups list");
4✔
546
   }
547

548
   if(len % 2 == 1) {
2,903✔
549
      throw Decoding_Error("Supported groups list of strange size");
×
550
   }
551

552
   const size_t elems = len / 2;
2,903✔
553

554
   for(size_t i = 0; i != elems; ++i) {
23,894✔
555
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
20,991✔
556
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
557
      if(!value_exists(m_groups, group)) {
41,982✔
558
         m_groups.push_back(group);
20,991✔
559
      }
560
   }
561
}
2,907✔
562

563
std::vector<uint8_t> Supported_Point_Formats::serialize(Connection_Side /*whoami*/) const {
5,106✔
564
   // if this extension is sent, it MUST include uncompressed (RFC 4492, section 5.1)
565
   if(m_prefers_compressed) {
5,106✔
566
      return std::vector<uint8_t>{2, ANSIX962_COMPRESSED_PRIME, UNCOMPRESSED};
10✔
567
   } else {
568
      return std::vector<uint8_t>{1, UNCOMPRESSED};
5,096✔
569
   }
570
}
571

572
Supported_Point_Formats::Supported_Point_Formats(TLS_Data_Reader& reader, uint16_t extension_size) {
3,193✔
573
   uint8_t len = reader.get_byte();
3,193✔
574

575
   if(len + 1 != extension_size) {
3,193✔
576
      throw Decoding_Error("Inconsistent length field in supported point formats list");
2✔
577
   }
578

579
   bool includes_uncompressed = false;
3,196✔
580
   for(size_t i = 0; i != len; ++i) {
3,196✔
581
      uint8_t format = reader.get_byte();
3,195✔
582

583
      if(static_cast<ECPointFormat>(format) == UNCOMPRESSED) {
3,195✔
584
         m_prefers_compressed = false;
3,180✔
585
         reader.discard_next(len - i - 1);
3,180✔
586
         return;
3,180✔
587
      } else if(static_cast<ECPointFormat>(format) == ANSIX962_COMPRESSED_PRIME) {
15✔
588
         m_prefers_compressed = true;
10✔
589
         std::vector<uint8_t> remaining_formats = reader.get_fixed<uint8_t>(len - i - 1);
10✔
590
         includes_uncompressed =
10✔
591
            std::any_of(std::begin(remaining_formats), std::end(remaining_formats), [](uint8_t remaining_format) {
10✔
592
               return static_cast<ECPointFormat>(remaining_format) == UNCOMPRESSED;
593
            });
594
         break;
10✔
595
      }
10✔
596

597
      // ignore ANSIX962_COMPRESSED_CHAR2, we don't support these curves
598
   }
599

600
   // RFC 4492 5.1.:
601
   //   If the Supported Point Formats Extension is indeed sent, it MUST contain the value 0 (uncompressed)
602
   //   as one of the items in the list of point formats.
603
   // Note:
604
   //   RFC 8422 5.1.2. explicitly requires this check,
605
   //   but only if the Supported Groups extension was sent.
606
   if(!includes_uncompressed) {
11✔
607
      throw TLS_Exception(Alert::IllegalParameter,
1✔
608
                          "Supported Point Formats Extension must contain the uncompressed point format");
1✔
609
   }
610
}
611

612
namespace {
613

614
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
4,723✔
615
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
4,723✔
616

617
   std::vector<uint8_t> buf;
4,723✔
618

619
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,723✔
620

621
   buf.push_back(get_byte<0>(len));
4,723✔
622
   buf.push_back(get_byte<1>(len));
4,723✔
623

624
   for(Signature_Scheme scheme : schemes) {
46,267✔
625
      buf.push_back(get_byte<0>(scheme.wire_code()));
41,544✔
626
      buf.push_back(get_byte<1>(scheme.wire_code()));
41,544✔
627
   }
628

629
   return buf;
4,723✔
630
}
×
631

632
std::vector<Signature_Scheme> parse_signature_algorithms(TLS_Data_Reader& reader, uint16_t extension_size) {
2,932✔
633
   uint16_t len = reader.get_uint16_t();
2,932✔
634

635
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
2,931✔
636
      throw Decoding_Error("Bad encoding on signature algorithms extension");
1✔
637
   }
638

639
   std::vector<Signature_Scheme> schemes;
2,930✔
640
   schemes.reserve(len / 2);
2,930✔
641
   while(len > 0) {
30,738✔
642
      schemes.emplace_back(reader.get_uint16_t());
27,808✔
643
      len -= 2;
27,808✔
644
   }
645

646
   return schemes;
2,930✔
647
}
×
648

649
}  // namespace
650

651
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
4,721✔
652
   return serialize_signature_algorithms(m_schemes);
4,721✔
653
}
654

655
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
2,930✔
656
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2,930✔
657

658
std::vector<uint8_t> Signature_Algorithms_Cert::serialize(Connection_Side /*whoami*/) const {
2✔
659
   return serialize_signature_algorithms(m_schemes);
2✔
660
}
661

662
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
2✔
663
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2✔
664

665
Session_Ticket_Extension::Session_Ticket_Extension(TLS_Data_Reader& reader, uint16_t extension_size) :
4,976✔
666
      m_ticket(Session_Ticket(reader.get_elem<uint8_t, std::vector<uint8_t>>(extension_size))) {}
4,976✔
667

668
SRTP_Protection_Profiles::SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size) :
10✔
669
      m_pp(reader.get_range<uint16_t>(2, 0, 65535)) {
10✔
670
   const std::vector<uint8_t> mki = reader.get_range<uint8_t>(1, 0, 255);
9✔
671

672
   if(m_pp.size() * 2 + mki.size() + 3 != extension_size) {
9✔
673
      throw Decoding_Error("Bad encoding for SRTP protection extension");
×
674
   }
675

676
   if(!mki.empty()) {
9✔
677
      throw Decoding_Error("Unhandled non-empty MKI for SRTP protection extension");
×
678
   }
679
}
9✔
680

681
std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const {
5✔
682
   std::vector<uint8_t> buf;
5✔
683

684
   const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2);
5✔
685
   buf.push_back(get_byte<0>(pp_len));
5✔
686
   buf.push_back(get_byte<1>(pp_len));
5✔
687

688
   for(uint16_t pp : m_pp) {
12✔
689
      buf.push_back(get_byte<0>(pp));
7✔
690
      buf.push_back(get_byte<1>(pp));
7✔
691
   }
692

693
   buf.push_back(0);  // srtp_mki, always empty here
5✔
694

695
   return buf;
5✔
696
}
×
697

698
Extended_Master_Secret::Extended_Master_Secret(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
5,508✔
699
   if(extension_size != 0) {
5,508✔
700
      throw Decoding_Error("Invalid extended_master_secret extension");
2✔
701
   }
702
}
5,506✔
703

704
std::vector<uint8_t> Extended_Master_Secret::serialize(Connection_Side /*whoami*/) const {
5,236✔
705
   return std::vector<uint8_t>();
5,236✔
706
}
707

708
Encrypt_then_MAC::Encrypt_then_MAC(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
808✔
709
   if(extension_size != 0) {
808✔
710
      throw Decoding_Error("Invalid encrypt_then_mac extension");
×
711
   }
712
}
808✔
713

714
std::vector<uint8_t> Encrypt_then_MAC::serialize(Connection_Side /*whoami*/) const {
3,977✔
715
   return std::vector<uint8_t>();
3,977✔
716
}
717

718
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,479✔
719
   std::vector<uint8_t> buf;
4,479✔
720

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

729
      buf.push_back(len);
4,050✔
730

731
      for(Protocol_Version version : m_versions) {
9,218✔
732
         buf.push_back(version.major_version());
5,168✔
733
         buf.push_back(version.minor_version());
5,168✔
734
      }
735
   }
736

737
   return buf;
4,479✔
738
}
739

740
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,469✔
741
   if(offer.is_datagram_protocol()) {
3,469✔
742
#if defined(BOTAN_HAS_TLS_12)
743
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
400✔
744
         m_versions.push_back(Protocol_Version::DTLS_V12);
400✔
745
      }
746
#endif
747
   } else {
748
#if defined(BOTAN_HAS_TLS_13)
749
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,150✔
750
         m_versions.push_back(Protocol_Version::TLS_V13);
988✔
751
      }
752
#endif
753
#if defined(BOTAN_HAS_TLS_12)
754
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
4,057✔
755
         m_versions.push_back(Protocol_Version::TLS_V12);
3,040✔
756
      }
757
#endif
758
   }
759
}
3,469✔
760

761
Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
1,824✔
762
   if(from == Connection_Side::Server) {
1,824✔
763
      if(extension_size != 2) {
541✔
764
         throw Decoding_Error("Server sent invalid supported_versions extension");
×
765
      }
766
      m_versions.push_back(Protocol_Version(reader.get_uint16_t()));
541✔
767
   } else {
768
      auto versions = reader.get_range<uint16_t>(1, 1, 127);
1,283✔
769

770
      for(auto v : versions) {
4,555✔
771
         m_versions.push_back(Protocol_Version(v));
3,272✔
772
      }
773

774
      if(extension_size != 1 + 2 * versions.size()) {
1,283✔
775
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
776
      }
777
   }
1,283✔
778
}
1,824✔
779

780
bool Supported_Versions::supports(Protocol_Version version) const {
1,485✔
781
   for(auto v : m_versions) {
1,996✔
782
      if(version == v) {
1,977✔
783
         return true;
1,485✔
784
      }
785
   }
786
   return false;
787
}
788

789
Record_Size_Limit::Record_Size_Limit(const uint16_t limit) : m_limit(limit) {
16✔
790
   BOTAN_ASSERT(limit >= 64, "RFC 8449 does not allow record size limits smaller than 64 bytes");
16✔
791
   BOTAN_ASSERT(limit <= MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */,
16✔
792
                "RFC 8449 does not allow record size limits larger than 2^14+1");
793
}
16✔
794

795
Record_Size_Limit::Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
45✔
796
   if(extension_size != 2) {
45✔
797
      throw TLS_Exception(Alert::DecodeError, "invalid record_size_limit extension");
×
798
   }
799

800
   m_limit = reader.get_uint16_t();
45✔
801

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

820
   // RFC 8449 4.
821
   //    Endpoints MUST NOT send a "record_size_limit" extension with a value
822
   //    smaller than 64.  An endpoint MUST treat receipt of a smaller value
823
   //    as a fatal error and generate an "illegal_parameter" alert.
824
   if(m_limit < 64) {
45✔
825
      throw TLS_Exception(Alert::IllegalParameter, "Received a record size limit smaller than 64 bytes");
×
826
   }
827
}
45✔
828

829
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side /*whoami*/) const {
53✔
830
   std::vector<uint8_t> buf;
53✔
831

832
   buf.push_back(get_byte<0>(m_limit));
53✔
833
   buf.push_back(get_byte<1>(m_limit));
53✔
834

835
   return buf;
53✔
836
}
×
837

838
#if defined(BOTAN_HAS_TLS_13)
839
Cookie::Cookie(const std::vector<uint8_t>& cookie) : m_cookie(cookie) {}
4✔
840

841
Cookie::Cookie(TLS_Data_Reader& reader, uint16_t extension_size) {
12✔
842
   if(extension_size == 0) {
12✔
843
      return;
844
   }
845

846
   const uint16_t len = reader.get_uint16_t();
12✔
847

848
   if(len == 0) {
12✔
849
      // Based on RFC 8446 4.2.2, len of the Cookie buffer must be at least 1
850
      throw Decoding_Error("Cookie length must be at least 1 byte");
1✔
851
   }
852

853
   if(len > reader.remaining_bytes()) {
11✔
854
      throw Decoding_Error("Not enough bytes in the buffer to decode Cookie");
×
855
   }
856

857
   for(size_t i = 0; i < len; ++i) {
719✔
858
      m_cookie.push_back(reader.get_byte());
708✔
859
   }
860
}
1✔
861

862
std::vector<uint8_t> Cookie::serialize(Connection_Side /*whoami*/) const {
10✔
863
   std::vector<uint8_t> buf;
10✔
864

865
   const uint16_t len = static_cast<uint16_t>(m_cookie.size());
10✔
866

867
   buf.push_back(get_byte<0>(len));
10✔
868
   buf.push_back(get_byte<1>(len));
10✔
869

870
   for(const auto& cookie_byte : m_cookie) {
712✔
871
      buf.push_back(cookie_byte);
702✔
872
   }
873

874
   return buf;
10✔
875
}
×
876

877
std::vector<uint8_t> PSK_Key_Exchange_Modes::serialize(Connection_Side /*whoami*/) const {
1,184✔
878
   std::vector<uint8_t> buf;
1,184✔
879

880
   BOTAN_ASSERT_NOMSG(m_modes.size() < 256);
1,184✔
881
   buf.push_back(static_cast<uint8_t>(m_modes.size()));
1,184✔
882
   for(const auto& mode : m_modes) {
2,368✔
883
      buf.push_back(static_cast<uint8_t>(mode));
1,184✔
884
   }
885

886
   return buf;
1,184✔
887
}
×
888

889
PSK_Key_Exchange_Modes::PSK_Key_Exchange_Modes(TLS_Data_Reader& reader, uint16_t extension_size) {
1,072✔
890
   if(extension_size < 2) {
1,072✔
891
      throw Decoding_Error("Empty psk_key_exchange_modes extension is illegal");
×
892
   }
893

894
   const auto mode_count = reader.get_byte();
1,072✔
895
   for(uint16_t i = 0; i < mode_count; ++i) {
2,148✔
896
      const auto mode = static_cast<PSK_Key_Exchange_Mode>(reader.get_byte());
1,076✔
897
      if(mode == PSK_Key_Exchange_Mode::PSK_KE || mode == PSK_Key_Exchange_Mode::PSK_DHE_KE) {
1,076✔
898
         m_modes.push_back(mode);
1,070✔
899
      }
900
   }
901
}
1,072✔
902

903
std::vector<uint8_t> Certificate_Authorities::serialize(Connection_Side /*whoami*/) const {
81✔
904
   std::vector<uint8_t> out;
81✔
905
   std::vector<uint8_t> dn_list;
81✔
906

907
   for(const auto& dn : m_distinguished_names) {
162✔
908
      std::vector<uint8_t> encoded_dn;
81✔
909
      auto encoder = DER_Encoder(encoded_dn);
81✔
910
      dn.encode_into(encoder);
81✔
911
      append_tls_length_value(dn_list, encoded_dn, 2);
81✔
912
   }
162✔
913

914
   append_tls_length_value(out, dn_list, 2);
81✔
915

916
   return out;
81✔
917
}
81✔
918

919
Certificate_Authorities::Certificate_Authorities(TLS_Data_Reader& reader, uint16_t extension_size) {
3✔
920
   if(extension_size < 2) {
3✔
921
      throw Decoding_Error("Empty certificate_authorities extension is illegal");
×
922
   }
923

924
   const uint16_t purported_size = reader.get_uint16_t();
3✔
925

926
   if(reader.remaining_bytes() != purported_size) {
3✔
927
      throw Decoding_Error("Inconsistent length in certificate_authorities extension");
×
928
   }
929

930
   while(reader.has_remaining()) {
9✔
931
      std::vector<uint8_t> name_bits = reader.get_tls_length_value(2);
6✔
932

933
      BER_Decoder decoder(name_bits.data(), name_bits.size());
6✔
934
      m_distinguished_names.emplace_back();
6✔
935
      decoder.decode(m_distinguished_names.back());
6✔
936
   }
12✔
937
}
3✔
938

939
Certificate_Authorities::Certificate_Authorities(std::vector<X509_DN> acceptable_DNs) :
82✔
940
      m_distinguished_names(std::move(acceptable_DNs)) {}
82✔
941

942
std::vector<uint8_t> EarlyDataIndication::serialize(Connection_Side /*whoami*/) const {
8✔
943
   std::vector<uint8_t> result;
8✔
944
   if(m_max_early_data_size.has_value()) {
8✔
945
      const auto max_data = m_max_early_data_size.value();
2✔
946
      result.push_back(get_byte<0>(max_data));
2✔
947
      result.push_back(get_byte<1>(max_data));
2✔
948
      result.push_back(get_byte<2>(max_data));
2✔
949
      result.push_back(get_byte<3>(max_data));
2✔
950
   }
951
   return result;
8✔
952
}
×
953

954
EarlyDataIndication::EarlyDataIndication(TLS_Data_Reader& reader,
5✔
955
                                         uint16_t extension_size,
956
                                         Handshake_Type message_type) {
5✔
957
   if(message_type == Handshake_Type::NewSessionTicket) {
5✔
958
      if(extension_size != 4) {
1✔
959
         throw TLS_Exception(Alert::DecodeError,
×
960
                             "Received an early_data extension in a NewSessionTicket message "
961
                             "without maximum early data size indication");
×
962
      }
963

964
      m_max_early_data_size = reader.get_uint32_t();
1✔
965
   } else if(extension_size != 0) {
4✔
966
      throw TLS_Exception(Alert::DecodeError,
×
967
                          "Received an early_data extension containing an unexpected data "
968
                          "size indication");
×
969
   }
970
}
5✔
971

972
bool EarlyDataIndication::empty() const {
8✔
973
   // This extension may be empty by definition but still carry information
974
   return false;
8✔
975
}
976

977
#endif
978
}  // 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