Coverage Report

Created: 2020-05-23 13:54

/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/x509_dn.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_SRP_IDENTIFIER         = 12,
40
   TLSEXT_SIGNATURE_ALGORITHMS   = 13,
41
   TLSEXT_USE_SRTP               = 14,
42
   TLSEXT_ALPN                   = 16,
43
44
   TLSEXT_ENCRYPT_THEN_MAC       = 22,
45
   TLSEXT_EXTENDED_MASTER_SECRET = 23,
46
47
   TLSEXT_SESSION_TICKET         = 35,
48
49
   TLSEXT_SUPPORTED_VERSIONS     = 43,
50
51
   TLSEXT_SAFE_RENEGOTIATION     = 65281,
52
};
53
54
/**
55
* Base class representing a TLS extension of some kind
56
*/
57
class BOTAN_UNSTABLE_API Extension
58
   {
59
   public:
60
      /**
61
      * @return code number of the extension
62
      */
63
      virtual Handshake_Extension_Type type() const = 0;
64
65
      /**
66
      * @return serialized binary for the extension
67
      */
68
      virtual std::vector<uint8_t> serialize(Connection_Side whoami) const = 0;
69
70
      /**
71
      * @return if we should encode this extension or not
72
      */
73
      virtual bool empty() const = 0;
74
75
270k
      virtual ~Extension() = default;
76
   };
77
78
/**
79
* Server Name Indicator extension (RFC 3546)
80
*/
81
class BOTAN_UNSTABLE_API Server_Name_Indicator final : public Extension
82
   {
83
   public:
84
      static Handshake_Extension_Type static_type()
85
99.0k
         { return TLSEXT_SERVER_NAME_INDICATION; }
86
87
16.5k
      Handshake_Extension_Type type() const override { return static_type(); }
88
89
      explicit Server_Name_Indicator(const std::string& host_name) :
90
5.24k
         m_sni_host_name(host_name) {}
91
92
      Server_Name_Indicator(TLS_Data_Reader& reader,
93
                            uint16_t extension_size);
94
95
18.0k
      std::string host_name() const { return m_sni_host_name; }
96
97
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
98
99
5.24k
      bool empty() const override { return m_sni_host_name.empty(); }
100
   private:
101
      std::string m_sni_host_name;
102
   };
103
104
#if defined(BOTAN_HAS_SRP6)
105
/**
106
* SRP identifier extension (RFC 5054)
107
*/
108
class BOTAN_UNSTABLE_API SRP_Identifier final : public Extension
109
   {
110
   public:
111
      static Handshake_Extension_Type static_type()
112
5.27k
         { return TLSEXT_SRP_IDENTIFIER; }
113
114
5.27k
      Handshake_Extension_Type type() const override { return static_type(); }
115
116
      explicit SRP_Identifier(const std::string& identifier) :
117
5.24k
         m_srp_identifier(identifier) {}
118
119
      SRP_Identifier(TLS_Data_Reader& reader,
120
                     uint16_t extension_size);
121
122
0
      std::string identifier() const { return m_srp_identifier; }
123
124
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
125
126
5.24k
      bool empty() const override { return m_srp_identifier.empty(); }
127
   private:
128
      std::string m_srp_identifier;
129
   };
130
#endif
131
132
/**
133
* Renegotiation Indication Extension (RFC 5746)
134
*/
135
class BOTAN_UNSTABLE_API Renegotiation_Extension final : public Extension
136
   {
137
   public:
138
      static Handshake_Extension_Type static_type()
139
127k
         { return TLSEXT_SAFE_RENEGOTIATION; }
140
141
28.1k
      Handshake_Extension_Type type() const override { return static_type(); }
142
143
3.89k
      Renegotiation_Extension() = default;
144
145
      explicit Renegotiation_Extension(const std::vector<uint8_t>& bits) :
146
10.1k
         m_reneg_data(bits) {}
147
148
      Renegotiation_Extension(TLS_Data_Reader& reader,
149
                             uint16_t extension_size);
150
151
      const std::vector<uint8_t>& renegotiation_info() const
152
17.8k
         { return m_reneg_data; }
153
154
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
155
156
10.1k
      bool empty() const override { return false; } // always send this
157
   private:
158
      std::vector<uint8_t> m_reneg_data;
159
   };
