code wiki / (root) / nx_tls13_mtls_finished.nx

nx_tls13_mtls_finished.nx

buildroot/runtime/nx_tls13_mtls_finished.nx

11888 B196 linesdepth 11pulls 36 transitivereach 3 importersview sourcekind tooltopic tls13
docsdependenciesstructsconstsfunctions

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

nx_syscalls.nx nx_tls13.nx nx_tls13_record.nx nx_tls13_transcript.nx nx_tls13_kdf.nx nx_hmac.nx nx_hkdf.nx nx_tls13_server_session.nx nx_tls13_mtls_finished.nx nx_tls13_server_session_run_mtls.n

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

main mf_w sys_write sys_mmap mf_mksession sys_mmap ↻ nx_tls13_transcript_new sys_mmap ↻ sha256_init sys_mmap ↻ sha256_k sha384_init nx_tls13_transcript_update sha256_update sha256_compress_ni_blocks blk_set_byte sha256_compress sha256_compress_ni blk_word blk_byte sha512_update sha512_blk_set_byte blk_get_i64 blk_set_i64 sha512_compress sys_mmap ↻ blk_get_i64 ↻ sha512_gamma0 rotr64_v shr64_v sha512_gamma1 rotr64_v ↻ shr64_v ↻ sha512_sigma1 rotr64_v ↻ sha512_ch sha512_k sha512_sigma0 rotr64_v ↻ sha512_maj

structs

none

consts

21const NX_MFIN_CV_LEN: i64 = 32
22const NX_MFIN_REC_HEADER: i64 = 5
23const NX_MFIN_REC_TAG: i64 = 16

functions

25func nx_mfin_eq32(a: *u8, b: *u8) -> i64
31func nx_mfin_empty_hash(h: *u8) -> i64
41func nx_tls13_mtls_recv_finished(s: *Tls13ServerSession, record: *u8, record_len: i64, th_app: *u8) -> i64
87func 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 }
called by 2: mf_rowmain calls 1: sys_write
88func 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 }
called by 1: main calls 1: mf_w
90func mf_mksession(hs: *u8, chts: *u8, key: *u8, iv: *u8) -> *Tls13ServerSession
106func mf_build_finished_rec(chts: *u8, th_mac: *u8, key: *u8, iv: *u8, rec: *u8) -> i64
125func mf_expected_capkey(hs: *u8, thash: *u8, out: *u8) -> i64
135func main() -> i64