Botan 2.19.1
Crypto and TLS for C&
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
18namespace Botan {
19
20class Certificate_Store;
21class X509_Certificate;
22
23namespace OCSP {
24
25class Response;
26
27}
28
29namespace TLS {
30
31class Handshake_Message;
32class Policy;
33class Extensions;
34class 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,
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,
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
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
#define BOTAN_UNUSED(...)
Definition: assert.h:142
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
virtual std::vector< uint8_t > tls_provide_cert_status(const std::vector< X509_Certificate > &chain, const Certificate_Status_Request &csr)
virtual std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const
virtual void tls_emit_data(const uint8_t data[], size_t size)=0
virtual ~Callbacks()=default
virtual void tls_log_debug(const char *what)
virtual void tls_session_activated()
Definition: tls_callbacks.h:97
virtual bool tls_session_established(const Session &session)=0
virtual void tls_log_debug_bin(const char *descr, const uint8_t val[], size_t val_len)
virtual void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size)=0
virtual void tls_log_error(const char *err)
virtual void tls_alert(Alert alert)=0
bool tls_session_established(const Session &session) override
std::function< void(Alert, const uint8_t[], size_t)> alert_cb
std::function< std::string(std::vector< std::string >)> next_protocol_fn
std::string tls_server_choose_app_protocol(const std::vector< std::string > &client_protos) override
void tls_inspect_handshake_msg(const Handshake_Message &hmsg) override
std::function< void(const Handshake_Message &)> handshake_msg_cb
std::function< bool(const Session &)> handshake_cb
std::function< void(const uint8_t[], size_t)> data_cb
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)
void tls_alert(Alert alert) override
void tls_emit_data(const uint8_t data[], size_t size) override
std::function< void(const uint8_t[], size_t)> output_fn
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)
void tls_record_received(uint64_t, const uint8_t data[], size_t size) override
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Definition: alg_id.cpp:13
Usage_Type
Definition: x509cert.h:23
Signature_Format
Definition: pk_keys.h:23
Definition: bigint.h:1143