Coverage Report

Created: 2021-04-07 06:07

/src/botan/build/include/botan/tls_extensions.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* TLS Extensions
3
* (C) 2011,2012,2016,2018,2019 Jack Lloyd
4
* (C) 2016 Juraj Somorovsky
5
* (C) 2016 Matthias Gierlings
6
*
7
* Botan is released under the Simplified BSD License (see license.txt)
8
*/
9
10
#ifndef BOTAN_TLS_EXTENSIONS_H_
11
#define BOTAN_TLS_EXTENSIONS_H_
12
13
#include <botan/tls_algos.h>
14
#include <botan/tls_magic.h>
15
#include <botan/tls_version.h>
16
#include <botan/secmem.h>
17
#include <botan/pkix_types.h>
18
#include <vector>
19
#include <string>
20
#include <map>
21
#include <set>
22
23
namespace Botan {
24
25
namespace TLS {
26
27
class Policy;
28
29
class TLS_Data_Reader;
30
31
// This will become an enum class in a future major release
32
enum Handshake_Extension_Type {
33
   TLSEXT_SERVER_NAME_INDICATION = 0,
34
   TLSEXT_CERT_STATUS_REQUEST    = 5,
35
36
   TLSEXT_CERTIFICATE_TYPES      = 9,
37
   TLSEXT_SUPPORTED_GROUPS       = 10,
38
   TLSEXT_EC_POINT_FORMATS       = 11,
39
   TLSEXT_SIGNATURE_ALGORITHMS   = 13,
40
   TLSEXT_USE_SRTP               = 14,
41
   TLSEXT_ALPN                   = 16,
42
43
   TLSEXT_ENCRYPT_THEN_MAC       = 22,
44
   TLSEXT_EXTENDED_MASTER_SECRET = 23,
45
46
   TLSEXT_SESSION_TICKET         = 35,
47
48
   TLSEXT_SUPPORTED_VERSIONS     = 43,
49
50
   TLSEXT_SAFE_RENEGOTIATION     = 65281,
51
};
52
53
/**
54
* Base class representing a TLS extension of some kind
55
*/
56
class BOTAN_UNSTABLE_API Extension
57
   {
58
   public:
59
      /**
60
      * @return code number of the extension
61
      */
62
      virtual Handshake_Extension_Type type() const = 0;
63
64
      /**
65
      * @return serialized binary for the extension
66
      */
67
      virtual std::vector<uint8_t> serialize(Connection_Side whoami) const = 0;
68
69
      /**
70
      * @return if we should encode this extension or not
71
      */
72
      virtual bool empty() const = 0;
73
74
265k
      virtual ~Extension() = default;
75
   };
76
77
/**
78
* Server Name Indicator extension (RFC 3546)
79
*/
80
class BOTAN_UNSTABLE_API Server_Name_Indicator final : public Extension
81
   {
82
   public:
83
      static Handshake_Extension_Type static_type()
84
61.0k
         { return TLSEXT_SERVER_NAME_INDICATION; }
85
86
6.47k
      Handshake_Extension_Type type() const override { return static_type(); }
87
88
      explicit Server_Name_Indicator(const std::string& host_name) :
89
1.92k
         m_sni_host_name(host_name) {}
90
91
      Server_Name_Indicator(TLS_Data_Reader& reader,
92
                            uint16_t extension_size);
93
94
4.08k
      std::string host_name() const { return m_sni_host_name; }
95
96
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
97
98
1.92k
      bool empty() const override { return m_sni_host_name.empty(); }
99
   private:
100
      std::string m_sni_host_name;
101
   };
102
103
/**
104
* Renegotiation Indication Extension (RFC 5746)
105
*/
106
class BOTAN_UNSTABLE_API Renegotiation_Extension final : public Extension
107
   {
108
   public:
109
      static Handshake_Extension_Type static_type()
110
154k
         { return TLSEXT_SAFE_RENEGOTIATION; }
111
112
44.9k
      Handshake_Extension_Type type() const override { return static_type(); }
113
114
14.1k
      Renegotiation_Extension() = default;
115
116
      explicit Renegotiation_Extension(const std::vector<uint8_t>& bits) :
117
15.2k
         m_reneg_data(bits) {}
118
119
      Renegotiation_Extension(TLS_Data_Reader& reader,
120
                             uint16_t extension_size);
121
122
      const std::vector<uint8_t>& renegotiation_info() const
123
28.8k
         { return m_reneg_data; }
124
125
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
126
127
15.2k
      bool empty() const override { return false; } // always send this
128
   private:
129
      std::vector<uint8_t> m_reneg_data;
130
   };
131
132
/**
133
* ALPN (RFC 7301)
134
*/
135
class BOTAN_UNSTABLE_API Application_Layer_Protocol_Notification final : public Extension
136
   {
137
   public:
138
80.9k
      static Handshake_Extension_Type static_type() { return TLSEXT_ALPN; }
139
140
37.5k
      Handshake_Extension_Type type() const override { return static_type(); }
141
142
10.7k
      const std::vector<std::string>& protocols() const { return m_protocols; }
143
144
      const std::string& single_protocol() const;
145
146
      /**
147
      * Single protocol, used by server
148
      */
149
      explicit Application_Layer_Protocol_Notification(const std::string& protocol) :
150
10.6k
         m_protocols(1, protocol) {}
151
152
      /**
153
      * List of protocols, used by client
154
      */
155
      explicit Application_Layer_Protocol_Notification(const std::vector<std::string>& protocols) :
156
0
         m_protocols(protocols) {}
157
158
      Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
159
                                              uint16_t extension_size);
160
161
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
162
163
10.6k
      bool empty() const override { return m_protocols.empty(); }
164
   private:
165
      std::vector<std::string> m_protocols;
166
   };
167
168
/**
169
* Session Ticket Extension (RFC 5077)
170
*/
171
class BOTAN_UNSTABLE_API Session_Ticket final : public Extension
172
   {
173
   public:
174
      static Handshake_Extension_Type static_type()
175
56.2k
         { return TLSEXT_SESSION_TICKET; }
176
177
12.1k
      Handshake_Extension_Type type() const override { return static_type(); }
178
179
      /**
180
      * @return contents of the session ticket
181
      */
182
2.76k
      const std::vector<uint8_t>& contents() const { return m_ticket; }
183
184
      /**
185
      * Create empty extension, used by both client and server
186
      */
187
4.60k
      Session_Ticket() = default;
188
189
      /**
190
      * Extension with ticket, used by client
191
      */
192
      explicit Session_Ticket(const std::vector<uint8_t>& session_ticket) :
193
0
         m_ticket(session_ticket) {}
194
195
      /**
196
      * Deserialize a session ticket
197
      */
198
      Session_Ticket(TLS_Data_Reader& reader, uint16_t extension_size);
199
200
4.60k
      std::vector<uint8_t> serialize(Connection_Side) const override { return m_ticket; }
201
202
4.60k
      bool empty() const override { return false; }
203
   private:
204
      std::vector<uint8_t> m_ticket;
205
   };
206
207
208
/**
209
* Supported Groups Extension (RFC 7919)
210
*/
211
class BOTAN_UNSTABLE_API Supported_Groups final : public Extension
212
   {
213
   public:
214
      static Handshake_Extension_Type static_type()
215
68.1k
         { return TLSEXT_SUPPORTED_GROUPS; }
216
217
25.3k
      Handshake_Extension_Type type() const override { return static_type(); }
218
219
      std::vector<Group_Params> ec_groups() const;
220
      std::vector<Group_Params> dh_groups() const;
221
222
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
223
224
      explicit Supported_Groups(const std::vector<Group_Params>& groups);
225
226
      Supported_Groups(TLS_Data_Reader& reader,
227
                       uint16_t extension_size);
228
229
1.92k
      bool empty() const override { return m_groups.empty(); }
230
   private:
231
      std::vector<Group_Params> m_groups;
232
   };
233
234
// previously Supported Elliptic Curves Extension (RFC 4492)
235
//using Supported_Elliptic_Curves = Supported_Groups;
236
237
/**
238
* Supported Point Formats Extension (RFC 4492)
239
*/
240
class BOTAN_UNSTABLE_API Supported_Point_Formats final : public Extension
241
   {
242
   public:
243
      enum ECPointFormat : uint8_t {
244
         UNCOMPRESSED = 0,
245
         ANSIX962_COMPRESSED_PRIME = 1,
246
         ANSIX962_COMPRESSED_CHAR2 = 2, // don't support these curves
247
      };
248
249
      static Handshake_Extension_Type static_type()
250
55.8k
         { return TLSEXT_EC_POINT_FORMATS; }
251
252
35.4k
      Handshake_Extension_Type type() const override { return static_type(); }
253
254
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
255
256
      explicit Supported_Point_Formats(bool prefer_compressed) :
257
12.3k
         m_prefers_compressed(prefer_compressed) {}
258
259
      Supported_Point_Formats(TLS_Data_Reader& reader,
260
                              uint16_t extension_size);
261
262
12.3k
      bool empty() const override { return false; }
263
264
10.3k
      bool prefers_compressed() { return m_prefers_compressed; }
265
266
   private:
267
      bool m_prefers_compressed = false;
268
   };
269
270
/**
271
* Signature Algorithms Extension for TLS 1.2 (RFC 5246)
272
*/
273
class BOTAN_UNSTABLE_API Signature_Algorithms final : public Extension
274
   {
275
   public:
276
      static Handshake_Extension_Type static_type()
277
5.18k
         { return TLSEXT_SIGNATURE_ALGORITHMS; }
278
279
5.07k
      Handshake_Extension_Type type() const override { return static_type(); }
280
281
77
      const std::vector<Signature_Scheme>& supported_schemes() const { return m_schemes; }
282
283
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
284
285
1.92k
      bool empty() const override { return m_schemes.empty(); }
286
287
      explicit Signature_Algorithms(const std::vector<Signature_Scheme>& schemes) :
288
1.92k
         m_schemes(schemes) {}
289
290
      Signature_Algorithms(TLS_Data_Reader& reader,
291
                           uint16_t extension_size);
292
   private:
293
      std::vector<Signature_Scheme> m_schemes;
294
   };
295
296
/**
297
* Used to indicate SRTP algorithms for DTLS (RFC 5764)
298
*/
299
class BOTAN_UNSTABLE_API SRTP_Protection_Profiles final : public Extension
300
   {
301
   public:
302
      static Handshake_Extension_Type static_type()
303
438
         { return TLSEXT_USE_SRTP; }
304
305
8
      Handshake_Extension_Type type() const override { return static_type(); }
306
307
0
      const std::vector<uint16_t>& profiles() const { return m_pp; }
308
309
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
310
311
0
      bool empty() const override { return m_pp.empty(); }
312
313
0
      explicit SRTP_Protection_Profiles(const std::vector<uint16_t>& pp) : m_pp(pp) {}
314
315
0
      explicit SRTP_Protection_Profiles(uint16_t pp) : m_pp(1, pp) {}
316
317
      SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size);
318
   private:
319
      std::vector<uint16_t> m_pp;
320
   };
