nx_tls13_mtls_finished.nx
buildroot/runtime/nx_tls13_mtls_finished.nx
about
nx_tls13_mtls_finished.nx -- R7: the mTLS-aware client Finished handler (the dual-snapshot key schedule).
In mutual TLS the server receives the client's Finished AFTER the client Certificate + CertificateVerify,
so the transcript at that point runs THROUGH ClientCertVerify. RFC 8446 §4.4.4 says the client Finished MAC
is over that (current) transcript -- but §7.1 says the application traffic secrets are derived over the
transcript THROUGH SERVER FINISHED. A plain recv_cf uses ONE snapshot for both => wrong app keys under mTLS.
This handler takes th_app (the through-ServerFinished snapshot, captured by the run loop right after emit_sf)
explicitly: it verifies the Finished MAC over the CURRENT transcript snapshot, and derives the app keys over
th_app. Extracted from the run loop so this exact split is GATED (not just compile-checked): the gate proves
the function uses th_app for app keys and the current transcript for the MAC, by passing two DIFFERENT values.
license_tier: ORIGINAL expect_exit: 0
dependencies 8 imports · 1 importers
imports: nx_syscalls.nxnx_tls13.nxnx_tls13_record.nxnx_tls13_transcript.nxnx_tls13_kdf.nxnx_hmac.nxnx_hkdf.nxnx_tls13_server_session.nx
imported by: nx_tls13_server_session_run_mtls.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 21 | const NX_MFIN_CV_LEN: i64 = 32 |
| 22 | const NX_MFIN_REC_HEADER: i64 = 5 |
| 23 | const NX_MFIN_REC_TAG: i64 = 16 |
functions
| 25 | func nx_mfin_eq32(a: *u8, b: *u8) -> i64 |
| 31 | func nx_mfin_empty_hash(h: *u8) -> i64 |
| 41 | func nx_tls13_mtls_recv_finished(s: *Tls13ServerSession, record: *u8, record_len: i64, th_app: *u8) -> i64 |
| 87 | func mf_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 88 | func mf_row(name: *u8, ok: i64) -> i64 { if ok == 1 { mf_w(" PASS " as *u8) } else { mf_w(" FAIL " as *u8) } mf_w(name); mf_w("\n" as *u8); return ok } |
| 90 | func mf_mksession(hs: *u8, chts: *u8, key: *u8, iv: *u8) -> *Tls13ServerSession |
| 106 | func mf_build_finished_rec(chts: *u8, th_mac: *u8, key: *u8, iv: *u8, rec: *u8) -> i64 |
| 125 | func mf_expected_capkey(hs: *u8, thash: *u8, out: *u8) -> i64 called by 1: main calls 5: sys_mmapnx_mfin_empty_hashtls13_hkdf_expand_labelhkdf_extracttls13_derive_secret |
| 135 | func main() -> i64 |