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

randombit / botan / 23949924622

03 Apr 2026 02:35PM UTC coverage: 89.531% (+0.05%) from 89.479%
23949924622

Pull #5478

github

web-flow
Merge 543049103 into eaf12915e
Pull Request #5478: Add PKCS#12 KDF

105670 of 118026 relevant lines covered (89.53%)

11548366.4 hits per line

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

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

13
#include <botan/tls_extensions.h>
14

15
#include <botan/tls_exceptn.h>
16
#include <botan/tls_policy.h>
17
#include <botan/internal/fmt.h>
18
#include <botan/internal/parsing.h>
19
#include <botan/internal/stl_util.h>
20
#include <botan/internal/tls_reader.h>
21
#include <algorithm>
22

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

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

31
namespace Botan::TLS {
32

33
namespace {
34

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

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

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

52
      case Extension_Code::SignatureAlgorithms:
2,936✔
53
         return std::make_unique<Signature_Algorithms>(reader, size);
2,936✔
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:
411✔
62
         return std::make_unique<Application_Layer_Protocol_Notification>(reader, size, from);
411✔
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::RecordSizeLimit:
45✔
71
         return std::make_unique<Record_Size_Limit>(reader, size, from);
45✔
72

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

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

80
      case Extension_Code::SafeRenegotiation:
6,220✔
81
         return std::make_unique<Renegotiation_Extension>(reader, size);
6,220✔
82

83
      case Extension_Code::ExtendedMasterSecret:
6,024✔
84
         return std::make_unique<Extended_Master_Secret>(reader, size);
6,024✔
85

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

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

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

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

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

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

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

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

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

132
}  // namespace
133

134
Extensions::~Extensions() = default;
23,327✔
135

136
Extension* Extensions::get(Extension_Code type) const {
227,481✔
137
   const auto i =
227,481✔
138
      std::find_if(m_extensions.cbegin(), m_extensions.cend(), [type](const auto& ext) { return ext->type() == type; });
1,150,447✔
139

140
   return (i != m_extensions.end()) ? i->get() : nullptr;
227,481✔
141
}
142

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

149
   m_extensions.emplace_back(extn.release());
86,564✔
150
}
86,564✔
151

152
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
8,524✔
153
   if(reader.has_remaining()) {
8,524✔
154
      const uint16_t all_extn_size = reader.get_uint16_t();
8,518✔
155

156
      if(reader.remaining_bytes() != all_extn_size) {
8,517✔
157
         throw Decoding_Error("Bad extension size");
129✔
158
      }
159

160
      while(reader.has_remaining()) {
49,435✔
161
         const uint16_t extension_code = reader.get_uint16_t();
41,117✔
162
         const uint16_t extension_size = reader.get_uint16_t();
41,116✔
163

164
         const auto type = static_cast<Extension_Code>(extension_code);
41,115✔
165

166
         if(this->has(type)) {
41,115✔
167
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
19✔
168
         }
169

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

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

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

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

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

200
   return !diff.empty();
1,915✔
201
}
3,438✔
202

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

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

213
   return result;
522✔
214
}
215

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

219
   for(const auto& extn : m_extensions) {
59,064✔
220
      if(extn->empty()) {
52,522✔
221
         continue;
3,122✔
222
      }
223

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

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

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

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

234
      buf += extn_val;
49,400✔
235
   }
49,400✔
236

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

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

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

247
   return buf;
6,238✔
248
}
6,542✔
249

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

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

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

266
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
2,831✔
267
   /*
268
   RFC 6066 Section 3
269

270
      A server that receives a client hello containing the "server_name"
271
      extension MAY use the information contained in the extension to guide
272
      its selection of an appropriate certificate to return to the client,
273
      and/or other aspects of security policy.  In this event, the server
274
      SHALL include an extension of type "server_name" in the (extended)
275
      server hello.  The "extension_data" field of this extension SHALL be
276
      empty.
277
   */
