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

randombit / botan / 6132015988

09 Sep 2023 10:17AM CUT coverage: 91.705% (-0.006%) from 91.711%
6132015988

push

github

web-flow
Merge pull request #3687 from mateuszb/master

Implement Certificate Authority serialization

78586 of 85694 relevant lines covered (91.71%)

8531067.27 hits per line

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

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

12
#include <botan/tls_extensions.h>
13

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

21
#include <iterator>
22

23
namespace Botan::TLS {
24

25
namespace {
26

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

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

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

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

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

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

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

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

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

62
      case Extension_Code::ExtendedMasterSecret:
5,259✔
63
         return std::make_unique<Extended_Master_Secret>(reader, size);
5,259✔
64

65
      case Extension_Code::RecordSizeLimit:
42✔
66
         return std::make_unique<Record_Size_Limit>(reader, size, from);
42✔
67

68
      case Extension_Code::EncryptThenMac:
762✔
69
         return std::make_unique<Encrypt_then_MAC>(reader, size);
762✔
70

71
      case Extension_Code::SessionTicket:
4,724✔
72
         return std::make_unique<Session_Ticket_Extension>(reader, size);
4,724✔
73

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

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

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

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

87
      case Extension_Code::PskKeyExchangeModes:
937✔
88
         return std::make_unique<PSK_Key_Exchange_Modes>(reader, size);
937✔
89

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

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

98
   return std::make_unique<Unknown_Extension>(static_cast<Extension_Code>(code), reader, size);
4,534✔
99
}
100

101
}  // namespace
102

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

109
   m_extensions.emplace_back(extn.release());
81,341✔
110
}
81,341✔
111

112
void Extensions::deserialize(TLS_Data_Reader& reader, const Connection_Side from, const Handshake_Type message_type) {
7,639✔
113
   if(reader.has_remaining()) {
7,639✔
114
      const uint16_t all_extn_size = reader.get_uint16_t();
7,634✔
115

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

120
      while(reader.has_remaining()) {
46,644✔
121
         const uint16_t extension_code = reader.get_uint16_t();
39,185✔
122
         const uint16_t extension_size = reader.get_uint16_t();
39,184✔
123

124
         const auto type = static_cast<Extension_Code>(extension_code);
39,184✔
125

126
         if(this->has(type)) {
39,184✔
127
            throw TLS_Exception(TLS::Alert::DecodeError, "Peer sent duplicated extensions");
13✔
128
         }
129

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

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

144
   std::vector<Extension_Code> diff;
3,338✔
145
   std::set_difference(
3,338✔
146
      found.cbegin(), found.end(), allowed_extensions.cbegin(), allowed_extensions.cend(), std::back_inserter(diff));
147

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

156
      // ... if yes, `contains_other_than` is true
157
      return itr != diff.cend();
1,490✔
158
   }
159

160
   return !diff.empty();
1,848✔
161
}
3,338✔
162

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

167
   std::unique_ptr<Extension> result;
476✔
168
   if(i != m_extensions.end()) {
476✔
169
      std::swap(result, *i);
226✔
170
      m_extensions.erase(i);
226✔
171
   }
172

173
   return result;
476✔
174
}
175

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

179
   for(const auto& extn : m_extensions) {
54,534✔
180
      if(extn->empty()) {
48,255✔
181
         continue;
696✔
182
      }
183

184
      const uint16_t extn_code = static_cast<uint16_t>(extn->type());
47,559✔
185

186
      const std::vector<uint8_t> extn_val = extn->serialize(whoami);
47,559✔
187

188
      buf.push_back(get_byte<0>(extn_code));
47,559✔
189
      buf.push_back(get_byte<1>(extn_code));
47,559✔
190

191
      buf.push_back(get_byte<0>(static_cast<uint16_t>(extn_val.size())));
47,559✔
192
      buf.push_back(get_byte<1>(static_cast<uint16_t>(extn_val.size())));
47,559✔
193

194
      buf += extn_val;
47,559✔
195
   }
47,559✔
196

197
   const uint16_t extn_size = static_cast<uint16_t>(buf.size() - 2);
6,279✔
198

199
   buf[0] = get_byte<0>(extn_size);
6,279✔
200
   buf[1] = get_byte<1>(extn_size);
6,279✔
201

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

207
   return buf;
6,279✔
208
}
6,279✔
209

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

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

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

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