160
161
/**
162
* ALPN (RFC 7301)
163
*/
164
class BOTAN_UNSTABLE_API Application_Layer_Protocol_Notification final : public Extension
165
   {
166
   public:
167
56.3k
      static Handshake_Extension_Type static_type() { return TLSEXT_ALPN; }
168
169
19.0k
      Handshake_Extension_Type type() const override { return static_type(); }
170
171
5.17k
      const std::vector<std::string>& protocols() const { return m_protocols; }
172
173
      const std::string& single_protocol() const;
174
175
      /**
176
      * Single protocol, used by server
177
      */
178
      explicit Application_Layer_Protocol_Notification(const std::string& protocol) :
179
5.13k
         m_protocols(1, protocol) {}
180
181
      /**
182
      * List of protocols, used by client
183
      */
184
      explicit Application_Layer_Protocol_Notification(const std::vector<std::string>& protocols) :
185
0
         m_protocols(protocols) {}
186
187
      Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
188
                                              uint16_t extension_size);
189
190
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
191
192
5.13k
      bool empty() const override { return m_protocols.empty(); }
193
   private:
194
      std::vector<std::string> m_protocols;
195
   };
196
197
/**
198
* Session Ticket Extension (RFC 5077)
199
*/
200
class BOTAN_UNSTABLE_API Session_Ticket final : public Extension
201
   {
202
   public:
203
      static Handshake_Extension_Type static_type()
204
62.0k
         { return TLSEXT_SESSION_TICKET; }
205
206
14.8k
      Handshake_Extension_Type type() const override { return static_type(); }
207
208
      /**
209
      * @return contents of the session ticket
210
      */
211
956
      const std::vector<uint8_t>& contents() const { return m_ticket; }
212
213
      /**
214
      * Create empty extension, used by both client and server
215
      */
216
6.07k
      Session_Ticket() = default;
217
218
      /**
219
      * Extension with ticket, used by client
220
      */
221
      explicit Session_Ticket(const std::vector<uint8_t>& session_ticket) :
222
0
         m_ticket(session_ticket) {}
223
224
      /**
225
      * Deserialize a session ticket
226
      */
227
      Session_Ticket(TLS_Data_Reader& reader, uint16_t extension_size);
228
229
6.07k
      std::vector<uint8_t> serialize(Connection_Side) const override { return m_ticket; }
230
231
6.07k
      bool empty() const override { return false; }
232
   private:
233
      std::vector<uint8_t> m_ticket;
234
   };
235
236
237
/**
238
* Supported Groups Extension (RFC 7919)
239
*/
240
class BOTAN_UNSTABLE_API Supported_Groups final : public Extension
241
   {
242
   public:
243
      static Handshake_Extension_Type static_type()
244
74.1k
         { return TLSEXT_SUPPORTED_GROUPS; }
245
246
29.0k
      Handshake_Extension_Type type() const override { return static_type(); }
247
248
      std::vector<Group_Params> ec_groups() const;
249
      std::vector<Group_Params> dh_groups() const;
250
251
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
252
253
      explicit Supported_Groups(const std::vector<Group_Params>& groups);
254
255
      Supported_Groups(TLS_Data_Reader& reader,
256
                       uint16_t extension_size);
257
258
5.24k
      bool empty() const override { return m_groups.empty(); }
259
   private:
260
      std::vector<Group_Params> m_groups;
261
   };
262
263
// previously Supported Elliptic Curves Extension (RFC 4492)
264
//using Supported_Elliptic_Curves = Supported_Groups;
265
266
/**
267
* Supported Point Formats Extension (RFC 4492)
268
*/
269
class BOTAN_UNSTABLE_API Supported_Point_Formats final : public Extension
270
   {
271
   public:
272
      enum ECPointFormat : uint8_t {
273
         UNCOMPRESSED = 0,
274
         ANSIX962_COMPRESSED_PRIME = 1,
275
         ANSIX962_COMPRESSED_CHAR2 = 2, // don't support these curves
276
      };
277
278
      static Handshake_Extension_Type static_type()
279
29.1k
         { return TLSEXT_EC_POINT_FORMATS; }
280
281
13.2k
      Handshake_Extension_Type type() const override { return static_type(); }
282
283
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
284
285
      explicit Supported_Point_Formats(bool prefer_compressed) :
286
5.81k
         m_prefers_compressed(prefer_compressed) {}
287
288
      Supported_Point_Formats(TLS_Data_Reader& reader,
289
                              uint16_t extension_size);
290
291
5.81k
      bool empty() const override { return false; }
292
293
649
      bool prefers_compressed() { return m_prefers_compressed; }
294
295
   private:
296
      bool m_prefers_compressed = false;
297
   };