278
   if(from == Connection_Side::Server) {
2,831✔
279
      if(extension_size != 0) {
36✔
280
         throw TLS_Exception(Alert::IllegalParameter, "Server sent non-empty SNI extension");
×
281
      }
282
   } else {
283
      // Clients are required to send at least one name in the SNI
284
      if(extension_size == 0) {
2,795✔
285
         throw TLS_Exception(Alert::IllegalParameter, "Client sent empty SNI extension");
×
286
      }
287

288
      const uint16_t name_bytes = reader.get_uint16_t();
2,795✔
289

290
      if(name_bytes + 2 != extension_size || name_bytes < 3) {
2,795✔
291
         throw Decoding_Error("Bad encoding of SNI extension");
×
292
      }
293

294
      BOTAN_ASSERT_NOMSG(reader.remaining_bytes() == name_bytes);
2,795✔
295

296
      while(reader.has_remaining()) {
5,590✔
297
         const uint8_t name_type = reader.get_byte();
2,795✔
298

299
         if(name_type == 0) {
2,795✔
300
            /*
301
            RFC 6066 Section 3
302
               The ServerNameList MUST NOT contain more than one name of the same name_type.
303
            */
304
            if(!m_sni_host_name.empty()) {
2,795✔
305
               throw Decoding_Error("TLS ServerNameIndicator contains more than one host_name");
×
306
            }
307
            m_sni_host_name = reader.get_string(2, 1, 65535);
2,795✔
308
         } else {
309
            /*
310
            Unknown name type - skip its length-prefixed value and continue
311

312
            RFC 6066 Section 3
313
               For backward compatibility, all future data structures associated
314
               with new NameTypes MUST begin with a 16-bit length field.
315
            */
316
            const uint16_t unknown_name_len = reader.get_uint16_t();
×
317
            reader.discard_next(unknown_name_len);
×
318
         }
319
      }
320
   }
321
}
2,831✔
322

323
std::vector<uint8_t> Server_Name_Indicator::serialize(Connection_Side whoami) const {
4,657✔
324
   // RFC 6066
325
   //    [...] the server SHALL include an extension of type "server_name" in
326
   //    the (extended) server hello. The "extension_data" field of this
327
   //    extension SHALL be empty.
328
   if(whoami == Connection_Side::Server) {
4,657✔
329
      return {};
366✔
330
   }
331

332
   std::vector<uint8_t> buf;
4,291✔
333

334
   const size_t name_len = m_sni_host_name.size();
4,291✔
335

336
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,291✔
337
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,291✔
338
   buf.push_back(0);  // DNS
4,291✔
339

340
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,291✔
341
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,291✔
342

343
   buf += as_span_of_bytes(m_sni_host_name);
4,291✔
344

345
   return buf;
4,291✔
346
}
4,291✔
347

348
bool Server_Name_Indicator::hostname_acceptable_for_sni(std::string_view hostname) {
3,685✔
349
   // Avoid sending an IPv4/IPv6 address in SNI as this is prohibited
350

351
   if(hostname.empty()) {
3,685✔
352
      return false;
353
   }
354

355
   if(string_to_ipv4(hostname).has_value()) {
3,638✔
356
      return false;
357
   }
358

359
   // IPv6? Anyway ':' is not valid in DNS
360
   if(hostname.find(':') != std::string_view::npos) {
3,638✔
361
      return false;
362
   }
363

364
   return true;
365
}
366

367
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
411✔
368
                                                                                 uint16_t extension_size,
369
                                                                                 Connection_Side from) {
411✔
370
   if(extension_size == 0) {
411✔
371
      return;  // empty extension
372
   }
373

374
   const uint16_t name_bytes = reader.get_uint16_t();
411✔
375

376
   size_t bytes_remaining = extension_size - 2;
411✔
377

378
   if(name_bytes != bytes_remaining) {
411✔
379
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
2✔
380
   }
381

382
   while(bytes_remaining > 0) {
1,090✔
383
      const std::string p = reader.get_string(1, 0, 255);
688✔
384

385
      if(bytes_remaining < p.size() + 1) {
688✔
386
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
387
      }
388

389
      if(p.empty()) {
688✔
390
         throw Decoding_Error("Empty ALPN protocol not allowed");
7✔
391
      }
392

393
      bytes_remaining -= (p.size() + 1);
681✔
394

395
      m_protocols.push_back(p);
681✔
396
   }
688✔
397

398
   // RFC 7301 3.1
399
   //    The "extension_data" field of the [...] extension is structured the
400
   //    same as described above for the client "extension_data", except that
401
   //    the "ProtocolNameList" MUST contain exactly one "ProtocolName".
402
   if(from == Connection_Side::Server && m_protocols.size() != 1) {
402✔
403
      throw TLS_Exception(
×
404
         Alert::DecodeError,
405
         "Server sent " + std::to_string(m_protocols.size()) + " protocols in ALPN extension response");
×
406
   }
407
}
9✔
408

