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

randombit / botan / 13219613273

08 Feb 2025 08:36PM UTC coverage: 91.657% (+0.003%) from 91.654%
13219613273

push

github

web-flow
Merge pull request #4650 from randombit/jack/header-minimization

Reorganize code and reduce header dependencies

94838 of 103471 relevant lines covered (91.66%)

11212567.02 hits per line

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

89.2
/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/stl_util.h>
20
#include <botan/internal/tls_reader.h>
21

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

25
namespace Botan::TLS {
26

27
namespace {
28

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

109
}  // namespace
110

111
Extension* Extensions::get(Extension_Code type) const {
214,289✔
112
   const auto i =
214,289✔
113
      std::find_if(m_extensions.cbegin(), m_extensions.cend(), [type](const auto& ext) { return ext->type() == type; });
1,107,001✔
114

115
   return (i != m_extensions.end()) ? i->get() : nullptr;
214,289✔
116
}
117

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

124
   m_extensions.emplace_back(extn.release());
84,655✔
125
}
84,655✔
126

127
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
7,957✔
128
   if(reader.has_remaining()) {
7,957✔
129
      const uint16_t all_extn_size = reader.get_uint16_t();
7,952✔
130

131
      if(reader.remaining_bytes() != all_extn_size) {
7,952✔
132
         throw Decoding_Error("Bad extension size");
119✔
133
      }
134

135
      while(reader.has_remaining()) {
47,120✔
136
         const uint16_t extension_code = reader.get_uint16_t();
39,342✔
137
         const uint16_t extension_size = reader.get_uint16_t();
39,341✔
138

139
         const auto type = static_cast<Extension_Code>(extension_code);
39,341✔
140

141
         if(this->has(type)) {
39,341✔
142
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
13✔
143
         }
144

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

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

159
   std::vector<Extension_Code> diff;
3,437✔
160
   std::set_difference(
3,437✔
161
      found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
162

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

171
      // ... if yes, `contains_other_than` is true
172
      return itr != diff.cend();
1,523✔
173
   }
174

175
   return !diff.empty();
1,914✔
176
}
3,437✔
177

178
std::unique_ptr<Extension> Extensions::take(Extension_Code type) {
506✔
179
   const auto i =
506✔
180
      std::find_if(m_extensions.begin(), m_extensions.end(), [type](const auto& ext) { return ext->type() == type; });
3,069✔
181

182
   std::unique_ptr<Extension> result;
506✔
183
   if(i != m_extensions.end()) {
506✔
184
      std::swap(result, *i);
244✔
185
      m_extensions.erase(i);
244✔
186
   }
187

188
   return result;
506✔
189
}
190

191
std::vector<uint8_t> Extensions::serialize(Connection_Side whoami) const {
6,524✔
192
   std::vector<uint8_t> buf(2);  // 2 bytes for length field
6,524✔
193

194
   for(const auto& extn : m_extensions) {
58,869✔
195
      if(extn->empty()) {
52,345✔
196
         continue;
3,116✔
197
      }
198

199
      const uint16_t extn_code = static_cast<uint16_t>(extn->type());
49,229✔
200

201
      const std::vector<uint8_t> extn_val = extn->serialize(whoami);
49,229✔
202

203
      buf.push_back(get_byte<0>(extn_code));
49,229✔
204
      buf.push_back(get_byte<1>(extn_code));
49,229✔
205

206
      buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
49,229✔
207
      buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
49,229✔
208

209
      buf += extn_val;
49,229✔
210
   }
49,229✔
211

212
   const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
6,524✔
213

214
   buf[0] = get_byte<0>(extn_size);
6,524✔
215
   buf[1] = get_byte<1>(extn_size);
6,524✔
216

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

222
   return buf;
6,220✔
223
}
6,524✔
224

225
std::set<Extension_Code> Extensions::extension_types() const {
8,080✔
226
   std::set<Extension_Code> offers;
8,080✔
227
   std::transform(
8,080✔
228
      m_extensions.cbegin(), m_extensions.cend(), std::inserter(offers, offers.begin()), [](const auto& ext) {
43,525✔
229
         return ext->type();
43,525✔
230
      });
231
   return offers;
8,080✔
232
}
×
233

234
Unknown_Extension::Unknown_Extension(Extension_Code type, TLS_Data_Reader& reader, uint16_t extension_size) :
2,692✔
235
      m_type(type), m_value(reader.get_fixed<uint8_t>(extension_size)) {}
2,692✔
236

237
std::vector<uint8_t> Unknown_Extension::serialize(Connection_Side /*whoami*/) const {
2✔
238
   return m_value;
2✔
239
}
240

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

249
   uint16_t name_bytes = reader.get_uint16_t();
2,784✔
250

251
   if(name_bytes + 2 != extension_size) {
2,784✔
252
      throw Decoding_Error("Bad encoding of SNI extension");
×
253
   }
254

255
   while(name_bytes) {
5,568✔
256
      uint8_t name_type = reader.get_byte();
2,784✔
257
      name_bytes--;
2,784✔
258

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

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

280
   std::vector<uint8_t> buf;
4,281✔
281

282
   size_t name_len = m_sni_host_name.size();
4,281✔
283

284
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,281✔
285
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,281✔
286
   buf.push_back(0);  // DNS
4,281✔
287

288
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,281✔
289
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,281✔
290

291
   buf += std::make_pair(cast_char_ptr_to_uint8(m_sni_host_name.data()), m_sni_host_name.size());
4,281✔
292

293
   return buf;
4,281✔
294
}
4,281✔
295

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

303
std::vector<uint8_t> Renegotiation_Extension::serialize(Connection_Side /*whoami*/) const {
5,252✔
304
   std::vector<uint8_t> buf;
5,252✔
305
   append_tls_length_value(buf, m_reneg_data, 1);
5,252✔
306
   return buf;
5,252✔
307
}
×
308

309
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
391✔
310
                                                                                 uint16_t extension_size,
311
                                                                                 Connection_Side from) {
391✔
312
   if(extension_size == 0) {
391✔
313
      return;  // empty extension
314
   }
315

316
   const uint16_t name_bytes = reader.get_uint16_t();
391✔
317

318
   size_t bytes_remaining = extension_size - 2;
391✔
319

320
   if(name_bytes != bytes_remaining) {
391✔
321
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
×
322
   }
323

324
   while(bytes_remaining) {
1,044✔
325
      const std::string p = reader.get_string(1, 0, 255);
660✔
326

327
      if(bytes_remaining < p.size() + 1) {
660✔
328
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
329
      }
330

331
      if(p.empty()) {
660✔
332
         throw Decoding_Error("Empty ALPN protocol not allowed");
7✔
333
      }
334

335
      bytes_remaining -= (p.size() + 1);
653✔
336

337
      m_protocols.push_back(p);
653✔
338
   }
660✔
339

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

351
std::string Application_Layer_Protocol_Notification::single_protocol() const {
141✔
352
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
141✔
353
   return m_protocols.front();
141✔
354
}
355

356
std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const {
349✔
357
   std::vector<uint8_t> buf(2);
349✔
358

359
   for(auto&& p : m_protocols) {
917✔
360
      if(p.length() >= 256) {
568✔
361
         throw TLS_Exception(Alert::InternalError, "ALPN name too long");
×
362
      }
363
      if(!p.empty()) {
568✔
364
         append_tls_length_value(buf, cast_char_ptr_to_uint8(p.data()), p.size(), 1);
568✔
365
      }
366
   }
367

368
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
349✔
369
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
349✔
370

371
   return buf;
349✔
372
}
×
373

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

382
   return "Unknown";
×
383
}
384

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

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

