# gizlang:tls

TLS over a TCP Stream of gizlang:system. After `client` or `server` succeeds, the same Stream reads and writes through TLS, and `close` sends close_notify first. A failed handshake leaves the stream to close. Failures are IoError values whose message() names the TLS or certificate error. Importing this module links OpenSSL.

```gizlang
import * as Tls from "gizlang:tls";
```

## Types

### `Credentials`

```gizlang
type Credentials
```

One shared, replaceable native TLS context. Its creating task owns it.
Keep that task alive while servers and renewal use these credentials.

Opaque: create and use it through this module's functions.

### `Opened`

```gizlang
type Opened = { incoming: Http.Incoming; url: Http.Url; }
```

A resource opened on the public Internet: its response, still streaming (the caller closes it), and the URL it
ended at.

- `incoming`: `gizlang_http.Incoming`
- `url`: `gizlang_http.Url`

## Functions

### `credentials`

```gizlang
function credentials(sys: System, chainPath: string, keyPath: string): Credentials throws IoError
```

The credentials from the PEM files CHAINPATH and KEYPATH.

Effects: fail, io.

### `credentialsOf`

```gizlang
function credentialsOf(sys: System, chain: bytes, key: bytes): Credentials throws IoError
```

The credentials of the PEM values CHAIN and KEY, such as an ACME certificate
(gizlang:acme renew replaces them). They have no files for reload to read.

Effects: fail, io.

### `keepStapled`

```gizlang
function keepStapled(self: Credentials, failed: (message: string) => void): i64
```

Staples and then asks again at half the time left, at least a minute and at most a day, until the task is cancelled; `failed` is
called with each error (it asks again in a minute). Run it in a task of its own: `Task.spawn(() => { return keepStapled(c, log); })`.

Effects: fail, read, write, console, io.

### `authority`

```gizlang
function authority(data: bytes): bool throws IoError
```

Admit only a bounded public PEM CA certificate bundle through the same
native context parser used for handshakes. No network or host roots.

Effects: fail.

### `pem`

```gizlang
function pem(system: System, path: string): bytes throws IoError
```

Read one absolute PEM configuration file through its opened handle. The
declared and returned byte counts are checked before accepting bounded data.

Effects: fail, io.

### `client`

```gizlang
function client(stream: Stream, host: string): Stream throws IoError
```

Secure a connection to `host`, verifying its certificate against the
system's trusted roots and checking that it names `host`.

Effects: fail, io.

### `clientTrusting`

```gizlang
function clientTrusting(stream: Stream, host: string, authority: bytes): Stream throws IoError
```

The same, trusting only the PEM certificates in `authority`.

Effects: fail, io.

### `openUrl`

```gizlang
function openUrl(system: System, u: Http.Url, request: Http.Request): Http.Incoming throws Http.HttpError
```

A request to `u`, over TLS when it is https, its body read as it arrives;
the request's path is replaced by the URL's target.

Effects: fail, write, io.

### `openUrlTrusting`

```gizlang
function openUrlTrusting(system: System, u: Http.Url, request: Http.Request, authority: bytes): Http.Incoming throws Http.HttpError
```

Explicit immutable HTTPS trust, never a plaintext or system-root fallback.

Effects: fail, write, io.

### `download`

```gizlang
function download(system: System, u: Http.Url, dir: Dir, path: string, headers: Vec<Http.Header>, limit: i64): bool throws Http.HttpError
```

Stream a successful response into the existing durable file publisher.
A 304 leaves the file untouched. Redirects are not followed implicitly. A body of more than `limit` bytes
(0: no limit) fails and leaves no file.

Effects: fail, read, write, console, io.

### `openAt`

```gizlang
function openAt(system: System, address: string, u: Http.Url, request: Http.Request): Http.Incoming throws Http.HttpError
```

openUrl connected to `address` (one of System.addresses(u.host), checked by
the caller) instead of looking the host up again; TLS still verifies that
the certificate names u.host.

Effects: fail, write, io.

### `openAtTrusting`

```gizlang
function openAtTrusting(system: System, address: string, u: Http.Url, request: Http.Request, pem: bytes): Http.Incoming throws Http.HttpError
```

openAt, with the certificates of PEM as the only trusted roots (for a private certificate authority).

Effects: fail, write, io.

### `pool`

