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

randombit / botan / 5230455705

10 Jun 2023 02:30PM UTC coverage: 91.715% (-0.03%) from 91.746%
5230455705

push

github

randombit
Merge GH #3584 Change clang-format AllowShortFunctionsOnASingleLine config from All to Inline

77182 of 84154 relevant lines covered (91.72%)

11975295.43 hits per line

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

89.16
/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
*
8
* Botan is released under the Simplified BSD License (see license.txt)
9
*/
10

11
#include <botan/tls_extensions.h>
12

13
#include <botan/ber_dec.h>
14
#include <botan/tls_exceptn.h>
15
#include <botan/tls_policy.h>
16
#include <botan/internal/stl_util.h>
17
#include <botan/internal/tls_reader.h>
18

19
#include <iterator>
20

21
namespace Botan::TLS {
22

23
namespace {
24

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

36
      case Extension_Code::SupportedGroups:
2,716✔
37
         return std::make_unique<Supported_Groups>(reader, size);
2,716✔
38

39
      case Extension_Code::CertificateStatusRequest:
2,496✔
40
         return std::make_unique<Certificate_Status_Request>(reader, size, message_type, from);
2,496✔
41

42
      case Extension_Code::EcPointFormats:
3,039✔
43
         return std::make_unique<Supported_Point_Formats>(reader, size);
3,039✔
44

45
      case Extension_Code::SafeRenegotiation:
5,412✔
46
         return std::make_unique<Renegotiation_Extension>(reader, size);
5,412✔
47

48
      case Extension_Code::SignatureAlgorithms:
2,738✔
49
         return std::make_unique<Signature_Algorithms>(reader, size);
2,738✔
50

51
      case Extension_Code::CertSignatureAlgorithms:
×
52
         return std::make_unique<Signature_Algorithms_Cert>(reader, size);
×
53

54
      case Extension_Code::UseSrtp:
10✔
55
         return std::make_unique<SRTP_Protection_Profiles>(reader, size);
10✔
56

57
      case Extension_Code::ApplicationLayerProtocolNegotiation:
395✔
58
         return std::make_unique<Application_Layer_Protocol_Notification>(reader, size, from);
395✔
59

60
      case Extension_Code::ExtendedMasterSecret:
5,236✔
61
         return std::make_unique<Extended_Master_Secret>(reader, size);
5,236✔
62

63
      case Extension_Code::RecordSizeLimit:
40✔
64
         return std::make_unique<Record_Size_Limit>(reader, size, from);
40✔
65

66
      case Extension_Code::EncryptThenMac:
750✔
67
         return std::make_unique<Encrypt_then_MAC>(reader, size);
750✔
68

69
      case Extension_Code::SessionTicket:
4,694✔
70
         return std::make_unique<Session_Ticket_Extension>(reader, size);
4,694✔
71

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

75
#if defined(BOTAN_HAS_TLS_13)
76
      case Extension_Code::PresharedKey:
206✔
77
         return std::make_unique<PSK>(reader, size, message_type);
206✔
78

79
      case Extension_Code::EarlyData:
5✔
80
         return std::make_unique<EarlyDataIndication>(reader, size, message_type);
5✔
81

82
      case Extension_Code::Cookie:
10✔
83
         return std::make_unique<Cookie>(reader, size);
10✔
84

85
      case Extension_Code::PskKeyExchangeModes:
931✔
86
         return std::make_unique<PSK_Key_Exchange_Modes>(reader, size);
931✔
87

88
      case Extension_Code::CertificateAuthorities:
3✔
89
         return std::make_unique<Certificate_Authorities>(reader, size);
3✔
90

91
      case Extension_Code::KeyShare:
1,439✔
92
         return std::make_unique<Key_Share>(reader, size, message_type);
1,439✔
93
#endif
94
   }
95

96
   return std::make_unique<Unknown_Extension>(static_cast<Extension_Code>(code), reader, size);
4,516✔
97
}
98

99
}  // namespace
100

101
void Extensions::add(std::unique_ptr<Extension> extn) {
80,908✔
102
   if(has(extn->type())) {
80,908✔
103
      throw Invalid_Argument("cannot add the same extension twice: " +
×
104
                             std::to_string(static_cast<uint16_t>(extn->type())));
×
105
   }
106

107
   m_extensions.emplace_back(extn.release());
80,908✔
108
}
80,908✔
109

