qb  2.0.0.0
C++17 Actor Framework
qb Issue Watch Star Fork Follow @isndev
Loading...
Searching...
No Matches
qb::io::tcp::ssl::socket Class Reference

Class implementing secure SSL/TLS TCP socket functionality. More...

#include <socket.h>

Inheritance diagram for qb::io::tcp::ssl::socket:
Collaboration diagram for qb::io::tcp::ssl::socket:

Public Member Functions

 ~socket () noexcept
 Destructor.
 socket () noexcept
 Default constructor.
 socket (SSL *ssl_ptr, tcp::socket &sock) noexcept
 Constructor from an existing OpenSSL SSL structure and an established tcp::socket.
 socket (socket const &rhs)=delete
 Deleted copy constructor.
 socket (socket &&rhs)=default
 Default move constructor.
socketoperator= (socket &&rhs)=default
 Default move assignment operator.
void init (SSL *handle=nullptr) noexcept
 Initialize the SSL socket with an OpenSSL SSL handle.
int connect (endpoint const &ep, std::string const &hostname="") noexcept
 Establish a blocking SSL/TLS connection to a remote endpoint.
int connect (uri const &u) noexcept
 Establish a blocking SSL/TLS connection to a remote endpoint specified by a URI.
int connect_v4 (std::string const &host, uint16_t port) noexcept
 Establish a blocking SSL/TLS connection to an IPv4 server.
int connect_v6 (std::string const &host, uint16_t port) noexcept
 Establish a blocking SSL/TLS connection to an IPv6 server.
int connect_un (std::string const &path) noexcept
 Establish a blocking SSL/TLS connection over a Unix domain socket (conceptual, as SSL is typically over TCP).
int n_connect (qb::io::endpoint const &ep, std::string const &hostname="") noexcept
 Initiate a non-blocking SSL/TLS connection to a remote endpoint.
int connected () noexcept
 Finalizes a non-blocking SSL connection after the underlying TCP socket is connected.
int n_connect (uri const &u) noexcept
 Initiate a non-blocking SSL/TLS connection to a remote URI.
int n_connect_v4 (std::string const &host, uint16_t port) noexcept
 Initiate a non-blocking SSL/TLS connection to an IPv4 server.
int n_connect_v6 (std::string const &host, uint16_t port) noexcept
 Initiate a non-blocking SSL/TLS connection to an IPv6 server.
int n_connect_un (std::string const &path) noexcept
 Initiate a non-blocking SSL/TLS connection over a Unix domain socket.
int disconnect () noexcept
 Gracefully shut down the SSL/TLS connection and close the underlying socket.
int read (void *data, std::size_t size) noexcept
 Read decrypted data from the secure SSL/TLS socket.
int write (const void *data, std::size_t size) noexcept
 Write data to be encrypted and sent over the SSL/TLS socket.
SSL * ssl_handle () const noexcept
 Get the underlying OpenSSL SSL handle.
qb::io::ssl::Certificate get_peer_certificate_details () const noexcept
 Get details of the peer's certificate, if available.
std::string get_negotiated_cipher_suite () const noexcept
 Get the negotiated cipher suite string.
std::string get_negotiated_tls_version () const noexcept
 Get the negotiated TLS protocol version string.
std::string get_alpn_selected_protocol () const noexcept
 Get the ALPN protocol selected by the peer (typically for clients) or by this endpoint (for servers).
std::string get_last_ssl_error_string () const noexcept
 Get the last OpenSSL error string for the current SSL handle.
bool disable_session_resumption () noexcept
 Disable SSL/TLS session resumption for this specific connection (client-side).
bool request_ocsp_stapling (bool enable=true) noexcept
 Request OCSP stapling from the server for this connection (client-side).
std::vector< qb::io::ssl::Certificateget_peer_certificate_chain () const noexcept
 Get the peer's full certificate chain.
qb::io::ssl::Session get_session () const noexcept
 Retrieves the current SSL session from this connection.
bool set_session (qb::io::ssl::Session &session) noexcept
 Sets an SSL session to be used for resumption on this connection (client-side).
bool request_client_post_handshake_auth () noexcept
 Request Post-Handshake Authentication from the server (client-side, TLS 1.3+).
bool set_sni_hostname (const std::string &hostname) noexcept
 Set the Server Name Indication (SNI) hostname for this SSL connection.
bool set_alpn_protocols (const std::vector< std::string > &protocols) noexcept
 Set the ALPN protocols to offer for this specific SSL connection (client-side).
