TLS API Spec
Overview
The TLS module provides Transport Layer Security (TLS) for HTTP connections, implemented on top of mbedTLS 3.x. It manages TLS context creation, certificate/key loading, cipher suite configuration, TLS 1.3 support, mutual TLS (mTLS), session caching, and TLS handshake lifecycle. The module is guarded by the UVHTTP_FEATURE_TLS compile-time feature gate.
Interfaces
uvhttp_tls_context_new
- Signature:
uvhttp_error_t uvhttp_tls_context_new(uvhttp_tls_context_t** ctx) - Purpose: Create a new TLS context with default mbedTLS server configuration
- Preconditions:
ctxmust be a non-NULL pointer touvhttp_tls_context_t*. - Postconditions: On success,
*ctxpoints to a valid TLS context with initialized mbedTLS config, entropy, DRBG, certificate store, and SSL cache. Defaults to server mode with stream transport and preset defaults. On failure,*ctxis set to NULL. - Error conditions:
UVHTTP_ERROR_INVALID_PARAM:ctxis NULLUVHTTP_ERROR_OUT_OF_MEMORY: allocation failureUVHTTP_ERROR_TLS_INIT: DRBG seeding failedUVHTTP_ERROR_TLS_CONTEXT: mbedtls_ssl_config_defaults failed
- Thread safety: Not thread-safe.
uvhttp_tls_context_free
- Signature:
void uvhttp_tls_context_free(uvhttp_tls_context_t* ctx) - Purpose: Free a TLS context and all associated mbedTLS resources
- Preconditions:
ctxcan be NULL (no-op). Must have been created byuvhttp_tls_context_new. - Postconditions: All mbedTLS contexts (SSL config, certificates, private key, CA cert, CRL, entropy, DRBG, cache) are freed. The context memory is released. The pointer is invalid after return.
- Thread safety: Not thread-safe.
uvhttp_tls_context_load_cert_chain
- Signature:
uvhttp_error_t uvhttp_tls_context_load_cert_chain(uvhttp_tls_context_t* ctx, const char* cert_file) - Purpose: Load a certificate (chain) from a PEM file
- Preconditions:
ctxmust be valid.cert_filemust be non-NULL and point to a readable PEM file. - Postconditions: The certificate is parsed and configured as the server's own certificate.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxorcert_fileis NULLUVHTTP_ERROR_TLS_CERT: mbedTLS cert parse or config failed
- Thread safety: Not thread-safe.
uvhttp_tls_context_load_private_key
- Signature:
uvhttp_error_t uvhttp_tls_context_load_private_key(uvhttp_tls_context_t* ctx, const char* key_file) - Purpose: Load a private key from a PEM file
- Preconditions:
ctxmust be valid.key_filemust be non-NULL and point to a readable PEM key file. The certificate should have been loaded first (uvhttp_tls_context_load_cert_chain). - Postconditions: The private key is parsed and associated with the context.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxorkey_fileis NULLUVHTTP_ERROR_TLS_KEY: mbedTLS key parse failed
- Thread safety: Not thread-safe.
uvhttp_tls_context_load_ca_file
- Signature:
uvhttp_error_t uvhttp_tls_context_load_ca_file(uvhttp_tls_context_t* ctx, const char* ca_file) - Purpose: Load a CA certificate file for client certificate verification
- Preconditions:
ctxmust be valid.ca_filemust be non-NULL. - Postconditions: The CA certificate is parsed and is set as the trusted CA chain for verification.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxorca_fileis NULLUVHTTP_ERROR_TLS_CA: mbedTLS CA cert parse failed
- Thread safety: Not thread-safe.
uvhttp_tls_context_enable_tls13
- Signature:
uvhttp_error_t uvhttp_tls_context_enable_tls13(uvhttp_tls_context_t* ctx, int enable) - Purpose: Enable or disable TLS 1.3 (minimum version)
- Preconditions:
ctxmust be valid. - Postconditions: When enabled, the minimum TLS version is set to TLS 1.3 (MBEDTLS_SSL_MINOR_VERSION_4). When disabled, the minimum is set to TLS 1.2 (MBEDTLS_SSL_MINOR_VERSION_3).
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxis NULL
- Thread safety: Not thread-safe.
uvhttp_tls_context_set_cipher_suites
- Signature:
uvhttp_error_t uvhttp_tls_context_set_cipher_suites(uvhttp_tls_context_t* ctx, const int* cipher_suites) - Purpose: Set the preferred cipher suites for the TLS context
- Preconditions:
ctxmust be valid.cipher_suitesmust be non-NULL and point to a zero-terminated array of mbedTLS cipher suite identifiers. - Postconditions: The TLS configuration uses the specified cipher suites in preference order.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxorcipher_suitesis NULL
- Thread safety: Not thread-safe.
uvhttp_tls_context_enable_client_auth
- Signature:
uvhttp_error_t uvhttp_tls_context_enable_client_auth(uvhttp_tls_context_t* ctx, int require_cert) - Purpose: Enable or disable client certificate authentication (mTLS)
- Preconditions:
ctxmust be valid. - Postconditions: When
require_certis non-zero, auth mode is set toMBEDTLS_SSL_VERIFY_REQUIRED(client must present a valid certificate). When zero, auth mode isMBEDTLS_SSL_VERIFY_NONE. - Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxis NULL
- Thread safety: Not thread-safe.
uvhttp_tls_context_set_verify_depth
- Signature:
uvhttp_error_t uvhttp_tls_context_set_verify_depth(uvhttp_tls_context_t* ctx, int depth) - Purpose: Set the certificate chain verification depth (currently a no-op placeholder)
- Preconditions:
ctxmust be valid. - Postconditions: Currently returns UVHTTP_OK without modification (reserved for future use).
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxis NULL
- Thread safety: Not thread-safe.
uvhttp_tls_context_enable_session_tickets
- Signature:
uvhttp_error_t uvhttp_tls_context_enable_session_tickets(uvhttp_tls_context_t* ctx, int enable) - Purpose: Enable or disable TLS session tickets (currently a no-op placeholder)
- Preconditions:
ctxmust be valid. - Postconditions: Returns UVHTTP_OK. Session ticket support is temporarily disabled in the mbedTLS configuration.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxis NULL
- Thread safety: Not thread-safe.
uvhttp_tls_context_set_session_cache
- Signature:
uvhttp_error_t uvhttp_tls_context_set_session_cache(uvhttp_tls_context_t* ctx, int max_sessions) - Purpose: Set the maximum number of entries in the TLS session cache
- Preconditions:
ctxmust be valid.max_sessionsmust be >= 0. - Postconditions: The session cache entry limit is updated.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxis NULL
- Thread safety: Not thread-safe.
uvhttp_tls_create_ssl
- Signature:
mbedtls_ssl_context* uvhttp_tls_create_ssl(uvhttp_tls_context_t* ctx) - Purpose: Create an SSL session context from a TLS context
- Preconditions:
ctxmust be valid. - Postconditions: Returns a valid mbedTLS SSL context on success, NULL on failure.
- Error conditions:
- Returns NULL:
ctxis NULL, allocation failure, or mbedtls_ssl_setup failed
- Returns NULL:
- Thread safety: Not thread-safe.
uvhttp_tls_setup_ssl
- Signature:
uvhttp_error_t uvhttp_tls_setup_ssl(mbedtls_ssl_context* ssl, int fd) - Purpose: Attach a socket file descriptor to an SSL context for BIO
- Preconditions:
sslmust be non-NULL.fdmust be a valid socket descriptor. - Postconditions: Custom BIO callbacks (
mbedtls_net_send/mbedtls_net_recv) are set on the SSL context, using the provided file descriptor. - Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:sslis NULL
- Thread safety: Not thread-safe.
uvhttp_tls_handshake
- Signature:
uvhttp_error_t uvhttp_tls_handshake(mbedtls_ssl_context* ssl) - Purpose: Perform the TLS handshake (non-blocking)
- Preconditions:
sslmust be non-NULL and must have been set up with a socket viauvhttp_tls_setup_ssl. - Postconditions: On success, the TLS handshake is complete. Non-blocking states return specific error codes.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:sslis NULLUVHTTP_ERROR_TLS_WANT_READ: handshake needs more data from socket (non-blocking)UVHTTP_ERROR_TLS_WANT_WRITE: handshake needs to write to socket (non-blocking)UVHTTP_ERROR_TLS_HANDSHAKE: handshake failed
- Thread safety: Not thread-safe.
uvhttp_tls_read
- Signature:
uvhttp_error_t uvhttp_tls_read(mbedtls_ssl_context* ssl, void* buf, size_t len) - Purpose: Read decrypted data from a TLS connection
- Preconditions:
sslmust be non-NULL and handshake must be complete.bufmust be non-NULL. - Postconditions: On success, returns the number of bytes read (positive value). On non-blocking WANT_READ/WANT_WRITE, returns the corresponding error code.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:sslorbufis NULLUVHTTP_ERROR_TLS_WANT_READ: non-blocking, need more dataUVHTTP_ERROR_TLS_WANT_WRITE: non-blocking, need to writeUVHTTP_ERROR_TLS_READ: read error
- Thread safety: Not thread-safe.
uvhttp_tls_write
- Signature:
uvhttp_error_t uvhttp_tls_write(mbedtls_ssl_context* ssl, const void* buf, size_t len) - Purpose: Write encrypted data to a TLS connection
- Preconditions:
sslmust be non-NULL and handshake must be complete.bufmust be non-NULL. - Postconditions: On success, returns the number of bytes written (positive value). On non-blocking WANT_READ/WANT_WRITE, returns the corresponding error code.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:sslorbufis NULLUVHTTP_ERROR_TLS_WANT_READ: non-blocking, need to readUVHTTP_ERROR_TLS_WANT_WRITE: non-blocking, need to writeUVHTTP_ERROR_TLS_WRITE: write error
- Thread safety: Not thread-safe.
uvhttp_tls_init / uvhttp_tls_cleanup
- Signature:
uvhttp_error_t uvhttp_tls_init(uvhttp_context_t* context)/void uvhttp_tls_cleanup(uvhttp_context_t* context) - Purpose: Initialize/cleanup the global TLS subsystem (entropy source, DRBG)
- Preconditions:
contextmust be non-NULL. Foruvhttp_tls_cleanup, the context must have been initialized. - Postconditions:
context->tls_initializedis set to 1 on success, 0 after cleanup. - Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:contextis NULLUVHTTP_ERROR_TLS_INIT: DRBG seeding failed
- Thread safety: Not thread-safe.
uvhttp_tls_verify_peer_cert
- Signature:
int uvhttp_tls_verify_peer_cert(mbedtls_ssl_context* ssl) - Purpose: Verify the peer's certificate chain
- Preconditions:
sslmust be non-NULL and handshake must be complete. - Postconditions: Returns 1 if verification succeeded (flags=0), 0 otherwise.
- Thread safety: Thread-safe for reads after handshake.
uvhttp_tls_verify_hostname
- Signature:
int uvhttp_tls_verify_hostname(mbedtls_x509_crt* cert, const char* hostname) - Purpose: Verify a hostname against a certificate (CN and SAN)
- Preconditions:
certandhostnamemust be non-NULL. - Postconditions: Returns 1 if the hostname matches the certificate's CN or any SAN entry, 0 otherwise.
- Thread safety: Thread-safe for reads.
uvhttp_tls_check_cert_validity
- Signature:
int uvhttp_tls_check_cert_validity(mbedtls_x509_crt* cert) - Purpose: Check if a certificate is within its validity period
- Preconditions:
certmust be non-NULL. - Postconditions: Returns 1 if the certificate is valid (not yet expired and not before its valid_from date), 0 otherwise.
- Thread safety: Thread-safe for reads.
uvhttp_tls_get_stats / uvhttp_tls_reset_stats
- Signature:
uvhttp_error_t uvhttp_tls_get_stats(uvhttp_tls_context_t* ctx, uvhttp_tls_stats_t* stats)/uvhttp_error_t uvhttp_tls_reset_stats(uvhttp_tls_context_t* ctx) - Purpose: Get or reset TLS performance statistics
- Preconditions:
ctxmust be valid. Foruvhttp_tls_get_stats,statsmust be non-NULL. - Postconditions: Statistics are copied to the output struct or zeroed.
- Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:ctxorstats(for get) is NULL
- Thread safety: Not thread-safe.
uvhttp_tls_get_connection_info
- Signature:
uvhttp_error_t uvhttp_tls_get_connection_info(mbedtls_ssl_context* ssl, char* buf, size_t buf_size) - Purpose: Get a human-readable string with TLS version and cipher suite
- Preconditions:
sslandbufmust be non-NULL. - Postconditions:
bufis filled with a string like "Version: TLSv1.3, Cipher: TLS-AES-256-GCM-SHA384". - Error conditions:
UVHTTP_ERROR_TLS_INVALID_PARAM:sslorbufis NULL
- Thread safety: Thread-safe for reads after handshake.
uvhttp_tls_get_error_string / uvhttp_tls_print_error
- Signature:
void uvhttp_tls_get_error_string(int ret, char* buf, size_t buf_size)/void uvhttp_tls_print_error(int ret) - Purpose: Convert an mbedTLS error code to a human-readable string
- Preconditions:
bufmust be non-NULL andbuf_size> 0 foruvhttp_tls_get_error_string. - Postconditions: The error string is written to the buffer or logged.
- Thread safety: Thread-safe.
TLS Handshake Lifecycle
- Context creation:
uvhttp_tls_context_newcreates a server-side TLS context with default configuration. - Certificate loading:
uvhttp_tls_context_load_cert_chainloads the server certificate.uvhttp_tls_context_load_private_keyloads the corresponding private key. - Optional CA loading:
uvhttp_tls_context_load_ca_fileloads CA certificates for client verification. - Optional configuration: Cipher suites, TLS 1.3, mTLS, session cache, and CRL are configured as needed.
- SSL session creation:
uvhttp_tls_create_sslcreates an SSL session from the context. - BIO setup:
uvhttp_tls_setup_sslattaches the socket file descriptor to the SSL session. - Handshake:
uvhttp_tls_handshakeperforms the TLS handshake. This is non-blocking and may returnWANT_READ/WANT_WRITEto be called again after the socket is ready. - Data transfer:
uvhttp_tls_readanduvhttp_tls_writehandle encrypted data transfer. - Cleanup: The SSL session is freed by the caller. The TLS context is freed via
uvhttp_tls_context_free.
Behavior Rules
mbedTLS backend: All TLS operations are delegated to mbedTLS 3.x. The library provides entropy, DRBG, certificate parsing, SSL handshake, and cipher operations.
Non-blocking handshake: The handshake uses custom BIO callbacks (
mbedtls_net_send/mbedtls_net_recv) that translate EAGAIN/EWOULDBLOCK toMBEDTLS_ERR_SSL_WANT_READ/WANT_WRITE. These are propagated to the caller asUVHTTP_ERROR_TLS_WANT_READ/UVHTTP_ERROR_TLS_WANT_WRITEfor integration with libuv's event loop.Session cache: The session cache is initialized but currently disconnected from the SSL config (pending thread-safety verification). Sessions are not cached in the current version.
TLS 1.3 support: When enabled, the minimum TLS version is set to TLS 1.3 (MBEDTLS_SSL_MINOR_VERSION_4). When disabled, minimum is TLS 1.2.
mTLS support: Client certificate authentication is configurable via
uvhttp_tls_context_enable_client_auth. Requires CA certificates to be loaded first.Certificate validation: The
uvhttp_tls_check_cert_validitychecks bothvalid_fromandvalid_todates. Theuvhttp_tls_verify_peer_certchecks the verification result flags.Hostname verification: CN (Common Name) and SAN (Subject Alternative Name) are both checked. Uses exact string matching (wildcard support is not yet implemented).
CRL checking: Certificate Revocation List checking can be enabled via
uvhttp_tls_context_enable_crl_checking. CRL files are loaded viauvhttp_tls_load_crl_file.Double-free protection:
uvhttp_tls_context_freehandles NULL gracefully. All mbedTLS sub-contexts are freed in order.Statistics: The TLS context tracks handshake count, errors, bytes sent/received, session hits/misses, and average handshake time.
Performance Requirements
- TLS context creation: O(1) with mbedTLS initialization
- SSL session creation: O(1)
- Handshake: O(n) where n is the certificate chain length; typically 2-3 RTT for TLS 1.2, 1-2 RTT for TLS 1.3
- Data transfer: O(n) where n is the data size; encryption overhead ~5-15% CPU
- Memory: ~1KB per TLS context, ~512 bytes per SSL session
- Cipher suite selection: O(1) via mbedTLS internal lookup
Test Requirements
- TLS context creation and destruction
- Certificate and key loading (valid and invalid files)
- TLS 1.3 enable/disable
- Cipher suite configuration
- mTLS client auth enable/disable
- SSL session creation, setup, and handshake
- Non-blocking handshake with WANT_READ/WANT_WRITE handling
- TLS read/write operations
- Peer certificate verification (valid and invalid)
- Hostname verification (CN match, SAN match, no match)
- Certificate validity checking (valid, expired, not-yet-valid)
- Certificate subject/issuer/serial retrieval
- CRL enable and file loading
- Session cache configuration
- TLS statistics get and reset
- Connection info string formatting
- NULL parameter handling for all public functions
- Memory cleanup (no leaks on free)
- Feature gate: builds without UVHTTP_FEATURE_TLS