400
Client_Certificate_Type::Client_Certificate_Type(const Client_Certificate_Type& cct, const Policy& policy) :
1✔
401
      Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
1✔
402

403
Server_Certificate_Type::Server_Certificate_Type(const Server_Certificate_Type& sct, const Policy& policy) :
1✔
404
      Certificate_Type_Base(sct, policy.accepted_server_certificate_types()) {}
1✔
405

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

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

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

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

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

473
void Certificate_Type_Base::validate_selection(const Certificate_Type_Base& from_server) const {
2✔
474
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Client);
2✔
475
   BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
2✔
476

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

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

494
Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) {}
4,040✔
495

496
const std::vector<Group_Params>& Supported_Groups::groups() const {
948✔
497
   return m_groups;
948✔
498
}
499

500
std::vector<Group_Params> Supported_Groups::ec_groups() const {
5,006✔
501
   std::vector<Group_Params> ec;
5,006✔
502
   for(auto g : m_groups) {
50,162✔
503
      if(g.is_pure_ecc_group()) {
90,312✔
504
         ec.push_back(g);
34,600✔
505
      }
506
   }
507
   return ec;
5,006✔
508
}
×
509

510
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,498✔
511
   std::vector<Group_Params> dh;
1,498✔
512
   for(auto g : m_groups) {
10,964✔
513
      if(g.is_in_ffdhe_range()) {
12,255✔
514
         dh.push_back(g);
533✔
515
      }
516
   }
517
   return dh;
1,498✔
518
}
×
519

520
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,715✔
521
   std::vector<uint8_t> buf(2);
4,715✔
522

