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