234
   uint16_t name_bytes = reader.get_uint16_t();
2,638✔
235

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

240
   while(name_bytes) {
5,276✔
241
      uint8_t name_type = reader.get_byte();
2,638✔
242
      name_bytes--;
2,638✔
243

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

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

265
   std::vector<uint8_t> buf;
4,158✔
266

267
   size_t name_len = m_sni_host_name.size();
4,158✔
268

269
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len + 3)));
4,158✔
270
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len + 3)));
4,158✔
271
   buf.push_back(0);  // DNS
4,158✔
272

273
   buf.push_back(get_byte<0>(static_cast<uint16_t>(name_len)));
4,158✔
274
   buf.push_back(get_byte<1>(static_cast<uint16_t>(name_len)));
4,158✔
275

276
   buf += std::make_pair(cast_char_ptr_to_uint8(m_sni_host_name.data()), m_sni_host_name.size());
4,158✔
277

278
   return buf;
4,158✔
279
}
4,513✔
280

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

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

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

301
   const uint16_t name_bytes = reader.get_uint16_t();
395✔
302

303
   size_t bytes_remaining = extension_size - 2;
395✔
304

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

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

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

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

320
      bytes_remaining -= (p.size() + 1);
657✔
321

322
      m_protocols.push_back(p);
657✔
323
   }
664✔
324

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

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

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

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

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

356
   return buf;
353✔
357
}
×
358

359
Supported_Groups::Supported_Groups(const std::vector<Group_Params>& groups) : m_groups(groups) {}
3,952✔
360

361
const std::vector<Group_Params>& Supported_Groups::groups() const {
882✔
362
   return m_groups;
882✔
363
}
364

365
std::vector<Group_Params> Supported_Groups::ec_groups() const {
4,832✔
366
   std::vector<Group_Params> ec;
4,832✔
367
   for(auto g : m_groups) {
54,696✔
368
      if(group_param_is_dh(g) == false) {
49,864✔
369
         ec.push_back(g);
31,198✔
370
      }
371
   }
372
   return ec;
4,832✔
373
}
×
374

375
std::vector<Group_Params> Supported_Groups::dh_groups() const {
1,378✔
376
   std::vector<Group_Params> dh;
1,378✔
377
   for(auto g : m_groups) {
9,816✔
378
      if(group_param_is_dh(g) == true) {
8,438✔
379
         dh.push_back(g);
1,281✔
380
      }
381
   }
382
   return dh;
1,378✔
383
}
×
384

385
std::vector<uint8_t> Supported_Groups::serialize(Connection_Side /*whoami*/) const {
4,564✔
386
   std::vector<uint8_t> buf(2);
4,564✔
387

388
   for(auto g : m_groups) {
58,281✔
389
      const uint16_t id = static_cast<uint16_t>(g);
53,717✔
390

391
      if(id > 0) {
53,717✔
392
         buf.push_back(get_byte<0>(id));
53,717✔
393
         buf.push_back(get_byte<1>(id));
53,717✔
394
      }
395
   }
396

397
   buf[0] = get_byte<0>(static_cast<uint16_t>(buf.size() - 2));
4,564✔
398
   buf[1] = get_byte<1>(static_cast<uint16_t>(buf.size() - 2));
4,564✔
399

400
   return buf;
4,564✔
401
}
×
402

403
Supported_Groups::Supported_Groups(TLS_Data_Reader& reader, uint16_t extension_size) {
2,734✔
404
   const uint16_t len = reader.get_uint16_t();
2,734✔
405

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

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

414
   const size_t elems = len / 2;
2,730✔
415

416
   for(size_t i = 0; i != elems; ++i) {
20,865✔
417
      const auto group = static_cast<Group_Params>(reader.get_uint16_t());
18,135✔
418
      // Note: RFC 8446 does not explicitly enforce that groups must be unique.
419
      if(!value_exists(m_groups, group)) {
36,270✔
420
         m_groups.push_back(group);
18,135✔
421
      }
422
   }
423
}
2,734✔
424

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