110
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
7,610✔
111
   if(reader.has_remaining()) {
7,610✔
112
      const uint16_t all_extn_size = reader.get_uint16_t();
7,605✔
113

114
      if(reader.remaining_bytes() != all_extn_size) {
7,605✔
115
         throw Decoding_Error("Bad extension size");
119✔
116
      }
117

118
      while(reader.has_remaining()) {
46,375✔
119
         const uint16_t extension_code = reader.get_uint16_t();
38,944✔
120
         const uint16_t extension_size = reader.get_uint16_t();
38,943✔
121

122
         const auto type = static_cast<Extension_Code>(extension_code);
38,943✔
123

124
         if(this->has(type)) {
38,943✔
125
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
13✔
126
         }
127

128
         // TODO offer a function on reader that returns a byte range as a reference
129
         // to avoid this copy of the extension data
130
         const std::vector<uint8_t> extn_data = reader.get_fixed<uint8_t>(extension_size);
38,930✔
131
         TLS_Data_Reader extn_reader("Extension", extn_data);
38,922✔
132
         this->add(make_extension(extn_reader, type, from, message_type));
38,922✔
133
         extn_reader.assert_done();
38,889✔
134
      }
38,889✔
135
   }
136
}
7,436✔
137

138
bool Extensions::contains_other_than(const std::set<Extension_Code>& allowed_extensions,
3,333✔
139
                                     const bool allow_unknown_extensions) const {
140
   const auto found = extension_types();
3,333✔
141

142
   std::vector<Extension_Code> diff;
3,333✔
143
   std::set_difference(
3,333✔
144
      found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
145

146
   if(allow_unknown_extensions) {
3,333✔
147
      // Go through the found unexpected extensions whether any of those
148
      // is known to this TLS implementation.
149
      const auto itr = std::find_if(diff.cbegin(), diff.cend(), [this](const auto ext_type) {
1,489✔
150
         const auto ext = get(ext_type);
10✔
151
         return ext && ext->is_implemented();
10✔
152
      });
153

154
      // ... if yes, `contains_other_than` is true
155
      return itr != diff.cend();
1,489✔
156
   }
157

158
   return !diff.empty();
1,844✔
159
}
3,333✔
160

161
std::unique_ptr<Extension> Extensions::take(Extension_Code type) {
462✔
162
   const auto i =
462✔
163
      std::find_if(m_extensions.begin(), m_extensions.end(), [type](const auto& ext) { return ext->type() == type; });
2,879✔
164

165
   std::unique_ptr<Extension> result;
462✔
166
   if(i != m_extensions.end()) {
462✔
167
      std::swap(result, *i);
212✔
168
      m_extensions.erase(i);
212✔
169
   }
170

171
   return result;
462✔
172
}
173

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

177
   for(const auto& extn : m_extensions) {
53,830✔
178
      if(extn->empty()) {
47,612✔
179
         continue;
690✔
180
      }
181

182
      const uint16_t extn_code = static_cast<uint16_t>(extn->type());
46,922✔
183

184
      const std::vector<uint8_t> extn_val = extn->serialize(whoami);
46,922✔
185

186
      buf.push_back(get_byte<0>(extn_code));
46,922✔
187
      buf.push_back(get_byte<1>(extn_code));
46,922✔
188

189
      buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
46,922✔
190
      buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
46,922✔
191

192
      buf += extn_val;
46,922✔
193
   }
46,922✔
194

195
   const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
6,218✔
196

197
   buf[0] = get_byte<0>(extn_size);
6,218✔
198
   buf[1] = get_byte<1>(extn_size);
6,218✔
199

200
   // avoid sending a completely empty extensions block
201
   if(buf.size() == 2) {
6,218✔
202
      return std::vector<uint8_t>();
283✔
203
   }
204

205
   return buf;
6,218✔
206
}
6,218✔
207

208
std::set<Extension_Code> Extensions::extension_types() const {
7,702✔
209
   std::set<Extension_Code> offers;
7,702✔
210
   std::transform(
7,702✔
211
      m_extensions.cbegin(), m_extensions.cend(), std::inserter(offers, offers.begin()), [](const auto& ext) {
39,274✔
212
         return ext->type();
39,274✔
213
      });
214
   return offers;
7,702✔
215
}
×
216

217
Unknown_Extension::Unknown_Extension(Extension_Code type, TLS_Data_Reader& reader, uint16_t extension_size) :
4,516✔
218
      m_type(type), m_value(reader.get_fixed<uint8_t>(extension_size)) {}
4,516✔
219

220
std::vector<uint8_t> Unknown_Extension::serialize(Connection_Side /*whoami*/) const {
2✔
221
   return m_value;
2✔
222
}
223