321
322
/**
323
* Extended Master Secret Extension (RFC 7627)
324
*/
325
class BOTAN_UNSTABLE_API Extended_Master_Secret final : public Extension
326
   {
327
   public:
328
      static Handshake_Extension_Type static_type()
329
41.8k
         { return TLSEXT_EXTENDED_MASTER_SECRET; }
330
331
9.67k
      Handshake_Extension_Type type() const override { return static_type(); }
332
333
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
334
335
3.81k
      bool empty() const override { return false; }
336
337
3.81k
      Extended_Master_Secret() = default;
338
339
      Extended_Master_Secret(TLS_Data_Reader& reader, uint16_t extension_size);
340
   };
341
342
/**
343
* Encrypt-then-MAC Extension (RFC 7366)
344
*/
345
class BOTAN_UNSTABLE_API Encrypt_then_MAC final : public Extension
346
   {
347
   public:
348
      static Handshake_Extension_Type static_type()
349
21.8k
         { return TLSEXT_ENCRYPT_THEN_MAC; }
350
351
4.93k
      Handshake_Extension_Type type() const override { return static_type(); }
352
353
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
354
355
2.27k
      bool empty() const override { return false; }
356
357
2.27k
      Encrypt_then_MAC() = default;
358
359
      Encrypt_then_MAC(TLS_Data_Reader& reader, uint16_t extension_size);
360
   };
