AxlTls – TLS Support
Optional TLS 1.2 support using mbedTLS 3.6. Provides HTTPS server/client, self-signed certificate generation, and transparent TCP encryption.
Build requirement: make AXL_TLS=1 (adds ~200KB to the binary).
Without this flag, all TLS functions return -1/NULL/false.
Header: <axl/axl-tls.h>
Overview
AXL’s TLS module wraps mbedTLS to provide:
Self-signed ECDSA P-256 certificate generation
TLS 1.2 server contexts (for HTTPS)
TLS 1.2 client contexts (for HTTPS GET/POST)
Transparent integration with
AxlHttpServerandAxlHttpClient
HTTPS Server
Generate a certificate and enable TLS on the HTTP server:
#include <axl.h>
axl_tls_init();
// Generate self-signed cert (valid 10 years, ECDSA P-256)
void *cert, *key;
size_t cert_len, key_len;
axl_tls_generate_self_signed("MyServer", NULL, 0,
&cert, &cert_len, &key, &key_len);
// Create HTTPS server
AxlHttpServer *s = axl_http_server_new(8443);
axl_http_server_use_tls(s, cert, cert_len, key, key_len);
axl_http_server_add_route(s, "GET", "/", handler, NULL);
axl_free(cert);
axl_free(key);
axl_http_server_run(s); // serves HTTPS
HTTPS Client
HTTPS is automatic – just use an https:// URL:
AXL_AUTOPTR(AxlHttpClient) c = axl_http_client_new();
AXL_AUTOPTR(AxlHttpClientResponse) resp = NULL;
// TLS handshake happens automatically
axl_http_get(c, "https://192.168.1.1:8443/api/status", &resp);
Certificate Generation
axl_tls_generate_self_signed creates an ECDSA P-256 certificate
with SHA-256 signature:
Subject:
CN=<name>,O=AximCodeValidity: current year to +10 years
SubjectAltName:
DNS:localhost,IP:127.0.0.1, plus any provided IP addressesOutput: DER-encoded certificate and private key (caller frees)
Entropy
mbedTLS needs random numbers for key generation and TLS handshakes. AXL provides entropy via:
EFI_RNG_PROTOCOL (hardware RNG) – preferred, used when available
Software fallback – system time + monotonic counter mixing. A warning is logged when the fallback is used.
Security Considerations
Self-signed certificates are not trusted by browsers or standard TLS clients. Use
curl --insecureor configure trust-on-first-use.Certificate verification is disabled for client connections (
MBEDTLS_SSL_VERIFY_NONE). This is appropriate for BMC/embedded use but not for public internet TLS.The software entropy fallback is not cryptographically strong. For production use on hardware without an RNG, consider providing your own entropy source.
API Reference
Typedefs
-
typedef struct AxlTlsContext AxlTlsContext
-
typedef struct AxlTcp AxlTcp
-
typedef struct AxlLoop AxlLoop
Functions
-
bool axl_tls_available(void)
Check if TLS support was compiled in.
- Returns:
true if AXL_TLS=1 was set at build time.
-
int axl_tls_init(void)
Initialize the TLS subsystem. Call once at startup.
- Returns:
0 on success, -1 if TLS not compiled in or init failed.
-
void axl_tls_cleanup(void)
Shut down the TLS subsystem and free global resources.
-
int axl_tls_generate_self_signed(const char *cn, const AxlIPv4Address *ips, size_t ip_count, void **cert_der, size_t *cert_len, void **key_der, size_t *key_len)
Generate a self-signed ECDSA P-256 certificate.
The certificate includes SubjectAltName entries for localhost and any provided IP addresses. Valid for 10 years. Caller frees cert_der and key_der with axl_free().
- Parameters:
cn – Common Name (e.g. “MyServer”)
ips – IP addresses for SAN (may be NULL)
ip_count – number of IP addresses
cert_der – [out] DER-encoded certificate
cert_len – [out] certificate length
key_der – [out] DER-encoded private key
key_len – [out] key length
- Returns:
0 on success, -1 on failure.
-
int axl_tls_server_set_cert(const void *cert_der, size_t cert_len, const void *key_der, size_t key_len)
Load a server certificate and private key for TLS.
After this call, TLS accept operations use this certificate.
- Parameters:
cert_der – DER-encoded certificate
cert_len – certificate length
key_der – DER-encoded private key
key_len – key length
- Returns:
0 on success, -1 on failure.
-
AxlTlsContext *axl_tls_accept(AxlTcp *sock)
Create a TLS server context for an accepted TCP connection.
Wraps the socket for TLS. Call axl_tls_handshake() after to complete the TLS handshake.
- Parameters:
sock – accepted TCP socket
- Returns:
context, or NULL on failure.
-
AxlTlsContext *axl_tls_connect(AxlTcp *sock, const char *hostname)
Create a TLS client context for an outbound TCP connection.
hostname is used for SNI (Server Name Indication). Call axl_tls_handshake() after to complete the handshake.
- Parameters:
sock – connected TCP socket
hostname – server hostname for SNI
- Returns:
context, or NULL on failure.
-
int axl_tls_handshake(AxlTlsContext *ctx)
Perform or continue a TLS handshake.
May need to be called multiple times if data isn’t available yet.
- Parameters:
ctx – TLS context
- Returns:
0 on success (handshake complete), 1 if more data needed (call again after recv), -1 on error.
-
int axl_tls_read(AxlTlsContext *ctx, void *buf, size_t size, size_t *out_len)
Read decrypted data from a TLS connection.
- Parameters:
ctx – TLS context
buf – output buffer
size – buffer capacity
out_len – [out] bytes read
- Returns:
0 on success, -1 on error, 1 if more data needed.
-
int axl_tls_write(AxlTlsContext *ctx, const void *data, size_t len)
Write data over a TLS connection.
Encrypts and sends data via the underlying TCP socket.
- Parameters:
ctx – TLS context
data – plaintext data
len – data length
- Returns:
0 on success, -1 on error.
-
void axl_tls_stage_data(AxlTlsContext *ctx, const void *data, size_t len)
Stage received TCP data for TLS processing.
Points the TLS BIO recv callback at the provided buffer (zero-copy). Call before axl_tls_handshake() or axl_tls_read().
- Parameters:
ctx – TLS context
data – received TCP data
len – data length
-
void axl_tls_free(AxlTlsContext *ctx)
Free a TLS context. Sends close_notify. NULL-safe.
- Parameters:
ctx – context to free