bool set_verify_callback (int(*callback)(int, X509_STORE_CTX *), int verification_mode) noexcept
 Set a custom X.509 certificate verification callback and mode for this SSL connection.
bool set_verify_depth (int depth) noexcept
 Set the maximum verification depth for the peer certificate chain for this SSL connection.
int do_handshake () noexcept
Public Member Functions inherited from qb::io::tcp::socket
 socket ()=default
 Default constructor.
 socket (socket const &)=delete
 Deleted copy constructor.
 socket (socket &&)=default
 Default move constructor.
socketoperator= (socket &&)=default
 Default move assignment operator.
 socket (io::socket &&sock) noexcept
 Constructor from a generic qb::io::socket (move semantics).
socketoperator= (io::socket &&sock) noexcept
 Move assignment operator from a generic qb::io::socket.
int init (int af=AF_INET) noexcept
 Initialize (open) the TCP socket.
int bind (qb::io::endpoint const &ep) noexcept
 Bind the socket to a specific local endpoint.
int bind (qb::io::uri const &u) noexcept
 Bind the socket to an endpoint specified by a URI.
int connect (qb::io::endpoint const &ep) noexcept
 Connect to a remote TCP endpoint.
int connect (uri const &u) noexcept
 Connect to a remote TCP endpoint specified by a URI.
int connect_v4 (std::string const &host, uint16_t port) noexcept
 Connect to an IPv4 TCP server.
int connect_v6 (std::string const &host, uint16_t port) noexcept
 Connect to an IPv6 TCP server.
int connect_un (std::string const &path) noexcept
 Connect to a Unix domain TCP-style socket.
int n_connect (qb::io::endpoint const &ep) noexcept
 Initiate a non-blocking connect to a remote TCP endpoint.
void connected () noexcept
 Called after a non-blocking connect attempt succeeds or needs to be finalized.
int n_connect (uri const &u) noexcept
 Initiate a non-blocking connect to a remote TCP endpoint specified by a URI.
int n_connect_v4 (std::string const &host, uint16_t port) noexcept
 Initiate a non-blocking connect to an IPv4 TCP server.
int n_connect_v6 (std::string const &host, uint16_t port) noexcept
 Initiate a non-blocking connect to an IPv6 TCP server.
int n_connect_un (std::string const &path) noexcept
 Initiate a non-blocking connect to a Unix domain TCP-style socket.
int read (void *dest, std::size_t len) const noexcept
 Read data from the connected TCP socket.
int write (const void *data, std::size_t size) const noexcept
 Write data to the connected TCP socket.
int disconnect () const noexcept
 Disconnect the TCP socket.

Static Public Member Functions

static constexpr bool is_secure () noexcept
 Indicates that this socket implementation is secure.
Static Public Member Functions inherited from qb::io::tcp::socket
static constexpr bool is_secure () noexcept
 Indicates that this socket implementation is not secure.

Detailed Description

Class implementing secure SSL/TLS TCP socket functionality.

This class provides secure socket functionality using OpenSSL for encrypted communications. It inherits from qb::io::tcp::socket and adds an SSL/TLS encryption layer to the TCP connection. It handles the SSL handshake process and transparently encrypts/decrypts data for read and write operations.

Constructor & Destructor Documentation

◆ ~socket()

qb::io::tcp::ssl::socket::~socket ( )
noexcept

Destructor.

Ensures the SSL connection is shut down and the SSL object is freed if managed. The base class destructor handles closing the underlying TCP socket.

◆ socket() [1/3]

qb::io::tcp::ssl::socket::socket ( )
noexcept

Default constructor.

Creates an uninitialized SSL socket. Call init() with an SSL_CTX and then a connect or accept related method.

◆ socket() [2/3]

qb::io::tcp::ssl::socket::socket ( SSL * ssl_ptr,
tcp::socket & sock )
noexcept

Constructor from an existing OpenSSL SSL structure and an established tcp::socket.

Parameters
ssl_ptrPointer to an initialized SSL object (e.g., from SSL_new with an SSL_CTX). This ssl::socket will take ownership if ssl_ptr is not null.
sockA tcp::socket that is already connected (for clients) or accepted (for servers). The file descriptor from sock will be associated with the SSL object. The state of sock is moved into this ssl::socket.

◆ socket() [3/3]

qb::io::tcp::ssl::socket::socket ( socket const & rhs)
delete

Deleted copy constructor.

SSL sockets are not copyable.

Member Function Documentation

◆ operator=()

socket & qb::io::tcp::ssl::socket::operator= ( socket && rhs)
default

Default move assignment operator.

Returns
Reference to this socket.

◆ init()

