include/boost/corosio/tls_context.hpp

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