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