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