Botan  2.11.0
Crypto and TLS for C++11
tls_callbacks.h
Go to the documentation of this file.
1 /*
2 * TLS Callbacks
3 * (C) 2016 Matthias Gierlings
4 * 2016 Jack Lloyd
5 * 2017 Harry Reimann, Rohde & Schwarz Cybersecurity
6 *
7 * Botan is released under the Simplified BSD License (see license.txt)
8 */
9 
10 #ifndef BOTAN_TLS_CALLBACKS_H_
11 #define BOTAN_TLS_CALLBACKS_H_
12 
13 #include <botan/tls_session.h>
14 #include <botan/tls_alert.h>
15 #include <botan/pubkey.h>
16 #include <functional>
17 
18 namespace Botan {
19 
20 class Certificate_Store;
21 class X509_Certificate;
22 
23 namespace OCSP {
24 
25 class Response;
26 
27 }
28 
29 namespace TLS {
30 
31 class Handshake_Message;
32 class Policy;
33 class Extensions;
34 class Certificate_Status_Request;
35 
36 /**
37 * Encapsulates the callbacks that a TLS channel will make which are due to
38 * channel specific operations.
39 */
41  {
42  public:
43  virtual ~Callbacks() = default;
44 
45  /**
46  * Mandatory callback: output function
47  * The channel will call this with data which needs to be sent to the peer
48  * (eg, over a socket or some other form of IPC). The array will be overwritten
49  * when the function returns so a copy must be made if the data cannot be
50  * sent immediately.
51  *
52  * @param data the vector of data to send
53  *
54  * @param size the number of bytes to send
55  */
56  virtual void tls_emit_data(const uint8_t data[], size_t size) = 0;
57 
58  /**
59  * Mandatory callback: process application data
60  * Called when application data record is received from the peer.
61  * Again the array is overwritten immediately after the function returns.
62  *
63  * @param seq_no the underlying TLS/DTLS record sequence number
64  *
65  * @param data the vector containing the received record
66  *
67  * @param size the length of the received record, in bytes
68  */
69  virtual void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) = 0;
70 
71  /**
72  * Mandatory callback: alert received
73  * Called when an alert is received from the peer
74  * If fatal, the connection is closing. If not fatal, the connection may
75  * still be closing (depending on the error and the peer).
76  *
77  * @param alert the source of the alert
78  */
79  virtual void tls_alert(Alert alert) = 0;
80 
81  /**
82  * Mandatory callback: session established
83  * Called when a session is established. Throw an exception to abort
84  * the connection.
85  *
86  * @param session the session descriptor
87  *
88  * @return return false to prevent the session from being cached,
89  * return true to cache the session in the configured session manager
90  */
91  virtual bool tls_session_established(const Session& session) = 0;
92 
93  /**
94  * Optional callback: session activated
95  * Called when a session is active and can be written to
96  */
97  virtual void tls_session_activated() {}
98 
99  /**
100  * Optional callback with default impl: verify cert chain
101  *
102  * Default implementation performs a standard PKIX validation
103  * and initiates network OCSP request for end-entity cert.
104  * Override to provide different behavior.
105  *
106  * Check the certificate chain is valid up to a trusted root, and
107  * optionally (if hostname != "") that the hostname given is
108  * consistent with the leaf certificate.
109  *
110  * This function should throw an exception derived from
111  * std::exception with an informative what() result if the
112  * certificate chain cannot be verified.
113  *
114  * @param cert_chain specifies a certificate chain leading to a
115  * trusted root CA certificate.
116  * @param ocsp_responses the server may have provided some
117  * @param trusted_roots the list of trusted certificates
118  * @param usage what this cert chain is being used for
119  * Usage_Type::TLS_SERVER_AUTH for server chains,
120  * Usage_Type::TLS_CLIENT_AUTH for client chains,
121  * Usage_Type::UNSPECIFIED for other uses
122  * @param hostname when authenticating a server, this is the hostname
123  * the client requested (eg via SNI). When authenticating a client,
124  * this is the server name the client is authenticating *to*.
125  * Empty in other cases or if no hostname was used.
126  * @param policy the TLS policy associated with the session being authenticated
127  * using the certificate chain
128  */
129  virtual void tls_verify_cert_chain(
130  const std::vector<X509_Certificate>& cert_chain,
131  const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses,
132  const std::vector<Certificate_Store*>& trusted_roots,
133  Usage_Type usage,
134  const std::string& hostname,
135  const TLS::Policy& policy);
136 
137  /**
138  * Called by default `tls_verify_cert_chain` to get the timeout to use for OCSP
139  * requests. Return 0 to disable online OCSP checks.
140  *
141  * This function should not be "const" since the implementation might need
142  * to perform some side effecting operation to compute the result.
143  */
144  virtual std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const
145  {
146  return std::chrono::milliseconds(0);
147  }
148 
149  /**
150  * Called by the TLS server whenever the client included the
151  * status_request extension (see RFC 6066, a.k.a OCSP stapling)
152  * in the ClientHello.
153  *
154  * @return the encoded OCSP response to be sent to the client which
155  * indicates the revocation status of the server certificate. Return an
156  * empty vector to indicate that no response is available, and thus
157  * suppress the Certificate_Status message.
158  */
159  virtual std::vector<uint8_t> tls_provide_cert_status(const std::vector<X509_Certificate>& chain,
160  const Certificate_Status_Request& csr)
161  {
162  BOTAN_UNUSED(chain);
163  BOTAN_UNUSED(csr);
164  return std::vector<uint8_t>();
165  }
166 
167  /**
168  * Optional callback with default impl: sign a message
169  *
170  * Default implementation uses PK_Signer::sign_message().
171  * Override to provide a different approach, e.g. using an external device.
172  *
173  * @param key the private key of the signer
174  * @param rng a random number generator
175  * @param emsa the encoding method to be applied to the message
176  * @param format the signature format
177  * @param msg the input data for the signature
178  *
179  * @return the signature
180  */
181  virtual std::vector<uint8_t> tls_sign_message(
182  const Private_Key& key,
184  const std::string& emsa,
185  Signature_Format format,
186  const std::vector<uint8_t>& msg);
187 
188  /**
189  * Optional callback with default impl: verify a message signature
190  *
191  * Default implementation uses PK_Verifier::verify_message().
192  * Override to provide a different approach, e.g. using an external device.
193  *
194  * @param key the public key of the signer
195  * @param emsa the encoding method to be applied to the message
196  * @param format the signature format
197  * @param msg the input data for the signature
198  * @param sig the signature to be checked
199  *
200  * @return true if the signature is valid, false otherwise
201  */
202  virtual bool tls_verify_message(
203  const Public_Key& key,
204  const std::string& emsa,
205  Signature_Format format,
206  const std::vector<uint8_t>& msg,
207  const std::vector<uint8_t>& sig);
208 
209  /**
210  * Optional callback with default impl: client side DH agreement
211  *
212  * Default implementation uses PK_Key_Agreement::derive_key().
213  * Override to provide a different approach, e.g. using an external device.
214  *
215  * @param modulus the modulus p of the discrete logarithm group
216  * @param generator the generator of the DH subgroup
217  * @param peer_public_value the public value of the peer
218  * @param policy the TLS policy associated with the session being established
219  * @param rng a random number generator
220  *
221  * @return a pair consisting of the agreed raw secret and our public value
222  */
223  virtual std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> tls_dh_agree(
224  const std::vector<uint8_t>& modulus,
225  const std::vector<uint8_t>& generator,
226  const std::vector<uint8_t>& peer_public_value,
227  const Policy& policy,
228  RandomNumberGenerator& rng);
229 
230  /**
231  * Optional callback with default impl: client side ECDH agreement
232  *
233  * Default implementation uses PK_Key_Agreement::derive_key().
234  * Override to provide a different approach, e.g. using an external device.
235  *
236  * @param curve_name the name of the elliptic curve
237  * @param peer_public_value the public value of the peer
238  * @param policy the TLS policy associated with the session being established
239  * @param rng a random number generator
240  * @param compressed the compression preference for our public value
241  *
242  * @return a pair consisting of the agreed raw secret and our public value
243  */
244  virtual std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> tls_ecdh_agree(
245  const std::string& curve_name,
246  const std::vector<uint8_t>& peer_public_value,
247  const Policy& policy,
249  bool compressed);
250 
251  /**
252  * Optional callback: inspect handshake message
253  * Throw an exception to abort the handshake.
254  * Default simply ignores the message.
255  *
256  * @param message the handshake message
257  */
258  virtual void tls_inspect_handshake_msg(const Handshake_Message& message);
259 
260  /**
261  * Optional callback for server: choose ALPN protocol
262  * ALPN (RFC 7301) works by the client sending a list of application
263  * protocols it is willing to negotiate. The server then selects which
264  * protocol to use, which is not necessarily even on the list that
265  * the client sent.
266  *
267  * @param client_protos the vector of protocols the client is willing to negotiate
268  *
269  * @return the protocol selected by the server, which need not be on the
270  * list that the client sent; if this is the empty string, the server ignores the
271  * client ALPN extension. Default return value is empty string.
272  */
273  virtual std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos);
274 
275  /**
276  * Optional callback: examine/modify Extensions before sending.
277  *
278  * Both client and server will call this callback on the Extensions object
279  * before serializing it in the client/server hellos. This allows an
280  * application to modify which extensions are sent during the
281  * handshake.
282  *
283  * Default implementation does nothing.
284  *
285  * @param extn the extensions
286  * @param which_side will be CLIENT or SERVER which is the current
287  * applications role in the exchange.
288  */
289  virtual void tls_modify_extensions(Extensions& extn, Connection_Side which_side);
290 
291  /**
292  * Optional callback: examine peer extensions.
293  *
294  * Both client and server will call this callback with the Extensions
295  * object after receiving it from the peer. This allows examining the
296  * Extensions, for example to implement a custom extension. It also allows
297  * an application to require that a particular extension be implemented;
298  * throw an exception from this function to abort the handshake.
299  *
300  * Default implementation does nothing.
301  *
302  * @param extn the extensions
303  * @param which_side will be CLIENT if these are are the clients extensions (ie we are
304  * the server) or SERVER if these are the server extensions (we are the client).
305  */
306  virtual void tls_examine_extensions(const Extensions& extn, Connection_Side which_side);
307 
308  /**
309  * Optional callback: decode TLS group ID
310  *
311  * TLS uses a 16-bit field to identify ECC and DH groups. This callback
312  * handles the decoding. You only need to implement this if you are using
313  * a custom ECC or DH group (this is extremely uncommon).
314  *
315  * Default implementation uses the standard (IETF-defined) mappings.
316  */
317  virtual std::string tls_decode_group_param(Group_Params group_param);
318 
319  /**
320  * Optional callback: return peer network identity
321  *
322  * There is no expected or specified format. The only expectation is this
323  * function will return a unique value. For example returning the peer
324  * host IP and port.
325  *
326  * This is used to bind the DTLS cookie to a particular network identity.
327  * It is only called if the dtls-cookie-secret PSK is also defined.
328  */
329  virtual std::string tls_peer_network_identity();
330 
331  /**
332  * Optional callback: error logging. (not currently called)
333  * @param err An error message related to this connection.
334  */
335  virtual void tls_log_error(const char* err)
336  {
337  BOTAN_UNUSED(err);
338  }
339 
340  /**
341  * Optional callback: debug logging. (not currently called)
342  * @param what Some hopefully informative string
343  */
344  virtual void tls_log_debug(const char* what)
345  {
346  BOTAN_UNUSED(what);
347  }
348 
349  /**
350  * Optional callback: debug logging taking a buffer. (not currently called)
351  * @param descr What this buffer is
352  * @param val the bytes
353  * @param val_len length of val
354  */
355  virtual void tls_log_debug_bin(const char* descr, const uint8_t val[], size_t val_len)
356  {
357  BOTAN_UNUSED(descr, val, val_len);
358  }
359  };
360 
361 /**
362 * TLS::Callbacks using std::function for compatability with the old API signatures.
363 * This type is only provided for backward compatibility.
364 * New implementations should derive from TLS::Callbacks instead.
365 */
367  {
368  public:
369  typedef std::function<void (const uint8_t[], size_t)> output_fn;
370  typedef std::function<void (const uint8_t[], size_t)> data_cb;
371  typedef std::function<void (Alert, const uint8_t[], size_t)> alert_cb;
372  typedef std::function<bool (const Session&)> handshake_cb;
373  typedef std::function<void (const Handshake_Message&)> handshake_msg_cb;
374  typedef std::function<std::string (std::vector<std::string>)> next_protocol_fn;
375 
376  /**
377  * @param data_output_fn is called with data for the outbound socket
378  *
379  * @param app_data_cb is called when new application data is received
380  *
381  * @param recv_alert_cb is called when a TLS alert is received
382  *
383  * @param hs_cb is called when a handshake is completed
384  *
385  * @param hs_msg_cb is called for each handshake message received
386  *
387  * @param next_proto is called with ALPN protocol data sent by the client
388  */
389  BOTAN_DEPRECATED("Use TLS::Callbacks (virtual interface).")
390  Compat_Callbacks(output_fn data_output_fn, data_cb app_data_cb, alert_cb recv_alert_cb,
391  handshake_cb hs_cb, handshake_msg_cb hs_msg_cb = nullptr,
392  next_protocol_fn next_proto = nullptr)
393  : m_output_function(data_output_fn), m_app_data_cb(app_data_cb),
394  m_alert_cb(std::bind(recv_alert_cb, std::placeholders::_1, nullptr, 0)),
395  m_hs_cb(hs_cb), m_hs_msg_cb(hs_msg_cb), m_next_proto(next_proto) {}
396 
397  BOTAN_DEPRECATED("Use TLS::Callbacks (virtual interface).")
398  Compat_Callbacks(output_fn data_output_fn, data_cb app_data_cb,
399  std::function<void (Alert)> recv_alert_cb,
400  handshake_cb hs_cb,
401  handshake_msg_cb hs_msg_cb = nullptr,
402  next_protocol_fn next_proto = nullptr)
403  : m_output_function(data_output_fn), m_app_data_cb(app_data_cb),
404  m_alert_cb(recv_alert_cb),
405  m_hs_cb(hs_cb), m_hs_msg_cb(hs_msg_cb), m_next_proto(next_proto) {}
406 
407  enum class SILENCE_DEPRECATION_WARNING { PLEASE = 0 };
409  output_fn data_output_fn, data_cb app_data_cb,
410  std::function<void (Alert)> recv_alert_cb,
411  handshake_cb hs_cb,
412  handshake_msg_cb hs_msg_cb = nullptr,
413  next_protocol_fn next_proto = nullptr)
414  : m_output_function(data_output_fn),
415  m_app_data_cb(app_data_cb),
416  m_alert_cb(recv_alert_cb),
417  m_hs_cb(hs_cb),
418  m_hs_msg_cb(hs_msg_cb),
419  m_next_proto(next_proto) {}
420 
422  output_fn data_output_fn, data_cb app_data_cb, alert_cb recv_alert_cb,
423  handshake_cb hs_cb, handshake_msg_cb hs_msg_cb = nullptr,
424  next_protocol_fn next_proto = nullptr)
425  : m_output_function(data_output_fn), m_app_data_cb(app_data_cb),
426  m_alert_cb(std::bind(recv_alert_cb, std::placeholders::_1, nullptr, 0)),
427  m_hs_cb(hs_cb), m_hs_msg_cb(hs_msg_cb), m_next_proto(next_proto) {}
428 
429 
430  void tls_emit_data(const uint8_t data[], size_t size) override
431  {
432  BOTAN_ASSERT(m_output_function != nullptr,
433  "Invalid TLS output function callback.");
434  m_output_function(data, size);
435  }
436 
437  void tls_record_received(uint64_t /*seq_no*/, const uint8_t data[], size_t size) override
438  {
439  BOTAN_ASSERT(m_app_data_cb != nullptr,
440  "Invalid TLS app data callback.");
441  m_app_data_cb(data, size);
442  }
443 
444  void tls_alert(Alert alert) override
445  {
446  BOTAN_ASSERT(m_alert_cb != nullptr,
447  "Invalid TLS alert callback.");
448  m_alert_cb(alert);
449  }
450 
451  bool tls_session_established(const Session& session) override
452  {
453  BOTAN_ASSERT(m_hs_cb != nullptr,
454  "Invalid TLS handshake callback.");
455  return m_hs_cb(session);
456  }
457 
458  std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos) override
459  {
460  if(m_next_proto != nullptr) { return m_next_proto(client_protos); }
461  return "";
462  }
463 
464  void tls_inspect_handshake_msg(const Handshake_Message& hmsg) override
465  {
466  // The handshake message callback is optional so we can
467  // not assume it has been set.
468  if(m_hs_msg_cb != nullptr) { m_hs_msg_cb(hmsg); }
469  }
470 
471  private:
472  const output_fn m_output_function;
473  const data_cb m_app_data_cb;
474  const std::function<void (Alert)> m_alert_cb;
475  const handshake_cb m_hs_cb;
476  const handshake_msg_cb m_hs_msg_cb;
477  const next_protocol_fn m_next_proto;
478  };
479 
480 }
481 
482 }
483 
484 #endif
std::function< void(const uint8_t[], size_t)> data_cb
void tls_emit_data(const uint8_t data[], size_t size) override
virtual void tls_log_debug(const char *what)
Compat_Callbacks(SILENCE_DEPRECATION_WARNING, output_fn data_output_fn, data_cb app_data_cb, std::function< void(Alert)> recv_alert_cb, handshake_cb hs_cb, handshake_msg_cb hs_msg_cb=nullptr, next_protocol_fn next_proto=nullptr)
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Signature_Format
Definition: pubkey.h:28
Definition: bigint.h:1136
void tls_alert(Alert alert) override
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
std::function< bool(const Session &)> handshake_cb
std::function< void(Alert, const uint8_t[], size_t)> alert_cb
bool tls_session_established(const Session &session) override
virtual std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const
Definition: alg_id.cpp:13
#define BOTAN_UNUSED(...)
Definition: assert.h:142
Compat_Callbacks(SILENCE_DEPRECATION_WARNING, output_fn data_output_fn, data_cb app_data_cb, alert_cb recv_alert_cb, handshake_cb hs_cb, handshake_msg_cb hs_msg_cb=nullptr, next_protocol_fn next_proto=nullptr)
virtual void tls_session_activated()
Definition: tls_callbacks.h:97
std::function< void(const uint8_t[], size_t)> output_fn
std::function< void(const Handshake_Message &)> handshake_msg_cb
std::function< std::string(std::vector< std::string >)> next_protocol_fn
void tls_inspect_handshake_msg(const Handshake_Message &hmsg) override
std::string tls_server_choose_app_protocol(const std::vector< std::string > &client_protos) override
virtual void tls_log_error(const char *err)
virtual void tls_log_debug_bin(const char *descr, const uint8_t val[], size_t val_len)
Usage_Type
Definition: x509cert.h:25
virtual std::vector< uint8_t > tls_provide_cert_status(const std::vector< X509_Certificate > &chain, const Certificate_Status_Request &csr)
void tls_record_received(uint64_t, const uint8_t data[], size_t size) override