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

randombit / botan / 11087146043

28 Sep 2024 09:28PM UTC coverage: 92.003% (+0.7%) from 91.274%
11087146043

push

github

web-flow
Create terraform.yml

82959 of 90170 relevant lines covered (92.0%)

9376319.11 hits per line

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

86.47
/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 <iterator>
23

24
namespace Botan::TLS {
25

26
namespace {
27

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

94
      case Extension_Code::PskKeyExchangeModes:
950✔
95
         return std::make_unique<PSK_Key_Exchange_Modes>(reader, size);
950✔
96

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

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

105
   return std::make_unique<Unknown_Extension>(static_cast<Extension_Code>(code), reader, size);
4,536✔
106
}
107

108
}  // namespace
109

110
void Extensions::add(std::unique_ptr<Extension> extn) {
83,686✔
111
   if(has(extn->type())) {
83,686✔
112
      throw Invalid_Argument("cannot add the same extension twice: " +
×
113
                             std::to_string(static_cast<uint16_t>(extn->type())));
×
114
   }
115

116
   m_extensions.emplace_back(extn.release());
83,686✔
117
}
83,686✔
118

119
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
7,690✔
120
   if(reader.has_remaining()) {
7,690✔
121
      const uint16_t all_extn_size = reader.get_uint16_t();
7,685✔
122

123
      if(reader.remaining_bytes() != all_extn_size) {
7,685✔
124
         throw Decoding_Error("Bad extension size");
119✔
125
      }
126

127
      while(reader.has_remaining()) {
46,902✔
128
         const uint16_t extension_code = reader.get_uint16_t();
39,391✔
129
         const uint16_t extension_size = reader.get_uint16_t();
39,390✔
130

131
         const auto type = static_cast<Extension_Code>(extension_code);
39,390✔
132

133
         if(this->has(type)) {
39,390✔
134
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
13✔
135
         }
136

137
         // TODO offer a function on reader that returns a byte range as a reference
138
         // to avoid this copy of the extension data
139
         const std::vector<uint8_t> extn_data = reader.get_fixed<uint8_t>(extension_size);
39,377✔
140
         TLS_Data_Reader extn_reader("Extension", extn_data);
39,369✔
141
         this->add(make_extension(extn_reader, type, from, message_type));
39,369✔
142
         extn_reader.assert_done();
39,336✔
143
      }
39,336✔
144
   }
145
}
7,516✔
146