224
Server_Name_Indicator::Server_Name_Indicator(TLS_Data_Reader& reader, uint16_t extension_size) {
2,653✔
225
   /*
226
   * This is used by the server to confirm that it knew the name
227
   */
228
   if(extension_size == 0) {
2,653✔
229
      return;
230
   }
231

232
   uint16_t name_bytes = reader.get_uint16_t();
2,624✔
233

234
   if(name_bytes + 2 != extension_size) {
2,624✔
235
      throw Decoding_Error("Bad encoding of SNI extension");
×
236
   }
237

238
   while(name_bytes) {
5,248✔
239
      uint8_t name_type = reader.get_byte();
2,624✔
240
      name_bytes--;
2,624✔
241

242
      if(name_type == 0)  // DNS
2,624✔
243
      {
244
         m_sni_host_name = reader.get_string(2, 1, 65535);
2,624✔
245
         name_bytes -= static_cast<uint16_t>(2 + m_sni_host_name.size());
2,624✔
246
      } else  // some other unknown name type
247
      {
248
         reader.discard_next(name_bytes);
×
249
         name_bytes = 0;
×
250
      }
251
   }
252
}
×
253

254
std::vector<uint8_t> Server_Name_Indicator::serialize(Connection_Side whoami) const {
4,459✔
255
   // RFC 6066
256
   //    [...] the server SHALL include an extension of type "server_name" in
257
   //    the (extended) server hello. The "extension_data" field of this
258
   //    extension SHALL be empty.
259
   if(whoami == Connection_Side::Server) {
4,459✔
260
      return {};
351✔
261
   }
262

263
   std::vector<uint8_t> buf;
4,108✔
264

265
   size_t name_len = m_sni_host_name.size();
4,108✔
266

267
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,108✔
268
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,108✔
269
   buf.push_back(0);  // DNS
4,108✔
270

271
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,108✔
272
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,108✔
273

274
   buf += std::make_pair(cast_char_ptr_to_uint8(m_sni_host_name.data()), m_sni_host_name.size());
4,108✔
275

276
   return buf;
4,108✔
277
}
4,459✔
278

279
Renegotiation_Extension::Renegotiation_Extension(TLS_Data_Reader& reader, uint16_t extension_size) :
5,412✔
280
      m_reneg_data(reader.get_range<uint8_t>(1, 0, 255)) {
5,412✔
281
   if(m_reneg_data.size() + 1 != extension_size) {
5,410✔
282
      throw Decoding_Error("Bad encoding for secure renegotiation extn");
1✔
283
   }
284
}
5,410✔
285

286
std::vector<uint8_t> Renegotiation_Extension::serialize(Connection_Side /*whoami*/) const {
5,038✔
287
   std::vector<uint8_t> buf;
5,038✔
288
   append_tls_length_value(buf, m_reneg_data, 1);
5,038✔
289
   return buf;
5,038✔
290
}
×
291

292
Application_Layer_Protocol_Notification::Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
395✔
293
                                                                                 uint16_t extension_size,
294
                                                                                 Connection_Side from) {
395✔
295
   if(extension_size == 0) {
395✔
296
      return;  // empty extension
297
   }
298

299
   const uint16_t name_bytes = reader.get_uint16_t();
395✔
300

301
   size_t bytes_remaining = extension_size - 2;
395✔
302

303
   if(name_bytes != bytes_remaining) {
395✔
304
      throw Decoding_Error("Bad encoding of ALPN extension, bad length field");
×
305
   }
306

307
   while(bytes_remaining) {
1,052✔
308
      const std::string p = reader.get_string(1, 0, 255);
664✔
309

310
      if(bytes_remaining < p.size() + 1) {
664✔
311
         throw Decoding_Error("Bad encoding of ALPN, length field too long");
×
312
      }
313

314
      if(p.empty()) {
664✔
315
         throw Decoding_Error("Empty ALPN protocol not allowed");
7✔
316
      }
317

318
      bytes_remaining -= (p.size() + 1);
657✔
319

320
      m_protocols.push_back(p);
657✔
321
   }
664✔
322

323
   // RFC 7301 3.1
324
   //    The "extension_data" field of the [...] extension is structured the
325
   //    same as described above for the client "extension_data", except that
326
   //    the "ProtocolNameList" MUST contain exactly one "ProtocolName".
327
   if(from == Connection_Side::Server && m_protocols.size() != 1) {
388✔
328
      throw TLS_Exception(
×
329
         Alert::DecodeError,
330
         "Server sent " + std::to_string(m_protocols.size()) + " protocols in ALPN extension response");
×
331
   }
332
}
7✔
333

