These libraries are experimental. APIs may change without notice. Generated from source with koruc 0.1.7 on 8/19/2026.
OpenSSL
@korulang/openssl@0.0.1Client-side TLS for Koru, lifted from OpenSSL with verified-by-default connections and phantom free-chain obligations
openssl/index.kz · 6 tors
@koru/openssl — the definitive Koru client-TLS edition (scope v0) · 30 more lines
@koru/openssl — the definitive Koru client-TLS edition (scope v0)
Wraps industry-standard OpenSSL (libssl/libcrypto) and lifts its most
infamous footguns into Koru's type system:
1. VERIFIED BY DEFAULT. `connect` ALWAYS verifies the peer certificate
AND the hostname. There is no knob to turn verification off. The only
way to get an unverified channel is to type a *different, loudly named*
event — `connect.insecure` — so a skipped-verification connection can
never happen by omission. Decades of CVEs come from SSL_VERIFY_NONE and
forgotten SSL_set1_host; here the safe path is the only unmarked path.
2. HANDSHAKE IS A PHANTOM STATE. `connect` performs the full handshake
before it hands you an `open!` connection, so "read before handshake"
is unrepresentable. `shutdown` transitions the connection out of the
`open` state into `closing`, so "write after shutdown" does not compile.
3. THE FREE-CHAIN IS ONE PHANTOM OBLIGATION. SSL_free + SSL_CTX_free +
closing the socket are the classic OpenSSL leak trio. Here they are a
single `open!` obligation discharged by `close`. Forget it and the
build fails (KORU030) — you cannot leak an SSL context.
4. THE ERROR QUEUE IS LIFTED. OpenSSL's ERR_get_error() drain-the-queue
model becomes an honest `| err` branch on every fallible event, with
the queue drained and the first diagnostic surfaced. Never silent.
Grounded in the koru phantom-type suite: obligation threading follows
sqlite3's `next`/`col.*` (consume `<!open>`, re-emit `<open!>`); the
open! -> closing! -> discharge chain follows tests/regression/.../330_051
(`start-close` transition + `finalize` union `<!opened|closing>`).
Phantom lifecycles
Derived from the phantom labels in the declarations below — state! issues an
obligation the compiler will chase, !state discharges it, a bare state holds it without moving it. Nothing here is hand-drawn.
Tls 2 states open!closing!// connect — VERIFIED client TLS. The only safe constructor.
// Performs: TCP connect, SSL_VERIFY_PEER, system CA trust store, SNI, strict
// hostname verification (SSL_set1_host), full handshake, and a belt-and-braces
// SSL_get_verify_result check. Any failure returns `err` loudly — it never
// hands back an unverified connection.
~pub tor connect { host: string, port: u16, allocator: ?std.mem.Allocator }
| ok *Tls<open!>
| err Error// connect.insecure — THE EXPLICITLY-NAMED UNSAFE ESCAPE HATCH.
// !!! DANGER !!! This skips certificate AND hostname verification. It exists so
// that "no verification" is something you must TYPE, in a name that screams what
// it is — never something that happens because you forgot a flag. Use it only
// for talking to a host with a self-signed cert you already trust out-of-band
// (e.g. local dev). Everything downstream (read/write/shutdown/close) is
// identical, so the ONLY signal of danger is at the call site — which is the
// point.
~pub tor connect.insecure { host: string, port: u16, allocator: ?std.mem.Allocator }
| ok *Tls<open!>
| err Error// write — requires `open`, so it cannot run before connect or after shutdown.
~pub tor write { conn: *Tls<!open>, data: string }
| ok { conn: *Tls<open!>, n: usize }
| err { conn: *Tls<open!>, code: c_ulong, msg: string }// read — fills a caller-owned buffer (zero-copy). Requires `open`.
// `bytes` is a slice INTO the caller's `buf`, so there is nothing extra to free.
~pub tor read { conn: *Tls<!open>, buf: []u8 }
| data { conn: *Tls<open!>, bytes: []u8 }
| eof *Tls<open!>
| err { conn: *Tls<open!>, code: c_ulong, msg: string }// shutdown — clean TLS close_notify. Transitions `open` -> `closing`.
// After shutdown the connection is no longer `open`, so read/write no longer
// type-check against it. The free obligation rides along as `closing!` — you
// still MUST call `close`.
~pub tor shutdown { conn: *Tls<!open> }
| ok *Tls<closing!>
| err { conn: *Tls<closing!>, code: c_ulong, msg: string }// close — discharges the free obligation. Frees SSL + SSL_CTX + socket.
// Accepts EITHER `open` (close without an explicit shutdown) OR `closing`
// (close after shutdown). Union input is grounded in 330_051's `finalize`.
~pub tor close { conn: *Tls<!open|closing> }