434
Supported_Point_Formats::Supported_Point_Formats(TLS_Data_Reader& reader, uint16_t extension_size) {
3,053✔
435
   uint8_t len = reader.get_byte();
3,053✔
436

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

441
   bool includes_uncompressed = false;
3,056✔
442
   for(size_t i = 0; i != len; ++i) {
3,056✔
443
      uint8_t format = reader.get_byte();
3,055✔
444

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

459
      // ignore ANSIX962_COMPRESSED_CHAR2, we don't support these curves
460
   }
461

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

474
namespace {
475

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

479
   std::vector<uint8_t> buf;
4,537✔
480

481
   const uint16_t len = static_cast<uint16_t>(schemes.size() * 2);
4,537✔
482

483
   buf.push_back(get_byte<0>(len));
4,537✔
484
   buf.push_back(get_byte<1>(len));
4,537✔
485

486
   for(Signature_Scheme scheme : schemes) {
44,460✔
487
      buf.push_back(get_byte<0>(scheme.wire_code()));
39,923✔
488
      buf.push_back(get_byte<1>(scheme.wire_code()));
39,923✔
489
   }
490

491
   return buf;
4,537✔
492
}
×
493

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

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

501
   std::vector<Signature_Scheme> schemes;
2,752✔
502
   schemes.reserve(len / 2);
2,752✔
503
   while(len) {
29,144✔
504
      schemes.emplace_back(reader.get_uint16_t());
26,392✔
505
      len -= 2;
26,392✔
506
   }
507

508
   return schemes;
2,752✔
509
}
×
510

511
}  // namespace
512

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

517
Signature_Algorithms::Signature_Algorithms(TLS_Data_Reader& reader, uint16_t extension_size) :
2,752✔
518
      m_schemes(parse_signature_algorithms(reader, extension_size)) {}
2,752✔
519

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

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

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

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

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

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

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

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

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

555
   buf.push_back(0);  // srtp_mki, always empty here
5✔
556

557
   return buf;
5✔
558
}
×
559

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

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

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

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

580
std::vector<uint8_t> Supported_Versions::serialize(Connection_Side whoami) const {
4,304✔
581
   std::vector<uint8_t> buf;
4,304✔
582

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

591
      buf.push_back(len);
3,900✔
592

593
      for(Protocol_Version version : m_versions) {
8,886✔
594
         buf.push_back(version.major_version());
4,986✔
595
         buf.push_back(version.minor_version());
4,986✔
596
      }
597
   }
598

599
   return buf;
4,304✔
600
}
×
601

602
Supported_Versions::Supported_Versions(Protocol_Version offer, const Policy& policy) {
3,383✔
603
   if(offer.is_datagram_protocol()) {
3,383✔
604
#if defined(BOTAN_HAS_TLS_12)
605
      if(offer >= Protocol_Version::DTLS_V12 && policy.allow_dtls12()) {
358✔
606
         m_versions.push_back(Protocol_Version::DTLS_V12);
358✔
607
      }
608
#endif
609
   } else {
610
#if defined(BOTAN_HAS_TLS_13)
611
      if(offer >= Protocol_Version::TLS_V13 && policy.allow_tls13()) {
5,095✔
612
         m_versions.push_back(Protocol_Version::TLS_V13);
955✔
613
      }
614
#endif
615
#if defined(BOTAN_HAS_TLS_12)
616
      if(offer >= Protocol_Version::TLS_V12 && policy.allow_tls12()) {
3,980✔
617
         m_versions.push_back(Protocol_Version::TLS_V12);
3,003✔
618
      }
619
#endif
620
   }
621
}
3,383✔
622

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

632
      for(auto v : versions) {
3,981✔
633
         m_versions.push_back(Protocol_Version(v));
2,843✔
634
      }
635

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

642
bool Supported_Versions::supports(Protocol_Version version) const {
1,406✔
643
   for(auto v : m_versions) {
1,885✔
644
      if(version == v) {
1,869✔
645
         return true;
1,406✔
646
      }
647
   }
648
   return false;
649
}
650

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

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

662
   m_limit = reader.get_uint16_t();
42✔
663

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

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

691
std::vector<uint8_t> Record_Size_Limit::serialize(Connection_Side) const {
46✔
692
   std::vector<uint8_t> buf;
46✔
693

694
   buf.push_back(get_byte<0>(m_limit));
46✔
695
   buf.push_back(get_byte<1>(m_limit));
46✔
696

697
   return buf;
46✔
698
}
×
699

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

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

708
   const uint16_t len = reader.get_uint16_t();
12✔
709

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

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

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

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