334
std::string Application_Layer_Protocol_Notification::single_protocol() const {
145✔
335
   BOTAN_STATE_CHECK(m_protocols.size() == 1);
145✔
336
   return m_protocols.front();
145✔
337
}
338

339
std::vector<uint8_t> Application_Layer_Protocol_Notification::serialize(Connection_Side /*whoami*/) const {
353✔
340
   std::vector<uint8_t> buf(2);
353✔
341

342
   for(auto&& p : m_protocols) {
925✔
343
      if(p.length() >= 256) {
572✔
344
         throw TLS_Exception(Alert::InternalError, "ALPN name too long");
×
345
      }
346
      if(!p.empty()) {
572✔
347
         append_tls_length_value(buf, cast_char_ptr_to_uint8(p.data()), p.size(), 1);
572✔
348
      }
349
   }
350

351
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
353✔
352
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
353✔
353

354
   return buf;
353✔
355
}
×
356

357
Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) {}
3,940✔
358

359
const std::vector<Group_Params>& Supported_Groups::groups() const {
876✔
360
   return m_groups;
876✔
361
}
362

363
std::vector<Group_Params> Supported_Groups::ec_groups() const {
4,819✔
364
   std::vector<Group_Params> ec;
4,819✔
365
   for(auto g : m_groups) {
53,824✔
366
      if(group_param_is_dh(g) == false) {
49,005✔
367
         ec.push_back(g);
30,884✔
368
      }
369
   }
370
   return ec;
4,819✔
371
}
×
372

373
std::vector<Group_Params> Supported_Groups::dh_groups() const {
7✔
374
   std::vector<Group_Params> dh;
7✔
375
   for(auto g : m_groups) {
55✔
376
      if(group_param_is_dh(g) == true) {
48✔
377
         dh.push_back(g);
22✔
378
      }
379
   }
380
   return dh;
7✔
381
}
×
382

383
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,510✔
384
   std::vector<uint8_t> buf(2);
4,510✔
385

386
   for(auto g : m_groups) {
56,313✔
387
      const uint16_t id = static_cast<uint16_t>(g);
51,803✔
388

389
      if(id > 0) {
51,803✔
390
         buf.push_back(get_byte<0>(id));
51,803✔
391
         buf.push_back(get_byte<1>(id));
51,803✔
392
      }
393
   }
394

395
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,510✔
396
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,510✔
397

398
   return buf;
4,510✔
399
}
×
400

401
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
2,718✔
402
   const uint16_t len = reader.get_uint16_t();
2,718✔
403

404
   if(len + 2 != extension_size) {
2,718✔
405
      throw Decoding_Error("Inconsistent length field in supported groups list");
4✔
406
   }
407

408
   if(len % 2 == 1) {
2,714✔
409
      throw Decoding_Error("Supported groups list of strange size");
×
410
   }
411

412
   const size_t elems = len / 2;
2,714✔
413

414
   for(size_t i = 0; i != elems; ++i) {
20,543✔
415
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
17,829✔
416
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
417
      if(!value_exists(m_groups, group)) {
35,658✔
418
         m_groups.push_back(group);
17,829✔
419
      }
420
   }
421
}
2,718✔
422

423
std::vector<uint8_t> Supported_Point_Formats::serialize(Connection_Side /*whoami*/) const {
4,892✔
424
   // if this extension is sent, it MUST include uncompressed (RFC 4492, section 5.1)
425
   if(m_prefers_compressed) {
4,892✔
426
      return std::vector<uint8_t>{2, ANSIX962_COMPRESSED_PRIME, UNCOMPRESSED};
10✔
427
   } else {
428
      return std::vector<uint8_t>{1, UNCOMPRESSED};
4,882✔
429
   }
430
}
431

