• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5454043422

04 Jul 2023 11:13AM CUT coverage: 91.659% (-0.07%) from 91.732%
5454043422

Pull #3609

github

web-flow
Merge 5741e183c into cf8d8a6ca
Pull Request #3609: [TLS 1.3] Hybrid PQ/T key establishment

78635 of 85791 relevant lines covered (91.66%)

12300857.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.75
/src/lib/tls/tls_callbacks.h
1
/*
2
* TLS Callbacks
3
* (C) 2016 Matthias Gierlings
4
*     2016 Jack Lloyd
5
*     2017 Harry Reimann, Rohde & Schwarz Cybersecurity
6
*     2022 René Meusel, Rohde & Schwarz Cybersecurity
7
*
8
* Botan is released under the Simplified BSD License (see license.txt)
9
*/
10

11
#ifndef BOTAN_TLS_CALLBACKS_H_
12
#define BOTAN_TLS_CALLBACKS_H_
13

14
#include <botan/dl_group.h>
15
#include <botan/ocsp.h>
16
#include <botan/pubkey.h>
17
#include <botan/tls_alert.h>
18
#include <botan/tls_session.h>
19
#include <chrono>
20
#include <optional>
21

22
namespace Botan {
23

24
class Certificate_Store;
25
class X509_Certificate;
26

27
namespace OCSP {
28

29
class Response;
30

31
}
32

33
namespace TLS {
34

35
class Handshake_Message;
36
class Policy;
37
class Extensions;
38
class Certificate_Status_Request;
39

40
/**
41
* Encapsulates the callbacks that a TLS channel will make which are due to
42
* channel specific operations.
43
*/
44
class BOTAN_PUBLIC_API(2, 0) Callbacks {
6,067✔
45
   public:
46
      virtual ~Callbacks() = default;
4,076✔
47

48
      /**
49
       * Mandatory callback: output function
50
       * The channel will call this with data which needs to be sent to the peer
51
       * (eg, over a socket or some other form of IPC). The array will be overwritten
52
       * when the function returns so a copy must be made if the data cannot be
53
       * sent immediately.
54
       *
55
       * @param data a contiguous data buffer to send
56
       */
57
      virtual void tls_emit_data(std::span<const uint8_t> data) = 0;
58

59
      /**
60
       * Mandatory callback: process application data
61
       * Called when application data record is received from the peer.
62
       * Again the array is overwritten immediately after the function returns.
63
       *
64
       * @param seq_no the underlying TLS/DTLS record sequence number
65
       *
66
       * @param data a contiguous data buffer containing the received record
67
       */
68
      virtual void tls_record_received(uint64_t seq_no, std::span<const uint8_t> data) = 0;
69

70
      /**
71
       * Mandatory callback: alert received
72
       * Called when an alert is received from the peer
73
       * If fatal, the connection is closing. If not fatal, the connection may
74
       * still be closing (depending on the error and the peer).
75
       *
76
       * @param alert the source of the alert
77
       */
78
      virtual void tls_alert(Alert alert) = 0;
79

80
      /**
81
       * Optional callback: session established
82
       * Called when a session is established. Throw an exception to abort
83
       * the connection.
84
       *
85
       * @param session the session descriptor
86
       */
87
      virtual void tls_session_established(const Session_Summary& session) { BOTAN_UNUSED(session); }
72✔
88

89
      /**
90
       * Optional callback: session activated
91
       * Called when a session is active and can be written to
92
       */
93
      virtual void tls_session_activated() {}
320✔
94

95
      /**
96
       * Optional callback: peer closed connection (sent a "close_notify" alert)
97
       *
98
       * The peer signaled that it wishes to shut down the connection. The
99
       * application should not expect to receive any more data from the peer
100
       * and may tear down the underlying transport socket.
101
       *
102
       * Prior to TLS 1.3 it was required that peers discard pending writes
103
       * and immediately respond with their own "close_notify". With TLS 1.3,
104
       * applications can continue to send data despite the peer having already
105
       * signaled their wish to shut down.
106
       *
107
       * Returning `true` will cause the TLS 1.3 implementation to write all
108
       * pending data and then also signal a connection shut down. Otherwise
109
       * the application is responsible to call the `Channel::close()` method.
110
       *
111
       * For TLS 1.2 the return value has no effect.
112
       *
113
       * @return true causes the implementation to respond with a "close_notify"
114
       */
115
      virtual bool tls_peer_closed_connection() { return true; }
2,048✔
116

117
      /**
118
       * Optional callback: Resumption information was received/established
119
       *
120
       * TLS 1.3 calls this when we sent or received a TLS 1.3 session ticket at
121
       * any point after the initial handshake has finished.
122
       *
123
       * TLS 1.2 calls this when a session was established successfully and
124
       * its resumption information may be stored for later usage.
125
       *
126
       * Note that for servers this is called as soon as resumption information
127
       * is available and _could_ be sent to the client. If this callback
128
       * returns 'false', the information will neither be cached nor sent.
129
       *
130
       * @param session the session descriptor
131
       *
132
       * @return false to prevent the resumption information from being cached,
133
       *         and true to cache it in the configured Session_Manager
134
       */
135
      virtual bool tls_should_persist_resumption_information(const Session& session);
136

137
      /**
138
       * Optional callback with default impl: verify cert chain
139
       *
140
       * Default implementation performs a standard PKIX validation
141
       * and initiates network OCSP request for end-entity cert.
142
       * Override to provide different behavior.
143
       *
144
       * Check the certificate chain is valid up to a trusted root, and
145
       * optionally (if hostname != "") that the hostname given is
146
       * consistent with the leaf certificate.
147
       *
148
       * This function should throw an exception derived from
149
       * std::exception with an informative what() result if the
150
       * certificate chain cannot be verified.
151
       *
152
       * @param cert_chain specifies a certificate chain leading to a
153
       *        trusted root CA certificate.
154
       * @param ocsp_responses the server may have provided some
155
       * @param trusted_roots the list of trusted certificates
156
       * @param usage what this cert chain is being used for
157
       *        Usage_Type::TLS_SERVER_AUTH for server chains,
158
       *        Usage_Type::TLS_CLIENT_AUTH for client chains,
159
       *        Usage_Type::UNSPECIFIED for other uses
160
       * @param hostname when authenticating a server, this is the hostname
161
       *        the client requested (eg via SNI). When authenticating a client,
162
       *        this is the server name the client is authenticating *to*.
163
       *        Empty in other cases or if no hostname was used.
164
       * @param policy the TLS policy associated with the session being authenticated
165
       *        using the certificate chain
166
       */
167
      virtual void tls_verify_cert_chain(const std::vector<X509_Certificate>& cert_chain,
168
                                         const std::vector<std::optional<OCSP::Response>>& ocsp_responses,
169
                                         const std::vector<Certificate_Store*>& trusted_roots,
170
                                         Usage_Type usage,
171
                                         std::string_view hostname,
172
                                         const TLS::Policy& policy);
173

174
      /**
175
       * Called by default `tls_verify_cert_chain` to get the timeout to use for OCSP
176
       * requests. Return 0 to disable online OCSP checks.
177
       *
178
       * This function should not be "const" since the implementation might need
179
       * to perform some side effecting operation to compute the result.
180
       */
181
      virtual std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const {
106✔
182
         return std::chrono::milliseconds(0);
106✔
183
      }
184

185
      /**
186
       * Called by the TLS server whenever the client included the
187
       * status_request extension (see RFC 6066, a.k.a OCSP stapling)
188
       * in the ClientHello.
189
       *
190
       * @return the encoded OCSP response to be sent to the client which
191
       * indicates the revocation status of the server certificate. Return an
192
       * empty vector to indicate that no response is available, and thus
193
       * suppress the Certificate_Status message.
194
       */
195
      virtual std::vector<uint8_t> tls_provide_cert_status(const std::vector<X509_Certificate>& chain,
140✔
196
                                                           const Certificate_Status_Request& csr) {
197
         BOTAN_UNUSED(chain);
140✔
198
         BOTAN_UNUSED(csr);
140✔
199
         return std::vector<uint8_t>();
140✔
200
      }
201

202
      /**
203
       * Called by TLS 1.3 client or server whenever the peer indicated that
204
       * OCSP stapling is supported. In contrast to `tls_provide_cert_status`,
205
       * this allows providing OCSP responses for each certificate in the chain.
206
       *
207
       * The default implementation invokes `tls_provide_cert_status` assuming
208
       * that no OCSP responses for intermediate certificates are available.
209
       *
210
       * @return a vector of OCSP response buffers. An empty buffer indicates
211
       *         that no OCSP response should be provided for the respective
212
       *         certificate (at the same list index). The returned vector
213
       *         MUST be exactly the same length as the incoming \p chain.
214
       */
215
      virtual std::vector<std::vector<uint8_t>> tls_provide_cert_chain_status(
216
         const std::vector<X509_Certificate>& chain, const Certificate_Status_Request& csr);
217

218
      /**
219
       * Optional callback with default impl: sign a message
220
       *
221
       * Default implementation uses PK_Signer::sign_message().
222
       * Override to provide a different approach, e.g. using an external device.
223
       *
224
       * @param key the private key of the signer
225
       * @param rng a random number generator
226
       * @param padding the encoding method to be applied to the message
227
       * @param format the signature format
228
       * @param msg the input data for the signature
229
       *
230
       * @return the signature
231
       */
232
      virtual std::vector<uint8_t> tls_sign_message(const Private_Key& key,
233
                                                    RandomNumberGenerator& rng,
234
                                                    std::string_view padding,
235
                                                    Signature_Format format,
236
                                                    const std::vector<uint8_t>& msg);
237

238
      /**
239
       * Optional callback with default impl: verify a message signature
240
       *
241
       * Default implementation uses PK_Verifier::verify_message().
242
       * Override to provide a different approach, e.g. using an external device.
243
       *
244
       * @param key the public key of the signer
245
       * @param padding the encoding method to be applied to the message
246
       * @param format the signature format
247
       * @param msg the input data for the signature
248
       * @param sig the signature to be checked
249
       *
250
       * @return true if the signature is valid, false otherwise
251
       */
252
      virtual bool tls_verify_message(const Public_Key& key,
253
                                      std::string_view padding,
254
                                      Signature_Format format,
255
                                      const std::vector<uint8_t>& msg,
256
                                      const std::vector<uint8_t>& sig);
257

258
      /**
259
       * Generate an ephemeral KEM key for a TLS 1.3 handshake
260
       *
261
       * Applications may use this to add custom KEM algorithms or entirely
262
       * different key exchange schemes to the TLS 1.3 handshake. For instance,
263
       * this could provide an entry point to implement a hybrid key exchange
264
       * with both a traditional algorithm like ECDH and a quantum-secure KEM.
265
       * Typical use cases of the library don't need to do that and serious
266
       * security risks are associated with customizing TLS's key encapsulation
267
       * mechanism.
268
       *
269
       * Note that the KEM interface is usable for TLS 1.3 handshakes, only.
270
       *
271
       * The default implementation simply delegates this to the
272
       * tls_generate_ephemeral_key() call when appropriate.
273
       *
274
       * @param group the group identifier to generate an ephemeral keypair for
275
       * @param rng   a random number generator
276
       *
277
       * @returns a keypair whose public key will be provided to the peer and
278
       *          the private key will be provided to tls_kem_decapsulate later
279
       *          in the handshake.
280
       */
281
      virtual std::unique_ptr<Private_Key> tls_kem_generate_key(TLS::Group_Params group, RandomNumberGenerator& rng);
282

283
      /**
284
       * Performs a key encapsulation operation (used for TLS 1.3 servers)
285
       *
286
       * Applications may use this to add custom KEM algorithms or entirely
287
       * different key exchange schemes to the TLS 1.3 handshake. For instance,
288
       * this could provide an entry point to implement a hybrid key exchange
289
       * with both a traditional algorithm like ECDH and a quantum-secure KEM.
290
       * Typical use cases of the library don't need to do that and serious
291
       * security risks are associated with customizing TLS's key encapsulation
292
       * mechanism.
293
       *
294
       * Note that the KEM interface is usable for TLS 1.3 handshakes, only.
295
       *
296
       * The default implementation implements this key encapsulation as a
297
       * combination of tls_generate_ephemeral_key() followed by
298
       * tls_ephemeral_key_agreement() with the provided @p encoded_public_key.
299
       * The just-generated ephemeral private key is destroyed immediately.
300
       *
301
       * @param group the group identifier of the KEM/KEX algorithm
302
       * @param encoded_public_key the public key used for encapsulation/KEX
303
       * @param rng a random number generator
304
       * @param policy a TLS policy object
305
       *
306
       * @returns the shared secret both in plaintext and encapsulated with
307
       *          @p encoded_public_key.
308
       */
309
      virtual KEM_Encapsulation tls_kem_encapsulate(TLS::Group_Params group,
310
                                                    const std::vector<uint8_t>& encoded_public_key,
311
                                                    RandomNumberGenerator& rng,
312
                                                    const Policy& policy);
313

314
      /**
315
       * Performs a key decapsulation operation (used for TLS 1.3 clients).
316
       *
317
       * Applications may use this to add custom KEM algorithms or entirely
318
       * different key exchange schemes to the TLS 1.3 handshake. For instance,
319
       * this could provide an entry point to implement a hybrid key exchange
320
       * with both a traditional algorithm like ECDH and a quantum-secure KEM.
321
       * Typical use cases of the library don't need to do that and serious
322
       * security risks are associated with customizing TLS's key encapsulation
323
       * mechanism.
324
       *
325
       * Note that the KEM interface is usable for TLS 1.3 handshakes, only.
326
       *
327
       * The default implementation simply delegates this to the
328
       * tls_ephemeral_key_agreement() callback to obtain the shared secret.
329
       *
330
       * @param group the group identifier of the KEM/KEX algorithm
331
       * @param private_key the private key used for decapsulation/KEX
332
       * @param encapsulated_bytes the content to decapsulate (or the public key share)
333
       * @param rng a random number generator
334
       * @param policy a TLS policy object
335
       *
336
       * @returns the plaintext shared secret from @p encapsulated_bytes after
337
       *          decapsulation with @p private_key.
338
       */
339
      virtual secure_vector<uint8_t> tls_kem_decapsulate(TLS::Group_Params group,
340
                                                         const Private_Key& private_key,
341
                                                         const std::vector<uint8_t>& encapsulated_bytes,
342
                                                         RandomNumberGenerator& rng,
343
                                                         const Policy& policy);
344

345
      /**
346
       * Generate an ephemeral key pair for the TLS handshake.
347
       *
348
       * Applications may use this to add custom groups, curves or entirely
349
       * different ephemeral key agreement mechanisms to the TLS handshake.
350
       * Note that this callback must be used in conjunction with
351
       * Callbacks::tls_ephemeral_key_agreement.
352
       *
353
       * Typical use cases of the library don't need to do that and serious
354
       * security risks are associated with customizing TLS's key exchange
355
       * mechanism.
356
       *
357
       * @throws TLS_Exception(Alert::DecodeError) if the @p group is not known.
358
       *
359
       * @param group the group identifier to generate an ephemeral keypair for
360
       *              TLS 1.2 allows for specifying custom discrete logarithm
361
       *              parameters as part of the protocol. Hence the variant<>.
362
       * @param rng a random number generator
363
       *
364
       * @return a private key of an algorithm usable for key agreement
365
       */
366
      virtual std::unique_ptr<PK_Key_Agreement_Key> tls_generate_ephemeral_key(
367
         const std::variant<TLS::Group_Params, DL_Group>& group, RandomNumberGenerator& rng);
368

369
      /**
370
       * Agree on a shared secret with the peer's ephemeral public key for
371
       * the TLS handshake.
372
       *
373
       * Applications may use this to add custom groups, curves or entirely
374
       * different ephemeral key agreement mechanisms to the TLS handshake.
375
       * Note that this callback must be used in conjunction with
376
       * Callbacks::tls_generate_ephemeral_key.
377
       *
378
       * Typical use cases of the library don't need to do that and serious
379
       * security risks are associated with customizing TLS's key exchange
380
       * mechanism.
381
       *
382
       * @param group         the TLS group identifier to be used
383
       *                      TLS 1.2 allows for specifying custom discrete
384
       *                      logarithm parameters as part of the protocol.
385
       *                      Hence the variant<>.
386
       * @param private_key   the private key (generated ahead in tls_generate_ephemeral_key)
387
       * @param public_value  the public key exchange information received by the peer
388
       * @param rng           a random number generator
389
       * @param policy        a TLS policy object
390
       *
391
       * @return the shared secret derived from public_value and private_key
392
       */
393
      virtual secure_vector<uint8_t> tls_ephemeral_key_agreement(const std::variant<TLS::Group_Params, DL_Group>& group,
394
                                                                 const PK_Key_Agreement_Key& private_key,
395
                                                                 const std::vector<uint8_t>& public_value,
396
                                                                 RandomNumberGenerator& rng,
397
                                                                 const Policy& policy);
398

399
      /**
400
       * Optional callback: inspect handshake message
401
       * Throw an exception to abort the handshake.
402
       * Default simply ignores the message.
403
       *
404
       * Note: On connections that negotiated TLS 1.3 this callback is also
405
       *       invoked for post-handshake messages.
406
       *
407
       * @param message the handshake message
408
       */
409
      virtual void tls_inspect_handshake_msg(const Handshake_Message& message);
410

411
      /**
412
       * Optional callback for server: choose ALPN protocol
413
       *
414
       * ALPN (RFC 7301) works by the client sending a list of application
415
       * protocols it is willing to negotiate. The server then selects which
416
       * protocol to use. RFC 7301 requires that if the server does not support
417
       * any protocols offered by the client, then it should close the connection
418
       * with an alert of no_application_protocol. Within this callback this would
419
       * be done by throwing a TLS_Exception(Alert::NoApplicationProtocol)
420
       *
421
       * @param client_protos the vector of protocols the client is willing to negotiate
422
       *
423
       * @return the protocol selected by the server; if the empty string is
424
       * returned, the server does not reply to the client ALPN extension.
425
       *
426
       * The default implementation returns the empty string, causing client
427
       * ALPN to be ignored.
428
       *
429
       * It is highly recommended to support ALPN whenever possible to avoid
430
       * cross-protocol attacks.
431
       */
432
      virtual std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos);
433

434
      /**
435
       * Optional callback: examine/modify Extensions before sending.
436
       *
437
       * Both client and server will call this callback on the Extensions object
438
       * before serializing it in the specific handshake message. This allows an
439
       * application to modify which extensions are sent during the handshake.
440
       *
441
       * Default implementation does nothing.
442
       *
443
       * @param extn the extensions
444
       * @param which_side will be Connection_Side::Client or Connection_Side::Server which is the current
445
       *                   applications role in the exchange.
446
       * @param which_message will state the handshake message type containing the extensions
447
       */
448
      virtual void tls_modify_extensions(Extensions& extn, Connection_Side which_side, Handshake_Type which_message);
449

450
      /**
451
       * Optional callback: examine peer extensions.
452
       *
453
       * Both client and server will call this callback with the Extensions
454
       * object after receiving it from the peer. This allows examining the
455
       * Extensions, for example to implement a custom extension. It also allows
456
       * an application to require that a particular extension be implemented;
457
       * throw an exception from this function to abort the handshake.
458
       *
459
       * Default implementation does nothing.
460
       *
461
       * @param extn the extensions
462
       * @param which_side will be Connection_Side::Client if these are are the clients extensions (ie we are
463
       *        the server) or Connection_Side::Server if these are the server extensions (we are the client).
464
       * @param which_message will state the handshake message type containing the extensions
465
       */
466
      virtual void tls_examine_extensions(const Extensions& extn,
467
                                          Connection_Side which_side,
468
                                          Handshake_Type which_message);
469

470
      /**
471
       * Optional callback: parse a single OCSP Response
472
       *
473
       * Note: Typically a user of the library would not want to override this
474
       *       callback. We provide this callback to be able to support OCSP
475
       *       related tests from BoringSSL's BoGo tests that provide unparsable
476
       *       responses.
477
       *
478
       * Default implementation tries to parse the provided raw OCSP response.
479
       *
480
       * This function should not throw an exception but return a std::nullopt
481
       * if the OCSP response cannot be parsed.
482
       *
483
       * @param raw_response raw OCSP response buffer
484
       * @returns the parsed OCSP response or std::nullopt on error
485
       */
486
      virtual std::optional<OCSP::Response> tls_parse_ocsp_response(const std::vector<uint8_t>& raw_response);
487

488
      /**
489
       * Optional callback: return peer network identity
490
       *
491
       * There is no expected or specified format. The only expectation is this
492
       * function will return a unique value. For example returning the peer
493
       * host IP and port.
494
       *
495
       * This is used to bind the DTLS cookie to a particular network identity.
496
       * It is only called if the dtls-cookie-secret PSK is also defined.
497
       */
498
      virtual std::string tls_peer_network_identity();
499

500
      /**
501
       * Optional callback: return a custom time stamp value
502
       *
503
       * This allows the library user to specify a custom "now" timestamp when
504
       * needed. By default it will use the current system clock time.
505
       *
506
       * Note that typical usages will not need to override this callback but it
507
       * is useful for testing purposes to allow for deterministic test outcomes.
508
       */
509
      virtual std::chrono::system_clock::time_point tls_current_timestamp();
510

511
      /**
512
       * Optional callback: error logging. (not currently called)
513
       * @param err An error message related to this connection.
514
       */
515
      virtual void tls_log_error(const char* err) { BOTAN_UNUSED(err); }
×
516

517
      /**
518
       * Optional callback: debug logging. (not currently called)
519
       * @param what Some hopefully informative string
520
       */
521
      virtual void tls_log_debug(const char* what) { BOTAN_UNUSED(what); }
×
522

523
      /**
524
       * Optional callback: debug logging taking a buffer. (not currently called)
525
       * @param descr What this buffer is
526
       * @param val the bytes
527
       * @param val_len length of val
528
       */
529
      virtual void tls_log_debug_bin(const char* descr, const uint8_t val[], size_t val_len) {
×
530
         BOTAN_UNUSED(descr, val, val_len);
×
531
      }
×
532
};
533

534
}  // namespace TLS
535

536
}  // namespace Botan
537

538
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc