code wiki / (root) / nx_tls13_client_session_recv_sh.nx

nx_tls13_client_session_recv_sh.nx

buildroot/runtime/nx_tls13_client_session_recv_sh.nx

12786 B270 linesdepth 11pulls 29 transitivereach 501 importersview sourcekind tooltopic tls13
docsdependenciesstructsconstsfunctions

about

nx_tls13_client_session_recv_sh.nx -- step 3c.2 of the nx_https_client wiring arc. Consumes the bytes of a TLS 1.3 ServerHello handshake message (provided by the caller -- this step doesn't do fd IO; that's the orchestrator wrapper 3c.6 in a later commit) and walks the full handshake-key-derivation cascade: 1. Parse the ServerHello message (via shipped tls13_server_hello_parse) 2. Find the key_share extension + extract server's X25519 pubkey 3. Compute shared_secret = x25519(my_priv, server_pub) 4. Run TLS 1.3 key schedule cascade (RFC 8446 ยง7.1): early_secret = HKDF-Extract(0, 0) derived_1 = Derive-Secret(early, "derived", "") handshake_secret = HKDF-Extract(derived_1, shared_secret) 5. Feed ServerHello bytes into transcript (so H1 = hash(CH || SH)) 6. Snapshot transcript -> H1 7. Derive c_hs_traffic_secret + s_hs_traffic_secret using H1 8. Expand each into AEAD key (32B) + IV (12B for ChaCha20-Poly1305 or AES-GCM) 9. Reset per-direction sequence numbers to 0 10. Advance state CH_SENT -> WAIT_EE After this primitive returns OK, the session is ready for the 3c.3 step (recv encrypted handshake records, decrypt with server_hs_traffic_key, dispatch via tls13_client_dispatch_with_validation). Public API: nx_tls13_client_session_recv_sh(session, sh_bytes, sh_len) -> verdict nx_tls13_recv_sh_verdict_is_valid(v) -> 0|1 Sealed verdict enum: NX_TLS13_RECV_SH_OK keys derived, state advanced NX_TLS13_RECV_SH_BAD_STATE session not in CH_SENT NX_TLS13_RECV_SH_BAD_FORMAT SH parse failed NX_TLS13_RECV_SH_NO_KEYSHARE SH extensions missing key_share NX_TLS13_RECV_SH_BAD_GROUP key_share group != X25519 (29) NX_TLS13_RECV_SH_BAD_KEYSHARE_LEN server keyshare != 32 bytes NX_TLS13_RECV_SH_INTERNAL HKDF/SHA-256/x25519 failed

dependencies 10 imports · 11 importers

nx_syscalls.nx nx_sha256.nx nx_x25519.nx nx_tls13.nx nx_tls13_hello.nx nx_tls13_transcript.nx nx_tls13_kdf.nx nx_tls13_schedule.nx nx_tls13_client_session.nx nx_p256_ecdh.nx nx_tls13_client_session_recv_s nx_porkbun_ping_probe.nx nx_sites_sni_cert_gate.nx nx_tls13_ch_compat_test.nx nx_tls13_client_h2run.nx nx_tls13_client_session_recv_hs_te nx_tls13_client_session_recv_sh_te nx_tls13_client_session_run.nx nx_tls13_p256_loopback_test.nx nx_tls13_recv_hs_diff_test.nx nx_tls13_recv_hs_probe_test.nx

diagram shows first 10 each side; +0 more imports, +1 more importers in the complete lists below.

imports: nx_syscalls.nxnx_sha256.nxnx_x25519.nxnx_tls13.nxnx_tls13_hello.nxnx_tls13_transcript.nxnx_tls13_kdf.nxnx_tls13_schedule.nxnx_tls13_client_session.nxnx_p256_ecdh.nx

imported by: nx_porkbun_ping_probe.nxnx_sites_sni_cert_gate.nxnx_tls13_ch_compat_test.nxnx_tls13_client_h2run.nxnx_tls13_client_session_recv_hs_test.nxnx_tls13_client_session_recv_sh_test.nxnx_tls13_client_session_run.nxnx_tls13_p256_loopback_test.nxnx_tls13_recv_hs_diff_test.nxnx_tls13_recv_hs_probe_test.nxnx_tls13_sh_probe_test.nx

structs

none

consts

69const NX_TLS13_RECV_SH_OK: i64 = 1
70const NX_TLS13_RECV_SH_BAD_STATE: i64 = 2
71const NX_TLS13_RECV_SH_BAD_FORMAT: i64 = 3
72const NX_TLS13_RECV_SH_NO_KEYSHARE: i64 = 4
73const NX_TLS13_RECV_SH_BAD_GROUP: i64 = 5
74const NX_TLS13_RECV_SH_BAD_KEYSHARE_LEN: i64 = 6
75const NX_TLS13_RECV_SH_INTERNAL: i64 = 7
76const NX_TLS13_RECV_SH_BAD_CIPHER: i64 = 8 // server picked cipher we don't speak
83const NX_TLS13_RECV_SH_NOT_TLS13: i64 = 9 // server negotiated DOWN: chose a non-0x13xx suite
84const NX_TLS13_RECV_SH_VERDICT_N: i64 = 10
86const NX_TLS13_GROUP_X25519: i64 = 29
87const NX_TLS13_GROUP_SECP256R1: i64 = 23

functions

89func nx_tls13_recv_sh_verdict_is_valid(v: i64) -> i64
called by 1: main
96func nx_tls13_client_session_recv_sh(
268func main() -> i64