include/boost/corosio/tls_context.hpp

87.5% Lines (14/0/16) 92.3% List of functions (12/0/13)
tls_context.hpp
f(x) Functions (13)
Function Calls Lines Blocks
boost::corosio::verify_context::certificate() const :181 0 0.0% 0.0% boost::corosio::tls_context::tls_context(boost::corosio::tls_context const&) :264 2x 100.0% 100.0% boost::corosio::tls_context::operator=(boost::corosio::tls_context const&) :275 1x 100.0% 100.0% boost::corosio::tls_context::tls_context(boost::corosio::tls_context&&) :284 2x 100.0% 100.0% boost::corosio::tls_context::operator=(boost::corosio::tls_context&&) :296 1x 100.0% 100.0% boost::corosio::tls_context::~tls_context() :304 55x 100.0% 100.0% void boost::corosio::tls_context::set_servername_callback<boost::corosio::tls_context_test::testServernameCallback()::{lambda(std::basic_string_view<char, std::char_traits<char> >)#1}>(boost::corosio::tls_context_test::testServernameCallback()::{lambda(std::basic_string_view<char, std::char_traits<char> >)#1}) :923 1x 100.0% 75.0% void boost::corosio::tls_context::set_password_callback<(anonymous namespace)::password_callback(boost::corosio::tls_context&)::{lambda(unsigned long, boost::corosio::tls_password_purpose)#1}>((anonymous namespace)::password_callback(boost::corosio::tls_context&)::{lambda(unsigned long, boost::corosio::tls_password_purpose)#1}) :930 1x 100.0% 75.0% void boost::corosio::tls_context::set_password_callback<(anonymous namespace)::password_env(boost::corosio::tls_context&)::{lambda(unsigned long, boost::corosio::tls_password_purpose)#1}>((anonymous namespace)::password_env(boost::corosio::tls_context&)::{lambda(unsigned long, boost::corosio::tls_password_purpose)#1}) :930 1x 100.0% 75.0% void boost::corosio::tls_context::set_password_callback<(anonymous namespace)::tls_test::testPasswordCallback()::{lambda(unsigned long, boost::corosio::tls_password_purpose)#1}>((anonymous namespace)::tls_test::testPasswordCallback()::{lambda(unsigned long, boost::corosio::tls_password_purpose)#1}) :930 1x 100.0% 75.0% void boost::corosio::tls_context::set_password_callback<boost::corosio::tls_context_test::testPasswordCallback()::{lambda(unsigned long, boost::corosio::tls_password_purpose)#1}>(boost::corosio::tls_context_test::testPasswordCallback()::{lambda(unsigned long, boost::corosio::tls_password_purpose)#1}) :930 1x 100.0% 75.0% void boost::corosio::tls_context::set_verify_callback<(anonymous namespace)::tls_test::testVerifyCallback()::{lambda(bool, boost::corosio::verify_context&)#1}>((anonymous namespace)::tls_test::testVerifyCallback()::{lambda(bool, boost::corosio::verify_context&)#1}) :937 1x 100.0% 75.0% void boost::corosio::tls_context::set_verify_callback<(anonymous namespace)::verify_callback(boost::corosio::tls_context&)::{lambda(bool, boost::corosio::verify_context&)#1}>((anonymous namespace)::verify_callback(boost::corosio::tls_context&)::{lambda(bool, boost::corosio::verify_context&)#1}) :937 1x 100.0% 75.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2026 Michael Vandeberg
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/corosio
9 //
10
11 #ifndef BOOST_COROSIO_TLS_CONTEXT_HPP
12 #define BOOST_COROSIO_TLS_CONTEXT_HPP
13
14 #include <boost/corosio/detail/config.hpp>
15
16 #include <cstddef>
17 #include <functional>
18 #include <span>
19 #include <system_error>
20 #include <memory>
21 #include <string_view>
22
23 namespace boost::corosio {
24
25 //
26 // Enumerations
27 //
28
29 /** TLS protocol version.
30
31 Specifies the minimum or maximum TLS protocol version to use
32 for connections. Only modern, secure versions are supported.
33
34 @see tls_context::set_min_protocol_version
35 @see tls_context::set_max_protocol_version
36 */
37 enum class tls_version
38 {
39 /// TLS 1.2 (RFC 5246).
40 tls_1_2,
41
42 /// TLS 1.3 (RFC 8446).
43 tls_1_3
44 };
45
46 /** Certificate and key file format.
47
48 Specifies the encoding format for certificate and key data.
49
50 @see tls_context::use_certificate
51 @see tls_context::use_private_key
52 */
53 enum class tls_file_format
54 {
55 /// PEM format (Base64-encoded with header/footer lines).
56 pem,
57
58 /// DER format (raw ASN.1 binary encoding).
59 der
60 };
61
62 /** Peer certificate verification mode.
63
64 Controls how the TLS implementation verifies the peer's
65 certificate during the handshake.
66
67 @see tls_context::set_verify_mode
68 */
69 enum class tls_verify_mode
70 {
71 /// Do not request or verify the peer certificate.
72 none,
73
74 /// Request and verify the peer certificate if presented.
75 peer,
76
77 /// Require and verify the peer certificate (fail if not presented).
78 require_peer
79 };
80
81 /** Certificate revocation checking policy.
82
83 Controls how certificate revocation status is checked during
84 verification.
85
86 @see tls_context::set_revocation_policy
87 */
88 enum class tls_revocation_policy
89 {
90 /// Do not check revocation status.
91 disabled,
92
93 /// Check revocation but allow connection if status is unknown.
94 soft_fail,
95
96 /// Require successful revocation check (fail if status is unknown).
97 hard_fail
98 };
99
100 /** Purpose for password callback invocation.
101
102 Indicates whether the password is needed for reading (decrypting)
103 or writing (encrypting) key material.
104
105 @see tls_context::set_password_callback
106 */
107 enum class tls_password_purpose
108 {
109 /// Password needed to decrypt/read protected key material.
110 for_reading,
111
112 /// Password needed to encrypt/write protected key material.
113 for_writing
114 };
115
116 class tls_context;
117
118 /** A non-owning view of certificate verification state.
119
120 An instance is passed to the callback installed via
121 tls_context::set_verify_callback during the TLS handshake. It
122 exposes the backend's native verification handle so the callback
123 can inspect the certificate and chain currently being verified.
124
125 The value returned by native_handle() is, for the OpenSSL and
126 WolfSSL backends, an `X509_STORE_CTX*`. For portable inspection that
127 works across backends (for example certificate pinning), prefer
128 certificate(), which returns the DER encoding of the certificate
129 currently being verified.
130
131 @par Lifetime
132
133 The wrapped handle and the certificate() bytes are owned by the TLS
134 backend and are valid only for the duration of a single callback
135 invocation. Do not retain them beyond the call.
136
137 @see tls_context::set_verify_callback
138 */
139 class verify_context
140 {
141 void* handle_;
142 unsigned char const* der_;
143 std::size_t der_len_;
144
145 public:
146 /** Construct from a native handle and the current certificate.
147
148 @param handle The backend verification handle (for OpenSSL and
149 WolfSSL, an `X509_STORE_CTX*`).
150 @param der Pointer to the DER encoding of the certificate under
151 verification, or `nullptr` if unavailable.
152 @param der_len Length of the DER encoding in bytes.
153 */
154 verify_context(
155 void* handle, unsigned char const* der, std::size_t der_len) noexcept
156 : handle_(handle), der_(der), der_len_(der_len)
157 {
158 }
159
160 /** Return the native verification handle.
161
162 Cast the result to the backend's verification context type
163 (e.g. `X509_STORE_CTX*`) to inspect the certificate chain using
164 backend-specific APIs.
165
166 @return The native handle, or `nullptr` if none is available.
167 */
168 void* native_handle() const noexcept { return handle_; }
169
170 /** Return the DER encoding of the certificate being verified.
171
172 This is the portable way to inspect the peer certificate from a
173 verification callback: it works identically on every backend,
174 without depending on backend-specific build options. A DER
175 certificate is an ASN.1 `SEQUENCE`, so the first byte is `0x30`.
176
177 @return A view of the certificate's DER bytes, valid only for the
178 duration of the callback. Empty if the certificate is not
179 available.
180 */
181 std::span<unsigned char const> certificate() const noexcept
182 {
183 return {der_, der_len_};
184 }
185 };
186
187 namespace detail {
188 struct tls_context_data;
189 tls_context_data const& get_tls_context_data(tls_context const&) noexcept;
190 } // namespace detail
191
192 #ifdef _MSC_VER
193 #pragma warning(push)
194 #pragma warning(disable : 4251) // shared_ptr needs dll-interface
195 #endif
196
197 /** A portable TLS context for certificate and settings storage.
198
199 The `tls_context` class provides a backend-agnostic interface for
200 configuring TLS connections. It stores credentials (certificates and
201 private keys), trust anchors, protocol settings, and verification
202 options that are used when establishing TLS connections.
203
204 This class is a shared handle to an opaque implementation. Copies
205 share the same underlying state. This allows contexts to be passed
206 by value and shared across multiple TLS streams.
207
208 This class abstracts the configuration phase of TLS across multiple
209 backend implementations (OpenSSL, WolfSSL, mbedTLS, Schannel, etc.),
210 allowing portable code that works regardless of which TLS library
211 is linked.
212
213 @par Modification After Stream Creation
214
215 Modifying a context after a TLS stream has been created from it
216 results in undefined behavior. The context's configuration is
217 captured when the first stream is constructed, and subsequent
218 modifications are not reflected in existing or new streams
219 sharing the context.
220
221 If different configurations are needed, create separate context
222 objects.
223
224 @par Thread Safety
225
226 Distinct objects: Safe.
227
228 Shared objects: Unsafe. A context must not be modified while
229 any thread is creating streams from it.
230
231 @par Example
232 @par !example tls_context
233
234 @see tls_role
235 */
236 class BOOST_COROSIO_DECL tls_context
237 {
238 struct implementation;
239 std::shared_ptr<implementation> impl_;
240
241 friend detail::tls_context_data const&
242 detail::get_tls_context_data(tls_context const&) noexcept;
243
244 public:
245 /** Construct a default TLS context.
246
247 Creates a context with default settings suitable for TLS 1.2
248 and TLS 1.3 connections. No certificates or trust anchors are
249 loaded; call the appropriate methods to configure credentials
250 and verification.
251
252 @par Example
253 @par !example tls_context
254 */
255 tls_context();
256
257 /** Copy constructor.
258
259 Creates a new handle that shares ownership of the underlying
260 TLS context state with `other`.
261
262 @param other The context to copy from.
263 */
264 2x tls_context(tls_context const& other) = default;
265
266 /** Copy assignment operator.
267
268 Releases the current context's shared ownership and acquires
269 shared ownership of `other`'s underlying state.
270
271 @param other The context to copy from.
272
273 @return Reference to this context.
274 */
275 1x tls_context& operator=(tls_context const& other) = default;
276
277 /** Move constructor.
278
279 Transfers ownership of the TLS context from another instance.
280 After the move, `other` is in a valid but empty state.
281
282 @param other The context to move from.
283 */
284 2x tls_context(tls_context&& other) noexcept = default;
285
286 /** Move assignment operator.
287
288 Releases the current context's shared ownership and transfers
289 ownership from another instance. After the move, `other` is
290 in a valid but empty state.
291
292 @param other The context to move from.
293
294 @return Reference to this context.
295 */
296 1x tls_context& operator=(tls_context&& other) noexcept = default;
297
298 /** Destructor.
299
300 Releases this handle's shared ownership of the underlying
301 context. The context state is destroyed when the last handle
302 is released.
303 */
304 55x ~tls_context() = default;
305
306 //
307 // Credential Loading
308 //
309
310 /** Load the entity certificate from a memory buffer.
311
312 Sets the certificate that identifies this endpoint to the peer.
313 For servers, this is the server certificate. For clients using
314 mutual TLS, this is the client certificate.
315
316 The certificate must match the private key loaded via
317 `use_private_key()` or `use_private_key_file()`.
318
319 @param certificate The certificate data.
320
321 @param format The encoding format of the certificate data.
322
323 @return Success. The certificate is recorded and decoded when the
324 native context is first built; a malformed certificate surfaces
325 as a handshake failure.
326
327 @see use_certificate_file
328 @see use_private_key
329 */
330 [[nodiscard]] std::error_code
331 use_certificate(std::string_view certificate, tls_file_format format);
332
333 /** Load the entity certificate from a file.
334
335 Sets the certificate that identifies this endpoint to the peer.
336 For servers, this is the server certificate. For clients using
337 mutual TLS, this is the client certificate.
338
339 @param filename Path to the certificate file.
340
341 @param format The encoding format of the file.
342
343 @return Success, or an error if the file could not be read. The
344 certificate is decoded when the native context is first built;
345 a malformed certificate surfaces as a handshake failure.
346
347 @par Example
348 @par !example use_certificate_file
349
350 @see use_certificate
351 @see use_private_key_file
352 */
353 [[nodiscard]] std::error_code
354 use_certificate_file(std::string_view filename, tls_file_format format);
355
356 /** Load a certificate chain from a memory buffer.
357
358 Loads the entity certificate followed by intermediate CA certificates.
359 The chain should be ordered from leaf to root (excluding the root).
360 This is the typical format for PEM certificate bundles.
361
362 @param chain The certificate chain data in PEM format (concatenated
363 certificates).
364
365 @return Success. The chain is recorded and decoded when the native
366 context is first built; a malformed chain surfaces as a
367 handshake failure.
368
369 @see use_certificate_chain_file
370 */
371 [[nodiscard]] std::error_code use_certificate_chain(std::string_view chain);
372
373 /** Load a certificate chain from a file.
374
375 Loads the entity certificate followed by intermediate CA certificates
376 from a PEM file. The file should contain concatenated PEM certificates
377 ordered from leaf to root (excluding the root).
378
379 @param filename Path to the certificate chain file.
380
381 @return Success, or an error if the file could not be read. The
382 chain is decoded when the native context is first built; a
383 malformed chain surfaces as a handshake failure.
384
385 @par Example
386 @par !example use_certificate_chain_file
387
388 @see use_certificate_chain
389 */
390 [[nodiscard]] std::error_code use_certificate_chain_file(std::string_view filename);
391
392 /** Load the private key from a memory buffer.
393
394 Sets the private key corresponding to the entity certificate.
395 The key must match the certificate loaded via `use_certificate()`
396 or `use_certificate_chain()`.
397
398 If the key is encrypted, set a password callback via
399 `set_password_callback()` before calling this function.
400
401 @param private_key The private key data.
402
403 @param format The encoding format of the key data.
404
405 @return Success. The key is recorded and decoded when the native
406 context is first built; a malformed key, a missing password
407 callback for an encrypted key, or a certificate mismatch
408 surfaces as a handshake failure.
409
410 @see use_private_key_file
411 @see set_password_callback
412 */
413 [[nodiscard]] std::error_code
414 use_private_key(std::string_view private_key, tls_file_format format);
415
416 /** Load the private key from a file.
417
418 Sets the private key corresponding to the entity certificate.
419 The key must match the certificate loaded via `use_certificate_file()`
420 or `use_certificate_chain_file()`.
421
422 If the key file is encrypted, set a password callback via
423 `set_password_callback()` before calling this function.
424
425 @param filename Path to the private key file.
426
427 @param format The encoding format of the file.
428
429 @return Success, or an error if the file could not be read. The
430 key is decoded when the native context is first built; a
431 malformed key or a certificate mismatch surfaces as a
432 handshake failure.
433
434 @par Example
435 @par !example use_private_key_file
436
437 @see use_private_key
438 @see set_password_callback
439 */
440 [[nodiscard]] std::error_code
441 use_private_key_file(std::string_view filename, tls_file_format format);
442
443 /** Load credentials from a PKCS#12 bundle in memory.
444
445 PKCS#12 (also known as PFX) is a binary format that bundles a
446 certificate, private key, and optionally intermediate certificates
447 into a single password-protected file.
448
449 @param data The PKCS#12 bundle data.
450
451 @param passphrase The password protecting the bundle.
452
453 @return Success. The bundle is recorded and decoded into the
454 certificate, private key, and chain when the native context is
455 first built; a malformed bundle or wrong passphrase surfaces as
456 a handshake failure.
457
458 @note Intermediate certificates inside the bundle are loaded and
459 sent during the handshake on both backends.
460
461 @see use_pkcs12_file
462 */
463 [[nodiscard]] std::error_code
464 use_pkcs12(std::string_view data, std::string_view passphrase);
465
466 /** Load credentials from a PKCS#12 file.
467
468 PKCS#12 (also known as PFX) is a binary format that bundles a
469 certificate, private key, and optionally intermediate certificates
470 into a single password-protected file. This is common on Windows
471 and for certificates exported from browsers.
472
473 @param filename Path to the PKCS#12 file.
474
475 @param passphrase The password protecting the file.
476
477 @return Success, or an error if the file could not be read. The
478 bundle is decoded when the native context is first built; a
479 malformed bundle or wrong passphrase surfaces as a handshake
480 failure.
481
482 @note Intermediate certificates inside the bundle are loaded and
483 sent during the handshake on both backends.
484
485 @par Example
486 @par !example use_pkcs12_file
487
488 @see use_pkcs12
489 */
490 [[nodiscard]] std::error_code
491 use_pkcs12_file(std::string_view filename, std::string_view passphrase);
492
493 //
494 // Trust Anchors
495 //
496
497 /** Add a certificate authority for peer verification.
498
499 Adds a single CA certificate to the trust store used for verifying
500 peer certificates. Call this multiple times to add multiple CAs,
501 or use `load_verify_file()` for a bundle.
502
503 @param ca The CA certificate data in PEM format.
504
505 @return Success. The certificate is recorded and decoded when the
506 native context is first built; a malformed certificate
507 surfaces as a handshake failure.
508
509 @see load_verify_file
510 @see set_default_verify_paths
511 */
512 [[nodiscard]] std::error_code add_certificate_authority(std::string_view ca);
513
514 /** Load CA certificates from a file.
515
516 Loads one or more CA certificates from a PEM file. The file may
517 contain multiple concatenated PEM certificates.
518
519 @param filename Path to a PEM file containing CA certificates.
520
521 @return Success, or an error if the file could not be read. The
522 certificates are decoded when the native context is first
523 built; malformed certificates surface as a handshake failure.
524
525 @par Example
526 @par !example load_verify_file
527
528 @see add_certificate_authority
529 @see add_verify_path
530 */
531 [[nodiscard]] std::error_code load_verify_file(std::string_view filename);
532
533 /** Add a directory of CA certificates for verification.
534
535 Adds a directory of CA certificates to the trust store. The
536 directory is applied when the native context is first built from
537 this context.
538
539 The expected directory layout depends on the backend. OpenSSL
540 performs on-demand lookups and requires each certificate file to
541 be named by its subject-name hash (as generated by
542 `openssl rehash` or `c_rehash`); WolfSSL loads every certificate
543 file in the directory.
544
545 @param path Path to the directory of CA certificates.
546
547 @return Success. The path is recorded and applied when the native
548 context is built; a directory that cannot be read at that time
549 is skipped rather than reported here.
550
551 @par Example
552 @par !example add_verify_path
553
554 @see load_verify_file
555 @see set_default_verify_paths
556 */
557 [[nodiscard]] std::error_code add_verify_path(std::string_view path);
558
559 /** Use the system default CA certificate store.
560
561 Configures the context to use the operating system's default
562 trust store for peer certificate verification. This is the
563 recommended approach for HTTPS clients connecting to public
564 servers.
565
566 The system store is loaded when the native context is first built
567 from this context. For a verified-safe client, combine this with
568 `set_verify_mode( tls_verify_mode::peer )` and, when connecting by
569 name, `tls_stream::set_hostname()`.
570
571 @return Success. The request is recorded and applied when the
572 native context is built; if the system store cannot be loaded
573 at that time it is skipped rather than reported here, so a
574 context that must reject unverified peers should also use
575 `set_verify_mode( tls_verify_mode::peer )`.
576
577 @note The OpenSSL backend honors the `SSL_CERT_FILE` and
578 `SSL_CERT_DIR` environment variables. The WolfSSL backend
579 requires a build with `WOLFSSL_SYS_CA_CERTS`; without it the
580 system store is unavailable and this call has no effect.
581
582 @par Example
583 @par !example set_default_verify_paths
584
585 @see load_verify_file
586 @see add_verify_path
587 @see set_verify_mode
588 */
589 [[nodiscard]] std::error_code set_default_verify_paths();
590
591 //
592 // Protocol Configuration
593 //
594
595 /** Set the minimum TLS protocol version.
596
597 Connections will reject protocol versions older than this.
598 The default allows TLS 1.2 and newer.
599
600 @param v The minimum protocol version to accept.
601
602 @return Success. The version is recorded and applied when the
603 native context is first built.
604
605 @par Example
606 @par !example set_min_protocol_version
607
608 @see set_max_protocol_version
609 */
610 [[nodiscard]] std::error_code set_min_protocol_version(tls_version v);
611
612 /** Set the maximum TLS protocol version.
613
614 Connections will not negotiate protocol versions newer than this.
615 The default allows the newest supported version.
616
617 @param v The maximum protocol version to accept.
618
619 @return Success. The version is recorded and applied when the
620 native context is first built.
621
622 @note On WolfSSL the ceiling is applied by selecting a
623 version-specific method (no native set-max API exists); an
624 invalid window where the minimum exceeds the maximum yields a
625 context that fails the handshake.
626
627 @see set_min_protocol_version
628 */
629 [[nodiscard]] std::error_code set_max_protocol_version(tls_version v);
630
631 /** Set the allowed cipher suites.
632
633 Configures which cipher suites may be used for connections.
634 The format is backend-specific but typically follows OpenSSL
635 cipher list syntax.
636
637 @param ciphers The cipher suite specification string.
638
639 @return Success. The string is recorded and applied when the
640 native context is first built; an invalid cipher string
641 surfaces as a handshake failure.
642
643 @par Example
644 @par !example set_ciphersuites
645
646 @note This configures cipher suites for TLS 1.2 and below. For
647 TLS 1.3, use @ref set_ciphersuites_tls13.
648 */
649 [[nodiscard]] std::error_code set_ciphersuites(std::string_view ciphers);
650
651 /** Set the allowed TLS 1.3 cipher suites.
652
653 TLS 1.3 uses a distinct, fixed set of cipher suites configured
654 separately from earlier versions. The format is a colon-separated
655 list of TLS 1.3 suite names.
656
657 @param ciphers The TLS 1.3 cipher suite list.
658
659 @return Success. The string is recorded and applied when the
660 native context is first built; an invalid cipher string
661 surfaces as a handshake failure.
662
663 @par Example
664 @par !example set_ciphersuites_tls13
665
666 @note On the WolfSSL backend, TLS 1.2 and TLS 1.3 suites share a
667 single cipher list; this call and @ref set_ciphersuites are
668 merged into one list.
669
670 @see set_ciphersuites
671 */
672 [[nodiscard]] std::error_code set_ciphersuites_tls13(std::string_view ciphers);
673
674 /** Set the ALPN protocol list.
675
676 Configures Application-Layer Protocol Negotiation (ALPN) for
677 the connection. ALPN is used to negotiate which application
678 protocol to use over the TLS connection (e.g., "h2" for HTTP/2,
679 "http/1.1" for HTTP/1.1).
680
681 The protocols are tried in preference order (first = highest).
682
683 @param protocols Ordered list of protocol identifiers.
684
685 @return Success, or an error if ALPN configuration fails.
686
687 @note Read the negotiated protocol after the handshake via
688 @ref tls_stream::alpn_protocol. On WolfSSL, ALPN requires a
689 build with `HAVE_ALPN`; without it, offering protocols fails
690 the handshake with `std::errc::function_not_supported` rather
691 than negotiate nothing silently.
692
693 @par Example
694 @par !example set_alpn
695 */
696 [[nodiscard]] std::error_code set_alpn(std::initializer_list<std::string_view> protocols);
697
698 //
699 // Certificate Verification
700 //
701
702 /** Set the peer certificate verification mode.
703
704 Controls whether and how peer certificates are verified during
705 the TLS handshake.
706
707 @param mode The verification mode to use.
708
709 @return Success. The mode is recorded and applied when the native
710 context is first built.
711
712 @par Example
713 @par !example set_verify_mode
714
715 @see tls_verify_mode
716 */
717 [[nodiscard]] std::error_code set_verify_mode(tls_verify_mode mode);
718
719 /** Set the maximum certificate chain verification depth.
720
721 Limits how many intermediate certificates can appear between
722 the peer certificate and a trusted root. The default is
723 typically 100, which is sufficient for most certificate chains.
724
725 @param depth Maximum number of intermediate certificates allowed.
726
727 @return Success. The depth is recorded and applied when the native
728 context is first built.
729 */
730 [[nodiscard]] std::error_code set_verify_depth(int depth);
731
732 /** Set a custom certificate verification callback.
733
734 Installs a callback that is invoked during certificate chain
735 verification. The callback can perform additional validation
736 beyond the standard checks and can override verification
737 results.
738
739 The callback receives the built-in verification result so far and
740 a verify_context describing the certificate being verified. Return
741 `true` to accept the certificate, `false` to reject. Inspect the
742 certificate portably via `verify_context::certificate()` (its DER
743 encoding) — for example to pin a specific certificate.
744
745 @par Backend Support
746
747 The exact set of certificates the callback sees differs by backend:
748
749 - OpenSSL: the callback runs once per certificate in the chain,
750 including certificates that passed the built-in checks. It can
751 therefore both relax verification (return `true` for a
752 certificate the library rejected) and tighten it (return `false`
753 for a certificate the library accepted, e.g. pinning).
754 - WolfSSL built with `WOLFSSL_ALWAYS_VERIFY_CB` (implied by
755 `--enable-opensslextra`): same as OpenSSL.
756 - WolfSSL without that option: the library invokes the callback
757 only on verification *failure*, so it cannot be honored on a
758 successful handshake. To avoid silently ignoring a
759 verification-tightening callback (which would fail open), a
760 context that carries a callback instead **fails the handshake**
761 with `std::errc::function_not_supported` on such a build. Rebuild
762 WolfSSL with `WOLFSSL_ALWAYS_VERIFY_CB`, or omit the callback.
763
764 @tparam Callback A callable with signature
765 `bool( bool preverified, verify_context& ctx )`.
766
767 @param callback The verification callback. Recorded here and
768 applied during the handshake; on a WolfSSL build that
769 cannot honor it, the handshake fails with
770 `std::errc::function_not_supported` (see Backend Support).
771
772 @par Example
773 @par !example set_verify_callback
774
775 @see verify_context
776 @see set_verify_mode
777 */
778 template<typename Callback>
779 void set_verify_callback(Callback callback);
780
781 /** Set a callback for Server Name Indication (SNI).
782
783 For server connections, this callback is invoked during the TLS
784 handshake when a client sends an SNI extension. The callback
785 receives the requested hostname and can accept or reject the
786 connection.
787
788 @tparam Callback A callable with signature
789 `bool( std::string_view hostname )`.
790
791 @param callback The SNI callback. Return `true` to accept the
792 connection or `false` to reject it with an alert.
793
794 @par Example
795 @par !example set_servername_callback
796
797 @note For virtual hosting with different certificates per hostname,
798 create separate contexts and select the appropriate one before
799 creating the TLS stream.
800
801 @see tls_stream::set_hostname
802 */
803 template<typename Callback>
804 void set_servername_callback(Callback callback);
805
806 private:
807 void set_servername_callback_impl(
808 std::function<bool(std::string_view)> callback);
809
810 void set_password_callback_impl(
811 std::function<std::string(std::size_t, tls_password_purpose)> callback);
812
813 void set_verify_callback_impl(
814 std::function<bool(bool, verify_context&)> callback);
815
816 public:
817 //
818 // Revocation Checking
819 //
820
821 /** Add a Certificate Revocation List from memory.
822
823 Adds a CRL to the verification store for checking whether
824 certificates have been revoked. CRLs are typically fetched
825 from the URLs in a certificate's CRL Distribution Points
826 extension.
827
828 @param crl The CRL data in DER or PEM format.
829
830 @return Success. The CRL is recorded and decoded when the native
831 context is first built; a malformed CRL surfaces as a
832 handshake failure.
833
834 @note CRLs are consulted only when a revocation policy is set via
835 @ref set_revocation_policy. On WolfSSL, CRL checking requires a
836 build with `HAVE_CRL`; without it, supplying a CRL or a
837 revocation policy fails the handshake with
838 `std::errc::function_not_supported`.
839
840 @see add_crl_file
841 @see set_revocation_policy
842 */
843 [[nodiscard]] std::error_code add_crl(std::string_view crl);
844
845 /** Add a Certificate Revocation List from a file.
846
847 Adds a CRL to the verification store for checking whether
848 certificates have been revoked.
849
850 @param filename Path to a CRL file (DER or PEM format).
851
852 @return Success, or an error if the file could not be read. The
853 CRL is decoded when the native context is first built; a
854 malformed CRL surfaces as a handshake failure.
855
856 @note CRLs are consulted only when a revocation policy is set via
857 @ref set_revocation_policy (WolfSSL requires a `HAVE_CRL`
858 build).
859
860 @par Example
861 @par !example add_crl_file
862
863 @see add_crl
864 @see set_revocation_policy
865 */
866 [[nodiscard]] std::error_code add_crl_file(std::string_view filename);
867
868 /** Set the certificate revocation checking policy.
869
870 Controls how certificate revocation status is checked during
871 verification via CRLs.
872
873 @param policy The revocation checking policy.
874
875 @par Example
876 @par !example set_revocation_policy
877
878 @note Revocation is checked via CRLs supplied with @ref add_crl /
879 @ref add_crl_file. `soft_fail` accepts a certificate whose
880 status cannot be determined (missing/expired CRL) but rejects
881 one that is actually revoked; `hard_fail` also rejects unknown
882 status. OCSP-based revocation is not available (see the TLS
883 guide). On WolfSSL a non-disabled policy requires a `HAVE_CRL`
884 build, else the handshake fails with
885 `std::errc::function_not_supported`.
886
887 @see tls_revocation_policy
888 @see add_crl
889 */
890 void set_revocation_policy(tls_revocation_policy policy);
891
892 //
893 // Password Handling
894 //
895
896 /** Set the password callback for encrypted keys.
897
898 Installs a callback that provides passwords for encrypted
899 private keys and PKCS#12 files. The callback is invoked when
900 loading encrypted key material.
901
902 @tparam Callback A callable with signature
903 `std::string( std::size_t max_length, password_purpose purpose )`.
904
905 @param callback The password callback. It receives the maximum
906 password length and the purpose (reading or writing), and
907 returns the password string.
908
909 @par Example
910 @par !example set_password_callback
911
912 @see tls_password_purpose
913 */
914 template<typename Callback>
915 void set_password_callback(Callback callback);
916 };
917 #ifdef _MSC_VER
918 #pragma warning(pop)
919 #endif
920
921 template<typename Callback>
922 void
923 1x tls_context::set_servername_callback(Callback callback)
924 {
925 1x set_servername_callback_impl(std::move(callback));
926 1x }
927
928 template<typename Callback>
929 void
930 4x tls_context::set_password_callback(Callback callback)
931 {
932 4x set_password_callback_impl(std::move(callback));
933 4x }
934
935 template<typename Callback>
936 void
937 2x tls_context::set_verify_callback(Callback callback)
938 {
939 2x set_verify_callback_impl(std::move(callback));
940 2x }
941
942 } // namespace boost::corosio
943
944 #endif
945