298
299
/**
300
* Signature Algorithms Extension for TLS 1.2 (RFC 5246)
301
*/
302
class BOTAN_UNSTABLE_API Signature_Algorithms final : public Extension
303
   {
304
   public:
305
      static Handshake_Extension_Type static_type()
306
13.3k
         { return TLSEXT_SIGNATURE_ALGORITHMS; }
307
308
13.0k
      Handshake_Extension_Type type() const override { return static_type(); }
309
310
325
      const std::vector<Signature_Scheme>& supported_schemes() const { return m_schemes; }
311
312
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
313
314
5.24k
      bool empty() const override { return m_schemes.empty(); }
315
316
      explicit Signature_Algorithms(const std::vector<Signature_Scheme>& schemes) :
317
5.24k
         m_schemes(schemes) {}
318
319
      Signature_Algorithms(TLS_Data_Reader& reader,
320
                           uint16_t extension_size);
321
   private:
322
      std::vector<Signature_Scheme> m_schemes;
323
   };
324
325
/**
326
* Used to indicate SRTP algorithms for DTLS (RFC 5764)
327
*/
328
class BOTAN_UNSTABLE_API SRTP_Protection_Profiles final : public Extension
329
   {
330
   public:
331
      static Handshake_Extension_Type static_type()
332
4.37k
         { return TLSEXT_USE_SRTP; }
333
334
8
      Handshake_Extension_Type type() const override { return static_type(); }
335
336
0
      const std::vector<uint16_t>& profiles() const { return m_pp; }
337
338
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
339
340
0
      bool empty() const override { return m_pp.empty(); }
341
342
0
      explicit SRTP_Protection_Profiles(const std::vector<uint16_t>& pp) : m_pp(pp) {}
343
344
0
      explicit SRTP_Protection_Profiles(uint16_t pp) : m_pp(1, pp) {}
345
346
      SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size);
347
   private:
348
      std::vector<uint16_t> m_pp;
349
   };
350
351
/**
352
* Extended Master Secret Extension (RFC 7627)
353
*/
354
class BOTAN_UNSTABLE_API Extended_Master_Secret final : public Extension
355
   {
356
   public:
357
      static Handshake_Extension_Type static_type()
358
62.8k
         { return TLSEXT_EXTENDED_MASTER_SECRET; }
359
360
25.7k
      Handshake_Extension_Type type() const override { return static_type(); }
361
362
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
363
364
9.55k
      bool empty() const override { return false; }
365
366
9.55k
      Extended_Master_Secret() = default;
367
368
      Extended_Master_Secret(TLS_Data_Reader& reader, uint16_t extension_size);
369
   };
370
371
/**
372
* Encrypt-then-MAC Extension (RFC 7366)
373
*/
374
class BOTAN_UNSTABLE_API Encrypt_then_MAC final : public Extension
375
   {
376
   public:
377
      static Handshake_Extension_Type static_type()
378
30.4k
         { return TLSEXT_ENCRYPT_THEN_MAC; }
379
380
14.0k
      Handshake_Extension_Type type() const override { return static_type(); }
381
382
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
383
384
5.53k
      bool empty() const override { return false; }
385
386
5.53k
      Encrypt_then_MAC() = default;
387
388
      Encrypt_then_MAC(TLS_Data_Reader& reader, uint16_t extension_size);
389
   };
390
391
/**
392
* Certificate Status Request (RFC 6066)
393
*/
394
class BOTAN_UNSTABLE_API Certificate_Status_Request final : public Extension
395
   {
396
   public:
397
      static Handshake_Extension_Type static_type()
398
37.3k
         { return TLSEXT_CERT_STATUS_REQUEST; }
399
400
13.5k
      Handshake_Extension_Type type() const override { return static_type(); }
401
402
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
403
404
6.16k
      bool empty() const override { return false; }
405
406
      const std::vector<uint8_t>& get_responder_id_list() const
407
0
         {
408
0
         return m_ocsp_names;
409
0
         }
410
411
      const std::vector<uint8_t>& get_request_extensions() const
412
0
         {
413
0
         return m_extension_bytes;
414
0
         }
415
416
      // Server generated version: empty
417
923
      Certificate_Status_Request() {}
418
419
      // Client version, both lists can be empty
420
      Certificate_Status_Request(const std::vector<uint8_t>& ocsp_responder_ids,
421
                                 const std::vector<std::vector<uint8_t>>& ocsp_key_ids);
422
423
      Certificate_Status_Request(TLS_Data_Reader& reader,
424
                                 uint16_t extension_size,
425
                                 Connection_Side side);
426
   private:
427
      std::vector<uint8_t> m_ocsp_names;
428
      std::vector<std::vector<uint8_t>> m_ocsp_keys; // is this field really needed
429
      std::vector<uint8_t> m_extension_bytes;
430
   };
