Coverage Report

Created: 2022-09-23 06:05

/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
7.12k
       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
337
       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
24
          {
164
24
          BOTAN_UNUSED(chain);
165
24
          BOTAN_UNUSED(csr);
166
24
          return std::vector<uint8_t>();
167
24
          }
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
       * TODO: Currently, this is called in TLS 1.2 only. The key agreement mechanics
226
       *       changed in TLS 1.3, so this callback would (at least) need to be aware
227
       *       of the negotiated protocol version.
228
       *       Suggestion: Lets think about a more generic interface for this and
229
       *                   deprecate/remove this callback in Botan 3.0
230
       */
231
       virtual std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> tls_dh_agree(
232
          const std::vector<uint8_t>& modulus,
233
          const std::vector<uint8_t>& generator,
234
          const std::vector<uint8_t>& peer_public_value,
235
          const Policy& policy,
236
          RandomNumberGenerator& rng);
237
238
       /**
239
       * Optional callback with default impl: client side ECDH agreement
240
       *
241
       * Default implementation uses PK_Key_Agreement::derive_key().
242
       * Override to provide a different approach, e.g. using an external device.
243
       *
244
       * @param curve_name the name of the elliptic curve
245
       * @param peer_public_value the public value of the peer
246
       * @param policy the TLS policy associated with the session being established
247
       * @param rng a random number generator
248
       * @param compressed the compression preference for our public value
249
       *
250
       * @return a pair consisting of the agreed raw secret and our public value
251
       *
252
       * TODO: Currently, this is called in TLS 1.2 only. The key agreement mechanics
253
       *       changed in TLS 1.3, so this callback would (at least) need to be aware
254
       *       of the negotiated protocol version.
255
       *       Suggestion: Lets think about a more generic interface for this and
256
       *                   deprecate/remove this callback in Botan 3.0
257
       */
258
       virtual std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> tls_ecdh_agree(
259
          const std::string& curve_name,
260
          const std::vector<uint8_t>& peer_public_value,
261
          const Policy& policy,
262
          RandomNumberGenerator& rng,
263
          bool compressed);
264
265
       /**
266
       * Optional callback: inspect handshake message
267
       * Throw an exception to abort the handshake.
268
       * Default simply ignores the message.
269
       *
270
       * @param message the handshake message
271
       */
272
       virtual void tls_inspect_handshake_msg(const Handshake_Message& message);
273
274
       /**
275
       * Optional callback for server: choose ALPN protocol
276
       *
277
       * ALPN (RFC 7301) works by the client sending a list of application
278
       * protocols it is willing to negotiate. The server then selects which
279
       * protocol to use. RFC 7301 requires that if the server does not support
280
       * any protocols offered by the client, then it should close the connection
281
       * with an alert of no_application_protocol. Within this callback this would
282
       * be done by throwing a TLS_Exception(Alert::NO_APPLICATION_PROTOCOL)
283
       *
284
       * @param client_protos the vector of protocols the client is willing to negotiate
285
       *
286
       * @return the protocol selected by the server; if the empty string is
287
       * returned, the server does not reply to the client ALPN extension.
288
       *
289
       * The default implementation returns the empty string, causing client
290
       * ALPN to be ignored.
291
       *
292
       * It is highly recommended to support ALPN whenever possible to avoid
293
       * cross-protocol attacks.
294
       */
295
       virtual std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos);
296
297
       /**
298
       * Optional callback: examine/modify Extensions before sending.
299
       *
300
       * Both client and server will call this callback on the Extensions object
301
       * before serializing it in the client/server hellos. This allows an
302
       * application to modify which extensions are sent during the
303
       * handshake.
304
       *
305
       * Default implementation does nothing.
306
       *
307
       * @param extn the extensions
308
       * @param which_side will be CLIENT or SERVER which is the current
309
       * applications role in the exchange.
310
       */
311
       virtual void tls_modify_extensions(Extensions& extn, Connection_Side which_side);
