xtc_tls(3)
---xtc_tls(3)
TLS over async sockets
| XTC_TLS(3) | Library Functions Manual | XTC_TLS(3) |
NAME
xtc_tls_ctx_create,
xtc_tls_ctx_destroy,
xtc_tls_create,
xtc_tls_create_transport,
xtc_tls_ctx_set_sni_cb,
xtc_tls_set_hostname,
xtc_tls_destroy,
xtc_tls_handshake,
xtc_tls_read, xtc_tls_write,
xtc_tls_shutdown,
xtc_tls_wants_read,
xtc_tls_wants_write,
xtc_tls_get_version,
xtc_tls_get_cipher,
xtc_tls_get_cipher_bits,
xtc_tls_get_alpn_selected,
xtc_tls_has_peer_cert,
xtc_tls_get_verify_error,
xtc_tls_get_peer_subject_dn,
xtc_tls_get_peer_common_name,
xtc_tls_get_peer_issuer_dn,
xtc_tls_get_peer_serial,
xtc_tls_get_server_cert_hash —
TLS over async sockets
SYNOPSIS
DESCRIPTION
xtc_tls provides TLS 1.2 / 1.3 over xtc_io
sockets. The implementation selects a backend at configure time
(‘--with-tls=openssl|none|auto’); in v0.x only OpenSSL is
implemented.
- xtc_tls_ctx_t
- Per-process state: cert, key, CA bundle, version range, ALPN profile.
Created once via
xtc_tls_ctx_create() with role (XTC_TLS_SERVER orXTC_TLS_CLIENT) plus opts. - xtc_tls_t
- Per-connection state. Wraps a single fd. Created via
xtc_tls_create(ctx, fd, &out).
xtc_tls_create(ctx, fd, &tls);
for (;;) {
int rc = xtc_tls_handshake(tls);
if (rc == XTC_OK) break;
if (rc != XTC_E_AGAIN) abort();
uint32_t want = xtc_tls_wants_read(tls)
? XTC_IO_READABLE : XTC_IO_WRITABLE;
xtc_proc_wait_fd(fd, want, -1, &revents);
}
xtc_tls_read()
and
xtc_tls_write()
follow the same pattern: return XTC_OK on progress,
XTC_E_AGAIN when the fd needs more poll
iterations.
xtc_tls_shutdown()
performs the bidirectional close-notify dance; same WANT_* translation.
OPTIONS
xtc_tls_opts_t fields:
- cert_file, key_file
- PEM paths for server-side certificate.
- ca_file
- PEM CA bundle for verifying the peer.
- verify_peer
1to require + validate the peer's cert.- verify_peer_mode
- Tri-state peer verification, taking precedence over
verify_peer when not
XTC_TLS_VERIFY_DEFAULT:XTC_TLS_VERIFY_NONE,XTC_TLS_VERIFY_REQUEST(request a client certificate but complete the handshake if none is presented), orXTC_TLS_VERIFY_REQUIRE. - alpn_protos
- ALPN wire-form list.
- min_version, max_version
XTC_TLS_VER_12orXTC_TLS_VER_13.- cipher_list, ciphersuites_13, groups
- TLS 1.2 cipher list, TLS 1.3 ciphersuites, and key-exchange groups.
- crl_file, crl_dir
- CRL file / hashed directory; either enables full-chain revocation checking.
- prefer_server_ciphers
- Honor the server's cipher order over the client's.
- passphrase_cb, passphrase_userdata
- Supply the passphrase for an encrypted key_file without an interactive prompt.
A server context is hardened by default (documented defaults, not knobs): TLS renegotiation and compression are disabled, session tickets and the session cache are off, and the moving-write-buffer mode required for correct non-blocking sends is enabled.
SNI AND CUSTOM TRANSPORT
xtc_tls_ctx_set_sni_cb(ctx,
cb, userdata) installs a Server
Name Indication selection callback on a
XTC_TLS_SERVER context. During the handshake, after
the ClientHello is parsed, the callback fires with the requested
server_name (or NULL if the client sent none) and may
return a DIFFERENT, pre-created server xtc_tls_ctx_t
whose certificate, key, CA, and verify mode are used for the rest of that
handshake -- the multi-tenant / multi-host TLS case (mirrors OpenSSL's
SSL_CTX_set_client_hello_cb()
plus
SSL_set_SSL_CTX()).
Returning NULL keeps the current context. Registering on a client context,
or on a backend that cannot swap mid-handshake, returns
XTC_E_NOSYS.
xtc_tls_set_hostname(tls,
name) is the client-side half: called before the
handshake on a client connection, it sends name in the
ClientHello SNI extension and enables RFC 6125 hostname verification against
the server certificate. A NULL or empty name clears it; it is a no-op on a
server connection.
xtc_tls_create_transport(ctx,
transport, &out) wraps the
TLS state machine around caller-supplied read_cb and
write_cb callbacks instead of an fd, so the consumer
owns the underlying recv/send -- to feed bytes already read off the socket
before deciding to negotiate TLS (pushback), to weave the I/O into its own
interrupt / cancellation / fiber-yield discipline, or to handle a platform
signal window. The callbacks are BIO-like: return the byte count, 0 for a
clean EOF, or XTC_E_AGAIN to signal would-block (the
caller then drives its own readiness and retries the TLS op). These are
OpenSSL-backend features; other backends return
XTC_E_NOSYS.
INTROSPECTION
Valid only after
xtc_tls_handshake()
returns XTC_OK.
xtc_tls_get_version()
and
xtc_tls_get_cipher()
return the negotiated protocol version and cipher name (or
NULL);
xtc_tls_get_cipher_bits()
the symmetric key strength;
xtc_tls_get_alpn_selected()
the negotiated ALPN protocol.
xtc_tls_has_peer_cert()
reports whether the peer presented a certificate that passed verification;
xtc_tls_get_verify_error()
reports the most recent peer-certificate verification result for
diagnostics: the backend verify code (OpenSSL
X509_V_*, X509_V_OK
== 0 on success) into
*x509_err and a human-readable reason string into
buf;
xtc_tls_get_peer_subject_dn(),
xtc_tls_get_peer_common_name(),
xtc_tls_get_peer_issuer_dn(),
and
xtc_tls_get_peer_serial()
read the peer certificate (RFC 2253 DN, commonName, issuer DN, decimal
serial), rejecting an embedded NUL with XTC_E_INVAL.
xtc_tls_get_server_cert_hash()
returns the RFC 5929
tls-server-end-point
hash of the local certificate for SCRAM channel binding (MD5/SHA-1
signatures are hashed with SHA-256, otherwise the digest matching the
certificate's signature algorithm). A backend that has not implemented these
returns NULL, 0, or
XTC_E_NOSYS.
SEE ALSO
HISTORY
Appeared in xtc 0.1. See docs/M_TLS.md for backend pluggability planning.
| May 28, 2026 | Debian |