431
432
/**
433
* Supported Versions from RFC 8446
434
*/
435
class BOTAN_UNSTABLE_API Supported_Versions final : public Extension
436
   {
437
   public:
438
      static Handshake_Extension_Type static_type()
439
40.3k
         { return TLSEXT_SUPPORTED_VERSIONS; }
440
441
10.5k
      Handshake_Extension_Type type() const override { return static_type(); }
442
443
      std::vector<uint8_t> serialize(Connection_Side whoami) const override;
444
445
5.24k
      bool empty() const override { return m_versions.empty(); }
446
447
      Supported_Versions(Protocol_Version version, const Policy& policy);
448
449
      Supported_Versions(Protocol_Version version)
450
0
         {
451
0
         m_versions.push_back(version);
452
0
         }
453
454
      Supported_Versions(TLS_Data_Reader& reader,
455
                         uint16_t extension_size,
456
                         Connection_Side from);
457
458
      bool supports(Protocol_Version version) const;
459
460
9
      const std::vector<Protocol_Version> versions() const { return m_versions; }
461
   private:
462
      std::vector<Protocol_Version> m_versions;
463
   };
464
465
/**
466
* Unknown extensions are deserialized as this type
467
*/
468
class BOTAN_UNSTABLE_API Unknown_Extension final : public Extension
469
   {
470
   public:
471
      Unknown_Extension(Handshake_Extension_Type type,
472
                        TLS_Data_Reader& reader,
473
                        uint16_t extension_size);
474
475
      std::vector<uint8_t> serialize(Connection_Side whoami) const override; // always fails
476
477
0
      const std::vector<uint8_t>& value() { return m_value; }
478
479
0
      bool empty() const override { return false; }
480
481
134k
      Handshake_Extension_Type type() const override { return m_type; }
482
483
   private:
484
      Handshake_Extension_Type m_type;
485
      std::vector<uint8_t> m_value;
486
   };
