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&) :266 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&&) :282 2x 100.0% 100.0% boost::corosio::tls_context::operator=(boost::corosio::tls_context&&) :292 1x 100.0% 100.0% boost::corosio::tls_context::~tls_context() :298 56x 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}) :929 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}) :936 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}) :936 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}) :936 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}) :936 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}) :943 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}) :943 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 the
214 OpenSSL and WolfSSL backends. Portable code therefore works
215 regardless of which TLS library is linked.
216
217 @par Modification After Stream Creation
218
219 Modifying a context after creating a TLS stream from it
220 results in undefined behavior. Most settings are captured at the
221 first handshake of any stream using it; others, such as callbacks,
222 are read later. A modification may therefore apply partly or not at
223 all.
224
225 If different configurations are needed, create separate context
226 objects.
227
228 @par Thread Safety
229
230 Distinct objects: Safe.
231
232 Shared objects: Unsafe. A context must not be modified while
233 any thread is creating streams from it.
234
235 @par Example
236 @par !example tls_context
237
238 @see tls_role
239 */
240 class BOOST_COROSIO_DECL tls_context
241 {
242 struct implementation;
243 std::shared_ptr<implementation> impl_;
244
245 friend detail::tls_context_data const&
246 detail::get_tls_context_data(tls_context const&) noexcept;
247
248 public:
249 /** Construct a default TLS context.
250
251 Creates a context with default settings suitable for TLS 1.2
252 and TLS 1.3 connections. No certificates or trust anchors are
253 loaded; call the appropriate methods to configure credentials
254 and verification.
255
256 @par Example
257 @par !example tls_context
258 */
259 tls_context();
260
261 /** Creates a new handle that shares ownership of the underlying
262 TLS context state with `other`.
263
264 @param other The context to copy from.
265 */
266 2x tls_context(tls_context const& other) = default;
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 /** Transfers ownership of the TLS context from another instance.
278 After the move, `other` is in a valid but empty state.
279
280 @param other The context to move from.
281 */
282 2x tls_context(tls_context&& other) noexcept = default;
283
284 /** Releases the current context's shared ownership and transfers
285 ownership from another instance. After the move, `other` is
286 in a valid but empty state.
287
288 @param other The context to move from.
289
290 @return Reference to this context.
291 */
292 1x tls_context& operator=(tls_context&& other) noexcept = default;
293
294 /** Releases this handle's shared ownership of the underlying
295 context. The context state is destroyed when the last handle
296 is released.
297 */
298 56x ~tls_context() = default;
299
300 //
301 // Credential Loading
302 //
303
304 /** Load the entity certificate from a memory buffer.
305
306 Sets the certificate that identifies this endpoint to the peer.
307 For servers, this is the server certificate. For clients using
308 mutual TLS, this is the client certificate.
309
310 The certificate must match the private key loaded via
311 `use_private_key()` or `use_private_key_file()`.
312
313 @param certificate The certificate data.
314
315 @param format The encoding format of the certificate data.
316
317 @return Success. The certificate is recorded and decoded when the
318 native context is first built; a malformed certificate surfaces
319 as a handshake failure.
320
321 @see use_certificate_file
322 @see use_private_key
323 */
324 [[nodiscard]] std::error_code
325 use_certificate(std::string_view certificate, tls_file_format format);
326
327 /** Load the entity certificate from a file.
328
329 Sets the certificate that identifies this endpoint to the peer.
330 For servers, this is the server certificate. For clients using
331 mutual TLS, this is the client certificate.
332
333 @param filename Path to the certificate file.
334
335 @param format The encoding format of the file.
336
337 @return Success, or an error if the file could not be read. The
338 certificate is decoded when the native context is first built;
339 a malformed certificate surfaces as a handshake failure.
340
341 @par Example
342 @par !example use_certificate_file
343
344 @see use_certificate
345 @see use_private_key_file
346 */
347 [[nodiscard]] std::error_code
348 use_certificate_file(std::string_view filename, tls_file_format format);
349
350 /** Load a certificate chain from a memory buffer.
351
352 Loads the entity certificate followed by intermediate CA certificates.
353 The chain should be ordered from leaf to root (excluding the root).
354 This is the typical format for PEM certificate bundles.
355
356 @param chain The certificate chain data in PEM format (concatenated
357 certificates).
358
359 @return Success. The chain is recorded and decoded when the native
360 context is first built; a malformed chain surfaces as a
361 handshake failure.
362
363 @see use_certificate_chain_file
364 */
365 [[nodiscard]] std::error_code use_certificate_chain(std::string_view chain);
366
367 /** Load a certificate chain from a file.
368
369 Loads the entity certificate followed by intermediate CA certificates
370 from a PEM file. The file should contain concatenated PEM certificates
371 ordered from leaf to root (excluding the root).
372
373 @param filename Path to the certificate chain file.
374
375 @return Success, or an error if the file could not be read. The
376 chain is decoded when the native context is first built; a
377 malformed chain surfaces as a handshake failure.
378
379 @par Example
380 @par !example use_certificate_chain_file
381
382 @see use_certificate_chain
383 */
384 [[nodiscard]] std::error_code
385 use_certificate_chain_file(std::string_view filename);
386
387 /** Load the private key from a memory buffer.
388
389 Sets the private key corresponding to the entity certificate.
390 The key must match the certificate loaded via `use_certificate()`
391 or `use_certificate_chain()`.
392
393 If the key is encrypted, set a password callback via
394 `set_password_callback()` before calling this function.
395
396 @param private_key The private key data.
397
398 @param format The encoding format of the key data.
399
400 @return Success. The key is recorded and decoded when the native
401 context is first built. Three faults surface only as a handshake
402 failure: a malformed key, a missing password callback for an
403 encrypted key, and a certificate mismatch.
404
405 @see use_private_key_file
406 @see set_password_callback
407 */
408 [[nodiscard]] std::error_code
409 use_private_key(std::string_view private_key, tls_file_format format);
410
411 /** Load the private key from a file.
412
413 Sets the private key corresponding to the entity certificate.
414 The key must match the certificate loaded via `use_certificate_file()`
415 or `use_certificate_chain_file()`.
416
417 If the key file is encrypted, set a password callback via
418 `set_password_callback()` before calling this function.
419
420 @param filename Path to the private key file.
421
422 @param format The encoding format of the file.
423
424 @return Success, or an error if the file could not be read. The
425 key is decoded when the native context is first built; a
426 malformed key or a certificate mismatch surfaces as a
427 handshake failure.
428
429 @par Example
430 @par !example use_private_key_file
431
432 @see use_private_key
433 @see set_password_callback
434 */
435 [[nodiscard]] std::error_code
436 use_private_key_file(std::string_view filename, tls_file_format format);
437
438 /** Load credentials from a PKCS#12 bundle in memory.
439
440 PKCS#12 (also known as PFX) is a binary format that bundles a
441 certificate, private key, and optionally intermediate certificates
442 into a single password-protected file.
443
444 @param data The PKCS#12 bundle data.
445
446 @param passphrase The password protecting the bundle.
447
448 @return Success. The bundle is recorded and decoded into the
449 certificate, private key, and chain when the native context is
450 first built. A malformed bundle or a wrong passphrase surfaces as a
451 handshake failure.
452
453 @note Intermediate certificates inside the bundle are loaded and
454 sent during the handshake on both backends.
455
456 @see use_pkcs12_file
457 */
458 [[nodiscard]] std::error_code
459 use_pkcs12(std::string_view data, std::string_view passphrase);
460
461 /** Load credentials from a PKCS#12 file.
462
463 PKCS#12 (also known as PFX) is a binary format that bundles a
464 certificate, private key, and optionally intermediate certificates
465 into a single password-protected file. This is common on Windows
466 and for certificates exported from browsers.
467
468 @param filename Path to the PKCS#12 file.
469
470 @param passphrase The password protecting the file.
471
472 @return Success, or an error if the file could not be read. The
473 bundle is decoded when the native context is first built; a
474 malformed bundle or wrong passphrase surfaces as a handshake
475 failure.
476
477 @note Intermediate certificates inside the bundle are loaded and
478 sent during the handshake on both backends.
479
480 @par Example
481 @par !example use_pkcs12_file
482
483 @see use_pkcs12
484 */
485 [[nodiscard]] std::error_code
486 use_pkcs12_file(std::string_view filename, std::string_view passphrase);
487
488 //
489 // Trust Anchors
490 //
491
492 /** Add a certificate authority for peer verification.
493
494 Adds one or more CA certificates to the trust store used for
495 verifying peer certificates. The data may contain multiple
496 concatenated PEM certificates.
497
498 @param ca The CA certificate data in PEM format.
499
500 @return Success. The certificates are recorded and decoded when
501 the native context is first built. Whether a malformed
502 certificate fails the handshake depends on the backend. On
503 OpenSSL, any one does. WolfSSL skips certificates it cannot
504 use and fails only when none load.
505
506 @see load_verify_file
507 @see set_default_verify_paths
508 */
509 [[nodiscard]] std::error_code
510 add_certificate_authority(std::string_view ca);
511
512 /** Load CA certificates from a file.
513
514 Loads one or more CA certificates from a PEM file. The file may
515 contain multiple concatenated PEM certificates.
516
517 @param filename Path to a PEM file containing CA certificates.
518
519 @return Success, or an error if the file could not be read. The
520 certificates are decoded when the native context is first
521 built. Malformed certificates are handled as described for
522 `add_certificate_authority()`.
523
524 @par Example
525 @par !example load_verify_file
526
527 @see add_certificate_authority
528 @see add_verify_path
529 */
530 [[nodiscard]] std::error_code load_verify_file(std::string_view filename);
531
532 /** Add a directory of CA certificates for verification.
533
534 Adds a directory of CA certificates to the trust store. The
535 directory is applied when the native context is first built from
536 this context.
537
538 The expected directory layout depends on the backend. OpenSSL
539 performs on-demand lookups. Each certificate file must be named
540 by its subject-name hash, as generated by `openssl rehash` or
541 `c_rehash`. WolfSSL loads every certificate file in the
542 directory.
543
544 @param path Path to the directory of CA certificates.
545
546 @return Success. The path is recorded and applied when the native
547 context is built. A directory that cannot be read at that time is
548 skipped rather than reported here.
549
550 @par Example
551 @par !example add_verify_path
552
553 @see load_verify_file
554 @see set_default_verify_paths
555 */
556 [[nodiscard]] std::error_code add_verify_path(std::string_view path);
557
558 /** Use the system default CA certificate store.
559
560 Configures the context to use the backend's default trust store
561 for peer certificate verification. This is the
562 recommended approach for HTTPS clients connecting to public
563 servers.
564
565 The system store is loaded when the native context is first built
566 from this context. For a verified-safe client, combine this with
567 `set_verify_mode( tls_verify_mode::peer )` and, when connecting by
568 name, `tls_stream::set_hostname()`.
569
570 @return Success. The request is recorded and applied when the
571 native context is built. A system store that cannot be loaded at
572 that time is skipped rather than reported here. A context that
573 must reject unverified peers should therefore also use
574 `set_verify_mode( tls_verify_mode::peer )`.
575
576 @note OpenSSL reads the CA file and directory it was built with,
577 or those named by `SSL_CERT_FILE` and `SSL_CERT_DIR`. It does
578 not read the macOS Keychain or the Windows Certificate Store.
579 WolfSSL reads the platform store and requires a build with
580 `WOLFSSL_SYS_CA_CERTS`; without it 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 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 do 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, because 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
673 set_ciphersuites_tls13(std::string_view ciphers);
674
675 /** Set the ALPN protocol list.
676
677 Configures Application-Layer Protocol Negotiation (ALPN) for
678 the connection. ALPN is used to negotiate which application
679 protocol to use over the TLS connection (e.g., "h2" for HTTP/2,
680 "http/1.1" for HTTP/1.1).
681
682 The protocols are tried in preference order (first = highest).
683
684 @param protocols Ordered list of protocol identifiers.
685
686 @return Success, or an error if ALPN configuration fails.
687
688 @note Read the negotiated protocol after the handshake via
689 @ref tls_stream::alpn_protocol. On WolfSSL, ALPN requires a
690 build with `HAVE_ALPN`; without it, offering protocols fails
691 the handshake with `std::errc::function_not_supported` rather
692 than negotiate nothing silently.
693
694 @par Example
695 @par !example set_alpn
696 */
697 [[nodiscard]] std::error_code
698 set_alpn(std::initializer_list<std::string_view> protocols);
699
700 //
701 // Certificate Verification
702 //
703
704 /** Set the peer certificate verification mode.
705
706 Controls whether and how peer certificates are verified during
707 the TLS handshake.
708
709 @param mode The verification mode to use.
710
711 @return Success. The mode is recorded and applied when the native
712 context is first built.
713
714 @par Example
715 @par !example set_verify_mode
716
717 @see tls_verify_mode
718 */
719 [[nodiscard]] std::error_code set_verify_mode(tls_verify_mode mode);
720
721 /** Set the maximum certificate chain verification depth.
722
723 Limits how many intermediate certificates can appear between
724 the peer certificate and a trusted root. The default is
725 typically 100, which is sufficient for most certificate chains.
726
727 @param depth Maximum number of intermediate certificates allowed.
728
729 @return Success. The depth is recorded and applied when the native
730 context is first built.
731
732 @par Example
733 @par !example set_verify_depth
734 */
735 [[nodiscard]] std::error_code set_verify_depth(int depth);
736
737 /** Set a custom certificate verification callback.
738
739 Installs a callback that is invoked during certificate chain
740 verification. The callback can perform additional validation
741 beyond the standard checks and can override verification
742 results.
743
744 The callback receives the built-in verification result so far and
745 a `verify_context` describing the certificate being verified. Return
746 `true` to accept the certificate, `false` to reject. Inspect the
747 certificate portably via `verify_context::certificate()` (its DER
748 encoding) — for example to pin a specific certificate.
749
750 @par Backend Support
751
752 The exact set of certificates the callback sees differs by backend:
753
754 - OpenSSL: the callback runs once per certificate in the chain,
755 including certificates that passed the built-in checks. It can
756 therefore relax verification by returning `true` for a
757 certificate the library rejected. It can also tighten
758 verification by returning `false` for a certificate the library
759 accepted, as pinning does.
760 - WolfSSL built with `WOLFSSL_ALWAYS_VERIFY_CB` (implied by
761 `--enable-opensslextra`): same as OpenSSL.
762 - WolfSSL without that option: the library invokes the callback
763 only on verification *failure*, so it cannot be honored on a
764 successful handshake. Silently ignoring a verification-tightening
765 callback would fail open. On such a build, a context that carries
766 a callback instead **fails the handshake** with
767 `std::errc::function_not_supported`. Rebuild
768 WolfSSL with `WOLFSSL_ALWAYS_VERIFY_CB`, or omit the callback.
769
770 @tparam Callback A callable with signature
771 `bool( bool preverified, verify_context& ctx )`.
772
773 @param callback The verification callback. Recorded here and
774 applied during the handshake; on a WolfSSL build that
775 cannot honor it, the handshake fails with
776 `std::errc::function_not_supported` (see Backend Support).
777
778 @par Example
779 @par !example set_verify_callback
780
781 @see verify_context
782 @see set_verify_mode
783 */
784 template<typename Callback>
785 void set_verify_callback(Callback callback);
786
787 /** Set a callback for Server Name Indication (SNI).
788
789 For server connections, this callback is invoked during the TLS
790 handshake when a client sends an SNI extension. The callback
791 receives the requested hostname and can accept or reject the
792 connection.
793
794 @tparam Callback A callable with signature
795 `bool( std::string_view hostname )`.
796
797 @param callback The SNI callback. Return `true` to accept the
798 connection or `false` to reject it with an alert.
799
800 @par Example
801 @par !example set_servername_callback
802
803 @note For virtual hosting with different certificates per hostname,
804 create separate contexts and select the appropriate one before
805 creating the TLS stream.
806
807 @see tls_stream::set_hostname
808 */
809 template<typename Callback>
810 void set_servername_callback(Callback callback);
811
812 private:
813 void set_servername_callback_impl(
814 std::function<bool(std::string_view)> callback);
815
816 void set_password_callback_impl(
817 std::function<std::string(std::size_t, tls_password_purpose)> callback);
818
819 void set_verify_callback_impl(
820 std::function<bool(bool, verify_context&)> callback);
821
822 public:
823 //
824 // Revocation Checking
825 //
826
827 /** Add a Certificate Revocation List from memory.
828
829 Adds a CRL to the verification store for checking whether
830 certificates are revoked. CRLs are typically fetched
831 from the URLs in a certificate's CRL Distribution Points
832 extension.
833
834 @param crl The CRL data in DER or PEM format.
835
836 @return Success. The CRL is recorded and decoded when the native
837 context is first built; a malformed CRL surfaces as a
838 handshake failure.
839
840 @note CRLs are consulted only when a revocation policy is set via
841 @ref set_revocation_policy. On WolfSSL, CRL checking requires a
842 build with `HAVE_CRL`; without it, a revocation policy
843 other than `disabled` fails the handshake with
844 `std::errc::function_not_supported`.
845
846 @see add_crl_file
847 @see set_revocation_policy
848 */
849 [[nodiscard]] std::error_code add_crl(std::string_view crl);
850
851 /** Add a Certificate Revocation List from a file.
852
853 Adds a CRL to the verification store for checking whether
854 certificates are revoked.
855
856 @param filename Path to a CRL file (DER or PEM format).
857
858 @return Success, or an error if the file could not be read. The
859 CRL is decoded when the native context is first built; a
860 malformed CRL surfaces as a handshake failure.
861
862 @note CRLs are consulted only when a revocation policy is set via
863 @ref set_revocation_policy (WolfSSL requires a `HAVE_CRL`
864 build).
865
866 @par Example
867 @par !example add_crl_file
868
869 @see add_crl
870 @see set_revocation_policy
871 */
872 [[nodiscard]] std::error_code add_crl_file(std::string_view filename);
873
874 /** Set the certificate revocation checking policy.
875
876 Controls how certificate revocation status is checked during
877 verification via CRLs.
878
879 @param policy The revocation checking policy.
880
881 @par Example
882 @par !example set_revocation_policy
883
884 @note Revocation is checked via CRLs supplied with @ref add_crl /
885 @ref add_crl_file. `soft_fail` accepts a certificate whose
886 status cannot be determined (missing/expired CRL) but rejects
887 one that is actually revoked; `hard_fail` also rejects unknown
888 status. OCSP-based revocation is not available (see the TLS
889 guide). On WolfSSL a non-disabled policy requires a `HAVE_CRL`
890 build, else the handshake fails with
891 `std::errc::function_not_supported`.
892
893 @see tls_revocation_policy
894 @see add_crl
895 */
896 void set_revocation_policy(tls_revocation_policy policy);
897
898 //
899 // Password Handling
900 //
901
902 /** Set the password callback for encrypted keys.
903
904 Installs a callback that provides passwords for encrypted
905 private keys and PKCS#12 files. The callback is invoked when
906 loading encrypted key material.
907
908 @tparam Callback A callable with signature
909 `std::string( std::size_t max_length, tls_password_purpose purpose )`.
910
911 @param callback The password callback. It receives the maximum
912 password length and the purpose (reading or writing), and
913 returns the password string.
914
915 @par Example
916 @par !example set_password_callback
917
918 @see tls_password_purpose
919 */
920 template<typename Callback>
921 void set_password_callback(Callback callback);
922 };
923 #ifdef _MSC_VER
924 #pragma warning(pop)
925 #endif
926
927 template<typename Callback>
928 void
929 1x tls_context::set_servername_callback(Callback callback)
930 {
931 1x set_servername_callback_impl(std::move(callback));
932 1x }
933
934 template<typename Callback>
935 void
936 4x tls_context::set_password_callback(Callback callback)
937 {
938 4x set_password_callback_impl(std::move(callback));
939 4x }
940
941 template<typename Callback>
942 void
943 2x tls_context::set_verify_callback(Callback callback)
944 {
945 2x set_verify_callback_impl(std::move(callback));
946 2x }
947
948 } // namespace boost::corosio
949
950 #endif
951