147
bool Extensions::contains_other_than(const std::set<Extension_Code>& allowed_extensions,
3,396✔
148
                                     const bool allow_unknown_extensions) const {
149
   const auto found = extension_types();
3,396✔
150

151
   std::vector<Extension_Code> diff;
3,396✔
152
   std::set_difference(
3,396✔
153
      found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
154

155
   if(allow_unknown_extensions) {
3,396✔
156
      // Go through the found unexpected extensions whether any of those
157
      // is known to this TLS implementation.
158
      const auto itr = std::find_if(diff.cbegin(), diff.cend(), [this](const auto ext_type) {
1,515✔
159
         const auto ext = get(ext_type);
10✔
160
         return ext && ext->is_implemented();
10✔
161
      });
162

163
      // ... if yes, `contains_other_than` is true
164
      return itr != diff.cend();
1,515✔
165
   }
166

167
   return !diff.empty();
1,881✔
168
}
3,396✔
169

170
std::unique_ptr<Extension> Extensions::take(Extension_Code type) {
497✔
171
   const auto i =
497✔
172
      std::find_if(m_extensions.begin(), m_extensions.end(), [type](const auto& ext) { return ext->type() == type; });
3,050✔
173

174
   std::unique_ptr<Extension> result;
497✔
175
   if(i != m_extensions.end()) {
497✔
176
      std::swap(result, *i);
242✔
177
      m_extensions.erase(i);
242✔
178
   }
179

180
   return result;
497✔
181
}
182

183
std::vector<uint8_t> Extensions::serialize(Connection_Side whoami) const {
6,331✔
184
   std::vector<uint8_t> buf(2);  // 2 bytes for length field
6,331✔
185

186
   for(const auto& extn : m_extensions) {
57,088✔
187
      if(extn->empty()) {
50,757✔
188
         continue;
2,960✔
189
      }
190

191
      const uint16_t extn_code = static_cast<uint16_t>(extn->type());
47,797✔
192

193
      const std::vector<uint8_t> extn_val = extn->serialize(whoami);
47,797✔
194

195
      buf.push_back(get_byte<0>(extn_code));
47,797✔
196
      buf.push_back(get_byte<1>(extn_code));
47,797✔
197

198
      buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
47,797✔
199
      buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
47,797✔
200

201
      buf += extn_val;
47,797✔
202
   }
47,797✔
203

204
   const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
6,331✔
205

206
   buf[0] = get_byte<0>(extn_size);
6,331✔
207
   buf[1] = get_byte<1>(extn_size);
6,331✔
208

209
   // avoid sending a completely empty extensions block
210
   if(buf.size() == 2) {
6,331✔
211
      return std::vector<uint8_t>();
294✔
212
   }
213

214
   return buf;
6,331✔
215
}
6,331✔
216

217
std::set<Extension_Code> Extensions::extension_types() const {
7,808✔
218
   std::set<Extension_Code> offers;
7,808✔
219
   std::transform(
7,808✔
220
      m_extensions.cbegin(), m_extensions.cend(), std::inserter(offers, offers.begin()), [](const auto& ext) {
42,215✔
221
         return ext->type();
42,215✔
222
      });
223
   return offers;
7,808✔
224
}
×
225

226
Unknown_Extension::Unknown_Extension(Extension_Code type, TLS_Data_Reader& reader, uint16_t extension_size) :
4,536✔
227
      m_type(type), m_value(reader.get_fixed<uint8_t>(extension_size)) {}
4,536✔
228

229
std::vector<uint8_t> Unknown_Extension::serialize(Connection_Side /*whoami*/) const {
2✔
230
   return m_value;
2✔
231
}
232

233
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, uint16_t extension_size) {
2,684✔
234
   /*
235
   * This is used by the server to confirm that it knew the name
236
   */
237
   if(extension_size == 0) {
2,684✔
238
      return;
239
   }
240

241
   uint16_t name_bytes = reader.get_uint16_t();
2,649✔
242

243
   if(name_bytes + 2 != extension_size) {
2,649✔
244
      throw Decoding_Error("Bad encoding of SNI extension");
×
245
   }
246

247
   while(name_bytes) {
5,298✔
248
      uint8_t name_type = reader.get_byte();
2,649✔
249
      name_bytes--;
2,649✔
250

251
      if(name_type == 0)  // DNS
2,649✔
252
      {
253
         m_sni_host_name = reader.get_string(2, 1, 65535);
2,649✔
254
         name_bytes -= static_cast<uint16_t>(2 + m_sni_host_name.size());
2,649✔
255
      } else  // some other unknown name type
256
      {
257
         reader.discard_next(name_bytes);
×
258
         name_bytes = 0;
×
259
      }
260
   }
261
}
×
262

263
std::vector<uint8_t> Server_Name_Indicator::serialize(Connection_Side whoami) const {
4,536✔
264
   // RFC 6066
265
   //    [...] the server SHALL include an extension of type "server_name" in
266
   //    the (extended) server hello. The "extension_data" field of this
267
   //    extension SHALL be empty.
268
   if(whoami == Connection_Side::Server) {
4,536✔
269
      return {};
364✔
270
   }
271

272
   std::vector<uint8_t> buf;
4,172✔
273

274
   size_t name_len = m_sni_host_name.size();
4,172✔
275

276
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,172✔
277
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,172✔
278
   buf.push_back(0);  // DNS
4,172✔
279

280
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,172✔
281
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,172✔
282

283
   buf += std::make_pair(cast_char_ptr_to_uint8(m_sni_host_name.data()), m_sni_host_name.size());
4,172✔
284

285
   return buf;
4,172✔
286
}
4,536✔
287

288
Renegotiation_Extension::Renegotiation_Extension(TLS_Data_Reader& reader, uint16_t extension_size) :
5,446✔
289
      m_reneg_data(reader.get_range<uint8_t>(1, 0, 255)) {
5,446✔
290
   if(m_reneg_data.size() + 1 != extension_size) {
5,444✔
291
      throw Decoding_Error("Bad encoding for secure renegotiation extn");
1✔
292
   }
293
}
5,444✔
294