409
std::string Application_Layer_Protocol_Notification::single_protocol() const {
149✔
410
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
149✔
411
   return m_protocols.front();
149✔
412
}
413

414
std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const {
367✔
415
   std::vector<uint8_t> buf(2);
367✔
416

417
   for(auto&& proto : m_protocols) {
963✔
418
      if(proto.length() >= 256) {
596✔
419
         throw TLS_Exception(Alert::InternalError, "ALPN name too long");
×
420
      }
421
      if(!proto.empty()) {
596✔
422
         append_tls_length_value(buf, proto, 1);
1,192✔
423
      }
424
   }
425

426
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
367✔
427
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
367✔
428

429
   return buf;
367✔
430
}
×
431

432
Certificate_Type_Base::Certificate_Type_Base(std::vector<Certificate_Type> supported_cert_types) :
1,976✔
433
      m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
1,976✔
434
   BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
1,976✔
435
}
1,976✔
436

437
Client_Certificate_Type::Client_Certificate_Type(const Client_Certificate_Type& cct, const Policy& policy) :
1✔
438
      Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
1✔
439

440
Server_Certificate_Type::Server_Certificate_Type(const Server_Certificate_Type& sct, const Policy& policy) :
1✔
441
      Certificate_Type_Base(sct, policy.accepted_server_certificate_types()) {}
1✔
442

443
Certificate_Type_Base::Certificate_Type_Base(const Certificate_Type_Base& certificate_type_from_client,
2✔
444
                                             const std::vector<Certificate_Type>& server_preference) :
2✔
445
      m_from(Connection_Side::Server) {
2✔
446
   // RFC 7250 4.2
447
   //    The server_certificate_type extension in the client hello indicates the
448
   //    types of certificates the client is able to process when provided by
449
   //    the server in a subsequent certificate payload. [...] With the
450
   //    server_certificate_type extension in the server hello, the TLS server
451
   //    indicates the certificate type carried in the Certificate payload.
452
   for(const auto server_supported_cert_type : server_preference) {
2✔
453
      if(value_exists(certificate_type_from_client.m_certificate_types, server_supported_cert_type)) {
4✔
454
         m_certificate_types.push_back(server_supported_cert_type);
2✔
455
         return;
2✔
456
      }
457
   }
458

459
   // RFC 7250 4.2 (2.)
460
   //    The server supports the extension defined in this document, but
461
   //    it does not have any certificate type in common with the client.
462
   //    Then, the server terminates the session with a fatal alert of
463
   //    type "unsupported_certificate".
464
   throw TLS_Exception(Alert::UnsupportedCertificate, "Failed to agree on certificate_type");
×
465
}
×
466

467
Certificate_Type_Base::Certificate_Type_Base(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) :
4✔
468
      m_from(from) {
4✔
469
   if(extension_size == 0) {
4✔
470
      throw Decoding_Error("Certificate type extension cannot be empty");
×
471
   }
472

473
   if(from == Connection_Side::Client) {
4✔
474
      const auto type_bytes = reader.get_tls_length_value(1);
2✔
475
      if(static_cast<size_t>(extension_size) != type_bytes.size() + 1) {
2✔
476
         throw Decoding_Error("certificate type extension had inconsistent length");
×
477
      }
478
      std::transform(
2✔
479
         type_bytes.begin(), type_bytes.end(), std::back_inserter(m_certificate_types), [](const auto type_byte) {
2✔
480
            return static_cast<Certificate_Type>(type_byte);
481
         });
482
   } else {
2✔
483
      // RFC 7250 4.2
484
      //    Note that only a single value is permitted in the
485
      //    server_certificate_type extension when carried in the server hello.
486
      if(extension_size != 1) {
2✔
487
         throw Decoding_Error("Server's certificate type extension must be of length 1");
×
488
      }
489
      const auto type_byte = reader.get_byte();
2✔
490
      m_certificate_types.push_back(static_cast<Certificate_Type>(type_byte));
2✔
491
   }
492
}
4✔
493