432
Supported_Point_Formats::Supported_Point_Formats(TLS_Data_Reader& reader, uint16_t extension_size) {
3,039✔
433
   uint8_t len = reader.get_byte();
3,039✔
434

435
   if(len + 1 != extension_size) {
3,039✔
436
      throw Decoding_Error("Inconsistent length field in supported point formats list");
2✔
437
   }
438

439
   bool includes_uncompressed = false;
3,042✔
440
   for(size_t i = 0; i != len; ++i) {
3,042✔
441
      uint8_t format = reader.get_byte();
3,041✔
442

443
      if(static_cast<ECPointFormat>(format) == UNCOMPRESSED) {
3,041✔
444
         m_prefers_compressed = false;
3,026✔
445
         reader.discard_next(len - i - 1);
3,026✔
446
         return;
3,026✔
447
      } else if(static_cast<ECPointFormat>(format) == ANSIX962_COMPRESSED_PRIME) {
15✔
448
         m_prefers_compressed = true;
10✔
449
         std::vector<uint8_t> remaining_formats = reader.get_fixed<uint8_t>(len - i - 1);
10✔
450
         includes_uncompressed =
10✔
451
            std::any_of(std::begin(remaining_formats), std::end(remaining_formats), [](uint8_t remaining_format) {
10✔
452
               return static_cast<ECPointFormat>(remaining_format) == UNCOMPRESSED;
453
            });
454
         break;
10✔
455
      }
10✔
456

457
      // ignore ANSIX962_COMPRESSED_CHAR2, we don't support these curves
458
   }
459

460
   // RFC 4492 5.1.:
461
   //   If the Supported Point Formats Extension is indeed sent, it MUST contain the value 0 (uncompressed)
462
   //   as one of the items in the list of point formats.
463
   // Note:
464
   //   RFC 8422 5.1.2. explicitly requires this check,
465
   //   but only if the Supported Groups extension was sent.
466
   if(!includes_uncompressed) {
11✔
467
      throw TLS_Exception(Alert::IllegalParameter,
1✔
468
                          "Supported Point Formats Extension must contain the uncompressed point format");
2✔
469
   }
470
}
471

472
namespace {
473

474
std::vector<uint8_t> serialize_signature_algorithms(const std::vector<Signature_Scheme>& schemes) {
4,488✔
475
   BOTAN_ASSERT(schemes.size() < 256, "Too many signature schemes");
4,488✔
476

477
   std::vector<uint8_t> buf;
4,488✔
478

479
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,488✔
480

481
   buf.push_back(get_byte<0>(len));
4,488✔
482
   buf.push_back(get_byte<1>(len));
4,488✔
483

484
   for(Signature_Scheme scheme : schemes) {
43,978✔
485
      buf.push_back(get_byte<0>(scheme.wire_code()));
39,490✔
486
      buf.push_back(get_byte<1>(scheme.wire_code()));
39,490✔
487
   }
488

489
   return buf;
4,488✔
490
}
×
491

492
std::vector<Signature_Scheme> parse_signature_algorithms(TLS_Data_Reader& reader, uint16_t extension_size) {
2,740✔
493
   uint16_t len = reader.get_uint16_t();
2,740✔
494

495
   if(len + 2 != extension_size || len % 2 == 1 || len == 0) {
2,739✔
496
      throw Decoding_Error("Bad encoding on signature algorithms extension");
1✔
497
   }
498

499
   std::vector<Signature_Scheme> schemes;
2,738✔
500
   schemes.reserve(len / 2);
2,738✔
501
   while(len) {
21,391✔
502
      schemes.emplace_back(reader.get_uint16_t());
18,653✔
503
      len -= 2;
18,653✔
504
   }
505

506
   return schemes;
2,738✔
507
}
×
508

509
}  // namespace
510

511
std::vector<uint8_t> Signature_Algorithms::serialize(Connection_Side /*whoami*/) const {
4,486✔
512
   return serialize_signature_algorithms(m_schemes);
4,486✔
513
}
514

515
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
2,738✔
516
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2,738✔
517

518
std::vector<uint8_t> Signature_Algorithms_Cert::serialize(Connection_Side /*whoami*/) const {
2✔
519
   return serialize_signature_algorithms(m_schemes);
2✔
520
}
521

522
Signature_Algorithms_Cert::Signature_Algorithms_Cert(TLS_Data_Reader& reader, uint16_t extension_size) :
2✔
523
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2✔
524

525
Session_Ticket_Extension::Session_Ticket_Extension(TLS_Data_Reader& reader, uint16_t extension_size) :
4,694✔
526
      m_ticket(Session_Ticket(reader.get_elem<uint8_t, std::vector<uint8_t>>(extension_size))) {}
4,694✔
527