295
std::vector<uint8_t> Renegotiation_Extension::serialize(Connection_Side /*whoami*/) const {
5,096✔
296
   std::vector<uint8_t> buf;
5,096✔
297
   append_tls_length_value(buf, m_reneg_data, 1);
5,096✔
298
   return buf;
5,096✔
299
}
×
300

301
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
391✔
302
                                                                                 uint16_t extension_size,
303
                                                                                 Connection_Side from) {
391✔
304
   if(extension_size == 0) {
391✔
305
      return;  // empty extension
306
   }
307

308
   const uint16_t name_bytes = reader.get_uint16_t();
391✔
309

310
   size_t bytes_remaining = extension_size - 2;
391✔
311

312
   if(name_bytes != bytes_remaining) {
391✔
313
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
×
314
   }
315

316
   while(bytes_remaining) {
1,044✔
317
      const std::string p = reader.get_string(1, 0, 255);
660✔
318

319
      if(bytes_remaining < p.size() + 1) {
660✔
320
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
321
      }
322

323
      if(p.empty()) {
660✔
324
         throw Decoding_Error("Empty ALPN protocol not allowed");
7✔
325
      }
326

327
      bytes_remaining -= (p.size() + 1);
653✔
328

329
      m_protocols.push_back(p);
653✔
330
   }
660✔
331

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

343
std::string Application_Layer_Protocol_Notification::single_protocol() const {
141✔
344
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
141✔
345
   return m_protocols.front();
141✔
346
}
347

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

351
   for(auto&& p : m_protocols) {
917✔
352
      if(p.length() >= 256) {
568✔
353
         throw TLS_Exception(Alert::InternalError, "ALPN name too long");
×
354
      }
355
      if(!p.empty()) {
568✔
356
         append_tls_length_value(buf, cast_char_ptr_to_uint8(p.data()), p.size(), 1);
568✔
357
      }
358
   }
359

360
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
349✔
361
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
349✔
362

363
   return buf;
349✔
364
}
×
365

366
std::string certificate_type_to_string(Certificate_Type type) {
24✔
367
   switch(type) {
24✔
368
      case Certificate_Type::X509:
24✔
369
         return "X509";
24✔
370
      case Certificate_Type::RawPublicKey:
×
371
         return "RawPublicKey";
×
372
   }
373

374
   return "Unknown";
×
375
}
376

377
Certificate_Type certificate_type_from_string(const std::string& type_str) {
4✔
378
   if(type_str == "X509") {
4✔
379
      return Certificate_Type::X509;
380
   } else if(type_str == "RawPublicKey") {
4✔
381
      return Certificate_Type::RawPublicKey;
382
   } else {
383
      throw Decoding_Error("Unknown certificate type: " + type_str);
×
384
   }
385
}
386

387
Certificate_Type_Base::Certificate_Type_Base(std::vector<Certificate_Type> supported_cert_types) :
1,934✔
388
      m_certificate_types(std::move(supported_cert_types)), m_from(Connection_Side::Client) {
1,934✔
389
   BOTAN_ARG_CHECK(!m_certificate_types.empty(), "at least one certificate type must be supported");
1,934✔
390
}
1,934✔
391

392
Client_Certificate_Type::Client_Certificate_Type(const Client_Certificate_Type& cct, const Policy& policy) :
1✔
393
      Certificate_Type_Base(cct, policy.accepted_client_certificate_types()) {}
2✔
394

395
Server_Certificate_Type::Server_Certificate_Type(const Server_Certificate_Type& sct, const Policy& policy) :
1✔
396
      Certificate_Type_Base(sct, policy.accepted_server_certificate_types()) {}
2✔
397

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

414
   // RFC 7250 4.2 (2.)
415
   //    The server supports the extension defined in this document, but
416
   //    it does not have any certificate type in common with the client.
417
   //    Then, the server terminates the session with a fatal alert of
418
   //    type "unsupported_certificate".
419
   throw TLS_Exception(Alert::UnsupportedCertificate, "Failed to agree on certificate_type");
×
420
}
×
421

