Coverage Report

Created: 2020-05-23 13:54

/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 <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
*/
40
class BOTAN_PUBLIC_API(2,0) Callbacks
41
   {
42
   public:
43
10.1k
       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
457
       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
626
          {
146
626
          return std::chrono::milliseconds(0);
147
626
          }
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
2
          {
162
2
          BOTAN_UNUSED(chain);
163
2
          BOTAN_UNUSED(csr);
164
2
          return std::vector<uint8_t>();
165
2
          }
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,
183
          RandomNumberGenerator& rng,
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,
248
          RandomNumberGenerator& rng,
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
0
          {
337
0
          BOTAN_UNUSED(err);
338
0
          }
Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_error(char const*)
Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_error(char const*)
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
0
          {
346
0
          BOTAN_UNUSED(what);
347
0
          }
Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_debug(char const*)
Unexecuted instantiation: Botan::TLS::Callbacks::tls_log_debug(char const*)
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
0
          {
357
0
          BOTAN_UNUSED(descr, val, val_len);
358
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)
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
*/
366
class BOTAN_PUBLIC_API(2,0) Compat_Callbacks final : public Callbacks
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
0
            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
0
            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 };
408
       Compat_Callbacks(SILENCE_DEPRECATION_WARNING,
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
0
            m_next_proto(next_proto) {}
420
421
       Compat_Callbacks(SILENCE_DEPRECATION_WARNING,
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
0
            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
0
          {
432
0
          BOTAN_ASSERT(m_output_function != nullptr,
433
0
                       "Invalid TLS output function callback.");
434
0
          m_output_function(data, size);
435
0
          }
Unexecuted instantiation: Botan::TLS::Compat_Callbacks::tls_emit_data(unsigned char const*, unsigned long)
Unexecuted instantiation: Botan::TLS::Compat_Callbacks::tls_emit_data(unsigned char const*, unsigned long)
436
437
       void tls_record_received(uint64_t /*seq_no*/, const uint8_t data[], size_t size) override
438
0
          {
439
0
          BOTAN_ASSERT(m_app_data_cb != nullptr,
440
0
                       "Invalid TLS app data callback.");
441
0
          m_app_data_cb(data, size);
442
0
          }
Unexecuted instantiation: Botan::TLS::Compat_Callbacks::tls_record_received(unsigned long, unsigned char const*, unsigned long)
Unexecuted instantiation: Botan::TLS::Compat_Callbacks::tls_record_received(unsigned long, unsigned char const*, unsigned long)
443
444
       void tls_alert(Alert alert) override
445
0
          {
446
0
          BOTAN_ASSERT(m_alert_cb != nullptr,
447
0
                       "Invalid TLS alert callback.");
448
0
          m_alert_cb(alert);
449
0
          }
Unexecuted instantiation: Botan::TLS::Compat_Callbacks::tls_alert(Botan::TLS::Alert)
Unexecuted instantiation: Botan::TLS::Compat_Callbacks::tls_alert(Botan::TLS::Alert)
450
451
       bool tls_session_established(const Session& session) override
452
0
          {
453
0
          BOTAN_ASSERT(m_hs_cb != nullptr,
454
0
                       "Invalid TLS handshake callback.");
455
0
          return m_hs_cb(session);
456
0
          }
Unexecuted instantiation: Botan::TLS::Compat_Callbacks::tls_session_established(Botan::TLS::Session const&)
Unexecuted instantiation: Botan::TLS::Compat_Callbacks::tls_session_established(Botan::TLS::Session const&)
457
458
       std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos) override
459
0
          {
460
0
          if(m_next_proto != nullptr) { return m_next_proto(client_protos); }
461
0
          return "";
462
0
          }
463
464
       void tls_inspect_handshake_msg(const Handshake_Message& hmsg) override
465
0
          {
466
0
          // The handshake message callback is optional so we can
467
0
          // not assume it has been set.
468
0
          if(m_hs_msg_cb != nullptr) { m_hs_msg_cb(hmsg); }
469
0
          }
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