727
   const uint16_t len = static_cast<uint16_t>(m_cookie.size());
10✔
728

729
   buf.push_back(get_byte<0>(len));
10✔
730
   buf.push_back(get_byte<1>(len));
10✔
731

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

736
   return buf;
10✔
737
}
×
738

739
std::vector<uint8_t> PSK_Key_Exchange_Modes::serialize(Connection_Side) const {
1,129✔
740
   std::vector<uint8_t> buf;
1,129✔
741

742
   BOTAN_ASSERT_NOMSG(m_modes.size() < 256);
1,129✔
743
   buf.push_back(static_cast<uint8_t>(m_modes.size()));
1,129✔
744
   for(const auto& mode : m_modes) {
2,258✔
745
      buf.push_back(static_cast<uint8_t>(mode));
1,129✔
746
   }
747

748
   return buf;
1,129✔
749
}
×
750

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

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

765
std::vector<uint8_t> Certificate_Authorities::serialize(Connection_Side) const {
×
766
   std::vector<uint8_t> out;
×
767
   std::vector<uint8_t> dn_list;
×
768

769
   for(const auto& dn : m_distinguished_names) {
×
770
      std::vector<uint8_t> encoded_dn;
×
771
      auto encoder = DER_Encoder(encoded_dn);
×
772
      dn.encode_into(encoder);
×
773
      append_tls_length_value(dn_list, encoded_dn, 2);
×
774
   }
×
775

776
   append_tls_length_value(out, dn_list, 2);
×
777

778
   return out;
×
779
}
×
780

781
Certificate_Authorities::Certificate_Authorities(TLS_Data_Reader& reader, uint16_t extension_size) {
3✔
782
   if(extension_size < 2) {
3✔
783
      throw Decoding_Error("Empty certificate_authorities extension is illegal");
×
784
   }
785

786
   const uint16_t purported_size = reader.get_uint16_t();
3✔
787

788
   if(reader.remaining_bytes() != purported_size) {
3✔
789
      throw Decoding_Error("Inconsistent length in certificate_authorities extension");
×
790
   }
791

792
   while(reader.has_remaining()) {
9✔
793
      std::vector<uint8_t> name_bits = reader.get_tls_length_value(2);
6✔
794

795
      BER_Decoder decoder(name_bits.data(), name_bits.size());
6✔
796
      m_distinguished_names.emplace_back();
6✔
797
      decoder.decode(m_distinguished_names.back());
6✔
798
   }
12✔
799
}
3✔
800

801
Certificate_Authorities::Certificate_Authorities(std::vector<X509_DN> acceptable_DNs) :
×
802
      m_distinguished_names(std::move(acceptable_DNs)) {}
×
803

804
std::vector<uint8_t> EarlyDataIndication::serialize(Connection_Side) const {
8✔
805
   std::vector<uint8_t> result;
8✔
806
   if(m_max_early_data_size.has_value()) {
8✔
807
      const auto max_data = m_max_early_data_size.value();
2✔
808
      result.push_back(get_byte<0>(max_data));
2✔
809
      result.push_back(get_byte<1>(max_data));
2✔
810
      result.push_back(get_byte<2>(max_data));
2✔
811
      result.push_back(get_byte<3>(max_data));
2✔
812
   }
813
   return result;
8✔
814
}
×
815

816
EarlyDataIndication::EarlyDataIndication(TLS_Data_Reader& reader,
5✔
817
                                         uint16_t extension_size,
818
                                         Handshake_Type message_type) {
5✔
819
   if(message_type == Handshake_Type::NewSessionTicket) {
5✔
820
      if(extension_size != 4) {
1✔
821
         throw TLS_Exception(Alert::DecodeError,
×
822
                             "Received an early_data extension in a NewSessionTicket message "
823
                             "without maximum early data size indication");
×
824
      }
825

826
      m_max_early_data_size = reader.get_uint32_t();
1✔
827
   } else if(extension_size != 0) {
4✔
828
      throw TLS_Exception(Alert::DecodeError,
×
829
                          "Received an early_data extension containing an unexpected data "
830
                          "size indication");
×
831
   }
832
}
5✔
833

834
bool EarlyDataIndication::empty() const {
8✔
835
   // This extension may be empty by definition but still carry information
836
   return false;
8✔
837
}
838

839
#endif
840
}  // 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

© 2025 Coveralls, Inc