523
   for(auto g : m_groups) {
52,045✔
524
      const uint16_t id = g.wire_code();
47,330✔
525

526
      if(id > 0) {
47,330✔
527
         buf.push_back(get_byte<0>(id));
47,330✔
528
         buf.push_back(get_byte<1>(id));
47,330✔
529
      }
530
   }
531

532
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,715✔
533
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,715✔
534

535
   return buf;
4,715✔
536
}
×
537

538
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
2,901✔
539
   const uint16_t len = reader.get_uint16_t();
2,901✔
540

541
   if(len + 2 != extension_size) {
2,901✔
542
      throw Decoding_Error("Inconsistent length field in supported groups list");
4✔
543
   }
544

545
   if(len % 2 == 1) {
2,897✔
546
      throw Decoding_Error("Supported groups list of strange size");
×
547
   }
548

549
   const size_t elems = len / 2;
2,897✔
550

551
   for(size_t i = 0; i != elems; ++i) {
22,846✔
552
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
19,949✔
553
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
554
      if(!value_exists(m_groups, group)) {
39,898✔
555
         m_groups.push_back(group);
19,949✔
556
      }
557
   }
558
}
2,901✔
559

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

569
Supported_Point_Formats::Supported_Point_Formats(TLS_Data_Reader& reader, uint16_t extension_size) {
3,187✔
570
   uint8_t len = reader.get_byte();
3,187✔
571

572
   if(len + 1 != extension_size) {
3,187✔
573
      throw Decoding_Error("Inconsistent length field in supported point formats list");
2✔
574
   }
575

576
   bool includes_uncompressed = false;
3,190✔
577
   for(size_t i = 0; i != len; ++i) {
3,190✔
578
      uint8_t format = reader.get_byte();
3,189✔
579

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

594
      // ignore ANSIX962_COMPRESSED_CHAR2, we don't support these curves
595
   }
596

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

609
namespace {
610

611
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
4,716✔
612
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
4,716✔
613

614
   std::vector<uint8_t> buf;
4,716✔
615

616
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,716✔
617

618
   buf.push_back(get_byte<0>(len));
4,716✔
619
   buf.push_back(get_byte<1>(len));
4,716✔
620

621
   for(Signature_Scheme scheme : schemes) {
46,191✔
622
      buf.push_back(get_byte<0>(scheme.wire_code()));
41,475✔
623
      buf.push_back(get_byte<1>(scheme.wire_code()));
41,475✔
624
   }
625

626
   return buf;
4,716✔
627
}
×
628

629
std::vector<Signature_Scheme> parse_signature_algorithms(TLS_Data_Reader& reader, uint16_t extension_size) {
2,926✔
630
   uint16_t len = reader.get_uint16_t();
2,926✔
631

632
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
2,925✔
633
      throw Decoding_Error("Bad encoding on signature algorithms extension");
1✔
634
   }
635

636
   std::vector<Signature_Scheme> schemes;
2,924✔
637
   schemes.reserve(len / 2);
2,924✔
638
   while(len) {
30,672✔
639
      schemes.emplace_back(reader.get_uint16_t());
27,748✔
640
      len -= 2;
27,748✔
641
   }
642

643
   return schemes;
2,924✔
644
}
×
645

646
}  // namespace
647

648
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
4,714✔
649
   return serialize_signature_algorithms(m_schemes);
4,714✔
650
}
651

652
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
2,924✔
653
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2,924✔
654

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

659
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
2✔
660
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2✔
661

662
Session_Ticket_Extension::Session_Ticket_Extension(TLS_Data_Reader& reader, uint16_t extension_size) :
4,970✔
663
      m_ticket(Session_Ticket(reader.get_elem<uint8_t, std::vector<uint8_t>>(extension_size))) {}
4,970✔
664

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

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

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

678
std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const {
5✔
679
   std::vector<uint8_t> buf;
5✔
680

681
   const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2);
5✔
682
   buf.push_back(get_byte<0>(pp_len));
5✔
683
   buf.push_back(get_byte<1>(pp_len));
5✔
684

685
   for(uint16_t pp : m_pp) {
12✔
686
      buf.push_back(get_byte<0>(pp));
7✔
687
      buf.push_back(get_byte<1>(pp));
7✔
688
   }
689

690
   buf.push_back(0);  // srtp_mki, always empty here
5✔
691

692
   return buf;
5✔
693
}
×
694

695
Extended_Master_Secret::Extended_Master_Secret(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
5,498✔
696
   if(extension_size != 0) {
5,498✔
697
      throw Decoding_Error("Invalid extended_master_secret extension");
2✔
698
   }
699
}
5,496✔
700

701
std::vector<uint8_t> Extended_Master_Secret::serialize(Connection_Side /*whoami*/) const {
5,226✔
702
   return std::vector<uint8_t>();
5,226✔
703
}
704