494
std::vector<uint8_t> Certificate_Type_Base::serialize(Connection_Side whoami) const {
12✔
495
   std::vector<uint8_t> result;
12✔
496
   if(whoami == Connection_Side::Client) {
12✔
497
      std::vector<uint8_t> type_bytes;
6✔
498
      std::transform(
6✔
499
         m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
500
            return static_cast<uint8_t>(type);
501
         });
502
      append_tls_length_value(result, type_bytes, 1);
12✔
503
   } else {
6✔
504
      BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
6✔
505
      result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
6✔
506
   }
507
   return result;
12✔
508
}
×
509

510
void Certificate_Type_Base::validate_selection(const Certificate_Type_Base& from_server) const {
2✔
511
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Client);
2✔
512
   BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
2✔
513

514
   // RFC 7250 4.2
515
   //    The value conveyed in the [client_]certificate_type extension MUST be
516
   //    selected from one of the values provided in the [client_]certificate_type
517
   //    extension sent in the client hello.
518
   if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
4✔
519
      throw TLS_Exception(Alert::IllegalParameter,
×
520
                          Botan::fmt("Selected certificate type was not offered: {}",
×
521
                                     certificate_type_to_string(from_server.selected_certificate_type())));
×
522
   }
523
}
2✔
524

525
Certificate_Type Certificate_Type_Base::selected_certificate_type() const {
6✔
526
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Server);
6✔
527
   BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
6✔
528
   return m_certificate_types.front();
6✔
529
}
530

531
Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) {}
4,048✔
532

533
const std::vector<Group_Params>& Supported_Groups::groups() const {
948✔
534
   return m_groups;
948✔
535
}
536

537
std::vector<Group_Params> Supported_Groups::ec_groups() const {
5,029✔
538
   std::vector<Group_Params> ec;
5,029✔
539
   for(auto g : m_groups) {
52,155✔
540
      if(g.is_pure_ecc_group()) {
94,252✔
541
         ec.push_back(g);
34,729✔
542
      }
543
   }
544
   return ec;
5,029✔
545
}
×
546

547
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,515✔
548
   std::vector<Group_Params> dh;
1,515✔
549
   for(auto g : m_groups) {
11,160✔
550
      if(g.is_in_ffdhe_range()) {
12,495✔
551
         dh.push_back(g);
558✔
552
      }
553
   }
554
   return dh;
1,515✔
555
}
×
556

557
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,725✔
558
   std::vector<uint8_t> buf(2);
4,725✔
559

560
   for(auto g : m_groups) {
54,934✔
561
      const uint16_t id = g.wire_code();
50,209✔
562

563
      if(id > 0) {
50,209✔
564
         buf.push_back(get_byte<0>(id));
50,209✔
565
         buf.push_back(get_byte<1>(id));
50,209✔
566
      }
567
   }
568

569
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,725✔
570
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,725✔
571

572
   return buf;
4,725✔
573
}
×
574

575
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
2,912✔
576
   const uint16_t len = reader.get_uint16_t();
2,912✔
577

578
   if(len + 2 != extension_size) {
2,912✔
579
      throw Decoding_Error("Inconsistent length field in supported groups list");
4✔
580
   }
581

582
   if(len % 2 == 1) {
2,908✔
583
      throw Decoding_Error("Supported groups list of strange size");
×
584
   }
585

586
   const size_t elems = len / 2;
2,908✔
587

588
   for(size_t i = 0; i != elems; ++i) {
23,924✔
589
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
21,016✔
590
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
591
      if(!value_exists(m_groups, group)) {
42,032✔
592
         m_groups.push_back(group);
21,016✔
593
      }
594
   }
595
}
2,912✔
596

