Module: net.tls
Source: ./net/tls.reef
Overview
net.tls - TLS/SSL secure connections using the system OpenSSL
Provides secure socket connections using the OS-provided OpenSSL library. Supports certificate verification, custom CA bundles, and error reporting.
Trust store: by default, connections trust the host OpenSSL's compiled-in system store. Set REEF_CA_BUNDLE (env var) to a CA bundle file to override it for the whole process, or configure a CA file/path explicitly per connection. An explicitly configured CA source (REEF_CA_BUNDLE or a configured CA) that fails to load is a hard error - Reef never falls back silently to a broader trust store.
Example - Simple connection: let ok = tls_init() let conn_r = tls_connect("example.com", 443) if result.is_ok(conn_r) let conn = result.unwrap_ok(conn_r) tls_send(conn, "GET / HTTP/1.0\r\n\r\n") let response_r = tls_recv_string(conn, 4096) tls_disconnect(conn) end if
Example - With certificate info: let conn_r = tls_connect("github.com", 443) if result.is_ok(conn_r) let conn = result.unwrap_ok(conn_r) println("TLS Version: " + tls_version(conn)) println("Cipher: " + tls_cipher(conn)) println("Server: " + tls_peer_subject(conn)) tls_disconnect(conn) end if
Error model: TLS errors come from OpenSSL, not errno, so every fallible op in this module returns Err(error.error(ErrorKind_IoError(), tls_last_error())) -- a single IoError catch-all carrying the OpenSSL error string. There is no errno-derived granularity (no Timeout/ Refused/etc distinction) the way net.tcp gets from net.socket's net_err() -- that is a known, documented weak spot of this module, not an oversight.
Functions
fn reef_tls_init(): int
fn reef_tls_error(): string
fn reef_tls_config_new(): pointer
fn reef_tls_config_free(config: pointer): void
fn reef_tls_config_insecure_noverifycert(config: pointer): void
fn reef_tls_config_insecure_noverifyname(config: pointer): void
fn reef_tls_config_set_ca_file(config: pointer, path: string): int
fn reef_tls_config_set_ca_path(config: pointer, path: string): int
fn reef_tls_client_new(): pointer
fn reef_tls_configure(ctx: pointer, config: pointer): int
fn reef_tls_connect(ctx: pointer, host: string, port: string): int
fn reef_tls_connect_socket(ctx: pointer, socket: int, servername: string): int
fn reef_tls_handshake(ctx: pointer): int
fn reef_tls_read(ctx: pointer, buf: pointer, buflen: int): int
fn reef_tls_write(ctx: pointer, data: pointer, len: int): int
fn reef_tls_conn_version(ctx: pointer): string
fn reef_tls_conn_cipher(ctx: pointer): string
fn reef_tls_peer_cert_subject(ctx: pointer): string
fn reef_tls_peer_cert_issuer(ctx: pointer): string
fn reef_tls_close(ctx: pointer): int
fn reef_tls_free(ctx: pointer): void
fn reef_tls_connect_simple(host: string, port: int): pointer
fn reef_tls_send_all(ctx: pointer, data: string, len: int): int
fn reef_tls_recv(ctx: pointer, buf: string, buflen: int): int
fn reef_string_alloc(len: int): string
String allocation from runtime
fn tls_err(): error.Error
Every TLS failure carries the same ErrorKind (IoError) -- OpenSSL gives us a string, not an errno, so there is no finer classification to make. Centralized here so every call site builds the Err the same way.
fn tls_init(): result.Result[bool, error.Error]
Initialize the TLS library (OpenSSL). Call once at program start. Ok(true) on success, Err(IoError, tls_last_error()) on failure.
fn tls_connect(host: string, port: int): result.Result[pointer, error.Error]
Connect to a TLS server Ok(connection handle) on success, Err(IoError, tls_last_error()) on failure (nil handle from the runtime).
fn tls_send(conn: pointer, data: string): result.Result[int, error.Error]
Send data over TLS connection Ok(number of bytes sent) on success, Err(IoError, tls_last_error()) on failure.
fn tls_recv(conn: pointer, buf: string, buflen: int): result.Result[int, error.Error]
Receive data into buffer (out-param buf kept) Ok(number of bytes received) on success (0 = EOF, still Ok); Err(IoError, tls_last_error()) on failure (runtime returns < 0).
fn tls_recv_string(conn: pointer, max_len: int): result.Result[string, error.Error]
Receive data as a new string (allocates memory) Ok(received string; n>0) on success; Ok("") on clean EOF (runtime returns 0 -- NOT an error); Err(IoError, tls_last_error()) on failure (runtime returns < 0).
fn tls_recv_bytes(conn: pointer, buffer: [uint8], max_len: int): result.Result[int, error.Error]
Receive data into byte array (for binary data; out-param buffer kept) Ok(number of bytes received) on success (0 = EOF, still Ok); Err(IoError, tls_last_error()) on failure (runtime returns < 0).
fn tls_version(conn: pointer): string
fn tls_cipher(conn: pointer): string
fn tls_peer_subject(conn: pointer): string
fn tls_peer_issuer(conn: pointer): string
fn tls_last_error(): string
fn tls_config_new(): result.Result[pointer, error.Error]
Ok(config handle) on success, Err(IoError, tls_last_error()) on failure (nil handle from the runtime -- e.g. allocation failure).
fn tls_config_set_ca_file(config: pointer, path: string): result.Result[bool, error.Error]
Ok(true) on success, Err(IoError, tls_last_error()) on failure. Part of the fail-closed CA story: an explicitly configured CA source that fails to load must be a hard error -- callers MUST check this Result rather than silently continuing with the default trust store.
fn tls_config_set_ca_path(config: pointer, path: string): result.Result[bool, error.Error]
Ok(true) on success, Err(IoError, tls_last_error()) on failure. See tls_config_set_ca_file: an explicitly configured CA source that fails to load is a hard error, never a silent fallback.
fn tls_client_new(): result.Result[pointer, error.Error]
Ok(client context handle) on success, Err(IoError, tls_last_error()) on failure (nil handle from the runtime -- e.g. allocation failure).
fn tls_client_configure(ctx: pointer, config: pointer): result.Result[bool, error.Error]
fn tls_client_connect(ctx: pointer, host: string, port: string): result.Result[bool, error.Error]
fn tls_client_handshake(ctx: pointer): result.Result[int, error.Error]
Ok(0) on success. Non-blocking retry sentinels (want-poll-in/out) and hard failures both come back as negative ints from the runtime and are collapsed to Err here, same as before this migration -- the raw int never distinguished them at the Reef level (the retry loop lives in reef_tls_connect_simple, in C). Err(IoError, tls_last_error()) on failure.
fn tls_read(ctx: pointer, buf: string, buflen: int): result.Result[int, error.Error]
Ok(number of bytes read) on success (0 = EOF, still Ok); Err(IoError, tls_last_error()) on failure (runtime returns < 0).
fn tls_write(ctx: pointer, data: string, len: int): result.Result[int, error.Error]
Ok(number of bytes written) on success, Err(IoError, tls_last_error()) on failure (runtime returns < 0).
fn tls_close(ctx: pointer): int
Procedures
proc tls_disconnect(conn: pointer)
Disconnect and free TLS connection
proc tls_config_free(config: pointer)
proc tls_config_insecure_noverifycert(config: pointer)
proc tls_config_insecure_noverifyname(config: pointer)
proc tls_free(ctx: pointer)
Generated by reefc doc