422
Certificate_Type_Base::Certificate_Type_Base(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) :
4✔
423
      m_from(from) {
4✔
424
   if(extension_size == 0) {
4✔
425
      throw Decoding_Error("Certificate type extension cannot be empty");
×
426
   }
427

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

449
std::vector<uint8_t> Certificate_Type_Base::serialize(Connection_Side whoami) const {
12✔
450
   std::vector<uint8_t> result;
12✔
451
   if(whoami == Connection_Side::Client) {
12✔
452
      std::vector<uint8_t> type_bytes;
6✔
453
      std::transform(
6✔
454
         m_certificate_types.begin(), m_certificate_types.end(), std::back_inserter(type_bytes), [](const auto type) {
455
            return static_cast<uint8_t>(type);
456
         });
457
      append_tls_length_value(result, type_bytes, 1);
12✔
458
   } else {
6✔
459
      BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
6✔
460
      result.push_back(static_cast<uint8_t>(m_certificate_types.front()));
6✔
461
   }
462
   return result;
12✔
463
}
×
464

465
void Certificate_Type_Base::validate_selection(const Certificate_Type_Base& from_server) const {
2✔
466
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Client);
2✔
467
   BOTAN_ASSERT_NOMSG(from_server.m_from == Connection_Side::Server);
2✔
468

469
   // RFC 7250 4.2
470
   //    The value conveyed in the [client_]certificate_type extension MUST be
471
   //    selected from one of the values provided in the [client_]certificate_type
472
   //    extension sent in the client hello.
473
   if(!value_exists(m_certificate_types, from_server.selected_certificate_type())) {
4✔
474
      throw TLS_Exception(Alert::IllegalParameter,
×
475
                          Botan::fmt("Selected certificate type was not offered: {}",
×
476
                                     certificate_type_to_string(from_server.selected_certificate_type())));
×
477
   }
478
}
2✔
479

480
Certificate_Type Certificate_Type_Base::selected_certificate_type() const {
6✔
481
   BOTAN_ASSERT_NOMSG(m_from == Connection_Side::Server);
6✔
482
   BOTAN_ASSERT_NOMSG(m_certificate_types.size() == 1);
6✔
483
   return m_certificate_types.front();
6✔
484
}
485

486
Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) {}
3,978✔
487

488
const std::vector<Group_Params>& Supported_Groups::groups() const {
904✔
489
   return m_groups;
904✔
490
}
491

492
std::vector<Group_Params> Supported_Groups::ec_groups() const {
4,847✔
493
   std::vector<Group_Params> ec;
4,847✔
494
   for(auto g : m_groups) {
58,601✔
495
      if(g.is_pure_ecc_group()) {
107,508✔
496
         ec.push_back(g);
34,033✔
497
      }
498
   }
499
   return ec;
4,847✔
500
}
×
501

502
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,387✔
503
   std::vector<Group_Params> dh;
1,387✔
504
   for(auto g : m_groups) {
10,136✔
505
      if(g.is_in_ffdhe_range()) {
11,121✔
506
         dh.push_back(g);
1,304✔
507
      }
508
   }
509
   return dh;
1,387✔
510
}
×
511

512
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,595✔
513
   std::vector<uint8_t> buf(2);
4,595✔
514

515
   for(auto g : m_groups) {
62,952✔
516
      const uint16_t id = g.wire_code();
58,357✔
517

518
      if(id > 0) {
58,357✔
519
         buf.push_back(get_byte<0>(id));
58,357✔
520
         buf.push_back(get_byte<1>(id));
58,357✔
521
      }
522
   }
523

524
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,595✔
525
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,595✔
526

527
   return buf;
4,595✔
528
}
×
529

530
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
2,757✔
531
   const uint16_t len = reader.get_uint16_t();
2,757✔
532

533
   if(len + 2 != extension_size) {
2,757✔
534
      throw Decoding_Error("Inconsistent length field in supported groups list");
4✔
535
   }
536

537
   if(len % 2 == 1) {
2,753✔
538
      throw Decoding_Error("Supported groups list of strange size");
×
539
   }
540

541
   const size_t elems = len / 2;
2,753✔
542

543
   for(size_t i = 0; i != elems; ++i) {
21,693✔
544
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
18,940✔
545
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
546
      if(!value_exists(m_groups, group)) {
37,880✔
547
         m_groups.push_back(group);
18,940✔
548
      }
549
   }
550
}
2,757✔
551

552
std::vector<uint8_t> Supported_Point_Formats::serialize(Connection_Side /*whoami*/) const {
4,943✔
553
   // if this extension is sent, it MUST include uncompressed (RFC 4492, section 5.1)
554
   if(m_prefers_compressed) {
4,943✔
555
      return std::vector<uint8_t>{2, ANSIX962_COMPRESSED_PRIME, UNCOMPRESSED};
10✔
556
   } else {
557
      return std::vector<uint8_t>{1, UNCOMPRESSED};
4,933✔
558
   }
559
}
560