void qb::io::tcp::ssl::socket::init ( SSL * handle = nullptr)
noexcept

Initialize the SSL socket with an OpenSSL SSL handle.

Parameters
handleA pointer to an SSL object, typically created using SSL_new() from an SSL_CTX. This ssl::socket takes ownership of the handle via std::unique_ptr. The underlying TCP socket must be set separately (e.g. via move construction or assignment from tcp::socket).
Note
The SSL object should not yet have a file descriptor associated if this socket is to be used for a new connection.

◆ connect() [1/2]

int qb::io::tcp::ssl::socket::connect ( endpoint const & ep,
std::string const & hostname = "" )
noexcept

Establish a blocking SSL/TLS connection to a remote endpoint.

Parameters
epThe qb::io::endpoint of the remote server.
hostnameOptional hostname string for Server Name Indication (SNI). If empty, SNI is not used.
Returns
0 on successful connection and SSL handshake, non-zero error code on failure.

Requires init(SSL_CTX*) to have been called first to set up the SSL context for this socket.

◆ connect() [2/2]

int qb::io::tcp::ssl::socket::connect ( uri const & u)
noexcept

Establish a blocking SSL/TLS connection to a remote endpoint specified by a URI.

Parameters
uThe qb::io::uri of the remote server. The URI's host is used for SNI if not overridden.
Returns
0 on success, non-zero error code on failure.

◆ connect_v4()

int qb::io::tcp::ssl::socket::connect_v4 ( std::string const & host,
uint16_t port )
noexcept

Establish a blocking SSL/TLS connection to an IPv4 server.

Parameters
hostThe hostname or IP address string of the server. Used for SNI.
portThe port number of the server.
Returns
0 on success, non-zero error code on failure.

◆ connect_v6()

int qb::io::tcp::ssl::socket::connect_v6 ( std::string const & host,
uint16_t port )
noexcept

Establish a blocking SSL/TLS connection to an IPv6 server.

Parameters
hostThe hostname or IP address string of the server. Used for SNI.
portThe port number of the server.
Returns
0 on success, non-zero error code on failure.

◆ connect_un()

int qb::io::tcp::ssl::socket::connect_un ( std::string const & path)
noexcept

Establish a blocking SSL/TLS connection over a Unix domain socket (conceptual, as SSL is typically over TCP).

Parameters
pathThe file system path of the Unix domain socket.
Returns
0 on success, non-zero error code on failure.
Note
SSL over Unix domain sockets is uncommon but technically possible if the peer expects it.

◆ n_connect() [1/2]

int qb::io::tcp::ssl::socket::n_connect ( qb::io::endpoint const & ep,
std::string const & hostname = "" )
noexcept

Initiate a non-blocking SSL/TLS connection to a remote endpoint.

Parameters
epThe qb::io::endpoint of the remote server.
hostnameOptional hostname for SNI. If empty, SNI is not used.
Returns
0 if TCP connection is in progress or succeeded (SSL handshake follows via connected()). Non-zero error code on immediate TCP connection failure.

Sets up SNI if hostname is provided. After this call, use event loop mechanisms to wait for socket writability, then call connected() to perform/complete the SSL handshake.

◆ connected()

int qb::io::tcp::ssl::socket::connected ( )
noexcept

Finalizes a non-blocking SSL connection after the underlying TCP socket is connected.

Returns
0 if SSL handshake completed successfully or is in progress without error (SSL_ERROR_WANT_READ/WRITE). A non-zero SSL error code or negative value on handshake failure.

This method performs the SSL handshake (SSL_connect or SSL_accept). It should be called when a non-blocking connect (or accept on server side) has established the TCP layer, and the socket is ready for the SSL handshake I/O. Sets the internal _connected flag on successful handshake.

◆ n_connect() [2/2]

int qb::io::tcp::ssl::socket::n_connect ( uri const & u)
noexcept

Initiate a non-blocking SSL/TLS connection to a remote URI.

Parameters
uThe qb::io::uri of the remote server. Host from URI is used for SNI.
Returns
0 on TCP connection progress/success, non-zero error on immediate failure.

◆ n_connect_v4()

int qb::io::tcp::ssl::socket::n_connect_v4 ( std::string const & host,
uint16_t port )
noexcept

Initiate a non-blocking SSL/TLS connection to an IPv4 server.

Parameters
hostHostname or IP string for connection and SNI.
portServer port number.
Returns
0 on TCP connection progress/success, non-zero error on immediate failure.

◆ n_connect_v6()

int qb::io::tcp::ssl::socket::n_connect_v6 ( std::string const & host,
uint16_t port )
noexcept