```gizlang
function pool(system: System, options: Http.PoolOptions): Http.Pool
```

A gizlang:http Pool whose https connections are secured with TLS and
verified against the system's trusted roots, as `open` does. A reused
connection keeps its TLS session.

Effects: fail, write.

### `poolTrusting`

```gizlang
function poolTrusting(system: System, options: Http.PoolOptions, pem: bytes): Http.Pool throws IoError
```

The same, trusting only the PEM certificates in `authority`.

Effects: fail, write.

### `fetch`

```gizlang
function fetch(system: System, origin: Http.Origin, request: Http.Request): Http.Response throws Http.HttpError
```

A request to `origin`, over TLS when it is https (the certificate must
name its host), read whole; the request keeps its path. The one fetch for
both schemes: gizlang:http's fetch is the plain-HTTP half.

Effects: fail, read, write, console, io.

### `server`

```gizlang
function server(stream: Stream, credentials: Credentials): Stream throws IoError
```

Secure an accepted connection with a snapshot of shared credentials.

Effects: fail, io.

### `serve`

```gizlang
function serve<F>(listener: Listener, credentials: Credentials, handler: F): i64 throws IoError
```

gizlang:http's serve over TLS: each accepted connection gets the TLS layer
at once and its handshake runs in its first read, by the task that reads
it, so a slow client holds no one else's handshake.

### `serveStreamed`

```gizlang
function serveStreamed<F>(listener: Listener, credentials: Credentials, handler: F, head: Http.RequestHead): i64 throws IoError
```

serve with gizlang:http serveStreamed's request-head hook.

### `openPublic`

```gizlang
function openPublic(system: System, start: Http.Url, first: Http.Request, redirects: i64, inside: bool): Opened throws string
```

`first` sent to `start` on the public Internet only, for a fetch that a person or an agent names: every address of
each host must be public (publicAddress), so no URL or redirect reaches this host, its network or a cloud metadata
service (169.254.169.254), and the connection goes to the address checked. `inside` (an operator's choice for an
installation in a company network) allows private addresses. Up to `redirects` redirects are followed (303, and a
POST's 301 and 302, go on as GET); after that a redirect is the answer.

Effects: fail, read, write, io.

## Methods

### `Credentials.replace`

```gizlang
function Credentials.replace(self: Credentials, chain: bytes, key: bytes): bool throws IoError
```

Validate both PEM values, then swap the context atomically. Failure leaves
the old context in use. New server calls use the new certificate.

Effects: fail, io.

### `Credentials.staple`

```gizlang
function Credentials.staple(self: Credentials): i64 throws string
```

Asks the OCSP responder named in the certificate for its status and staples the answer (RFC 6066, RFC 6960): a client that asks
for the status gets the answer in the handshake. The answer must be signed by the issuer (the second certificate of the chain),
good and current. The seconds until its next update; an error when the certificate names no responder or the answer fails.
Replacing the credentials drops the answer; ask again then.

Effects: fail, read, write, console, io.

### `Credentials.reload`

```gizlang
function Credentials.reload(self: Credentials): bool throws IoError
```

Reads the credentials' files again and replaces the credentials. Connections that start after it use the new ones.

Effects: fail, io.

### `Credentials.alias`

```gizlang
function Credentials.alias(self: Credentials, name: string, other: Credentials): bool throws IoError
```

These credentials answer a client that asks for NAME (the server name of its handshake) with OTHER's certificate: NAME is exact or
`*.suffix` (one label or more before the suffix). Over TLS and QUIC alike; renewing OTHER is seen at once. A later call for the same name
changes it. Both must live as long as the server does.

Effects: fail, io.

### `Credentials.unalias`

```gizlang
function Credentials.unalias(self: Credentials, name: string): bool throws IoError
```

These credentials no longer hand NAME to others.

Effects: fail, io.

### `Credentials.quic`

```gizlang
function Credentials.quic(self: Credentials, host: string, port: i64): i64 throws IoError
```

A QUIC listener on UDP HOST:PORT with this certificate (gizlang:http3 drives it); the handle, or an error when the OpenSSL has no QUIC server.

Effects: fail, io.

## Constants

### `MOST_AUTHORITY_BYTES`

```gizlang
const MOST_AUTHORITY_BYTES = 65536
```

The most bytes of a certificate authority list.

