Botan  2.4.0
Crypto and TLS for C++11
tls_extensions.h
Go to the documentation of this file.
1 /*
2 * TLS Extensions
3 * (C) 2011,2012,2016 Jack Lloyd
4 * 2016 Juraj Somorovsky
5 * 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/secmem.h>
14 #include <botan/ocsp.h>
15 #include <vector>
16 #include <string>
17 #include <map>
18 #include <set>
19 
20 namespace Botan {
21 
22 namespace TLS {
23 
24 class TLS_Data_Reader;
25 
29 
37 
40 
42 
44 };
45 
46 /**
47 * Base class representing a TLS extension of some kind
48 */
49 class Extension
50  {
51  public:
52  /**
53  * @return code number of the extension
54  */
55  virtual Handshake_Extension_Type type() const = 0;
56 
57  /**
58  * @return serialized binary for the extension
59  */
60  virtual std::vector<uint8_t> serialize() const = 0;
61 
62  /**
63  * @return if we should encode this extension or not
64  */
65  virtual bool empty() const = 0;
66 
67  virtual ~Extension() = default;
68  };
69 
70 /**
71 * Server Name Indicator extension (RFC 3546)
72 */
73 class Server_Name_Indicator final : public Extension
74  {
75  public:
78 
79  Handshake_Extension_Type type() const override { return static_type(); }
80 
81  explicit Server_Name_Indicator(const std::string& host_name) :
82  m_sni_host_name(host_name) {}
83 
85  uint16_t extension_size);
86 
87  std::string host_name() const { return m_sni_host_name; }
88 
89  std::vector<uint8_t> serialize() const override;
90 
91  bool empty() const override { return m_sni_host_name.empty(); }
92  private:
93  std::string m_sni_host_name;
94  };
95 
96 #if defined(BOTAN_HAS_SRP6)
97 /**
98 * SRP identifier extension (RFC 5054)
99 */
100 class SRP_Identifier final : public Extension
101  {
102  public:
103  static Handshake_Extension_Type static_type()
104  { return TLSEXT_SRP_IDENTIFIER; }
105 
106  Handshake_Extension_Type type() const override { return static_type(); }
107 
108  explicit SRP_Identifier(const std::string& identifier) :
109  m_srp_identifier(identifier) {}
110 
111  SRP_Identifier(TLS_Data_Reader& reader,
112  uint16_t extension_size);
113 
114  std::string identifier() const { return m_srp_identifier; }
115 
116  std::vector<uint8_t> serialize() const override;
117 
118  bool empty() const override { return m_srp_identifier.empty(); }
119  private:
120  std::string m_srp_identifier;
121  };
122 #endif
123 
124 /**
125 * Renegotiation Indication Extension (RFC 5746)
126 */
127 class Renegotiation_Extension final : public Extension
128  {
129  public:
131  { return TLSEXT_SAFE_RENEGOTIATION; }
132 
133  Handshake_Extension_Type type() const override { return static_type(); }
134 
135  Renegotiation_Extension() = default;
136 
137  explicit Renegotiation_Extension(const std::vector<uint8_t>& bits) :
138  m_reneg_data(bits) {}
139 
141  uint16_t extension_size);
142 
143  const std::vector<uint8_t>& renegotiation_info() const
144  { return m_reneg_data; }
145 
146  std::vector<uint8_t> serialize() const override;
147 
148  bool empty() const override { return false; } // always send this
149  private:
150  std::vector<uint8_t> m_reneg_data;
151  };
152 
153 /**
154 * ALPN (RFC 7301)
155 */
157  {
158  public:
160 
161  Handshake_Extension_Type type() const override { return static_type(); }
162 
163  const std::vector<std::string>& protocols() const { return m_protocols; }
164 
165  const std::string& single_protocol() const;
166 
167  /**
168  * Single protocol, used by server
169  */
170  explicit Application_Layer_Protocol_Notification(const std::string& protocol) :
171  m_protocols(1, protocol) {}
172 
173  /**
174  * List of protocols, used by client
175  */
176  explicit Application_Layer_Protocol_Notification(const std::vector<std::string>& protocols) :
177  m_protocols(protocols) {}
178 
180  uint16_t extension_size);
181 
182  std::vector<uint8_t> serialize() const override;
183 
184  bool empty() const override { return m_protocols.empty(); }
185  private:
186  std::vector<std::string> m_protocols;
187  };
188 
189 /**
190 * Session Ticket Extension (RFC 5077)
191 */
192 class Session_Ticket final : public Extension
193  {
194  public:
196  { return TLSEXT_SESSION_TICKET; }
197 
198  Handshake_Extension_Type type() const override { return static_type(); }
199 
200  /**
201  * @return contents of the session ticket
202  */
203  const std::vector<uint8_t>& contents() const { return m_ticket; }
204 
205  /**
206  * Create empty extension, used by both client and server
207  */
208  Session_Ticket() = default;
209 
210  /**
211  * Extension with ticket, used by client
212  */
213  explicit Session_Ticket(const std::vector<uint8_t>& session_ticket) :
214  m_ticket(session_ticket) {}
215 
216  /**
217  * Deserialize a session ticket
218  */
219  Session_Ticket(TLS_Data_Reader& reader, uint16_t extension_size);
220 
221  std::vector<uint8_t> serialize() const override { return m_ticket; }
222 
223  bool empty() const override { return false; }
224  private:
225  std::vector<uint8_t> m_ticket;
226  };
227 
228 
229 /**
230 * Supported Groups Extension (RFC 7919)
231 */
232 class Supported_Groups final : public Extension
233  {
234  public:
237 
238  Handshake_Extension_Type type() const override { return static_type(); }
239 
240  static std::string curve_id_to_name(uint16_t id);
241  static uint16_t name_to_curve_id(const std::string& name);
242 
243  static bool is_dh_group( const std::string& group_name );
244 
245  const std::vector<std::string>& curves() const { return m_curves; }
246  const std::vector<std::string>& dh_groups() const { return m_dh_groups; }
247 
248  std::vector<uint8_t> serialize() const override;
249 
250  explicit Supported_Groups(const std::vector<std::string>& groups);
251 
253  uint16_t extension_size);
254 
255  bool empty() const override { return m_groups.empty(); }
256  private:
257  std::vector<std::string> m_groups;
258  std::vector<std::string> m_curves;
259  std::vector<std::string> m_dh_groups;
260  };
261 
262 // previously Supported Elliptic Curves Extension (RFC 4492)
264 
265 /**
266 * Supported Point Formats Extension (RFC 4492)
267 */
268 class Supported_Point_Formats final : public Extension
269  {
270  public:
271  enum ECPointFormat : uint8_t {
272  UNCOMPRESSED = 0,
273  ANSIX962_COMPRESSED_PRIME = 1,
274  ANSIX962_COMPRESSED_CHAR2 = 2, // don't support these curves
275  };
276 
278  { return TLSEXT_EC_POINT_FORMATS; }
279 
280  Handshake_Extension_Type type() const override { return static_type(); }
281 
282  std::vector<uint8_t> serialize() const override;
283 
284  explicit Supported_Point_Formats(bool prefer_compressed) :
285  m_prefers_compressed(prefer_compressed) {}
286 
288  uint16_t extension_size);
289 
290  bool empty() const override { return false; }
291 
292  bool prefers_compressed() { return m_prefers_compressed; }
293 
294  private:
295  bool m_prefers_compressed = false;
296  };
297 
298 /**
299 * Signature Algorithms Extension for TLS 1.2 (RFC 5246)
300 */
301 class Signature_Algorithms final : public Extension
302  {
303  public:
305  { return TLSEXT_SIGNATURE_ALGORITHMS; }
306 
307  Handshake_Extension_Type type() const override { return static_type(); }
308 
309  static std::string hash_algo_name(uint8_t code);
310  static uint8_t hash_algo_code(const std::string& name);
311 
312  static std::string sig_algo_name(uint8_t code);
313  static uint8_t sig_algo_code(const std::string& name);
314 
315  // [(hash,sig),(hash,sig),...]
316  const std::vector<std::pair<std::string, std::string>>&
318  {
319  return m_supported_algos;
320  }
321 
322  std::vector<uint8_t> serialize() const override;
323 
324  bool empty() const override { return false; }
325 
326  Signature_Algorithms(const std::vector<std::string>& hashes,
327  const std::vector<std::string>& sig_algos);
328 
329  explicit Signature_Algorithms(const std::vector<std::pair<std::string, std::string>>& algos) :
330  m_supported_algos(algos) {}
331 
333  uint16_t extension_size);
334  private:
335  std::vector<std::pair<std::string, std::string>> m_supported_algos;
336  };
337 
338 /**
339 * Used to indicate SRTP algorithms for DTLS (RFC 5764)
340 */
342  {
343  public:
345  { return TLSEXT_USE_SRTP; }
346 
347  Handshake_Extension_Type type() const override { return static_type(); }
348 
349  const std::vector<uint16_t>& profiles() const { return m_pp; }
350 
351  std::vector<uint8_t> serialize() const override;
352 
353  bool empty() const override { return m_pp.empty(); }
354 
355  explicit SRTP_Protection_Profiles(const std::vector<uint16_t>& pp) : m_pp(pp) {}
356 
357  explicit SRTP_Protection_Profiles(uint16_t pp) : m_pp(1, pp) {}
358 
359  SRTP_Protection_Profiles(TLS_Data_Reader& reader, uint16_t extension_size);
360  private:
361  std::vector<uint16_t> m_pp;
362  };
363 
364 /**
365 * Extended Master Secret Extension (RFC 7627)
366 */
367 class Extended_Master_Secret final : public Extension
368  {
369  public:
372 
373  Handshake_Extension_Type type() const override { return static_type(); }
374 
375  std::vector<uint8_t> serialize() const override;
376 
377  bool empty() const override { return false; }
378 
379  Extended_Master_Secret() = default;
380 
381  Extended_Master_Secret(TLS_Data_Reader& reader, uint16_t extension_size);
382  };
383 
384 /**
385 * Encrypt-then-MAC Extension (RFC 7366)
386 */
387 class Encrypt_then_MAC final : public Extension
388  {
389  public:
391  { return TLSEXT_ENCRYPT_THEN_MAC; }
392 
393  Handshake_Extension_Type type() const override { return static_type(); }
394 
395  std::vector<uint8_t> serialize() const override;
396 
397  bool empty() const override { return false; }
398 
399  Encrypt_then_MAC() = default;
400 
401  Encrypt_then_MAC(TLS_Data_Reader& reader, uint16_t extension_size);
402  };
403 
404 /**
405 * Certificate Status Request (RFC 6066)
406 */
408  {
409  public:
411  { return TLSEXT_CERT_STATUS_REQUEST; }
412 
413  Handshake_Extension_Type type() const override { return static_type(); }
414 
415  std::vector<uint8_t> serialize() const override;
416 
417  bool empty() const override { return false; }
418 
419  // Server generated version: empty
421 
422  // Client version, both lists can be empty
423  Certificate_Status_Request(const std::vector<X509_DN>& ocsp_responder_ids,
424  const std::vector<std::vector<uint8_t>>& ocsp_key_ids);
425 
426  Certificate_Status_Request(TLS_Data_Reader& reader, uint16_t extension_size);
427  private:
428  std::vector<X509_DN> m_ocsp_names;
429  std::vector<std::vector<uint8_t>> m_ocsp_keys;
430  std::vector<uint8_t> m_extension_bytes;
431  bool m_server_side;
432  };
433 
434 /**
435 * Represents a block of extensions in a hello message
436 */
438  {
439  public:
440  std::set<Handshake_Extension_Type> extension_types() const;
441 
442  template<typename T>
443  T* get() const
444  {
445  Handshake_Extension_Type type = T::static_type();
446 
447  auto i = m_extensions.find(type);
448 
449  if(i != m_extensions.end())
450  return dynamic_cast<T*>(i->second.get());
451  return nullptr;
452  }
453 
454  template<typename T>
455  bool has() const
456  {
457  return get<T>() != nullptr;
458  }
459 
460  void add(Extension* extn)
461  {
462  m_extensions[extn->type()].reset(extn);
463  }
464 
465  std::vector<uint8_t> serialize() const;
466 
467  void deserialize(TLS_Data_Reader& reader);
468 
469  Extensions() = default;
470 
471  explicit Extensions(TLS_Data_Reader& reader) { deserialize(reader); }
472 
473  private:
474  Extensions(const Extensions&) = delete;
475  Extensions& operator=(const Extensions&) = delete;
476 
477  std::map<Handshake_Extension_Type, std::unique_ptr<Extension>> m_extensions;
478  };
479 
480 }
481 
482 }
483 
484 #endif
#define BOTAN_UNSTABLE_API
Definition: compiler.h:34
static Handshake_Extension_Type static_type()
static Handshake_Extension_Type static_type()
virtual std::vector< uint8_t > serialize() const =0
Extensions(TLS_Data_Reader &reader)
Handshake_Extension_Type type() const override
std::vector< uint8_t > serialize() const override
Server_Name_Indicator(const std::string &host_name)
Handshake_Extension_Type type() const override
Handshake_Extension_Type type() const override
void add(Extension *extn)
const std::vector< uint16_t > & profiles() const
static Handshake_Extension_Type static_type()
Handshake_Extension_Type type() const override
const std::vector< std::string > & curves() const
Handshake_Extension_Type type() const override
Handshake_Extension_Type type() const override
virtual ~Extension()=default
virtual Handshake_Extension_Type type() const =0
Signature_Algorithms(const std::vector< std::pair< std::string, std::string >> &algos)
static Handshake_Extension_Type static_type()
Application_Layer_Protocol_Notification(const std::string &protocol)
const std::vector< uint8_t > & renegotiation_info() const
static Handshake_Extension_Type static_type()
static Handshake_Extension_Type static_type()
static Handshake_Extension_Type static_type()
Definition: alg_id.cpp:13
Session_Ticket(const std::vector< uint8_t > &session_ticket)
const std::vector< uint8_t > & contents() const
static Handshake_Extension_Type static_type()
virtual bool empty() const =0
Handshake_Extension_Type type() const override
Handshake_Extension_Type type() const override
bool empty() const override
bool empty() const override
SRTP_Protection_Profiles(const std::vector< uint16_t > &pp)
fe T
Definition: ge.cpp:37
const std::vector< std::string > & protocols() const
static Handshake_Extension_Type static_type()
Handshake_Extension_Type type() const override
const std::vector< std::pair< std::string, std::string > > & supported_signature_algorthms() const
const std::vector< std::string > & dh_groups() const
Handshake_Extension_Type type() const override
Handshake_Extension_Type type() const override
static Handshake_Extension_Type static_type()
Supported_Point_Formats(bool prefer_compressed)
bool empty() const override
static Handshake_Extension_Type static_type()
Application_Layer_Protocol_Notification(const std::vector< std::string > &protocols)
Renegotiation_Extension(const std::vector< uint8_t > &bits)