code wiki / (root) / nx_tls13_cert_cache_gate.nx

nx_tls13_cert_cache_gate.nx source

↩ module page · 96 lines · 5555 B

1// nx_tls13_cert_cache_gate.nx -- proves the additive cert-validation CACHE in nx_tls13_client_validate_certificate: 2// a byte-identical cached cert short-circuits to OK (skipping the ECDSA chain crypto), ANY mismatch / no-cache runs 3// full validation, and the presented cert is captured to cert_out (bounded, no overflow). The test cert is 4// DELIBERATELY INVALID -- so a cache-hit returning OK conclusively proves the pipeline was skipped, and a 5// cache-miss returning non-OK proves it was NOT. GREEN + exit 0 iff all pass. license_tier: ORIGINAL expect_exit: 0 6import "nx_tls13_client_validate_certificate.nx" // TlsValidationContext + validator + transitive syscalls/pipeline 7import "nx_syscalls.nx" 8import "nx_gate_verdict.nx" 9 10func cg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 11func cg_putn(v: i64) -> i64 { 12 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 13 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 14 let d: *u8 = sys_mmap(24); var k: i64 = 0 15 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 16 var j: i64 = k - 1 17 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 } 18 return 0 19} 20func cg_memeq(a: *u8, an: i64, b: *u8, bn: i64) -> i64 { 21 if an != bn { return 0 } 22 var i: i64 = 0 23 while i < an { if a[i] != b[i] { return 0 } i = i + 1 } 24 return 1 25} 26func cg_row(name: *u8, ok: i64) -> i64 { 27 if ok == 1 { cg_puts(" PASS " as *u8) } else { cg_puts(" FAIL " as *u8) } 28 cg_puts(name); cg_puts("\n" as *u8) 29 return ok 30} 31 32func main() -> i64 { 33 cg_puts("tls cert-validation cache gate (fast-path skip on byte-exact match; miss/none => full validate; bounded capture)\n" as *u8) 34 // DELIBERATELY INVALID Certificate messages (full validation must reject them). No real trust store needed: 35 // the pipeline rejects an invalid cert at PARSE, before it dereferences ctx.store -- so ctx.store stays 0 (zeroed 36 // mmap) and is never touched. Keeps the gate self-contained (no certdata dep) while still hitting the reject path. 37 let certX: *u8 = sys_mmap(64); var xi: i64 = 0 38 while xi < 40 { certX[xi] = (0x41 + (xi % 26)) as u8; xi = xi + 1 } 39 let lenX: i64 = 40 40 let certY: *u8 = sys_mmap(64); var yi: i64 = 0 41 while yi < 40 { certY[yi] = (0x61 + (yi % 26)) as u8; yi = yi + 1 } 42 43 let sni: *u8 = "nishifamily.com" as *u8 44 let ctx: *TlsValidationContext = sys_mmap(128) as *TlsValidationContext 45 ctx.sni_host = sni; ctx.sni_host_len = 15; ctx.now_epoch = 1750000000 46 // store + cache fields are 0 from the zeroed mmap -> cache inactive for T1 47 48 var pass: i64 = 0 49 let total: i64 = 5 50 51 // T1 NEG-CONTROL: no cache -> full validation -> the invalid cert is REJECTED (proves the pipeline runs + rejects) 52 let v_none: i64 = nx_tls13_client_validate_certificate(certX, lenX, ctx) 53 var t1: i64 = 0 54 if v_none != NX_TLS13_CLIENT_CV_OK { t1 = 1 } 55 pass = pass + cg_row("T1 NEG no-cache: invalid cert -> full validation REJECTS (verdict != OK)\x00" as *u8, t1) 56 57 // T2: cache HIT (cached == certX) -> OK, despite the SAME cert being rejected in T1 -> proves the skip 58 ctx.cached_cert = certX; ctx.cached_cert_len = lenX 59 let v_hit: i64 = nx_tls13_client_validate_certificate(certX, lenX, ctx) 60 var t2: i64 = 0 61 if v_hit == NX_TLS13_CLIENT_CV_OK { t2 = 1 } 62 pass = pass + cg_row("T2 cache HIT: byte-identical cached cert -> OK (chain crypto SKIPPED; same cert T1 rejected)\x00" as *u8, t2) 63 64 // T3 NEG: cache MISS (cached = a DIFFERENT cert) -> falls through to full validation -> REJECTED 65 ctx.cached_cert = certY; ctx.cached_cert_len = 40 66 let v_miss: i64 = nx_tls13_client_validate_certificate(certX, lenX, ctx) 67 var t3: i64 = 0 68 if v_miss != NX_TLS13_CLIENT_CV_OK { t3 = 1 } 69 pass = pass + cg_row("T3 NEG cache MISS: different cached cert -> full validation REJECTS (no false accept)\x00" as *u8, t3) 70 71 // T4: cert_out capture -> the presented cert is copied out byte-exact + length set 72 let cob: *u8 = sys_mmap(256) 73 ctx.cached_cert_len = 0; ctx.cert_out = cob; ctx.cert_out_cap = 256 74 let _cap4: i64 = nx_tls13_client_validate_certificate(certX, lenX, ctx) 75 var t4: i64 = 0 76 if ctx.cert_out_len == lenX { if cg_memeq(cob, lenX, certX, lenX) == 1 { t4 = 1 } } 77 pass = pass + cg_row("T4 capture: presented cert copied to cert_out byte-exact + cert_out_len set\x00" as *u8, t4) 78 79 // T5 NEG: cert_out too small -> NOT written, cert_out_len == 0 (no overflow) 80 ctx.cert_out = cob; ctx.cert_out_cap = 10 81 let _cap5: i64 = nx_tls13_client_validate_certificate(certX, lenX, ctx) 82 var t5: i64 = 0 83 if ctx.cert_out_len == 0 { t5 = 1 } 84 pass = pass + cg_row("T5 NEG capture overflow: cap < cert -> cert_out_len=0, nothing written (bounded)\x00" as *u8, t5) 85 86 cg_puts("nx_tls13_cert_cache_gate pass=" as *u8); cg_putn(pass); cg_puts("/" as *u8); cg_putn(total); cg_puts("\n" as *u8) 87 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 88 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 89 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 90 let ctr__dry: *i64 = gv_ctr() 91 ctr__dry[0] = pass 92 ctr__dry[1] = total 93 let rc__dry: i64 = gv_verdict("TLS13-CERT-CACHE-GATE" as *u8, ctr__dry, "cache fast-path skips only on byte-exact match; miss/none full-validate; capture bounded" as *u8) 94 sys_exit(rc__dry) 95 return rc__dry 96}