docs(rv2-tls,status): F3c-net plan + net.connect_tls object-model default; session NEXT PLAN
- rv2 9 §F3c-net: the remaining live-gated slice with auto-approved defaults — getrandom ephemeral, system CA-bundle loader, net.connect_tls builtin returning the TCP fd (fd-keyed side table, blocking model like net.connect) driving the sans-io driver, then wo_tls_verify_chain; plus net.read_tls/write_tls and a live gate - status board NEXT PLAN: the TLS client security engine landed this session (E-F3c minus socket glue), F3c-net is the next rung, then jarvis Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> (cherry picked from commit ad87974fc722268e278f957f1f3d607f5dafa50d)
This commit is contained in:
parent
5f0ac2d434
commit
2391553658
2 changed files with 64 additions and 0 deletions
|
|
@ -76,6 +76,34 @@ behind this board; live Obsidian Dataview views:
|
|||
|
||||
## ▶ NEXT PLAN
|
||||
|
||||
### Landed 2026-09-08 — the TLS 1.3 client security engine (rv2 9, A–F3c minus the socket glue)
|
||||
|
||||
**What happened this session (code + docs):** the entire security-critical logic
|
||||
of a hand-rolled TLS 1.3 client is implemented and gold-KAT'd, in `runtime/src/`
|
||||
`crypto.c` + new `tls.c`/`tls.h`. Landed and vector-gated (ASan/UBSan clean):
|
||||
**E** X.509 chain-link verify + SPKI + validity + **SAN/hostname** (RFC 6125);
|
||||
**F1** record layer (RFC 8446 §5.2, both suites, byte-for-byte vs python);
|
||||
**F2** key schedule (§7.1, byte-for-byte vs **RFC 8448**); **F3a** ClientHello
|
||||
builder + ServerHello parser; **F3b** offline CertificateVerify + Finished
|
||||
verify; **F3c-core** the **sans-io handshake driver** (`wo_tls_client`, whole
|
||||
handshake driven offline against the RFC 8448 record trace — client Finished +
|
||||
app records byte-for-byte, tampered flight refused); **F3c-net security core**
|
||||
`wo_tls_verify_chain` (chain-link + anchor + host + validity, no partial trust).
|
||||
Tests: `test_tls` 100/0, `test_crypto` 95/0, full runtime suite 0 fail. Forks
|
||||
auto-approved 2026-09-08, marked `review_pending` in the story frontmatter for a
|
||||
developer second review before this drives a live connection.
|
||||
|
||||
**Next step — F3c-net (the only remaining rung before jarvis unblocks):** the I/O
|
||||
integration that must be gated **live** (a local `openssl s_server` / python TLS
|
||||
server), specified with auto-approved defaults in
|
||||
[rv2 9 §F3c-net](runtime-v2/09-in-process-tls.md): a `getrandom` ephemeral, the
|
||||
system CA-bundle PEM loader, and the **`net.connect_tls`** builtin (default:
|
||||
returns the TCP fd as an Int with `wo_tls_client` state in an fd-keyed side
|
||||
table, blocking model like `net.connect`) driving the sans-io driver over a real
|
||||
socket, then `wo_tls_verify_chain` against the loaded anchors. Then **G** (inbound
|
||||
server) for porch. After that, jarvis 1 is buildable. (Separately still open:
|
||||
language 41's marshal fix — below — unblocking porch 9.)
|
||||
|
||||
### Brainstormed 2026-09-06 — the porch track (2–8) and language 41's fix, both to `ready`
|
||||
|
||||
**What happened this session (docs only, no code):** the whole
|
||||
|
|
|
|||
|
|
@ -82,6 +82,42 @@ they may split into their own runtime-v2 iterations as they are picked up.
|
|||
| F — record + handshake (client) | 🔄 **F1–F3b LANDED 2026-09-08** — new `tls.c`/`tls.h`. **F1 record layer** (`wo_tls_record_seal`/`open`, RFC 8446 §5.2, per-record nonce = iv XOR seq, both suites) KAT'd byte-for-byte vs python. **F2 key schedule** (`wo_tls_derive_handshake`/`_application`/`_traffic_keys`/`_finished_verify`, §7.1) KAT'd byte-for-byte vs **RFC 8448 §3**. **F3a message layer** (`wo_tls_parse_server_hello` — attacker input, bounded, rejects HRR/bad suite/truncation; `wo_tls_build_client_hello` — SNI, x25519, sig-algs) KAT'd vs RFC 8448 SH + validated by an independent parser. **F3b offline handshake verification** (`wo_tls_verify_cert_verify` over phase E+D; server + client Finished) — the whole handshake **crypto** proven end-to-end offline vs RFC 8448. **F3c-core sans-io driver** (`wo_tls_client` — pure FSM, caller frames records: CH→SH→flight→Finished, message reassembly, per-message transcript timing, constant-time Finished, application encrypt/decrypt) KAT'd against the **full RFC 8448 record trace** — client Finished + first app record byte-for-byte, NewSessionTicket + server app data decrypt, tampered flight refused. **SAN/hostname** (`wo_x509_check_host`, RFC 6125) + driver enforcement landed. **Remaining F3c-net**: random ephemeral for production start, the multi-cert chain walk to a **system CA trust anchor**, and the `net.connect_tls` builtin + `net.read_tls`/`net.write_tls` VM plumbing (record framing over a real fd), gated live against `openssl s_server` | jarvis's path; the reason the story exists |
|
||||
| G — server (inbound) | the server handshake half, cert+key loading, signing CertificateVerify; porch terminates TLS | retires the inbound proxy requirement, and the doctrine docs |
|
||||
|
||||
## F3c-net — the remaining slice (decisions auto-approved 2026-09-08, review pending)
|
||||
|
||||
Everything security-critical is landed and offline-KAT'd. What is left is I/O
|
||||
integration that can only be gated **live** (against a local `openssl s_server`
|
||||
/ python TLS server), so it is a single cohesive slice, not further split:
|
||||
|
||||
1. **Random ephemeral.** A `getrandom(2)`-backed source for the per-connection
|
||||
X25519 private key (and the ClientHello random / session id). No `.wo`
|
||||
randomness builtin is assumed; this is internal to the connect path.
|
||||
2. **CA-bundle loader.** Parse the system PEM bundle
|
||||
(`/etc/ssl/certs/ca-certificates.crt`, confirmed present on the dev box) into
|
||||
DER trust anchors for `wo_tls_verify_chain`. Built **with** its consumer, not
|
||||
ahead of it (its memory model is the connect path's to own).
|
||||
3. **`net.connect_tls(host, port)` builtin.** TCP-connects (reusing the
|
||||
`net.connect` path), generates the ephemeral, runs the sans-io driver —
|
||||
framing records off the socket (read the 5-byte header, then the body) and
|
||||
flushing `take_output` — until ESTABLISHED, then validates the chain
|
||||
(`wo_tls_verify_chain` with the loaded anchors + the host). Plus
|
||||
`net.read_tls` / `net.write_tls` for application data.
|
||||
- **Handle representation (default, auto-approved):** mirror `net.connect` —
|
||||
the builtin returns the **TCP fd as an Int**, and the runtime keeps the
|
||||
`wo_tls_client` state in a side table keyed by fd; `net.read_tls` /
|
||||
`net.write_tls` / `net.close` look it up and free it on close. This is the
|
||||
smallest change to the language surface (no new class) and matches the
|
||||
existing fd-based net verbs. The alternative — a first-class `TlsConn`
|
||||
language object — is heavier and deferred unless the developer prefers it.
|
||||
- **Blocking model (default, auto-approved):** the handshake and app I/O
|
||||
block, exactly as today's `net.connect` does; the park-plane async refit is
|
||||
a later refinement, not a v1 requirement.
|
||||
- VM wiring: new `WO_B_NET_CONNECT_TLS` / `_READ_TLS` / `_WRITE_TLS` ids in
|
||||
`wob.h`, `emit.ml` / `types.ml` registration, `loader.c` arities,
|
||||
`builtin.c` dispatch, `sysio.c` implementation.
|
||||
4. **Live gate.** A `just` recipe dialing a local TLS server: full handshake,
|
||||
chain+host validation, a request/response round-trip, and the negative cases
|
||||
(wrong host, untrusted chain, expired cert) each refused.
|
||||
|
||||
## Consumers
|
||||
|
||||
Named, so this is not a capability shipped as decoration:
|
||||
|
|
|
|||
Loading…
Reference in a new issue