nx_tls13_client.nx
buildroot/runtime/nx_tls13_client.nx
about
nx_tls13_client.nx -- TLS 1.3 client state machine (Gap L sub-2).
Phase 0b §L of the Nishi TLS 1.3 stack per
docs/NISHI_TLS13_GAP_AUDIT.md. The dispatcher that walks the
server's encrypted handshake records past ServerHello: each
decrypted record body contains 1+ handshake messages, and this
state machine consumes them in the order RFC 8446 §A.1 dictates:
WAIT_EE -> EncryptedExtensions
|
WAIT_CERT -> Certificate
|
WAIT_CV -> CertificateVerify
|
WAIT_SF -> server Finished (verify MAC over transcript-before-SF)
|
CONNECTED
At every stage the message goes into the transcript hash AFTER
the stage-specific check passes -- except for server Finished,
which verifies the MAC over the transcript-BEFORE-SF then feeds
SF in. Getting that order wrong = MAC mismatch on a legitimate
server (the bug that catches every from-scratch TLS impl).
What it does today:
- dispatch one decrypted handshake message per call
- parse via shipped nx_tls13_auth + nx_tls13_finished
- feed transcript in spec-ordered way
- server_Finished MAC verify via constant-time compare
- emit our client_Finished (36-byte handshake message:
4-byte header + 32-byte HMAC over transcript)
- cert validation is INTENTIONALLY stubbed to "accept any"
-- Gap I will replace the stub with real RFC 5280 path
validation (chain build + signature chain verify + name
constraints + SAN match + validity period)
What it doesn't do yet:
- signature verification on CertificateVerify (composes
against nx_ed25519 / nx_ecdsa / nx_rsa_pss; Gap I)
- CertificateRequest (mutual TLS client-auth; rare)
dependencies 6 imports · 10 importers
imports: nx_syscalls.nxnx_tls13.nxnx_tls13_auth.nxnx_tls13_finished.nxnx_tls13_transcript.nxnx_tls13_schedule.nx
imported by: nx_https_loopback_test.nxnx_tls13_client_dispatch_with_validation.nxnx_tls13_client_dispatch_with_validation_test.nxnx_tls13_client_session_emit_finished.nxnx_tls13_client_session_recv_hs.nxnx_tls13_client_test.nxnx_tls13_full_tcp_test.nxnx_tls13_handshake_io.nxnx_tls13_handshake_tcp_test.nxnx_tls13_loopback_test.nx
structs
| none |
consts
| 83 | const NX_TLS13_CSTATE_WAIT_EE: i64 = 1 |
| 84 | const NX_TLS13_CSTATE_WAIT_CERT: i64 = 2 |
| 85 | const NX_TLS13_CSTATE_WAIT_CV: i64 = 3 |
| 86 | const NX_TLS13_CSTATE_WAIT_SF: i64 = 4 |
| 87 | const NX_TLS13_CSTATE_CONNECTED: i64 = 5 |
| 88 | const NX_TLS13_CSTATE_N: i64 = 6 |
| 91 | const NX_TLS13_CLIENT_VERDICT_OK: i64 = 1 |
| 92 | const NX_TLS13_CLIENT_VERDICT_BAD_MSG_TYPE: i64 = 2 |
| 93 | const NX_TLS13_CLIENT_VERDICT_BAD_FORMAT: i64 = 3 |
| 94 | const NX_TLS13_CLIENT_VERDICT_SF_BAD_MAC: i64 = 4 |
| 95 | const NX_TLS13_CLIENT_VERDICT_BAD_STATE: i64 = 5 |
| 96 | const NX_TLS13_CLIENT_VERDICT_N: i64 = 6 |
| 98 | const NX_TLS13_CLIENT_HASH_LEN: i64 = 32 |
functions
| 116 | func tls13_client_dispatch_handshake_message( |
| 222 | func tls13_client_emit_finished( |
| 254 | func nx_tls13_client_verdict_is_valid(v: i64) -> i64 called by 1: main |
| 260 | func nx_tls13_cstate_is_valid(s: i64) -> i64 called by 1: main |