nx_tls12_client_session.nx
buildroot/runtime/nx_tls12_client_session.nx
about
nx_tls12_client_session.nx -- PHASE 2 of the sovereign TLS 1.2 client:
the HANDSHAKE STATE MACHINE that completes a full TLS 1.2 handshake
(ECDHE-RSA-AES128-GCM-SHA256) and establishes an encrypted session.
WHY: api.porkbun.com (and every Porkbun endpoint) negotiates TLS 1.2
MAXIMUM; our nx_tls13_* client is 1.3-only and gets a protocol_version
alert. This organ drives the 1.2 handshake to CONNECTED so the Porkbun
API (nx_porkbun_set_txt -> ACME wildcard renew) works. Phase 3 wires
this into nx_acme_http + the live Porkbun e2e.
This is ORCHESTRATION of already-shipped, already-gated primitives
(verify-don't-rebuild) -- no new crypto:
tls12_client_hello_emit (nx_tls12_hello.nx) flight 1
tls12_parse_server_hello (nx_tls12_parse.nx) SH
tls12_parse_server_key_exchange(nx_tls12_parse.nx) SKE
nx_tls13_client_validate_certificate (the SAME cert-chain cert
bridge the 1.3 client uses) -- fed a 1.2->1.3 cert-msg
transform built here so the whole RFC-5280 path-validation
pipeline + Mozilla trust store is reused unchanged.
nx_x509_pubkey_extract_rsa (nx_x509_pubkey_rsa.nx) leaf key
nx_tls12_ske_verify (nx_tls12_ske_verify.nx) SKE sig
p256_ecdh_derive_priv/pub/shared (nx_p256_ecdh.nx) ECDHE
tls12_derive_master_secret / _key_block / _split_keys /
_finished_verify_data (nx_tls12_keys.nx) schedule
tls12_record_seal / _open (nx_tls12_record.nx) AEAD
sha256_digest (nx_sha256.nx) transcript
nx_tls13_read_record_from_fd (read framer, reused) IO
Pipeline (RFC 5246 ยง7.3, full ECDHE-RSA handshake):
1. Send ClientHello; start a running SHA-256 transcript over every
handshake message (4-byte type+len header + body, NO 5-byte
record header), in send/recv order.
2. Recv+reassemble ServerHello / Certificate / ServerKeyExchange /
ServerHelloDone; append each to the transcript.
3. VALIDATE the certificate chain to the trust store + SNI host
(reused bridge). FAIL CLOSED.
4. VERIFY the ServerKeyExchange RSA signature under the leaf key
over client_random||server_random||ECDHE_params. FAIL CLOSED.
5. ECDHE: derive client ephemeral P-256 key; pre_master = ECDH x.
6. master = derive_master_secret; key_block; split to
dependencies 15 imports · 4 importers
diagram shows first 10 each side; +5 more imports, +0 more importers in the complete lists below.
imports: nx_syscalls.nxnx_sha256.nxnx_u2048.nxnx_u256.nxnx_x509.nxnx_x509_pubkey_rsa.nxnx_x509_pubkey_ec.nxnx_tls12_hello.nxnx_tls12_parse.nxnx_tls12_keys.nxnx_tls12_record.nxnx_tls12_ske_verify.nxnx_p256_ecdh.nxnx_tls13_client_validate_certificate.nxnx_tls13_read_record_from_fd.nx
imported by: nx_acme_http.nxnx_https_fetch_follow.nxnx_https_fetch_lib.nxnx_tls12_handshake_gate.nx
structs
| 147 | struct Tls12ClientSession |
consts
| 93 | const NX_MAGIC_65536: i64 = 65536 |
| 94 | const NX_MAGIC_2048: i64 = 2048 |
| 95 | const NX_MAGIC_131072: i64 = 131072 |
| 96 | const NX_MAGIC_32768: i64 = 32768 |
| 97 | const NX_MAGIC_1024: i64 = 1024 |
| 100 | const NX_TLS12_SESS_OK: i64 = 1 |
| 101 | const NX_TLS12_SESS_EMIT_CH: i64 = 2 // ClientHello emit failed |
| 102 | const NX_TLS12_SESS_WRITE_FAIL: i64 = 3 // sys_write failed |
| 103 | const NX_TLS12_SESS_READ_FLIGHT: i64 = 4 // could not read server flight 1 |
| 104 | const NX_TLS12_SESS_ALERT: i64 = 5 // server sent a TLS alert |
| 105 | const NX_TLS12_SESS_UNEXPECTED: i64 = 6 // unexpected record content-type |
| 106 | const NX_TLS12_SESS_INCOMPLETE_FLIGHT: i64 = 7 // missing SH/Cert/SKE/SHD |
| 107 | const NX_TLS12_SESS_UNSUPPORTED_CIPHER: i64 = 8 // server picked a suite we don't complete |
| 108 | const NX_TLS12_SESS_CERT_FAIL: i64 = 9 // chain/host/trust validation failed |
| 109 | const NX_TLS12_SESS_LEAF_PARSE: i64 = 10 // leaf DER parse failed |
| 110 | const NX_TLS12_SESS_LEAF_PUBKEY: i64 = 11 // leaf RSA pubkey extract failed |
| 111 | const NX_TLS12_SESS_SKE_PARSE: i64 = 12 // SKE wire parse failed |
| 112 | const NX_TLS12_SESS_SKE_VERIFY: i64 = 13 // SKE RSA signature verify failed |
| 113 | const NX_TLS12_SESS_ECDH: i64 = 14 // ECDHE key-agreement failed |
| 114 | const NX_TLS12_SESS_READ_SF: i64 = 15 // could not read server flight 2 |
| 115 | const NX_TLS12_SESS_SF_OPEN: i64 = 16 // server Finished record GCM open failed |
| 116 | const NX_TLS12_SESS_SF_FORMAT: i64 = 17 // server Finished plaintext malformed |
| 117 | const NX_TLS12_SESS_SF_VERIFY: i64 = 18 // server Finished verify_data mismatch |
| 118 | const NX_TLS12_SESS_CERT_MSG_BAD: i64 = 19 // 1.2 Certificate body malformed |
| 120 | const NX_TLS12_SESS_BAD_STATE: i64 = 20 // session not CONNECTED |
| 121 | const NX_TLS12_SESS_EOF: i64 = 21 // peer closed the TCP connection |
| 122 | const NX_TLS12_SESS_READ_FAIL: i64 = 22 // record read error |
| 123 | const NX_TLS12_SESS_DECRYPT_FAIL: i64 = 23 // record AEAD open failed |
| 124 | const NX_TLS12_SESS_OVERFLOW: i64 = 24 // record exceeds caller buffer |
| 125 | const NX_TLS12_SESS_VERDICT_N: i64 = 25 |
| 134 | const NX_TLS12_SESS_STATE_CONNECTED: i64 = 1 |
| 138 | const NX_TLS12_SUITE_ECDHE_RSA_AES128_GCM_SHA256: i64 = 0xC02F |
| 139 | const NX_TLS12_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256: i64 = 0xC02B |
| 142 | const NX_TLS12_SESS_MAX_FLIGHT_RECORDS: i64 = 24 |
| 143 | const NX_TLS12_SESS_MAX_SF_RECORDS: i64 = 8 |
| 144 | const NX_TLS12_SESS_RECORD_BUF: i64 = 20000 |
functions
| 127 | func nx_tls12_sess_verdict_is_valid(v: i64) -> i64 |
| 163 | func _t12s_pn2(c0: i64, c1: i64, v: i64) -> i64 |
| 180 | func _t12s_write_n(fd: i64, buf: *u8, n: i64) -> i64 |
| 191 | func _t12s_send_record(fd: i64, ctype: i64, payload: *u8, plen: i64) -> i64 |
| 204 | func _t12s_seq8(seq: i64, out8: *u8) -> i64 |
| 215 | func _t12s_ct_eq(a: *u8, b: *u8, n: i64) -> i64 called by 1: _nx_tls12_run_core |
| 234 | func _t12s_certmsg_to_tls13(cl: *u8, cl_len: i64, out: *u8, out_cap: i64) -> i64 called by 1: _nx_tls12_run_core |
| 287 | func _nx_tls12_run_core( |
| 533 | func nx_tls12_client_session_run( |
| 546 | func nx_tls12_client_session_run_faulted( |
| 562 | func nx_tls12_session_send(s: *Tls12ClientSession, fd: i64, data: *u8, len: i64) -> i64 called by 2: _acme_http12_roundtriphf_fetch12_once calls 4: sys_mmap_t12s_seq8tls12_record_seal_t12s_send_record |
| 577 | func nx_tls12_session_recv(s: *Tls12ClientSession, fd: i64, out: *u8, out_cap: i64, out_ctype: *i64) -> i64 |
| 601 | func main() -> i64 |