561
Supported_Point_Formats::Supported_Point_Formats(TLS_Data_Reader& reader, uint16_t extension_size) {
3,054✔
562
   uint8_t len = reader.get_byte();
3,054✔
563

564
   if(len + 1 != extension_size) {
3,054✔
565
      throw Decoding_Error("Inconsistent length field in supported point formats list");
2✔
566
   }
567

568
   bool includes_uncompressed = false;
3,057✔
569
   for(size_t i = 0; i != len; ++i) {
3,057✔
570
      uint8_t format = reader.get_byte();
3,056✔
571

572
      if(static_cast<ECPointFormat>(format) == UNCOMPRESSED) {
3,056✔
573
         m_prefers_compressed = false;
3,041✔
574
         reader.discard_next(len - i - 1);
3,041✔
575
         return;
3,041✔
576
      } else if(static_cast<ECPointFormat>(format) == ANSIX962_COMPRESSED_PRIME) {
15✔
577
         m_prefers_compressed = true;
10✔
578
         std::vector<uint8_t> remaining_formats = reader.get_fixed<uint8_t>(len - i - 1);
10✔
579
         includes_uncompressed =
10✔
580
            std::any_of(std::begin(remaining_formats), std::end(remaining_formats), [](uint8_t remaining_format) {
10✔
581
               return static_cast<ECPointFormat>(remaining_format) == UNCOMPRESSED;
582
            });
583
         break;
10✔
584
      }
10✔
585

586
      // ignore ANSIX962_COMPRESSED_CHAR2, we don't support these curves
587
   }
588

589
   // RFC 4492 5.1.:
590
   //   If the Supported Point Formats Extension is indeed sent, it MUST contain the value 0 (uncompressed)
591
   //   as one of the items in the list of point formats.
592
   // Note:
593
   //   RFC 8422 5.1.2. explicitly requires this check,
594
   //   but only if the Supported Groups extension was sent.
595
   if(!includes_uncompressed) {
11✔
596
      throw TLS_Exception(Alert::IllegalParameter,
1✔
597
                          "Supported Point Formats Extension must contain the uncompressed point format");
2✔
598
   }
599
}
600

601
namespace {
602

603
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
4,561✔
604
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
4,561✔
605

606
   std::vector<uint8_t> buf;
4,561✔
607

608
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,561✔
609

610
   buf.push_back(get_byte<0>(len));
4,561✔
611
   buf.push_back(get_byte<1>(len));
4,561✔
612

613
   for(Signature_Scheme scheme : schemes) {
44,733✔
614
      buf.push_back(get_byte<0>(scheme.wire_code()));
40,172✔
615
      buf.push_back(get_byte<1>(scheme.wire_code()));
40,172✔
616
   }
617

618
   return buf;
4,561✔
619
}
×
620

621
std::vector<Signature_Scheme> parse_signature_algorithms(TLS_Data_Reader& reader, uint16_t extension_size) {
2,774✔
622
   uint16_t len = reader.get_uint16_t();
2,774✔
623

624
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
2,773✔
625
      throw Decoding_Error("Bad encoding on signature algorithms extension");
1✔
626
   }
627

628
   std::vector<Signature_Scheme> schemes;
2,772✔
629
   schemes.reserve(len / 2);
2,772✔
630
   while(len) {
29,356✔
631
      schemes.emplace_back(reader.get_uint16_t());
26,584✔
632
      len -= 2;
26,584✔
633
   }
634

635
   return schemes;
2,772✔
636
}
×
637

638
}  // namespace
639

640
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
4,559✔
641
   return serialize_signature_algorithms(m_schemes);
4,559✔
642
}
643

644
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
2,772✔
645
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2,772✔
646

647
std::vector<uint8_t> Signature_Algorithms_Cert::serialize(Connection_Side /*whoami*/) const {
2✔
648
   return serialize_signature_algorithms(m_schemes);
2✔
649
}
650

651
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
2✔
652
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2✔
653

