Coverage Report

Created: 2021-06-10 10:30

/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
291k
      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
65.2k
         { return TLSEXT_SERVER_NAME_INDICATION; }
85
86
6.58k
      Handshake_Extension_Type type() const override { return static_type(); }
87
88
      explicit Server_Name_Indicator(const std::string& host_name) :
89
2.08k
         m_sni_host_name(host_name) {}
90
91
      Server_Name_Indicator(TLS_Data_Reader& reader,
92
                            uint16_t extension_size);
93
94
3.75k
      std::string host_name() const { return m_sni_host_name; }
95
96
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
97
98
2.08k
      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
157k
         { return TLSEXT_SAFE_RENEGOTIATION; }
111
112
43.8k
      Handshake_Extension_Type type() const override { return static_type(); }
113
114
13.6k
      Renegotiation_Extension() = default;
115
116
      explicit Renegotiation_Extension(const std::vector<uint8_t>& bits) :
117
14.8k
         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.1k
         { return m_reneg_data; }
124
125
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
126
127
14.8k
      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
81.0k
      static Handshake_Extension_Type static_type() { return TLSEXT_ALPN; }
139
140
37.2k
      Handshake_Extension_Type type() const override { return static_type(); }
141
142
10.1k
      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.1k
         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.1k
      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
61.9k
         { return TLSEXT_SESSION_TICKET; }
176
177
14.2k
      Handshake_Extension_Type type() const override { return static_type(); }
178
179
      /**
180
      * @return contents of the session ticket
181
      */
182
3.26k
      const std::vector<uint8_t>& contents() const { return m_ticket; }
183
184
      /**
185
      * Create empty extension, used by both client and server
186
      */
187
5.24k
      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
5.24k
      std::vector<uint8_t> serialize(Connection_Side) const override { return m_ticket; }
201
202
5.24k
      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
73.6k
         { return TLSEXT_SUPPORTED_GROUPS; }
216
217
27.5k
      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
2.08k
      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
54.9k
         { return TLSEXT_EC_POINT_FORMATS; }
251
252
32.9k
      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
11.5k
         m_prefers_compressed(prefer_compressed) {}
258
259
      Supported_Point_Formats(TLS_Data_Reader& reader,
260
                              uint16_t extension_size);
261
262
11.5k
      bool empty() const override { return false; }
263
264
9.47k
      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
6.07k
         { return TLSEXT_SIGNATURE_ALGORITHMS; }
278
279
5.95k
      Handshake_Extension_Type type() const override { return static_type(); }
280
281
83
      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
2.08k
      bool empty() const override { return m_schemes.empty(); }
286
287
      explicit Signature_Algorithms(const std::vector<Signature_Scheme>& schemes) :
288
2.08k
         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
640
         { return TLSEXT_USE_SRTP; }
304
305
11
      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
54.4k
         { return TLSEXT_EXTENDED_MASTER_SECRET; }
330
331
19.8k
      Handshake_Extension_Type type() const override { return static_type(); }
332
333
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
334
335
7.16k
      bool empty() const override { return false; }
336
337
7.16k
      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
25.2k
         { return TLSEXT_ENCRYPT_THEN_MAC; }
350
351
5.53k
      Handshake_Extension_Type type() const override { return static_type(); }
352
353
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
354
355
2.52k
      bool empty() const override { return false; }
356
357
2.52k
      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
30.1k
         { return TLSEXT_CERT_STATUS_REQUEST; }
370
371
6.75k
      Handshake_Extension_Type type() const override { return static_type(); }
372
373
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
374
375
2.82k
      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
743
      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
40.9k
         { return TLSEXT_SUPPORTED_VERSIONS; }
411
412
5.59k
      Handshake_Extension_Type type() const override { return static_type(); }
413
414
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
415
416
2.08k
      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
1.39k
      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
145k
      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
446k
         {
470
446k
         return dynamic_cast<T*>(get(T::static_type()));
471
446k
         }
Botan::TLS::Renegotiation_Extension* Botan::TLS::Extensions::get<Botan::TLS::Renegotiation_Extension>() const
Line
Count
Source
469
114k
         {
470
114k
         return dynamic_cast<T*>(get(T::static_type()));
471
114k
         }
Botan::TLS::Extended_Master_Secret* Botan::TLS::Extensions::get<Botan::TLS::Extended_Master_Secret>() const
Line
Count
Source
469
34.6k
         {
470
34.6k
         return dynamic_cast<T*>(get(T::static_type()));
471
34.6k
         }
Botan::TLS::Encrypt_then_MAC* Botan::TLS::Extensions::get<Botan::TLS::Encrypt_then_MAC>() const
Line
Count
Source
469
19.7k
         {
470
19.7k
         return dynamic_cast<T*>(get(T::static_type()));
471
19.7k
         }
Botan::TLS::Certificate_Status_Request* Botan::TLS::Extensions::get<Botan::TLS::Certificate_Status_Request>() const
Line
Count
Source
469
23.4k
         {
470
23.4k
         return dynamic_cast<T*>(get(T::static_type()));
471
23.4k
         }