528
SRTP_Protection_Profiles::SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size) :
10✔
529
      m_pp(reader.get_range<uint16_t>(2, 0, 65535)) {
10✔
530
   const std::vector<uint8_t> mki = reader.get_range<uint8_t>(1, 0, 255);
9✔
531

532
   if(m_pp.size() * 2 + mki.size() + 3 != extension_size) {
9✔
533
      throw Decoding_Error("Bad encoding for SRTP protection extension");
×
534
   }
535

536
   if(!mki.empty()) {
9✔
537
      throw Decoding_Error("Unhandled non-empty MKI for SRTP protection extension");
×
538
   }
539
}
9✔
540

541
std::vector<uint8_t> SRTP_Protection_Profiles::serialize(Connection_Side /*whoami*/) const {
5✔
542
   std::vector<uint8_t> buf;
5✔
543

544
   const uint16_t pp_len = static_cast<uint16_t>(m_pp.size() * 2);
5✔
545
   buf.push_back(get_byte<0>(pp_len));
5✔
546
   buf.push_back(get_byte<1>(pp_len));
5✔
547

548
   for(uint16_t pp : m_pp) {
12✔
549
      buf.push_back(get_byte<0>(pp));
7✔
550
      buf.push_back(get_byte<1>(pp));
7✔
551
   }
552

553
   buf.push_back(0);  // srtp_mki, always empty here
5✔
554

555
   return buf;
5✔
556
}
×
557

558
Extended_Master_Secret::Extended_Master_Secret(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
5,236✔
559
   if(extension_size != 0) {
5,236✔
560
      throw Decoding_Error("Invalid extended_master_secret extension");
2✔
561
   }
562
}
5,234✔
563

564
std::vector<uint8_t> Extended_Master_Secret::serialize(Connection_Side /*whoami*/) const {
5,012✔
565
   return std::vector<uint8_t>();
5,012✔
566
}
567

568
Encrypt_then_MAC::Encrypt_then_MAC(TLS_Data_Reader& /*unused*/, uint16_t extension_size) {
750✔
569
   if(extension_size != 0) {
750✔
570
      throw Decoding_Error("Invalid encrypt_then_mac extension");
×
571
   }
572
}
750✔
573

574
std::vector<uint8_t> Encrypt_then_MAC::serialize(Connection_Side /*whoami*/) const {
3,802✔
575
   return std::vector<uint8_t>();
3,802✔
576
}
577

578
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,245✔
579
   std::vector<uint8_t> buf;
4,245✔
580

581
   if(whoami == Connection_Side::Server) {
4,245✔
582
      BOTAN_ASSERT_NOMSG(m_versions.size() == 1);
401✔
583
      buf.push_back(m_versions[0].major_version());
401✔
584
      buf.push_back(m_versions[0].minor_version());
401✔
585
   } else {
586
      BOTAN_ASSERT_NOMSG(!m_versions.empty());
3,844✔
587
      const uint8_t len = static_cast<uint8_t>(m_versions.size() * 2);
3,844✔
588

589
      buf.push_back(len);
3,844✔
590

591
      for(Protocol_Version version : m_versions) {
8,739✔
592
         buf.push_back(version.major_version());
4,895✔
593
         buf.push_back(version.minor_version());
4,895✔
594
      }
595
   }
596

597
   return buf;
4,245✔
598
}
×
599

600
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,366✔
601
   if(offer.is_datagram_protocol()) {
3,366✔
602
#if defined(BOTAN_HAS_TLS_12)
603
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
355✔
604
         m_versions.push_back(Protocol_Version::DTLS_V12);
355✔
605
      }
606
#endif
607
   } else {
608
#if defined(BOTAN_HAS_TLS_13)
609
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,072✔
610
         m_versions.push_back(Protocol_Version::TLS_V13);
950✔
611
      }
612
#endif
613
#if defined(BOTAN_HAS_TLS_12)
614
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
3,961✔
615
         m_versions.push_back(Protocol_Version::TLS_V12);
2,991✔
616
      }
617
#endif
618
   }
619
}
3,366✔
620

621
Supported_Versions::Supported_Versions(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
1,635✔
622
   if(from == Connection_Side::Server) {
1,635✔
623
      if(extension_size != 2) {
512✔
624
         throw Decoding_Error("Server sent invalid supported_versions extension");
×
625
      }
626
      m_versions.push_back(Protocol_Version(reader.get_uint16_t()));
512✔
627
   } else {
628
      auto versions = reader.get_range<uint16_t>(1, 1, 127);
1,123✔
629

630
      for(auto v : versions) {
3,948✔
631
         m_versions.push_back(Protocol_Version(v));
2,825✔
632
      }
633

634
      if(extension_size != 1 + 2 * versions.size()) {
1,123✔
635
         throw Decoding_Error("Client sent invalid supported_versions extension");
×
636
      }
637
   }
1,123✔
638
}
1,635✔
639

