Sockets: TLS
● Intermediate3 min
net.connect_tls encrypts a connection and checks the server's certificate; there is no way to skip the check.
const conn = try net.connect_tls("example.com:443", protocols: ["h2", "http/1.1"])
// a company's own certificate authority, and a client certificate (mutual TLS)
const inside = try net.connect_tls("billing.internal:443", roots: ca, cert: mine, key: my_key)
// a server
const listener = try net.listen_tls("0.0.0.0:443", cert, key, clients: ca)- TLS 1.3, or 1.2 for servers without 1.3. The server's certificate must be valid for the host name, checked against the root certificates built into Kavach and any you add in
roots. protocolsoffers protocols to the server (ALPN);conn.protocol()says which one it chose.- With
clients, a server accepts only clients whose certificate one of those authorities signed.conn.client_cert()then gives the names on it,ClientCert(common_name:, dns:, uris:), to allow callers by name; a SPIFFE id such asspiffe://shop/ordersis one of theuris. conn.peer_certificate()gives the other side's certificate as DERBytes, ornonewithout TLS. It is for channel binding, such as SCRAM'stls-server-end-point, which hashes it.keytakes a secret, so a key read withenvor kept in asecretfield needs noreveal.- A slow or silent client can't hold up the others: handshakes go on side by side.
TLS begun on a plain connection
Some protocols speak plain TCP first and then switch to TLS, as PostgreSQL's SSLRequest and SMTP's STARTTLS do. conn.start_tls is the client's side, conn.accept_tls the server's:
// the client asks in plain text, then starts TLS
try plain.write("TLS?".bytes())
const answer = try plain.read()
const secured = try plain.start_tls("db.internal", roots: ca)
// the server answers, then accepts TLS
const asked = try plain.read()
try plain.write("S".bytes())
const conn = try plain.accept_tls(cert, key)- Each gives the encrypted connection. The plain
connis closed from then on, so nothing is sent in the clear by mistake. start_tlschecks the server's certificate againsthostand takes the other settings ofconnect_tls;accept_tlstakes those oflisten_tls..timeout(d)sets the deadline of either, as it does forread.
A TLS example needs certificates, which expire, so this one isn't run on this page. The test below makes a fresh certificate authority and runs exactly this, mutual TLS and TLS begun on a plain connection included, every time Kavach's tests run.