Botan::TLS::Session_Ticket* Botan::TLS::Extensions::get<Botan::TLS::Session_Ticket>() const
Line
Count
Source
469
47.6k
         {
470
47.6k
         return dynamic_cast<T*>(get(T::static_type()));
471
47.6k
         }
Botan::TLS::SRTP_Protection_Profiles* Botan::TLS::Extensions::get<Botan::TLS::SRTP_Protection_Profiles>() const
Line
Count
Source
469
629
         {
470
629
         return dynamic_cast<T*>(get(T::static_type()));
471
629
         }
Botan::TLS::Application_Layer_Protocol_Notification* Botan::TLS::Extensions::get<Botan::TLS::Application_Layer_Protocol_Notification>() const
Line
Count
Source
469
43.8k
         {
470
43.8k
         return dynamic_cast<T*>(get(T::static_type()));
471
43.8k
         }
Botan::TLS::Supported_Point_Formats* Botan::TLS::Extensions::get<Botan::TLS::Supported_Point_Formats>() const
Line
Count
Source
469
21.9k
         {
470
21.9k
         return dynamic_cast<T*>(get(T::static_type()));
471
21.9k
         }
Botan::TLS::Signature_Algorithms* Botan::TLS::Extensions::get<Botan::TLS::Signature_Algorithms>() const
Line
Count
Source
469
123
         {
470
123
         return dynamic_cast<T*>(get(T::static_type()));
471
123
         }
Botan::TLS::Supported_Groups* Botan::TLS::Extensions::get<Botan::TLS::Supported_Groups>() const
Line
Count
Source
469
46.1k
         {
470
46.1k
         return dynamic_cast<T*>(get(T::static_type()));
471
46.1k
         }
Botan::TLS::Server_Name_Indicator* Botan::TLS::Extensions::get<Botan::TLS::Server_Name_Indicator>() const
Line
Count
Source
469
58.6k
         {
470
58.6k
         return dynamic_cast<T*>(get(T::static_type()));
471
58.6k
         }
Botan::TLS::Supported_Versions* Botan::TLS::Extensions::get<Botan::TLS::Supported_Versions>() const
Line
Count
Source
469
35.3k
         {
470
35.3k
         return dynamic_cast<T*>(get(T::static_type()));
471
35.3k
         }
472
473
      template<typename T>
474
      bool has() const
475
207k
         {
476
207k
         return get<T>() != nullptr;
477
207k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Renegotiation_Extension>() const
Line
Count
Source
475
72.2k
         {
476
72.2k
         return get<T>() != nullptr;
477
72.2k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Extended_Master_Secret>() const
Line
Count
Source
475
34.6k
         {
476
34.6k
         return get<T>() != nullptr;
477
34.6k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Encrypt_then_MAC>() const
Line
Count
Source
475
19.7k
         {
476
19.7k
         return get<T>() != nullptr;
477
19.7k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Certificate_Status_Request>() const
Line
Count
Source
475
23.4k
         {
476
23.4k
         return get<T>() != nullptr;
477
23.4k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Session_Ticket>() const
Line
Count
Source
475
24.1k
         {
476
24.1k
         return get<T>() != nullptr;
477
24.1k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Application_Layer_Protocol_Notification>() const
Line
Count
Source
475
33.6k
         {
476
33.6k
         return get<T>() != nullptr;
477
33.6k
         }
Unexecuted instantiation: bool Botan::TLS::Extensions::has<Botan::TLS::Signature_Algorithms>() const
478
479
      void add(std::unique_ptr<Extension> extn)
480
213k
         {
481
213k
         m_extensions[extn->type()].reset(extn.release());
482
213k
         }
483
484
      void add(Extension* extn)
485
76.2k
         {
486
76.2k
         m_extensions[extn->type()].reset(extn);
487
76.2k
         }
488
489
      Extension* get(Handshake_Extension_Type type) const
490
446k
         {
491
446k
         auto i = m_extensions.find(type);
492
493
446k
         if(i != m_extensions.end())
494
175k
            return i->second.get();
495
270k
         return nullptr;
496
270k
         }
497
498
      std::vector<uint8_t> serialize(Connection_Side whoami) const;
499
500
      void deserialize(TLS_Data_Reader& reader, Connection_Side from);
501
502
      /**
503
      * Remove an extension from this extensions object, if it exists.
504
      * Returns true if the extension existed (and thus is now removed),
505
      * otherwise false (the extension wasn't set in the first place).
506
      */
507
      bool remove_extension(Handshake_Extension_Type typ);
508
509
63.9k
      Extensions() = default;
510
511
      Extensions(TLS_Data_Reader& reader, Connection_Side side)
512
0
         {
513
0
         deserialize(reader, side);
514
0
         }
515
516
   private:
517
      Extensions(const Extensions&) = delete;
518
      Extensions& operator=(const Extensions&) = delete;
519
520
      std::map<Handshake_Extension_Type, std::unique_ptr<Extension>> m_extensions;
521
   };
522
523
}
524
525
}
526
527
#endif