Coverage Report

Created: 2021-02-21 07:20

/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
311k
      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
68.5k
         { return TLSEXT_SERVER_NAME_INDICATION; }
85
86
15.1k
      Handshake_Extension_Type type() const override { return static_type(); }
87
88
      explicit Server_Name_Indicator(const std::string& host_name) :
89
6.31k
         m_sni_host_name(host_name) {}
90
91
      Server_Name_Indicator(TLS_Data_Reader& reader,
92
                            uint16_t extension_size);
93
94
3.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
6.31k
      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
182k
         { return TLSEXT_SAFE_RENEGOTIATION; }
111
112
56.2k
      Handshake_Extension_Type type() const override { return static_type(); }
113
114
13.5k
      Renegotiation_Extension() = default;
115
116
      explicit Renegotiation_Extension(const std::vector<uint8_t>& bits) :
117
19.6k
         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
36.3k
         { return m_reneg_data; }
124
125
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
126
127
19.6k
      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
90.4k
      static Handshake_Extension_Type static_type() { return TLSEXT_ALPN; }
139
140
40.0k
      Handshake_Extension_Type type() const override { return static_type(); }
141
142
11.8k
      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
11.7k
         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
11.7k
      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
66.0k
         { return TLSEXT_SESSION_TICKET; }
176
177
20.8k
      Handshake_Extension_Type type() const override { return static_type(); }
178
179
      /**
180
      * @return contents of the session ticket
181
      */
182
2.07k
      const std::vector<uint8_t>& contents() const { return m_ticket; }
183
184
      /**
185
      * Create empty extension, used by both client and server
186
      */
187
8.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
8.24k
      std::vector<uint8_t> serialize(Connection_Side) const override { return m_ticket; }
201
202
8.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
77.0k
         { return TLSEXT_SUPPORTED_GROUPS; }
216
217
34.2k
      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
6.31k
      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
62.0k
         { return TLSEXT_EC_POINT_FORMATS; }
251
252
40.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
15.2k
         m_prefers_compressed(prefer_compressed) {}
258
259
      Supported_Point_Formats(TLS_Data_Reader& reader,
260
                              uint16_t extension_size);
261
262
15.2k
      bool empty() const override { return false; }
263
264
8.96k
      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
14.1k
         { return TLSEXT_SIGNATURE_ALGORITHMS; }
278
279
13.7k
      Handshake_Extension_Type type() const override { return static_type(); }
280
281
317
      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
6.31k
      bool empty() const override { return m_schemes.empty(); }
286
287
      explicit Signature_Algorithms(const std::vector<Signature_Scheme>& schemes) :
288
6.31k
         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
5.15k
         { return TLSEXT_USE_SRTP; }
304
305
7
      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
50.5k
         { return TLSEXT_EXTENDED_MASTER_SECRET; }
330
331
18.3k
      Handshake_Extension_Type type() const override { return static_type(); }
332
333
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
334
335
7.59k
      bool empty() const override { return false; }
336
337
7.59k
      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
32.2k
         { return TLSEXT_ENCRYPT_THEN_MAC; }
350
351
13.9k
      Handshake_Extension_Type type() const override { return static_type(); }
352
353
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
354
355
6.59k
      bool empty() const override { return false; }
356
357
6.59k
      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
37.4k
         { return TLSEXT_CERT_STATUS_REQUEST; }
370
371
14.8k
      Handshake_Extension_Type type() const override { return static_type(); }
372
373
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
374
375
6.80k
      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
493
      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
44.6k
         { return TLSEXT_SUPPORTED_VERSIONS; }
411
412
14.3k
      Handshake_Extension_Type type() const override { return static_type(); }
413
414
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
415
416
6.31k
      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.49k
      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
128k
      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
447k
         {
470
447k
         return dynamic_cast<T*>(get(T::static_type()));
471
447k
         }