597
namespace {
598

599
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
4,731✔
600
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
4,731✔
601

602
   std::vector<uint8_t> buf;
4,731✔
603

604
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,731✔
605

606
   buf.push_back(get_byte<0>(len));
4,731✔
607
   buf.push_back(get_byte<1>(len));
4,731✔
608

609
   for(const Signature_Scheme scheme : schemes) {
46,351✔
610
      buf.push_back(get_byte<0>(scheme.wire_code()));
41,620✔
611
      buf.push_back(get_byte<1>(scheme.wire_code()));
41,620✔
612
   }
613

614
   return buf;
4,731✔
615
}
×
616

617
std::vector<Signature_Scheme> parse_signature_algorithms(TLS_Data_Reader& reader, uint16_t extension_size) {
2,938✔
618
   uint16_t len = reader.get_uint16_t();
2,938✔
619

620
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
2,936✔
621
      throw Decoding_Error("Bad encoding on signature algorithms extension");
1✔
622
   }
623

624
   std::vector<Signature_Scheme> schemes;
2,935✔
625
   schemes.reserve(len / 2);
2,935✔
626
   while(len > 0) {
30,792✔
627
      schemes.emplace_back(reader.get_uint16_t());
27,857✔
628
      len -= 2;
27,857✔
629
   }
630

631
   return schemes;
2,935✔
632
}
×
633

634
}  // namespace
635

636
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
4,729✔
637
   return serialize_signature_algorithms(m_schemes);
4,729✔
638
}
639

640
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
2,936✔
641
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2,936✔
642

643
std::vector<uint8_t> Signature_Algorithms_Cert::serialize(Connection_Side /*whoami*/) const {
2✔
644
   return serialize_signature_algorithms(m_schemes);
2✔
645
}
646

647
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
2✔
648
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2✔
649

650
SRTP_Protection_Profiles::SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size) :
10✔
651
      m_pp(reader.get_range<uint16_t>(2, 0, 65535)) {
10✔
652
   const std::vector<uint8_t> mki = reader.get_range<uint8_t>(1, 0, 255);
9✔
653

654
   if(m_pp.size() * 2 + mki.size() + 3 != extension_size) {
9✔
655
      throw Decoding_Error("Bad encoding for SRTP protection extension");
×
656
   }
657

658
   if(!mki.empty()) {
9✔
659
      throw Decoding_Error("Unhandled non-empty MKI for SRTP protection extension");
×
660
   }
661
}
9✔
662

663
std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const {
5✔
664
   std::vector<uint8_t> buf;
5✔
665

666
   const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2);
5✔
667
   buf.push_back(get_byte<0>(pp_len));
5✔
668
   buf.push_back(get_byte<1>(pp_len));
5✔
669

670
   for(const uint16_t pp : m_pp) {
12✔
671
      buf.push_back(get_byte<0>(pp));
7✔
672
      buf.push_back(get_byte<1>(pp));
7✔
673
   }
674

675
   buf.push_back(0);  // srtp_mki, always empty here
5✔
676

677
   return buf;
5✔
678
}
×
679

680
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,485✔
681
   std::vector<uint8_t> buf;
4,485✔
682

683
   if(whoami == Connection_Side::Server) {
4,485✔
684
      BOTAN_ASSERT_NOMSG(m_versions.size() == 1);
429✔
685
      buf.push_back(m_versions[0].major_version());
429✔
686
      buf.push_back(m_versions[0].minor_version());
429✔
687
   } else {
688
      BOTAN_ASSERT_NOMSG(!m_versions.empty());
4,056✔
689
      const uint8_t len = static_cast<uint8_t>(m_versions.size() * 2);
4,056✔
690

691
      buf.push_back(len);
4,056✔
692

693
      for(const Protocol_Version version : m_versions) {
9,230✔
694
         buf.push_back(version.major_version());
5,174✔
695
         buf.push_back(version.minor_version());
5,174✔
696
      }
697
   }
698

699
   return buf;
4,485✔
700
}
×
701

702
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,474✔
703
   // RFC 8446 4.2.1
704
   //    The extension contains a list of supported versions in preference order,
705
   //    with the most preferred version first. Implementations [...] MUST send
706
   //    this extension in the ClientHello containing all versions of TLS which
707
   //    they are prepared to negotiate.
708
   //
709
   // We simply assume that we always want the newest available TLS version.