654
Session_Ticket_Extension::Session_Ticket_Extension(TLS_Data_Reader& reader, uint16_t extension_size) :
4,744✔
655
      m_ticket(Session_Ticket(reader.get_elem<uint8_t, std::vector<uint8_t>>(extension_size))) {}
4,744✔
656

657
SRTP_Protection_Profiles::SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size) :
10✔
658
      m_pp(reader.get_range<uint16_t>(2, 0, 65535)) {
10✔
659
   const std::vector<uint8_t> mki = reader.get_range<uint8_t>(1, 0, 255);
9✔
660

661
   if(m_pp.size() * 2 + mki.size() + 3 != extension_size) {
9✔
662
      throw Decoding_Error("Bad encoding for SRTP protection extension");
×
663
   }
664

665
   if(!mki.empty()) {
9✔
666
      throw Decoding_Error("Unhandled non-empty MKI for SRTP protection extension");
×
667
   }
668
}
9✔
669

670
std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const {
5✔
671
   std::vector<uint8_t> buf;
5✔
672

673
   const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2);
5✔
674
   buf.push_back(get_byte<0>(pp_len));
5✔
675
   buf.push_back(get_byte<1>(pp_len));
5✔
676

677
   for(uint16_t pp : m_pp) {
12✔
678
      buf.push_back(get_byte<0>(pp));
7✔
679
      buf.push_back(get_byte<1>(pp));
7✔
680
   }
681

682
   buf.push_back(0);  // srtp_mki, always empty here
5✔
683

684
   return buf;
5✔
685
}
×
686

687
Extended_Master_Secret::Extended_Master_Secret(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
5,270✔
688
   if(extension_size != 0) {
5,270✔
689
      throw Decoding_Error("Invalid extended_master_secret extension");
2✔
690
   }
691
}
5,268✔
692

693
std::vector<uint8_t> Extended_Master_Secret::serialize(Connection_Side /*whoami*/) const {
5,070✔
694
   return std::vector<uint8_t>();
5,070✔
695
}
696

697
Encrypt_then_MAC::Encrypt_then_MAC(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
777✔
698
   if(extension_size != 0) {
777✔
699
      throw Decoding_Error("Invalid encrypt_then_mac extension");
×
700
   }
701
}
777✔
702

703
std::vector<uint8_t> Encrypt_then_MAC::serialize(Connection_Side /*whoami*/) const {
3,871✔
704
   return std::vector<uint8_t>();
3,871✔
705
}
706

707
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,342✔
708
   std::vector<uint8_t> buf;
4,342✔
709

710
   if(whoami == Connection_Side::Server) {
4,342✔
711
      BOTAN_ASSERT_NOMSG(m_versions.size() == 1);
414✔
712
      buf.push_back(m_versions[0].major_version());
414✔
713
      buf.push_back(m_versions[0].minor_version());
414✔
714
   } else {
715
      BOTAN_ASSERT_NOMSG(!m_versions.empty());
3,928✔
716
      const uint8_t len = static_cast<uint8_t>(m_versions.size() * 2);
3,928✔
717

718
      buf.push_back(len);
3,928✔
719

720
      for(Protocol_Version version : m_versions) {
8,948✔
721
         buf.push_back(version.major_version());
5,020✔
722
         buf.push_back(version.minor_version());
5,020✔
723
      }
724
   }
725

726
   return buf;
4,342✔
727
}
×
728

729
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,406✔
730
   if(offer.is_datagram_protocol()) {
3,406✔
731
#if defined(BOTAN_HAS_TLS_12)
732
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
360✔
733
         m_versions.push_back(Protocol_Version::DTLS_V12);
360✔
734
      }
735
#endif
736
   } else {
737
#if defined(BOTAN_HAS_TLS_13)
738
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,125✔
739
         m_versions.push_back(Protocol_Version::TLS_V13);
967✔
740
      }
741
#endif
742
#if defined(BOTAN_HAS_TLS_12)
743
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
4,013✔
744
         m_versions.push_back(Protocol_Version::TLS_V12);
3,017✔
745
      }
746
#endif
747
   }
748
}
3,406✔
749