Initiate a non-blocking SSL/TLS connection to an IPv6 server.

Parameters
hostHostname or IP string for connection and SNI.
portServer port number.
Returns
0 on TCP connection progress/success, non-zero error on immediate failure.

◆ n_connect_un()

int qb::io::tcp::ssl::socket::n_connect_un ( std::string const & path)
noexcept

Initiate a non-blocking SSL/TLS connection over a Unix domain socket.

Parameters
pathPath to the Unix domain socket.
Returns
0 on TCP connection progress/success, non-zero error on immediate failure.

◆ disconnect()

int qb::io::tcp::ssl::socket::disconnect ( )
noexcept

Gracefully shut down the SSL/TLS connection and close the underlying socket.

Returns
0 on success, non-zero error code on failure during SSL shutdown.

Performs SSL_shutdown() and then calls the base class disconnect().

◆ read()

int qb::io::tcp::ssl::socket::read ( void * data,
std::size_t size )
noexcept

Read decrypted data from the secure SSL/TLS socket.

Parameters
dataPointer to the buffer where decrypted data will be stored.
sizeMaximum number of bytes to read into the buffer.
Returns
Number of bytes actually read and decrypted. Returns 0 if the peer performed an orderly SSL shutdown. Returns a negative value on error (e.g., SSL_ERROR_WANT_READ, SSL_ERROR_SYSCALL).

Internally calls SSL_read().

◆ write()

int qb::io::tcp::ssl::socket::write ( const void * data,
std::size_t size )
noexcept

Write data to be encrypted and sent over the SSL/TLS socket.

Parameters
dataPointer to the plaintext data to be encrypted and sent.
sizeNumber of bytes to send from the data buffer.
Returns
Number of bytes successfully encrypted and written to the SSL/TLS layer. This can be less than size if the SSL/TLS layer cannot accept all data immediately. Returns a negative value on error.

Internally calls SSL_write().

◆ ssl_handle()

SSL * qb::io::tcp::ssl::socket::ssl_handle ( ) const
nodiscardnoexcept

Get the underlying OpenSSL SSL handle.

Returns
Pointer to the SSL object, or nullptr if not initialized.
Note
Allows direct access to the OpenSSL API for advanced configuration or inspection if needed.

◆ get_peer_certificate_details()

qb::io::ssl::Certificate qb::io::tcp::ssl::socket::get_peer_certificate_details ( ) const
noexcept

Get details of the peer's certificate, if available.

Returns
A qb::io::ssl::Certificate structure. Empty if no certificate or handshake not complete.

◆ get_negotiated_cipher_suite()

std::string qb::io::tcp::ssl::socket::get_negotiated_cipher_suite ( ) const
noexcept

Get the negotiated cipher suite string.

Returns
A string describing the cipher suite, or empty if not connected/negotiated.

◆ get_negotiated_tls_version()

std::string qb::io::tcp::ssl::socket::get_negotiated_tls_version ( ) const
noexcept

Get the negotiated TLS protocol version string.

Returns
A string like "TLSv1.2", "TLSv1.3", or empty if not connected/negotiated.

◆ get_alpn_selected_protocol()

std::string qb::io::tcp::ssl::socket::get_alpn_selected_protocol ( ) const
noexcept

Get the ALPN protocol selected by the peer (typically for clients) or by this endpoint (for servers).

Returns
The selected protocol string (e.g., "h2", "http/1.1"), or empty if ALPN was not used or no protocol was selected.

◆ get_last_ssl_error_string()

std::string qb::io::tcp::ssl::socket::get_last_ssl_error_string ( ) const
noexcept

Get the last OpenSSL error string for the current SSL handle.

Returns
A string describing the last error on the OpenSSL error queue for this SSL connection. Returns an empty string if there is no error or the SSL handle is invalid.

◆ disable_session_resumption()

bool qb::io::tcp::ssl::socket::disable_session_resumption ( )
noexcept

Disable SSL/TLS session resumption for this specific connection (client-side).

Must be called before the SSL handshake (e.g., before connect or connected). This function sets the SSL_OP_NO_TICKET and SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION options and attempts to clear any previously set session using SSL_set_session(ssl, NULL).

Returns
true if options were set successfully and an SSL handle exists, false otherwise.

◆ request_ocsp_stapling()

bool qb::io::tcp::ssl::socket::request_ocsp_stapling ( bool enable = true)
noexcept

Request OCSP stapling from the server for this connection (client-side).

Must be called before the SSL handshake.