640
bool Supported_Versions::supports(Protocol_Version version) const {
1,398✔
641
   for(auto v : m_versions) {
1,874✔
642
      if(version == v) {
1,858✔
643
         return true;
1,398✔
644
      }
645
   }
646
   return false;
647
}
648

649
Record_Size_Limit::Record_Size_Limit(const uint16_t limit) : m_limit(limit) {
12✔
650
   BOTAN_ASSERT(limit >= 64, "RFC 8449 does not allow record size limits smaller than 64 bytes");
12✔
651
   BOTAN_ASSERT(limit <= MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */,
12✔
652
                "RFC 8449 does not allow record size limits larger than 2^14+1");
653
}
12✔
654

655
Record_Size_Limit::Record_Size_Limit(TLS_Data_Reader& reader, uint16_t extension_size, Connection_Side from) {
40✔
656
   if(extension_size != 2) {
40✔
657
      throw TLS_Exception(Alert::DecodeError, "invalid record_size_limit extension");
×
658
   }
659

660
   m_limit = reader.get_uint16_t();
40✔
661

662
   // RFC 8449 4.
663
   //    This value is the length of the plaintext of a protected record.
664
   //    The value includes the content type and padding added in TLS 1.3 (that
665
   //    is, the complete length of TLSInnerPlaintext).
666
   //
667
   //    A server MUST NOT enforce this restriction; a client might advertise
668
   //    a higher limit that is enabled by an extension or version the server
669
   //    does not understand. A client MAY abort the handshake with an
670
   //    "illegal_parameter" alert.
671
   //
672
   // Note: We are currently supporting this extension in TLS 1.3 only, hence
673
   //       we check for the TLS 1.3 limit. The TLS 1.2 limit would not include
674
   //       the "content type byte" and hence be one byte less!
675
   if(m_limit > MAX_PLAINTEXT_SIZE + 1 /* encrypted content type byte */ && from == Connection_Side::Server) {
40✔
676
      throw TLS_Exception(Alert::IllegalParameter,
×
677
                          "Server requested a record size limit larger than the protocol's maximum");
×
678
   }
679

680
   // RFC 8449 4.
681
   //    Endpoints MUST NOT send a "record_size_limit" extension with a value
682
   //    smaller than 64.  An endpoint MUST treat receipt of a smaller value
683
   //    as a fatal error and generate an "illegal_parameter" alert.
684
   if(m_limit < 64) {
40✔
685
      throw TLS_Exception(Alert::IllegalParameter, "Received a record size limit smaller than 64 bytes");
×
686
   }
687
}
40✔
688

689
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side) const {
39✔
690
   std::vector<uint8_t> buf;
39✔
691

692
   buf.push_back(get_byte<0>(m_limit));
39✔
693
   buf.push_back(get_byte<1>(m_limit));
39✔
694

695
   return buf;
39✔
696
}
×
697

698
#if defined(BOTAN_HAS_TLS_13)
699
Cookie::Cookie(const std::vector<uint8_t>& cookie) : m_cookie(cookie) {}
4✔
700

701
Cookie::Cookie(TLS_Data_Reader& reader, uint16_t extension_size) {
12✔
702
   if(extension_size == 0) {
12✔
703
      return;
704
   }
705

706
   const uint16_t len = reader.get_uint16_t();
12✔
707

708
   if(len == 0) {
12✔
709
      // Based on RFC 8446 4.2.2, len of the Cookie buffer must be at least 1
710
      throw Decoding_Error("Cookie length must be at least 1 byte");
1✔
711
   }
712

713
   if(len > reader.remaining_bytes()) {
11✔
714
      throw Decoding_Error("Not enough bytes in the buffer to decode Cookie");
×
715
   }
716

717
   for(size_t i = 0; i < len; ++i) {
719✔
718
      m_cookie.push_back(reader.get_byte());
708✔
719
   }
720
}
1✔
721

722
std::vector<uint8_t> Cookie::serialize(Connection_Side /*whoami*/) const {
10✔
723
   std::vector<uint8_t> buf;
10✔
724

725
   const uint16_t len = static_cast<uint16_t>(m_cookie.size());
10✔
726

727
   buf.push_back(get_byte<0>(len));
10✔
728
   buf.push_back(get_byte<1>(len));
10✔
729

730
   for(const auto& cookie_byte : m_cookie) {
712✔
731
      buf.push_back(cookie_byte);
702✔
732
   }
733

734
   return buf;
10✔
735
}
×
736