750
Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
1,686✔
751
   if(from == Connection_Side::Server) {
1,686✔
752
      if(extension_size != 2) {
523✔
753
         throw Decoding_Error("Server sent invalid supported_versions extension");
×
754
      }
755
      m_versions.push_back(Protocol_Version(reader.get_uint16_t()));
523✔
756
   } else {
757
      auto versions = reader.get_range<uint16_t>(1, 1, 127);
1,163✔
758

759
      for(auto v : versions) {
4,038✔
760
         m_versions.push_back(Protocol_Version(v));
2,875✔
761
      }
762

763
      if(extension_size != 1 + 2 * versions.size()) {
1,163✔
764
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
765
      }
766
   }
1,163✔
767
}
1,686✔
768

769
bool Supported_Versions::supports(Protocol_Version version) const {
1,429✔
770
   for(auto v : m_versions) {
1,911✔
771
      if(version == v) {
1,892✔
772
         return true;
1,429✔
773
      }
774
   }
775
   return false;
776
}
777

778
Record_Size_Limit::Record_Size_Limit(const uint16_t limit) : m_limit(limit) {
16✔
779
   BOTAN_ASSERT(limit >= 64, "RFC 8449 does not allow record size limits smaller than 64 bytes");
16✔
780
   BOTAN_ASSERT(limit <= MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */,
16✔
781
                "RFC 8449 does not allow record size limits larger than 2^14+1");
782
}
16✔
783

784
Record_Size_Limit::Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
44✔
785
   if(extension_size != 2) {
44✔
786
      throw TLS_Exception(Alert::DecodeError, "invalid record_size_limit extension");
×
787
   }
788

789
   m_limit = reader.get_uint16_t();
44✔
790

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

809
   // RFC 8449 4.
810
   //    Endpoints MUST NOT send a "record_size_limit" extension with a value
811
   //    smaller than 64.  An endpoint MUST treat receipt of a smaller value
812
   //    as a fatal error and generate an "illegal_parameter" alert.
813
   if(m_limit < 64) {
44✔
814
      throw TLS_Exception(Alert::IllegalParameter, "Received a record size limit smaller than 64 bytes");
×
815
   }
816
}
44✔
817

818
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side) const {
52✔
819
   std::vector<uint8_t> buf;
52✔
820

821
   buf.push_back(get_byte<0>(m_limit));
52✔
822
   buf.push_back(get_byte<1>(m_limit));
52✔
823

824
   return buf;
52✔
825
}
×
826

827
#if defined(BOTAN_HAS_TLS_13)
828
Cookie::Cookie(const std::vector<uint8_t>& cookie) : m_cookie(cookie) {}
4✔
829

830
Cookie::Cookie(TLS_Data_Reader& reader, uint16_t extension_size) {
12✔
831
   if(extension_size == 0) {
12✔
832
      return;
833
   }
834

835
   const uint16_t len = reader.get_uint16_t();
12✔
836

837
   if(len == 0) {
12✔
838
      // Based on RFC 8446 4.2.2, len of the Cookie buffer must be at least 1
839
      throw Decoding_Error("Cookie length must be at least 1 byte");
1✔
840
   }
841

842
   if(len > reader.remaining_bytes()) {
11✔
843
      throw Decoding_Error("Not enough bytes in the buffer to decode Cookie");
×
844
   }
845

846
   for(size_t i = 0; i < len; ++i) {
719✔
847
      m_cookie.push_back(reader.get_byte());
708✔
848
   }
849
}
1✔
850

851
std::vector<uint8_t> Cookie::serialize(Connection_Side /*whoami*/) const {
10✔
852
   std::vector<uint8_t> buf;
10✔
853

854
   const uint16_t len = static_cast<uint16_t>(m_cookie.size());
10✔
855

856
   buf.push_back(get_byte<0>(len));
10✔
857
   buf.push_back(get_byte<1>(len));
10✔
858

859
   for(const auto& cookie_byte : m_cookie) {
712✔
860
      buf.push_back(cookie_byte);
702✔
861
   }
862

863
   return buf;
10✔
864
}
×
865

866
std::vector<uint8_t> PSK_Key_Exchange_Modes::serialize(Connection_Side) const {
1,144✔
867
   std::vector<uint8_t> buf;
1,144✔
868

869
   BOTAN_ASSERT_NOMSG(m_modes.size() < 256);
1,144✔
870
   buf.push_back(static_cast<uint8_t>(m_modes.size()));
1,144✔
871
   for(const auto& mode : m_modes) {
2,288✔
872
      buf.push_back(static_cast<uint8_t>(mode));
1,144✔
873
   }
874

875
   return buf;
1,144✔
876
}
×
877