710
#if defined(BOTAN_HAS_TLS_13)
711
   if(!offer.is_datagram_protocol()) {
3,474✔
712
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,158✔
713
         m_versions.push_back(Protocol_Version::TLS_V13);
988✔
714
      }
715
   }
716
#endif
717

718
#if defined(BOTAN_HAS_TLS_12)
719
   if(offer.is_datagram_protocol()) {
3,474✔
720
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
401✔
721
         m_versions.push_back(Protocol_Version::DTLS_V12);
401✔
722
      }
723
   } else {
724
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
4,061✔
725
         m_versions.push_back(Protocol_Version::TLS_V12);
3,044✔
726
      }
727
   }
728
#endif
729

730
   // if no versions are supported, the input variables are not used
731
   BOTAN_UNUSED(offer, policy);
3,474✔
732
}
3,474✔
733

734
Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
1,831✔
735
   if(from == Connection_Side::Server) {
1,831✔
736
      if(extension_size != 2) {
542✔
737
         throw Decoding_Error("Server sent invalid supported_versions extension");
1✔
738
      }
739
      m_versions.push_back(Protocol_Version(reader.get_uint16_t()));
541✔
740
   } else {
741
      auto versions = reader.get_range<uint16_t>(1, 1, 127);
1,289✔
742

743
      for(auto v : versions) {
4,567✔
744
         m_versions.push_back(Protocol_Version(v));
3,278✔
745
      }
746

747
      if(extension_size != 1 + 2 * versions.size()) {
1,289✔
748
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
749
      }
750
   }
1,289✔
751
}
1,831✔
752

753
bool Supported_Versions::supports(Protocol_Version version) const {
1,486✔
754
   for(auto v : m_versions) {
1,997✔
755
      if(version == v) {
1,978✔
756
         return true;
1,486✔
757
      }
758
   }
759
   return false;
760
}
761

762
Record_Size_Limit::Record_Size_Limit(const uint16_t limit) : m_limit(limit) {
16✔
763
   BOTAN_ASSERT(limit >= 64, "RFC 8449 does not allow record size limits smaller than 64 bytes");
16✔
764
   BOTAN_ASSERT(limit <= MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */,
16✔
765
                "RFC 8449 does not allow record size limits larger than 2^14+1");
766
}
16✔
767

768
Record_Size_Limit::Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
45✔
769
   if(extension_size != 2) {
45✔
770
      throw TLS_Exception(Alert::DecodeError, "invalid record_size_limit extension");
×
771
   }
772

773
   m_limit = reader.get_uint16_t();
45✔
774

775
   // RFC 8449 4.
776
   //    This value is the length of the plaintext of a protected record.
777
   //    The value includes the content type and padding added in TLS 1.3 (that
778
   //    is, the complete length of TLSInnerPlaintext).
779
   //
780
   //    A server MUST NOT enforce this restriction; a client might advertise
781
   //    a higher limit that is enabled by an extension or version the server
782
   //    does not understand. A client MAY abort the handshake with an
783
   //    "illegal_parameter" alert.
784
   //
785
   // Note: We are currently supporting this extension in TLS 1.3 only, hence
786
   //       we check for the TLS 1.3 limit. The TLS 1.2 limit would not include
787
   //       the "content type byte" and hence be one byte less!
788
   if(m_limit > MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */ && from == Connection_Side::Server) {
45✔
789
      throw TLS_Exception(Alert::IllegalParameter,
×
790
                          "Server requested a record size limit larger than the protocol's maximum");
×
791
   }
792

793
   // RFC 8449 4.
794
   //    Endpoints MUST NOT send a "record_size_limit" extension with a value
795
   //    smaller than 64.  An endpoint MUST treat receipt of a smaller value
796
   //    as a fatal error and generate an "illegal_parameter" alert.
797
   if(m_limit < 64) {
45✔
798
      throw TLS_Exception(Alert::IllegalParameter, "Received a record size limit smaller than 64 bytes");
×
799
   }
800
}
45✔
801

802
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side /*whoami*/) const {
53✔
803
   std::vector<uint8_t> buf;
53✔
804

805
   buf.push_back(get_byte<0>(m_limit));
53✔
806
   buf.push_back(get_byte<1>(m_limit));
53✔
807

808
   return buf;
53✔
809
}
×
810

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