Botan  2.1.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 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #ifndef BOTAN_TLS_CALLBACKS_H__
10 #define BOTAN_TLS_CALLBACKS_H__
11 
12 #include <botan/tls_session.h>
13 #include <botan/tls_alert.h>
14 
15 namespace Botan {
16 
17 class Certificate_Store;
18 class X509_Certificate;
19 
20 namespace OCSP {
21 
22 class Response;
23 
24 }
25 
26 namespace TLS {
27 
28 class Handshake_Message;
29 class Policy;
30 
31 /**
32 * Encapsulates the callbacks that a TLS channel will make which are due to
33 * channel specific operations.
34 */
35 class BOTAN_DLL Callbacks
36  {
37  public:
38  virtual ~Callbacks() = default;
39 
40  /**
41  * Mandatory callback: output function
42  * The channel will call this with data which needs to be sent to the peer
43  * (eg, over a socket or some other form of IPC). The array will be overwritten
44  * when the function returns so a copy must be made if the data cannot be
45  * sent immediately.
46  *
47  * @param data the vector of data to send
48  *
49  * @param size the number of bytes to send
50  */
51  virtual void tls_emit_data(const uint8_t data[], size_t size) = 0;
52 
53  /**
54  * Mandatory callback: process application data
55  * Called when application data record is received from the peer.
56  * Again the array is overwritten immediately after the function returns.
57  *
58  * @param seq_no the underlying TLS/DTLS record sequence number
59  *
60  * @param data the vector containing the received record
61  *
62  * @param size the length of the received record, in bytes
63  */
64  virtual void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) = 0;
65 
66  /**
67  * Mandatory callback: alert received
68  * Called when an alert is received from the peer
69  * If fatal, the connection is closing. If not fatal, the connection may
70  * still be closing (depending on the error and the peer).
71  *
72  * @param alert the source of the alert
73  */
74  virtual void tls_alert(Alert alert) = 0;
75 
76  /**
77  * Mandatory callback: session established
78  * Called when a session is established. Throw an exception to abort
79  * the connection.
80  *
81  * @param session the session descriptor
82  *
83  * @return return false to prevent the session from being cached,
84  * return true to cache the session in the configured session manager
85  */
86  virtual bool tls_session_established(const Session& session) = 0;
87 
88  /**
89  * Optional callback: session activated
90  * Called when a session is active and can be written to
91  */
92  virtual void tls_session_activated() {}
93 
94  /**
95  * Optional callback with default impl: verify cert chain
96  *
97  * Default implementation performs a standard PKIX validation
98  * and initiates network OCSP request for end-entity cert.
99  * Override to provide different behavior.
100  *
101  * Check the certificate chain is valid up to a trusted root, and
102  * optionally (if hostname != "") that the hostname given is
103  * consistent with the leaf certificate.
104  *
105  * This function should throw an exception derived from
106  * std::exception with an informative what() result if the
107  * certificate chain cannot be verified.
108  *
109  * @param cert_chain specifies a certificate chain leading to a
110  * trusted root CA certificate.
111  * @param ocsp_responses the server may have provided some
112  * @param trusted_roots the list of trusted certificates
113  * @param usage what this cert chain is being used for
114  * Usage_Type::TLS_SERVER_AUTH for server chains,
115  * Usage_Type::TLS_CLIENT_AUTH for client chains,
116  * Usage_Type::UNSPECIFIED for other uses
117  * @param hostname when authenticating a server, this is the hostname
118  * the client requested (eg via SNI). When authenticating a client,
119  * this is the server name the client is authenticating *to*.
120  * Empty in other cases or if no hostname was used.
121  * @param policy the TLS policy associated with the session being authenticated
122  * using the certificate chain
123  */
124  virtual void tls_verify_cert_chain(
125  const std::vector<X509_Certificate>& cert_chain,
126  const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses,
127  const std::vector<Certificate_Store*>& trusted_roots,
128  Usage_Type usage,
129  const std::string& hostname,
130  const TLS::Policy& policy);
131 
132  /**
133  * Called by default `tls_verify_cert_chain` to get the timeout to use for OCSP
134  * requests. Return 0 to disable online OCSP checks.
135  */
136  virtual std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const
137  {
138  return std::chrono::milliseconds(0);
139  }
140 
141  /**
142  * Optional callback: inspect handshake message
143  * Throw an exception to abort the handshake.
144  * Default simply ignores the message.
145  *
146  * @param message the handshake message
147  */
148  virtual void tls_inspect_handshake_msg(const Handshake_Message& message);
149 
150  /**
151  * Optional callback for server: choose ALPN protocol
152  * ALPN (RFC 7301) works by the client sending a list of application
153  * protocols it is willing to negotiate. The server then selects which
154  * protocol to use, which is not necessarily even on the list that
155  * the client sent.
156  *
157  * @param client_protos the vector of protocols the client is willing to negotiate
158  *
159  * @return the protocol selected by the server, which need not be on the
160  * list that the client sent; if this is the empty string, the server ignores the
161  * client ALPN extension. Default return value is empty string.
162  */
163  virtual std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos);
164 
165  /**
166  * Optional callback: error logging. (not currently called)
167  * @param err An error message related to this connection.
168  */
169  virtual void tls_log_error(const char* err)
170  {
171  BOTAN_UNUSED(err);
172  }
173 
174  /**
175  * Optional callback: debug logging. (not currently called)
176  * @param what Some hopefully informative string
177  */
178  virtual void tls_log_debug(const char* what)
179  {
180  BOTAN_UNUSED(what);
181  }
182 
183  /**
184  * Optional callback: debug logging taking a buffer. (not currently called)
185  * @param descr What this buffer is
186  * @param val the bytes
187  * @param val_len length of val
188  */
189  virtual void tls_log_debug_bin(const char* descr, const uint8_t val[], size_t val_len)
190  {
191  BOTAN_UNUSED(descr);
192  BOTAN_UNUSED(val);
193  BOTAN_UNUSED(val_len);
194  }
195  };
196 
197 /**
198 * TLS::Callbacks using std::function for compatability with the old API signatures.
199 * This type is only provided for backward compatibility.
200 * New implementations should derive from TLS::Callbacks instead.
201 */
202 class BOTAN_DLL Compat_Callbacks final : public Callbacks
203  {
204  public:
205  typedef std::function<void (const uint8_t[], size_t)> output_fn;
206  typedef std::function<void (const uint8_t[], size_t)> data_cb;
207  typedef std::function<void (Alert, const uint8_t[], size_t)> alert_cb;
208  typedef std::function<bool (const Session&)> handshake_cb;
209  typedef std::function<void (const Handshake_Message&)> handshake_msg_cb;
210  typedef std::function<std::string (std::vector<std::string>)> next_protocol_fn;
211 
212  /**
213  * @param output_fn is called with data for the outbound socket
214  *
215  * @param app_data_cb is called when new application data is received
216  *
217  * @param alert_cb is called when a TLS alert is received
218  *
219  * @param hs_cb is called when a handshake is completed
220  *
221  * @param hs_msg_cb is called for each handshake message received
222  *
223  * @param next_proto is called with ALPN protocol data sent by the client
224  */
225  BOTAN_DEPRECATED("Use TLS::Callbacks (virtual interface).")
226  Compat_Callbacks(output_fn output_fn, data_cb app_data_cb, alert_cb alert_cb,
227  handshake_cb hs_cb, handshake_msg_cb hs_msg_cb = nullptr,
228  next_protocol_fn next_proto = nullptr)
229  : m_output_function(output_fn), m_app_data_cb(app_data_cb),
230  m_alert_cb(std::bind(alert_cb, std::placeholders::_1, nullptr, 0)),
231  m_hs_cb(hs_cb), m_hs_msg_cb(hs_msg_cb), m_next_proto(next_proto) {}
232 
233  BOTAN_DEPRECATED("Use TLS::Callbacks (virtual interface).")
234  Compat_Callbacks(output_fn output_fn, data_cb app_data_cb,
235  std::function<void (Alert)> alert_cb,
236  handshake_cb hs_cb,
237  handshake_msg_cb hs_msg_cb = nullptr,
238  next_protocol_fn next_proto = nullptr)
239  : m_output_function(output_fn), m_app_data_cb(app_data_cb),
240  m_alert_cb(alert_cb),
241  m_hs_cb(hs_cb), m_hs_msg_cb(hs_msg_cb), m_next_proto(next_proto) {}
242 
243  void tls_emit_data(const uint8_t data[], size_t size) override
244  {
245  BOTAN_ASSERT(m_output_function != nullptr,
246  "Invalid TLS output function callback.");
247  m_output_function(data, size);
248  }
249 
250  void tls_record_received(uint64_t /*seq_no*/, const uint8_t data[], size_t size) override
251  {
252  BOTAN_ASSERT(m_app_data_cb != nullptr,
253  "Invalid TLS app data callback.");
254  m_app_data_cb(data, size);
255  }
256 
257  void tls_alert(Alert alert) override
258  {
259  BOTAN_ASSERT(m_alert_cb != nullptr,
260  "Invalid TLS alert callback.");
261  m_alert_cb(alert);
262  }
263 
264  bool tls_session_established(const Session& session) override
265  {
266  BOTAN_ASSERT(m_hs_cb != nullptr,
267  "Invalid TLS handshake callback.");
268  return m_hs_cb(session);
269  }
270 
271  std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos) override
272  {
273  if(m_next_proto != nullptr) { return m_next_proto(client_protos); }
274  return "";
275  }
276 
277  void tls_inspect_handshake_msg(const Handshake_Message& hmsg) override
278  {
279  // The handshake message callback is optional so we can
280  // not assume it has been set.
281  if(m_hs_msg_cb != nullptr) { m_hs_msg_cb(hmsg); }
282  }
283 
284  private:
285  const output_fn m_output_function;
286  const data_cb m_app_data_cb;
287  const std::function<void (Alert)> m_alert_cb;
288  const handshake_cb m_hs_cb;
289  const handshake_msg_cb m_hs_msg_cb;
290  const next_protocol_fn m_next_proto;
291  };
292 
293 }
294 
295 }
296 
297 #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)
Definition: bigint.h:619
void tls_alert(Alert alert) override
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
std::function< bool(const Session &)> handshake_cb
class BOTAN_DLL BOTAN_DEPRECATED("LibraryInitializer is no longer required") LibraryInitializer
Definition: init.h:22
#define BOTAN_UNUSED(v)
Definition: assert.h:92
std::function< void(Alert, const uint8_t[], size_t)> alert_cb
bool tls_session_established(const Session &session) override
Definition: alg_id.cpp:13
virtual void tls_session_activated()
Definition: tls_callbacks.h:92
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
virtual std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const
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:24
void tls_record_received(uint64_t, const uint8_t data[], size_t size) override