361
362
/**
363
* Certificate Status Request (RFC 6066)
364
*/
365
class BOTAN_UNSTABLE_API Certificate_Status_Request final : public Extension
366
   {
367
   public:
368
      static Handshake_Extension_Type static_type()
369
27.7k
         { return TLSEXT_CERT_STATUS_REQUEST; }
370
371
5.99k
      Handshake_Extension_Type type() const override { return static_type(); }
372
373
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
374
375
2.61k
      bool empty() const override { return false; }
376
377
      const std::vector<uint8_t>& get_responder_id_list() const
378
0
         {
379
0
         return m_ocsp_names;
380
0
         }
381
382
      const std::vector<uint8_t>& get_request_extensions() const
383
0
         {
384
0
         return m_extension_bytes;
385
0
         }
386
387
      // Server generated version: empty
388
689
      Certificate_Status_Request() {}
389
390
      // Client version, both lists can be empty
391
      Certificate_Status_Request(const std::vector<uint8_t>& ocsp_responder_ids,
392
                                 const std::vector<std::vector<uint8_t>>& ocsp_key_ids);
393
394
      Certificate_Status_Request(TLS_Data_Reader& reader,
395
                                 uint16_t extension_size,
396
                                 Connection_Side side);
397
   private:
398
      std::vector<uint8_t> m_ocsp_names;
399
      std::vector<std::vector<uint8_t>> m_ocsp_keys; // is this field really needed
400
      std::vector<uint8_t> m_extension_bytes;
401
   };