312
313
       /**
314
       * Optional callback: examine peer extensions.
315
       *
316
       * Both client and server will call this callback with the Extensions
317
       * object after receiving it from the peer. This allows examining the
318
       * Extensions, for example to implement a custom extension. It also allows
319
       * an application to require that a particular extension be implemented;
320
       * throw an exception from this function to abort the handshake.
321
       *
322
       * Default implementation does nothing.
323
       *
324
       * @param extn the extensions
325
       * @param which_side will be CLIENT if these are are the clients extensions (ie we are
326
       *        the server) or SERVER if these are the server extensions (we are the client).
327
       */
328
       virtual void tls_examine_extensions(const Extensions& extn, Connection_Side which_side);
329
330
       /**
331
       * Optional callback: decode TLS group ID
332
       *
333
       * TLS uses a 16-bit field to identify ECC and DH groups. This callback
334
       * handles the decoding. You only need to implement this if you are using
335
       * a custom ECC or DH group (this is extremely uncommon).
336
       *
337
       * Default implementation uses the standard (IETF-defined) mappings.
338
       *
339
       * TODO: reconsider this callback together with `tls_dh_agree` and `tls_ecdh_agree`.
340
       */
341
       virtual std::string tls_decode_group_param(Group_Params group_param);
342
343
      /**
344
       * Optional callback: parse a single OCSP Response
345
       *
346
       * Note: Typically a user of the library would not want to override this
347
       *       callback. We provide this callback to be able to support OCSP
348
       *       related tests from BoringSSL's BoGo tests that provide unparsable
349
       *       responses.
350
       *
351
       * Default implementation tries to parse the provided raw OCSP response.
352
       *
353
       * This function should not throw an exception but return a std::nullopt
354
       * if the OCSP response cannot be parsed.
355
       *
356
       * @param raw_response raw OCSP response buffer
357
       * @returns the parsed OCSP response or std::nullopt on error
358
       */
359
       virtual std::optional<OCSP::Response> tls_parse_ocsp_response(const std::vector<uint8_t>& raw_response);
360
361
       /**
362
       * Optional callback: return peer network identity
363
       *
364
       * There is no expected or specified format. The only expectation is this
365
       * function will return a unique value. For example returning the peer
366
       * host IP and port.
367
       *
368
       * This is used to bind the DTLS cookie to a particular network identity.
369
       * It is only called if the dtls-cookie-secret PSK is also defined.
370
       */
371
       virtual std::string tls_peer_network_identity();
372
373
       /**
374
       * Optional callback: return a custom time stamp value
375
       *
376
       * This allows the library user to specify a custom "now" timestamp when
377
       * needed. By default it will use the current system clock time.
378
       *
379
       * Note that typical usages will not need to override this callback but it
380
       * is useful for testing purposes to allow for deterministic test outcomes.
381
       */
382
       virtual std::chrono::system_clock::time_point tls_current_timestamp();
383
384
       /**
385
       * Optional callback: error logging. (not currently called)
386
       * @param err An error message related to this connection.
387
       */
388
       virtual void tls_log_error(const char* err)
389
0
          {
390
0
          BOTAN_UNUSED(err);
391
0
          }
Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_error(char const*)
Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_error(char const*)
392
393
       /**
394
       * Optional callback: debug logging. (not currently called)
395
       * @param what Some hopefully informative string
396
       */
397
       virtual void tls_log_debug(const char* what)
398
0
          {
399
0
          BOTAN_UNUSED(what);
400
0
          }
Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_debug(char const*)
Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_debug(char const*)
401
402
       /**
403
       * Optional callback: debug logging taking a buffer. (not currently called)
404
       * @param descr What this buffer is
405
       * @param val the bytes
406
       * @param val_len length of val
407
       */
408
       virtual void tls_log_debug_bin(const char* descr, const uint8_t val[], size_t val_len)
409
0
          {
410
0
          BOTAN_UNUSED(descr, val, val_len);
411
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)
412
   };
413
414
}
415
416
}
417
418
#endif