/src/botan/build/include/botan/tls_callbacks.h
Line | Count | Source (jump to first uncovered line) |
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 <botan/ocsp.h> |
17 | | #include <optional> |
18 | | #include <chrono> |
19 | | |
20 | | namespace Botan { |
21 | | |
22 | | class Certificate_Store; |
23 | | class X509_Certificate; |
24 | | |
25 | | namespace OCSP { |
26 | | |
27 | | class Response; |
28 | | |
29 | | } |
30 | | |
31 | | namespace TLS { |
32 | | |
33 | | class Handshake_Message; |
34 | | class Policy; |
35 | | class Extensions; |
36 | | class Certificate_Status_Request; |
37 | | |
38 | | /** |
39 | | * Encapsulates the callbacks that a TLS channel will make which are due to |
40 | | * channel specific operations. |
41 | | */ |
42 | | class BOTAN_PUBLIC_API(2,0) Callbacks |
43 | | { |
44 | | public: |
45 | 5.96k | virtual ~Callbacks() = default; |
46 | | |
47 | | /** |
48 | | * Mandatory callback: output function |
49 | | * The channel will call this with data which needs to be sent to the peer |
50 | | * (eg, over a socket or some other form of IPC). The array will be overwritten |
51 | | * when the function returns so a copy must be made if the data cannot be |
52 | | * sent immediately. |
53 | | * |
54 | | * @param data the vector of data to send |
55 | | * |
56 | | * @param size the number of bytes to send |
57 | | */ |
58 | | virtual void tls_emit_data(const uint8_t data[], size_t size) = 0; |
59 | | |
60 | | /** |
61 | | * Mandatory callback: process application data |
62 | | * Called when application data record is received from the peer. |
63 | | * Again the array is overwritten immediately after the function returns. |
64 | | * |
65 | | * @param seq_no the underlying TLS/DTLS record sequence number |
66 | | * |
67 | | * @param data the vector containing the received record |
68 | | * |
69 | | * @param size the length of the received record, in bytes |
70 | | */ |
71 | | virtual void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) = 0; |
72 | | |
73 | | /** |
74 | | * Mandatory callback: alert received |
75 | | * Called when an alert is received from the peer |
76 | | * If fatal, the connection is closing. If not fatal, the connection may |
77 | | * still be closing (depending on the error and the peer). |
78 | | * |
79 | | * @param alert the source of the alert |
80 | | */ |
81 | | virtual void tls_alert(Alert alert) = 0; |
82 | | |
83 | | /** |
84 | | * Mandatory callback: session established |
85 | | * Called when a session is established. Throw an exception to abort |
86 | | * the connection. |
87 | | * |
88 | | * @param session the session descriptor |
89 | | * |
90 | | * @return return false to prevent the session from being cached, |
91 | | * return true to cache the session in the configured session manager |
92 | | */ |
93 | | virtual bool tls_session_established(const Session& session) = 0; |
94 | | |
95 | | /** |
96 | | * Optional callback: session activated |
97 | | * Called when a session is active and can be written to |
98 | | */ |
99 | 308 | virtual void tls_session_activated() {} |
100 | | |
101 | | /** |
102 | | * Optional callback with default impl: verify cert chain |
103 | | * |
104 | | * Default implementation performs a standard PKIX validation |
105 | | * and initiates network OCSP request for end-entity cert. |
106 | | * Override to provide different behavior. |
107 | | * |
108 | | * Check the certificate chain is valid up to a trusted root, and |
109 | | * optionally (if hostname != "") that the hostname given is |
110 | | * consistent with the leaf certificate. |
111 | | * |
112 | | * This function should throw an exception derived from |
113 | | * std::exception with an informative what() result if the |
114 | | * certificate chain cannot be verified. |
115 | | * |
116 | | * @param cert_chain specifies a certificate chain leading to a |
117 | | * trusted root CA certificate. |
118 | | * @param ocsp_responses the server may have provided some |
119 | | * @param trusted_roots the list of trusted certificates |
120 | | * @param usage what this cert chain is being used for |
121 | | * Usage_Type::TLS_SERVER_AUTH for server chains, |
122 | | * Usage_Type::TLS_CLIENT_AUTH for client chains, |
123 | | * Usage_Type::UNSPECIFIED for other uses |
124 | | * @param hostname when authenticating a server, this is the hostname |
125 | | * the client requested (eg via SNI). When authenticating a client, |
126 | | * this is the server name the client is authenticating *to*. |
127 | | * Empty in other cases or if no hostname was used. |
128 | | * @param policy the TLS policy associated with the session being authenticated |
129 | | * using the certificate chain |
130 | | */ |
131 | | virtual void tls_verify_cert_chain( |
132 | | const std::vector<X509_Certificate>& cert_chain, |
133 | | const std::vector<std::optional<OCSP::Response>>& ocsp_responses, |
134 | | const std::vector<Certificate_Store*>& trusted_roots, |
135 | | Usage_Type usage, |
136 | | const std::string& hostname, |
137 | | const TLS::Policy& policy); |
138 | | |
139 | | /** |
140 | | * Called by default `tls_verify_cert_chain` to get the timeout to use for OCSP |
141 | | * requests. Return 0 to disable online OCSP checks. |
142 | | * |
143 | | * This function should not be "const" since the implementation might need |
144 | | * to perform some side effecting operation to compute the result. |
145 | | */ |
146 | | virtual std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const |
147 | 0 | { |
148 | 0 | return std::chrono::milliseconds(0); |
149 | 0 | } |
150 | | |
151 | | /** |
152 | | * Called by the TLS server whenever the client included the |
153 | | * status_request extension (see RFC 6066, a.k.a OCSP stapling) |
154 | | * in the ClientHello. |
155 | | * |
156 | | * @return the encoded OCSP response to be sent to the client which |
157 | | * indicates the revocation status of the server certificate. Return an |
158 | | * empty vector to indicate that no response is available, and thus |
159 | | * suppress the Certificate_Status message. |
160 | | */ |
161 | | virtual std::vector<uint8_t> tls_provide_cert_status(const std::vector<X509_Certificate>& chain, |
162 | | const Certificate_Status_Request& csr) |
163 | 12 | { |
164 | 12 | BOTAN_UNUSED(chain); |
165 | 12 | BOTAN_UNUSED(csr); |
166 | 12 | return std::vector<uint8_t>(); |
167 | 12 | } |
168 | | |
169 | | /** |
170 | | * Optional callback with default impl: sign a message |
171 | | * |
172 | | * Default implementation uses PK_Signer::sign_message(). |
173 | | * Override to provide a different approach, e.g. using an external device. |
174 | | * |
175 | | * @param key the private key of the signer |
176 | | * @param rng a random number generator |
177 | | * @param emsa the encoding method to be applied to the message |
178 | | * @param format the signature format |
179 | | * @param msg the input data for the signature |
180 | | * |
181 | | * @return the signature |
182 | | */ |
183 | | virtual std::vector<uint8_t> tls_sign_message( |
184 | | const Private_Key& key, |
185 | | RandomNumberGenerator& rng, |
186 | | const std::string& emsa, |
187 | | Signature_Format format, |
188 | | const std::vector<uint8_t>& msg); |
189 | | |
190 | | /** |
191 | | * Optional callback with default impl: verify a message signature |
192 | | * |
193 | | * Default implementation uses PK_Verifier::verify_message(). |
194 | | * Override to provide a different approach, e.g. using an external device. |
195 | | * |
196 | | * @param key the public key of the signer |
197 | | * @param emsa the encoding method to be applied to the message |
198 | | * @param format the signature format |
199 | | * @param msg the input data for the signature |
200 | | * @param sig the signature to be checked |
201 | | * |
202 | | * @return true if the signature is valid, false otherwise |
203 | | */ |
204 | | virtual bool tls_verify_message( |
205 | | const Public_Key& key, |
206 | | const std::string& emsa, |
207 | | Signature_Format format, |
208 | | const std::vector<uint8_t>& msg, |
209 | | const std::vector<uint8_t>& sig); |
210 | | |
211 | | /** |
212 | | * Optional callback with default impl: client side DH agreement |
213 | | * |
214 | | * Default implementation uses PK_Key_Agreement::derive_key(). |
215 | | * Override to provide a different approach, e.g. using an external device. |
216 | | * |
217 | | * @param modulus the modulus p of the discrete logarithm group |
218 | | * @param generator the generator of the DH subgroup |
219 | | * @param peer_public_value the public value of the peer |
220 | | * @param policy the TLS policy associated with the session being established |
221 | | * @param rng a random number generator |
222 | | * |
223 | | * @return a pair consisting of the agreed raw secret and our public value |
224 | | */ |
225 | | virtual std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> tls_dh_agree( |
226 | | const std::vector<uint8_t>& modulus, |
227 | | const std::vector<uint8_t>& generator, |
228 | | const std::vector<uint8_t>& peer_public_value, |
229 | | const Policy& policy, |
230 | | RandomNumberGenerator& rng); |
231 | | |
232 | | /** |
233 | | * Optional callback with default impl: client side ECDH agreement |
234 | | * |
235 | | * Default implementation uses PK_Key_Agreement::derive_key(). |
236 | | * Override to provide a different approach, e.g. using an external device. |
237 | | * |
238 | | * @param curve_name the name of the elliptic curve |
239 | | * @param peer_public_value the public value of the peer |
240 | | * @param policy the TLS policy associated with the session being established |
241 | | * @param rng a random number generator |
242 | | * @param compressed the compression preference for our public value |
243 | | * |
244 | | * @return a pair consisting of the agreed raw secret and our public value |
245 | | */ |
246 | | virtual std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> tls_ecdh_agree( |
247 | | const std::string& curve_name, |
248 | | const std::vector<uint8_t>& peer_public_value, |
249 | | const Policy& policy, |
250 | | RandomNumberGenerator& rng, |
251 | | bool compressed); |
252 | | |
253 | | /** |
254 | | * Optional callback: inspect handshake message |
255 | | * Throw an exception to abort the handshake. |
256 | | * Default simply ignores the message. |
257 | | * |
258 | | * @param message the handshake message |
259 | | */ |
260 | | virtual void tls_inspect_handshake_msg(const Handshake_Message& message); |
261 | | |
262 | | /** |
263 | | * Optional callback for server: choose ALPN protocol |
264 | | * |
265 | | * ALPN (RFC 7301) works by the client sending a list of application |
266 | | * protocols it is willing to negotiate. The server then selects which |
267 | | * protocol to use. RFC 7301 requires that if the server does not support |
268 | | * any protocols offered by the client, then it should close the connection |
269 | | * with an alert of no_application_protocol. Within this callback this would |
270 | | * be done by throwing a TLS_Exception(Alert::NO_APPLICATION_PROTOCOL) |
271 | | * |
272 | | * @param client_protos the vector of protocols the client is willing to negotiate |
273 | | * |
274 | | * @return the protocol selected by the server; if the empty string is |
275 | | * returned, the server does not reply to the client ALPN extension. |
276 | | * |
277 | | * The default implementation returns the empty string, causing client |
278 | | * ALPN to be ignored. |
279 | | * |
280 | | * It is highly recommended to support ALPN whenever possible to avoid |
281 | | * cross-protocol attacks. |
282 | | */ |
283 | | virtual std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos); |
284 | | |
285 | | /** |
286 | | * Optional callback: examine/modify Extensions before sending. |
287 | | * |
288 | | * Both client and server will call this callback on the Extensions object |
289 | | * before serializing it in the client/server hellos. This allows an |
290 | | * application to modify which extensions are sent during the |
291 | | * handshake. |
292 | | * |
293 | | * Default implementation does nothing. |
294 | | * |
295 | | * @param extn the extensions |
296 | | * @param which_side will be CLIENT or SERVER which is the current |
297 | | * applications role in the exchange. |
298 | | */ |
299 | | virtual void tls_modify_extensions(Extensions& extn, Connection_Side which_side); |
300 | | |
301 | | /** |
302 | | * Optional callback: examine peer extensions. |
303 | | * |
304 | | * Both client and server will call this callback with the Extensions |
305 | | * object after receiving it from the peer. This allows examining the |
306 | | * Extensions, for example to implement a custom extension. It also allows |
307 | | * an application to require that a particular extension be implemented; |
308 | | * throw an exception from this function to abort the handshake. |
309 | | * |
310 | | * Default implementation does nothing. |
311 | | * |
312 | | * @param extn the extensions |
313 | | * @param which_side will be CLIENT if these are are the clients extensions (ie we are |
314 | | * the server) or SERVER if these are the server extensions (we are the client). |
315 | | */ |
316 | | virtual void tls_examine_extensions(const Extensions& extn, Connection_Side which_side); |
317 | | |
318 | | /** |
319 | | * Optional callback: decode TLS group ID |
320 | | * |
321 | | * TLS uses a 16-bit field to identify ECC and DH groups. This callback |
322 | | * handles the decoding. You only need to implement this if you are using |
323 | | * a custom ECC or DH group (this is extremely uncommon). |
324 | | * |
325 | | * Default implementation uses the standard (IETF-defined) mappings. |
326 | | * |
327 | | * TODO: reconsider this callback together with `tls_dh_agree` and `tls_ecdh_agree`. |
328 | | */ |
329 | | virtual std::string tls_decode_group_param(Group_Params group_param); |
330 | | |
331 | | /** |
332 | | * Optional callback: parse a single OCSP Response |
333 | | * |
334 | | * Note: Typically a user of the library would not want to override this |
335 | | * callback. We provide this callback to be able to support OCSP |
336 | | * related tests from BoringSSL's BoGo tests that provide unparsable |
337 | | * responses. |
338 | | * |
339 | | * Default implementation tries to parse the provided raw OCSP response. |
340 | | * |
341 | | * This function should not throw an exception but return a std::nullopt |
342 | | * if the OCSP response cannot be parsed. |
343 | | * |
344 | | * @param raw_response raw OCSP response buffer |
345 | | * @returns the parsed OCSP response or std::nullopt on error |
346 | | */ |
347 | | virtual std::optional<OCSP::Response> tls_parse_ocsp_response(const std::vector<uint8_t>& raw_response); |
348 | | |
349 | | /** |
350 | | * Optional callback: return peer network identity |
351 | | * |
352 | | * There is no expected or specified format. The only expectation is this |
353 | | * function will return a unique value. For example returning the peer |
354 | | * host IP and port. |
355 | | * |
356 | | * This is used to bind the DTLS cookie to a particular network identity. |
357 | | * It is only called if the dtls-cookie-secret PSK is also defined. |
358 | | */ |
359 | | virtual std::string tls_peer_network_identity(); |
360 | | |
361 | | /** |
362 | | * Optional callback: return a custom time stamp value |
363 | | * |
364 | | * This allows the library user to specify a custom "now" timestamp when |
365 | | * needed. By default it will use the current system clock time. |
366 | | * |
367 | | * Note that typical usages will not need to override this callback but it |
368 | | * is useful for testing purposes to allow for deterministic test outcomes. |
369 | | */ |
370 | | virtual std::chrono::system_clock::time_point tls_current_timestamp(); |
371 | | |
372 | | /** |
373 | | * Optional callback: error logging. (not currently called) |
374 | | * @param err An error message related to this connection. |
375 | | */ |
376 | | virtual void tls_log_error(const char* err) |
377 | 0 | { |
378 | 0 | BOTAN_UNUSED(err); |
379 | 0 | } Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_error(char const*) Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_error(char const*) |
380 | | |
381 | | /** |
382 | | * Optional callback: debug logging. (not currently called) |
383 | | * @param what Some hopefully informative string |
384 | | */ |
385 | | virtual void tls_log_debug(const char* what) |
386 | 0 | { |
387 | 0 | BOTAN_UNUSED(what); |
388 | 0 | } Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_debug(char const*) Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_debug(char const*) |
389 | | |
390 | | /** |
391 | | * Optional callback: debug logging taking a buffer. (not currently called) |
392 | | * @param descr What this buffer is |
393 | | * @param val the bytes |
394 | | * @param val_len length of val |
395 | | */ |
396 | | virtual void tls_log_debug_bin(const char* descr, const uint8_t val[], size_t val_len) |
397 | 0 | { |
398 | 0 | BOTAN_UNUSED(descr, val, val_len); |
399 | 0 | } Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_debug_bin(char const*, unsigned char const*, unsigned long) Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_debug_bin(char const*, unsigned char const*, unsigned long) |
400 | | }; |
401 | | |
402 | | } |
403 | | |
404 | | } |
405 | | |
406 | | #endif |