705
Encrypt_then_MAC::Encrypt_then_MAC(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
804✔
706
   if(extension_size != 0) {
804✔
707
      throw Decoding_Error("Invalid encrypt_then_mac extension");
×
708
   }
709
}
804✔
710

711
std::vector<uint8_t> Encrypt_then_MAC::serialize(Connection_Side /*whoami*/) const {
3,973✔
712
   return std::vector<uint8_t>();
3,973✔
713
}
714

715
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,473✔
716
   std::vector<uint8_t> buf;
4,473✔
717

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

726
      buf.push_back(len);
4,044✔
727

728
      for(Protocol_Version version : m_versions) {
9,206✔
729
         buf.push_back(version.major_version());
5,162✔
730
         buf.push_back(version.minor_version());
5,162✔
731
      }
732
   }
733

734
   return buf;
4,473✔
735
}
×
736

737
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,465✔
738
   if(offer.is_datagram_protocol()) {
3,465✔
739
#if defined(BOTAN_HAS_TLS_12)
740
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
398✔
741
         m_versions.push_back(Protocol_Version::DTLS_V12);
398✔
742
      }
743
#endif
744
   } else {
745
#if defined(BOTAN_HAS_TLS_13)
746
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,146✔
747
         m_versions.push_back(Protocol_Version::TLS_V13);
988✔
748
      }
749
#endif
750
#if defined(BOTAN_HAS_TLS_12)
751
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
4,055✔
752
         m_versions.push_back(Protocol_Version::TLS_V12);
3,038✔
753
      }
754
#endif
755
   }
756
}
3,465✔
757

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

767
      for(auto v : versions) {
4,543✔
768
         m_versions.push_back(Protocol_Version(v));
3,266✔
769
      }
770

771
      if(extension_size != 1 + 2 * versions.size()) {
1,277✔
772
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
773
      }
774
   }
1,277✔
775
}
1,818✔
776

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

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

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

797
   m_limit = reader.get_uint16_t();
45✔
798

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

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

826
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side) const {
53✔
827
   std::vector<uint8_t> buf;
53✔
828

829
   buf.push_back(get_byte<0>(m_limit));
53✔
830
   buf.push_back(get_byte<1>(m_limit));
53✔
831

832
   return buf;
53✔
833
}
×
834

835
#if defined(BOTAN_HAS_TLS_13)
836
Cookie::Cookie(const std::vector<uint8_t>& cookie) : m_cookie(cookie) {}
4✔
837

838
Cookie::Cookie(TLS_Data_Reader& reader, uint16_t extension_size) {
12✔
839
   if(extension_size == 0) {
12✔
840
      return;
841
   }
842

843
   const uint16_t len = reader.get_uint16_t();
12✔
844

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

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

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

859
std::vector<uint8_t> Cookie::serialize(Connection_Side /*whoami*/) const {
10✔
860
   std::vector<uint8_t> buf;
10✔
861

862
   const uint16_t len = static_cast<uint16_t>(m_cookie.size());
10✔
863

864
   buf.push_back(get_byte<0>(len));
10✔
865
   buf.push_back(get_byte<1>(len));
10✔
866

867
   for(const auto& cookie_byte : m_cookie) {
712✔
868
      buf.push_back(cookie_byte);
702✔
869
   }
870

871
   return buf;
10✔
872
}
×
873

874
std::vector<uint8_t> PSK_Key_Exchange_Modes::serialize(Connection_Side) const {
1,184✔
875
   std::vector<uint8_t> buf;
1,184✔
876

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

883
   return buf;
1,184✔
884
}
×
885

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

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

900
std::vector<uint8_t> Certificate_Authorities::serialize(Connection_Side) const {
81✔
901
   std::vector<uint8_t> out;
81✔
902
   std::vector<uint8_t> dn_list;
81✔
903

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

911
   append_tls_length_value(out, dn_list, 2);
81✔
912

913
   return out;
81✔
914
}
81✔
915

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

921
   const uint16_t purported_size = reader.get_uint16_t();
3✔
922

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

927
   while(reader.has_remaining()) {
9✔
928
      std::vector<uint8_t> name_bits = reader.get_tls_length_value(2);
6✔
929

930
      BER_Decoder decoder(name_bits.data(), name_bits.size());
6✔
931
      m_distinguished_names.emplace_back();
6✔
932
      decoder.decode(m_distinguished_names.back());
6✔
933
   }
12✔
934
}
3✔
935

936
Certificate_Authorities::Certificate_Authorities(std::vector<X509_DN> acceptable_DNs) :
82✔
937
      m_distinguished_names(std::move(acceptable_DNs)) {}
82✔
938

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

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

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

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

974
#endif
975
}  // 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