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