878
PSK_Key_Exchange_Modes::PSK_Key_Exchange_Modes(TLS_Data_Reader& reader, uint16_t extension_size) {
950✔
879
   if(extension_size < 2) {
950✔
880
      throw Decoding_Error("Empty psk_key_exchange_modes extension is illegal");
×
881
   }
882

883
   const auto mode_count = reader.get_byte();
950✔
884
   for(uint16_t i = 0; i < mode_count; ++i) {
1,904✔
885
      const auto mode = static_cast<PSK_Key_Exchange_Mode>(reader.get_byte());
954✔
886
      if(mode == PSK_Key_Exchange_Mode::PSK_KE || mode == PSK_Key_Exchange_Mode::PSK_DHE_KE) {
954✔
887
         m_modes.push_back(mode);
948✔
888
      }
889
   }
890
}
950✔
891

892
std::vector<uint8_t> Certificate_Authorities::serialize(Connection_Side) const {
×
893
   std::vector<uint8_t> out;
×
894
   std::vector<uint8_t> dn_list;
×
895

896
   for(const auto& dn : m_distinguished_names) {
×
897
      std::vector<uint8_t> encoded_dn;
×
898
      auto encoder = DER_Encoder(encoded_dn);
×
899
      dn.encode_into(encoder);
×
900
      append_tls_length_value(dn_list, encoded_dn, 2);
×
901
   }
×
902

903
   append_tls_length_value(out, dn_list, 2);
×
904

905
   return out;
×
906
}
×
907

908
Certificate_Authorities::Certificate_Authorities(TLS_Data_Reader& reader, uint16_t extension_size) {
3✔
909
   if(extension_size < 2) {
3✔
910
      throw Decoding_Error("Empty certificate_authorities extension is illegal");
×
911
   }
912

913
   const uint16_t purported_size = reader.get_uint16_t();
3✔
914

915
   if(reader.remaining_bytes() != purported_size) {
3✔
916
      throw Decoding_Error("Inconsistent length in certificate_authorities extension");
×
917
   }
918

919
   while(reader.has_remaining()) {
9✔
920
      std::vector<uint8_t> name_bits = reader.get_tls_length_value(2);
6✔
921

922
      BER_Decoder decoder(name_bits.data(), name_bits.size());
6✔
923
      m_distinguished_names.emplace_back();
6✔
924
      decoder.decode(m_distinguished_names.back());
6✔
925
   }
12✔
926
}
3✔
927

928
Certificate_Authorities::Certificate_Authorities(std::vector<X509_DN> acceptable_DNs) :
×
929
      m_distinguished_names(std::move(acceptable_DNs)) {}
×
930

931
std::vector<uint8_t> EarlyDataIndication::serialize(Connection_Side) const {
8✔
932
   std::vector<uint8_t> result;
8✔
933
   if(m_max_early_data_size.has_value()) {
8✔
934
      const auto max_data = m_max_early_data_size.value();
2✔
935
      result.push_back(get_byte<0>(max_data));
2✔
936
      result.push_back(get_byte<1>(max_data));
2✔
937
      result.push_back(get_byte<2>(max_data));
2✔
938
      result.push_back(get_byte<3>(max_data));
2✔
939
   }
940
   return result;
8✔
941
}
×
942

943
EarlyDataIndication::EarlyDataIndication(TLS_Data_Reader& reader,
5✔
944
                                         uint16_t extension_size,
945
                                         Handshake_Type message_type) {
5✔
946
   if(message_type == Handshake_Type::NewSessionTicket) {
5✔
947
      if(extension_size != 4) {
1✔
948
         throw TLS_Exception(Alert::DecodeError,
×
949
                             "Received an early_data extension in a NewSessionTicket message "
950
                             "without maximum early data size indication");
×
951
      }
952

953
      m_max_early_data_size = reader.get_uint32_t();
1✔
954
   } else if(extension_size != 0) {
4✔
955
      throw TLS_Exception(Alert::DecodeError,
×
956
                          "Received an early_data extension containing an unexpected data "
957
                          "size indication");
×
958
   }
959
}
5✔
960

961
bool EarlyDataIndication::empty() const {
8✔
962
   // This extension may be empty by definition but still carry information
963
   return false;
8✔
964
}
965

966
#endif
967
}  // 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