Botan::TLS::Renegotiation_Extension* Botan::TLS::Extensions::get<Botan::TLS::Renegotiation_Extension>() const
Line
Count
Source
469
126k
         {
470
126k
         return dynamic_cast<T*>(get(T::static_type()));
471
126k
         }
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::Encrypt_then_MAC* Botan::TLS::Extensions::get<Botan::TLS::Encrypt_then_MAC>() const
Line
Count
Source
469
18.3k
         {
470
18.3k
         return dynamic_cast<T*>(get(T::static_type()));
471
18.3k
         }
Botan::TLS::Certificate_Status_Request* Botan::TLS::Extensions::get<Botan::TLS::Certificate_Status_Request>() const
Line
Count
Source
469
22.6k
         {
470
22.6k
         return dynamic_cast<T*>(get(T::static_type()));
471
22.6k
         }
Botan::TLS::Session_Ticket* Botan::TLS::Extensions::get<Botan::TLS::Session_Ticket>() const
Line
Count
Source
469
45.2k
         {
470
45.2k
         return dynamic_cast<T*>(get(T::static_type()));
471
45.2k
         }
Botan::TLS::SRTP_Protection_Profiles* Botan::TLS::Extensions::get<Botan::TLS::SRTP_Protection_Profiles>() const
Line
Count
Source
469
5.14k
         {
470
5.14k
         return dynamic_cast<T*>(get(T::static_type()));
471
5.14k
         }
Botan::TLS::Application_Layer_Protocol_Notification* Botan::TLS::Extensions::get<Botan::TLS::Application_Layer_Protocol_Notification>() const
Line
Count
Source
469
50.3k
         {
470
50.3k
         return dynamic_cast<T*>(get(T::static_type()));
471
50.3k
         }
Botan::TLS::Supported_Point_Formats* Botan::TLS::Extensions::get<Botan::TLS::Supported_Point_Formats>() const
Line
Count
Source
469
21.0k
         {
470
21.0k
         return dynamic_cast<T*>(get(T::static_type()));
471
21.0k
         }
Botan::TLS::Signature_Algorithms* Botan::TLS::Extensions::get<Botan::TLS::Signature_Algorithms>() const
Line
Count
Source
469
353
         {
470
353
         return dynamic_cast<T*>(get(T::static_type()));
471
353
         }
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
53.3k
         {
470
53.3k
         return dynamic_cast<T*>(get(T::static_type()));
471
53.3k
         }
Botan::TLS::Supported_Versions* Botan::TLS::Extensions::get<Botan::TLS::Supported_Versions>() const
Line
Count
Source
469
30.3k
         {
470
30.3k
         return dynamic_cast<T*>(get(T::static_type()));
471
30.3k
         }
472
473
      template<typename T>
474
      bool has() const
475
206k
         {
476
206k
         return get<T>() != nullptr;
477
206k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Renegotiation_Extension>() const
Line
Count
Source
475
76.2k
         {
476
76.2k
         return get<T>() != nullptr;
477
76.2k
         }
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::Encrypt_then_MAC>() const
Line
Count
Source
475
18.3k
         {
476
18.3k
         return get<T>() != nullptr;
477
18.3k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Certificate_Status_Request>() const
Line
Count
Source
475
22.6k
         {
476
22.6k
         return get<T>() != nullptr;
477
22.6k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Session_Ticket>() const
Line
Count
Source
475
23.2k
         {
476
23.2k
         return get<T>() != nullptr;
477
23.2k
         }
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(Extension* extn)
480
309k
         {
481
309k
         m_extensions[extn->type()].reset(extn);
482
309k
         }
483
484
      Extension* get(Handshake_Extension_Type type) const
485
447k
         {
486
447k
         auto i = m_extensions.find(type);
487
488
447k
         if(i != m_extensions.end())
489
184k
            return i->second.get();
490
263k
         return nullptr;
491
263k
         }
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
65.8k
      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