nx_tls_cert_cache.nx
buildroot/runtime/nx_tls_cert_cache.nx
about
nx_tls_cert_cache.nx -- PERSIST the (already gate-proven) TLS cert-validation cache ACROSS PROCESSES.
F799 certloop cure, wiring half: nx_tls13_client_validate_certificate already supports ctx.cached_cert
(byte-identical presented Certificate message -> skip the ~3x450ms ECDSA chain walk; the handshake's
CertificateVerify possession proof ALWAYS still runs, so a MITM replaying cached bytes cannot finish)
and ctx.cert_out capture. What was missing: every tools/call fork-exec is a FRESH process, so the
in-process cache never survived -- each nx_https_get paid the full certloop. This lib persists the
validated Certificate message per host:
knowledge/tlscache/<host>.cert = "NXTCC1\n" [pad to 8] + epoch(8B LE) + len(8B LE) + cert bytes
SAFETY CONTRACT (mirrors the validator's own doc):
- per-host files; the caller passes the SAME host it will SNI-validate against.
- tcc_save ONLY after a session whose handshake completed (full validation ran OK on those bytes,
or the identical bytes were previously fully validated within TTL).
- freshness TTL (TCC_TTL_S = 7 days): a cache older than TTL is IGNORED -> full validation re-runs,
bounding the expired-but-unchanged-cert window far below any real cert lifetime. Rotation (new
bytes) is a natural miss -> full validation.
- fail-open everywhere: missing dir/file, bad magic, oversize, hostile hostname chars -> no cache,
classic full validation (byte-for-byte unchanged behavior).
Envelope: cert message <= TCC_CERT_CAP (16 KiB); hostname <= 200 chars of [A-Za-z0-9.-] else uncached.
license_tier: ORIGINAL expect_exit: 0 (lib; compile smoke main)
dependencies 2 imports · 6 importers
imports: nx_syscalls.nxnx_tls13_client_validate_certificate.nx
imported by: nx_https_fetch.nxnx_https_fetch_file.nxnx_https_fetch_lib.nxnx_https_get_cli.nxnx_https_get_cli2.nxnx_kaprobe.nx
structs
| none |
consts
| 23 | const TCC_TTL_S: i64 = 604800 |
| 24 | const TCC_CERT_CAP: i64 = 16384 |
| 25 | const TCC_HDR: i64 = 24 |
functions
| 27 | func tcc_err(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 } |
| 29 | func tcc_path(host: *u8, host_len: i64, dst: *u8) -> i64 |
| 56 | func tcc_r64(b: *u8, off: i64) -> i64 { var v: i64 = 0; var i: i64 = 7; while i >= 0 { v = (v << 8) | (b[off + i] & 0xff); i = i - 1 } return v } called by 1: tcc_load |
| 57 | func tcc_w64(b: *u8, off: i64, v: i64) -> i64 { var m: i64 = v; var i: i64 = 0; while i < 8 { b[off + i] = (m & 0xff) as u8; m = m >> 8; i = i + 1 } return 0 } called by 1: tcc_save |
| 59 | func tcc_load(host: *u8, host_len: i64, now: i64, ctx: *TlsValidationContext) -> i64 called by 4: nx_https_fetch_hdrhf_openmainka_handshake calls 7: sys_mmaptcc_pathsys_openat_rdsys_readsys_closetcc_r64+1 |
| 88 | func tcc_arm(ctx: *TlsValidationContext) -> i64 |
| 97 | func tcc_save(host: *u8, host_len: i64, now: i64, ctx: *TlsValidationContext) -> i64 called by 4: nx_https_fetch_hdrhf_openmainka_handshake calls 10: sys_mmaptcc_pathsys_mkdirtcc_w64sys_openat_wrsys_write+4 |
| 145 | func main() -> i64 { return 0 } |