737
std::vector<uint8_t> PSK_Key_Exchange_Modes::serialize(Connection_Side) const {
1,088✔
738
   std::vector<uint8_t> buf;
1,088✔
739

740
   BOTAN_ASSERT_NOMSG(m_modes.size() < 256);
1,088✔
741
   buf.push_back(static_cast<uint8_t>(m_modes.size()));
1,088✔
742
   for(const auto& mode : m_modes) {
2,176✔
743
      buf.push_back(static_cast<uint8_t>(mode));
1,088✔
744
   }
745

746
   return buf;
1,088✔
747
}
×
748

749
PSK_Key_Exchange_Modes::PSK_Key_Exchange_Modes(TLS_Data_Reader& reader, uint16_t extension_size) {
931✔
750
   if(extension_size < 2) {
931✔
751
      throw Decoding_Error("Empty psk_key_exchange_modes extension is illegal");
×
752
   }
753

754
   const auto mode_count = reader.get_byte();
931✔
755
   for(uint16_t i = 0; i < mode_count; ++i) {
1,866✔
756
      const auto mode = static_cast<PSK_Key_Exchange_Mode>(reader.get_byte());
935✔
757
      if(mode == PSK_Key_Exchange_Mode::PSK_KE || mode == PSK_Key_Exchange_Mode::PSK_DHE_KE) {
935✔
758
         m_modes.push_back(mode);
929✔
759
      }
760
   }
761
}
931✔
762

763
std::vector<uint8_t> Certificate_Authorities::serialize(Connection_Side) const {
×
764
   throw Not_Implemented("serializing Certificate_Authorities is NYI");
×
765
}
766

767
Certificate_Authorities::Certificate_Authorities(TLS_Data_Reader& reader, uint16_t extension_size) {
3✔
768
   if(extension_size < 2) {
3✔
769
      throw Decoding_Error("Empty certificate_authorities extension is illegal");
×
770
   }
771

772
   const uint16_t purported_size = reader.get_uint16_t();
3✔
773

774
   if(reader.remaining_bytes() != purported_size) {
3✔
775
      throw Decoding_Error("Inconsistent length in certificate_authorities extension");
×
776
   }
777

778
   while(reader.has_remaining()) {
9✔
779
      std::vector<uint8_t> name_bits = reader.get_tls_length_value(2);
6✔
780

781
      BER_Decoder decoder(name_bits.data(), name_bits.size());
6✔
782
      m_distinguished_names.emplace_back();
6✔
783
      decoder.decode(m_distinguished_names.back());
6✔
784
   }
12✔
785
}
3✔
786

787
Certificate_Authorities::Certificate_Authorities(std::vector<X509_DN> acceptable_DNs) :
×
788
      m_distinguished_names(std::move(acceptable_DNs)) {}
×
789

790
std::vector<uint8_t> EarlyDataIndication::serialize(Connection_Side) const {
8✔
791
   std::vector<uint8_t> result;
8✔
792
   if(m_max_early_data_size.has_value()) {
8✔
793
      const auto max_data = m_max_early_data_size.value();
2✔
794
      result.push_back(get_byte<0>(max_data));
2✔
795
      result.push_back(get_byte<1>(max_data));
2✔
796
      result.push_back(get_byte<2>(max_data));
2✔
797
      result.push_back(get_byte<3>(max_data));
2✔
798
   }
799
   return result;
8✔
800
}
×
801

802
EarlyDataIndication::EarlyDataIndication(TLS_Data_Reader& reader,
5✔
803
                                         uint16_t extension_size,
804
                                         Handshake_Type message_type) {
5✔
805
   if(message_type == Handshake_Type::NewSessionTicket) {
5✔
806
      if(extension_size != 4) {
1✔
807
         throw TLS_Exception(Alert::DecodeError,
×
808
                             "Received an early_data extension in a NewSessionTicket message "
809
                             "without maximum early data size indication");
×
810
      }
811

812
      m_max_early_data_size = reader.get_uint32_t();
1✔
813
   } else if(extension_size != 0) {
4✔
814
      throw TLS_Exception(Alert::DecodeError,
×
815
                          "Received an early_data extension containing an unexpected data "
816
                          "size indication");
×
817
   }
818
}
5✔
819

820
bool EarlyDataIndication::empty() const {
8✔
821
   // This extension may be empty by definition but still carry information
822
   return false;
8✔
823
}
824

825
#endif
826
}  // 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