402
403
/**
404
* Supported Versions from RFC 8446
405
*/
406
class BOTAN_UNSTABLE_API Supported_Versions final : public Extension
407
   {
408
   public:
409
      static Handshake_Extension_Type static_type()
410
33.3k
         { return TLSEXT_SUPPORTED_VERSIONS; }
411
412
3.90k
      Handshake_Extension_Type type() const override { return static_type(); }
413
414
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
415
416
1.92k
      bool empty() const override { return m_versions.empty(); }
417
418
      Supported_Versions(Protocol_Version version, const Policy& policy);
419
420
      Supported_Versions(Protocol_Version version)
421
0
         {
422
0
         m_versions.push_back(version);
423
0
         }
424
425
      Supported_Versions(TLS_Data_Reader& reader,
426
                         uint16_t extension_size,
427
                         Connection_Side from);
428
429
      bool supports(Protocol_Version version) const;
430
431
34
      const std::vector<Protocol_Version> versions() const { return m_versions; }
432
   private:
433
      std::vector<Protocol_Version> m_versions;
434
   };
435
436
/**
437
* Unknown extensions are deserialized as this type
438
*/
439
class BOTAN_UNSTABLE_API Unknown_Extension final : public Extension
440
   {
441
   public:
442
      Unknown_Extension(Handshake_Extension_Type type,
443
                        TLS_Data_Reader& reader,
444
                        uint16_t extension_size);
445
446
      std::vector<uint8_t> serialize(Connection_Side whoami) const override; // always fails
447
448
0
      const std::vector<uint8_t>& value() { return m_value; }
449
450
0
      bool empty() const override { return false; }
451
452
131k
      Handshake_Extension_Type type() const override { return m_type; }
453
454
   private:
455
      Handshake_Extension_Type m_type;
456
      std::vector<uint8_t> m_value;
457
   };