487
488
/**
489
* Represents a block of extensions in a hello message
490
*/
491
class BOTAN_UNSTABLE_API Extensions final
492
   {
493
   public:
494
      std::set<Handshake_Extension_Type> extension_types() const;
495
496
      template<typename T>
497
      T* get() const
498
439k
         {
499
439k
         return dynamic_cast<T*>(get(T::static_type()));
500
439k
         }
Botan::TLS::Renegotiation_Extension* Botan::TLS::Extensions::get<Botan::TLS::Renegotiation_Extension>() const
Line
Count
Source
498
99.4k
         {
499
99.4k
         return dynamic_cast<T*>(get(T::static_type()));
500
99.4k
         }
Botan::TLS::Extended_Master_Secret* Botan::TLS::Extensions::get<Botan::TLS::Extended_Master_Secret>() const
Line
Count
Source
498
37.1k
         {
499
37.1k
         return dynamic_cast<T*>(get(T::static_type()));
500
37.1k
         }
Botan::TLS::Encrypt_then_MAC* Botan::TLS::Extensions::get<Botan::TLS::Encrypt_then_MAC>() const
Line
Count
Source
498
16.4k
         {
499
16.4k
         return dynamic_cast<T*>(get(T::static_type()));
500
16.4k
         }
Botan::TLS::Certificate_Status_Request* Botan::TLS::Extensions::get<Botan::TLS::Certificate_Status_Request>() const
Line
Count
Source
498
23.8k
         {
499
23.8k
         return dynamic_cast<T*>(get(T::static_type()));
500
23.8k
         }
Botan::TLS::Session_Ticket* Botan::TLS::Extensions::get<Botan::TLS::Session_Ticket>() const
Line
Count
Source
498
47.1k
         {
499
47.1k
         return dynamic_cast<T*>(get(T::static_type()));
500
47.1k
         }
Botan::TLS::SRTP_Protection_Profiles* Botan::TLS::Extensions::get<Botan::TLS::SRTP_Protection_Profiles>() const
Line
Count
Source
498
4.37k
         {
499
4.37k
         return dynamic_cast<T*>(get(T::static_type()));
500
4.37k
         }
Botan::TLS::Application_Layer_Protocol_Notification* Botan::TLS::Extensions::get<Botan::TLS::Application_Layer_Protocol_Notification>() const
Line
Count
Source
498
37.2k
         {
499
37.2k
         return dynamic_cast<T*>(get(T::static_type()));
500
37.2k
         }
Botan::TLS::Supported_Point_Formats* Botan::TLS::Extensions::get<Botan::TLS::Supported_Point_Formats>() const
Line
Count
Source
498
15.9k
         {
499
15.9k
         return dynamic_cast<T*>(get(T::static_type()));
500
15.9k
         }
Botan::TLS::Signature_Algorithms* Botan::TLS::Extensions::get<Botan::TLS::Signature_Algorithms>() const
Line
Count
Source
498
363
         {
499
363
         return dynamic_cast<T*>(get(T::static_type()));
500
363
         }
Botan::TLS::Supported_Groups* Botan::TLS::Extensions::get<Botan::TLS::Supported_Groups>() const
Line
Count
Source
498
45.1k
         {
499
45.1k
         return dynamic_cast<T*>(get(T::static_type()));
500
45.1k
         }
Botan::TLS::Server_Name_Indicator* Botan::TLS::Extensions::get<Botan::TLS::Server_Name_Indicator>() const
Line
Count
Source
498
82.5k
         {
499
82.5k
         return dynamic_cast<T*>(get(T::static_type()));
500
82.5k
         }
Unexecuted instantiation: Botan::TLS::SRP_Identifier* Botan::TLS::Extensions::get<Botan::TLS::SRP_Identifier>() const
Botan::TLS::Supported_Versions* Botan::TLS::Extensions::get<Botan::TLS::Supported_Versions>() const
Line
Count
Source
498
29.8k
         {
499
29.8k
         return dynamic_cast<T*>(get(T::static_type()));
500
29.8k
         }
501
502
      template<typename T>
503
      bool has() const
504
207k
         {
505
207k
         return get<T>() != nullptr;
506
207k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Renegotiation_Extension>() const
Line
Count
Source
504
77.7k
         {
505
77.7k
         return get<T>() != nullptr;
506
77.7k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Extended_Master_Secret>() const
Line
Count
Source
504
37.1k
         {
505
37.1k
         return get<T>() != nullptr;
506
37.1k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Encrypt_then_MAC>() const
Line
Count
Source
504
16.4k
         {
505
16.4k
         return get<T>() != nullptr;
506
16.4k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Certificate_Status_Request>() const
Line
Count
Source
504
23.8k
         {
505
23.8k
         return get<T>() != nullptr;
506
23.8k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Session_Ticket>() const
Line
Count
Source
504
24.0k
         {
505
24.0k
         return get<T>() != nullptr;
506
24.0k
         }
bool Botan::TLS::Extensions::has<Botan::TLS::Application_Layer_Protocol_Notification>() const
Line
Count
Source
504
28.1k
         {
505
28.1k
         return get<T>() != nullptr;
506
28.1k
         }
Unexecuted instantiation: bool Botan::TLS::Extensions::has<Botan::TLS::Signature_Algorithms>() const
507
508
      void add(Extension* extn)
509
268k
         {
510
268k
         m_extensions[extn->type()].reset(extn);
511
268k
         }
512
513
      Extension* get(Handshake_Extension_Type type) const
514
439k
         {
515
439k
         auto i = m_extensions.find(type);
516
439k
517
439k
         if(i != m_extensions.end())
518
120k
            return i->second.get();
519
318k
         return nullptr;
520
318k
         }
521
522
      std::vector<uint8_t> serialize(Connection_Side whoami) const;
523
524
      void deserialize(TLS_Data_Reader& reader, Connection_Side from);
525
526
      /**
527
      * Remvoe an extension from this extensions object, if it exists.
528
      * Returns true if the extension existed (and thus is now removed),
529
      * otherwise false (the extension wasn't set in the first place).
530
      */
531
      bool remove_extension(Handshake_Extension_Type typ);
532
533
64.3k
      Extensions() = default;
534
535
      Extensions(TLS_Data_Reader& reader, Connection_Side side)
536
0
         {
537
0
         deserialize(reader, side);
538
0
         }
539
540
   private:
541
      Extensions(const Extensions&) = delete;
542
      Extensions& operator=(const Extensions&) = delete;
543
544
      std::map<Handshake_Extension_Type, std::unique_ptr<Extension>> m_extensions;
545
   };
546
547
}
548
549
}
550
551
#endif