Parameters
enableSet to true to request OCSP stapling, false to not request (or clear previous request).
Returns
true if the request preference was set and an SSL handle exists, false otherwise.
Note
The actual handling of the OCSP response needs to be done via a callback set on the SSL_CTX using qb::io::ssl::set_ocsp_stapling_client_callback.

◆ get_peer_certificate_chain()

std::vector< qb::io::ssl::Certificate > qb::io::tcp::ssl::socket::get_peer_certificate_chain ( ) const
noexcept

Get the peer's full certificate chain.

Returns
A vector of qb::io::ssl::Certificate structures, representing the chain. The first certificate in the vector is the peer's end-entity certificate, followed by intermediate CAs. The vector is empty if not connected, no chain is available, or an error occurs.

◆ get_session()

qb::io::ssl::Session qb::io::tcp::ssl::socket::get_session ( ) const
noexcept

Retrieves the current SSL session from this connection.

This session can be cached by the client and later used with set_session() on a new connection to the same server to attempt session resumption. The caller is responsible for freeing the returned session using qb::io::ssl::free_session() when it is no longer needed.

Returns
A qb::io::ssl::Session object. If no session is available or an error occurs, the returned Session object will be !is_valid().
Note
The session should typically be retrieved after a successful handshake and before disconnect.

◆ set_session()

bool qb::io::tcp::ssl::socket::set_session ( qb::io::ssl::Session & session)
noexcept

Sets an SSL session to be used for resumption on this connection (client-side).

Must be called before the SSL handshake (e.g., before connect() or connected()). The provided session should be one previously obtained from get_session() from a connection to the same server and subsequently stored by the application.

Parameters
sessionThe qb::io::ssl::Session object to attempt to resume.
Returns
true if the session was successfully set on the SSL handle, false otherwise (e.g., no SSL handle, invalid session).
Note
Setting a session does not guarantee resumption; the server must also agree.

◆ request_client_post_handshake_auth()

bool qb::io::tcp::ssl::socket::request_client_post_handshake_auth ( )
noexcept

Request Post-Handshake Authentication from the server (client-side, TLS 1.3+).

This function initiates a post-handshake authentication request if the connection is TLS 1.3 or newer. The server must be configured to support PHA. The call is non-blocking; the application should monitor the connection for the server's response (e.g. CertificateRequest) through standard read/write mechanisms or SSL info callbacks.

Returns
true if the PHA request was successfully initiated, false on error (e.g., not TLS 1.3, SSL handle not valid, OpenSSL version too old, or PHA already in progress).

◆ set_sni_hostname()

bool qb::io::tcp::ssl::socket::set_sni_hostname ( const std::string & hostname)
noexcept

Set the Server Name Indication (SNI) hostname for this SSL connection.

Must be called before the SSL handshake (e.g., before connect() or connected()). This overrides any SNI set by connect methods if called after them but before handshake.

Parameters
hostnameThe hostname to use for SNI.
Returns
true if SNI was set successfully and an SSL handle exists, false otherwise.

◆ set_alpn_protocols()

bool qb::io::tcp::ssl::socket::set_alpn_protocols ( const std::vector< std::string > & protocols)
noexcept

Set the ALPN protocols to offer for this specific SSL connection (client-side).

Must be called before the SSL handshake. Overrides ALPN protocols set on the SSL_CTX for this connection.

Parameters
protocolsA vector of protocol strings (e.g., {"h2", "http/1.1"}).
Returns
true if ALPN protocols were set successfully and an SSL handle exists, false otherwise.

◆ set_verify_callback()

bool qb::io::tcp::ssl::socket::set_verify_callback ( int(* callback )(int, X509_STORE_CTX *),
int verification_mode )
noexcept

Set a custom X.509 certificate verification callback and mode for this SSL connection.

Must be called before the SSL handshake. Overrides the verification settings from the SSL_CTX.

Parameters
callbackA user-defined callback function. Signature: int callback(int preverify_ok, X509_STORE_CTX *x509_ctx). Return 1 for success, 0 for failure.
verification_modeThe verification mode (e.g., SSL_VERIFY_PEER).
Returns
true if the callback and mode were set on the SSL handle, false otherwise.

◆ set_verify_depth()

bool qb::io::tcp::ssl::socket::set_verify_depth ( int depth)
noexcept

Set the maximum verification depth for the peer certificate chain for this SSL connection.

Must be called before the SSL handshake. Overrides the depth set on the SSL_CTX.

Parameters
depthThe maximum number of intermediate CA certificates that may be traversed.
Returns
true if the depth was set successfully and an SSL handle exists, false otherwise.