458
459
/**
460
* Represents a block of extensions in a hello message
461
*/
462
class BOTAN_UNSTABLE_API Extensions final
463
   {
464
   public:
465
      std::set<Handshake_Extension_Type> extension_types() const;
466
467
      template<typename T>
468
      T* get() const
469
416k
         {
470
416k
         return dynamic_cast<T*>(get(T::static_type()));
471
416k
         }
Botan::TLS::Encrypt_then_MAC* Botan::TLS::Extensions::get<Botan::TLS::Encrypt_then_MAC>() const
Line
Count
Source
469
16.8k
         {
470
16.8k
         return dynamic_cast<T*>(get(T::static_type()));
471
16.8k
         }
Botan::TLS::Renegotiation_Extension* Botan::TLS::Extensions::get<Botan::TLS::Renegotiation_Extension>() const
Line
Count
Source
469
110k
         {
470
110k
         return dynamic_cast<T*>(get(T::static_type()));
471
110k
         }
Botan::TLS::Extended_Master_Secret* Botan::TLS::Extensions::get<Botan::TLS::Extended_Master_Secret>() const
Line
Count
Source
469
32.1k
         {
470
32.1k
         return dynamic_cast<T*>(get(T::static_type()));
471
32.1k
         }
Botan::TLS::Certificate_Status_Request* Botan::TLS::Extensions::get<Botan::TLS::Certificate_Status_Request>() const
Line
Count
Source
469
21.7k
         {
470
21.7k
         return dynamic_cast<T*>(get(T::static_type()));
471
21.7k
         }
Botan::TLS::Session_Ticket* Botan::TLS::Extensions::get<Botan::TLS::Session_Ticket>() const
Line
Count
Source
469
44.0k
         {
470
44.0k
         return dynamic_cast<T*>(get(T::static_type()));
471
44.0k
         }
Botan::TLS::SRTP_Protection_Profiles* Botan::TLS::Extensions::get<Botan::TLS::SRTP_Protection_Profiles>() const
Line
Count
Source
469
430
         {
470
430
         return dynamic_cast<T*>(get(T::static_type()));
471
430
         }
Botan::TLS::Application_Layer_Protocol_Notification* Botan::TLS::Extensions::get<Botan::TLS::Application_Layer_Protocol_Notification>() const
Line
Count
Source
469
43.3k
         {
470
43.3k
         return dynamic_cast<T*>(get(T::static_type()));
471
43.3k
         }
Botan::TLS::Supported_Point_Formats* Botan::TLS::Extensions::get<Botan::TLS::Supported_Point_Formats>() const
Line
Count
Source
469
20.4k
         {
470
20.4k
         return dynamic_cast<T*>(get(T::static_type()));
471
20.4k
         }
Botan::TLS::Signature_Algorithms* Botan::TLS::Extensions::get<Botan::TLS::Signature_Algorithms>() const
Line
Count
Source
469
114
         {
470
114
         return dynamic_cast<T*>(get(T::static_type()));
471
114
         }
Botan::TLS::Supported_Groups* Botan::TLS::Extensions::get<Botan::TLS::Supported_Groups>() const
Line
Count
Source
469
42.8k
         {
470
42.8k
         return dynamic_cast<T*>(get(T::static_type()));
471
42.8k
         }
Botan::TLS::Server_Name_Indicator* Botan::TLS::Extensions::get<Botan::TLS::Server_Name_Indicator>() const
Line
Count
Source
469
54.5k
         {
470
54.5k
         return dynamic_cast<T*>(get(T::static_type()));
471
54.5k
         }
Botan::TLS::Supported_Versions* Botan::TLS::Extensions::get<Botan::TLS::Supported_Versions>() const
Line
Count
Source
469
29.4k
         {
470
29.4k
         return dynamic_cast<T*>(get(T::static_type()));
471
29.4k
         }
472
473
      template<typename T>
474
      bool has() const
475
192k
         {
476
192k
         return get<T>() != nullptr;
477
192k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Encrypt_then_MAC>() const
Line
Count
Source
475
16.8k
         {
476
16.8k
         return get<T>() != nullptr;
477
16.8k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Renegotiation_Extension>() const
Line
Count
Source
475
67.0k
         {
476
67.0k
         return get<T>() != nullptr;
477
67.0k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Extended_Master_Secret>() const
Line
Count
Source
475
32.1k
         {
476
32.1k
         return get<T>() != nullptr;
477
32.1k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Certificate_Status_Request>() const
Line
Count
Source
475
21.7k
         {
476
21.7k
         return get<T>() != nullptr;
477
21.7k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Session_Ticket>() const
Line
Count
Source
475
22.2k
         {
476
22.2k
         return get<T>() != nullptr;
477
22.2k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Application_Layer_Protocol_Notification>() const
Line
Count
Source
475
32.5k
         {
476
32.5k
         return get<T>() != nullptr;
477
32.5k
         }
Unexecuted instantiation: bool Botan::TLS::Extensions::has<Botan::TLS::Signature_Algorithms>() const
478
479
      void add(Extension* extn)
480
263k
         {
481
263k
         m_extensions[extn->type()].reset(extn);
482
263k
         }
483
484
      Extension* get(Handshake_Extension_Type type) const
485
416k
         {
486
416k
         auto i = m_extensions.find(type);
487
488
416k
         if(i != m_extensions.end())
489
169k
            return i->second.get();
490
246k
         return nullptr;
491
246k
         }
492
493
      std::vector<uint8_t> serialize(Connection_Side whoami) const;
494
495
      void deserialize(TLS_Data_Reader& reader, Connection_Side from);
496
497
      /**
498
      * Remvoe an extension from this extensions object, if it exists.
499
      * Returns true if the extension existed (and thus is now removed),
500
      * otherwise false (the extension wasn't set in the first place).
501
      */
502
      bool remove_extension(Handshake_Extension_Type typ);
503
504
55.9k
      Extensions() = default;
505
506
      Extensions(TLS_Data_Reader& reader, Connection_Side side)
507
0
         {
508
0
         deserialize(reader, side);
509
0
         }
510
511
   private:
512
      Extensions(const Extensions&) = delete;
513
      Extensions& operator=(const Extensions&) = delete;
514
515
      std::map<Handshake_Extension_Type, std::unique_ptr<Extension>> m_extensions;
516
   };
517
518
}
519
520
}
521
522
#endif