LCOV - code coverage report
Current view: top level - corosio - tls_context.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 87.5 % 16 14 2
Test Date: 2026-08-21 20:48:07 Functions: 92.3 % 13 12 1

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

Generated by: LCOV version 2.3