nx_x509_chain_cache_gate.nx source
↩ module page · 34 lines · 2725 B
1// nx_x509_chain_cache_gate.nx -- durable regression witness for the cert-validation MEMOIZATION cache
2// (nx_x509_chain_verify: _cv_der_len + _cv_key_eq). The cache memoizes the PURE verify on
3// sha256(child_der||parent_der); a bug in _cv_der_len (wrong cert length -> key over wrong bytes) would risk a
4// false cache hit, and a bug in _cv_key_eq (loose 32-byte compare) would risk a cross-cert hit -- so both are
5// KAT-locked here. The live badssl gate (self-signed/expired/wrong-host rejected) covers end-to-end; this locks
6// the correctness-critical helpers so a future edit can't silently regress them. license_tier: ORIGINAL expect_exit:0
7import "nx_syscalls.nx"
8import "nx_x509_chain_verify.nx"
9
10func gcw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
11func gpn(v: i64) -> i64 { var m: i64=v; if m==0 { gcw("0" as *u8); return 0 } let t: *u8=sys_mmap(24); var k: i64=0; while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } let o: *u8=sys_mmap(24); var i: i64=0; while i<k { o[i]=t[k-1-i]; i=i+1 } sys_write(1,o,k); return 0 }
12func chk(name: *u8, got: i64, want: i64, f: *i64) -> i64 {
13 gcw(name); gcw(" got=" as *u8); gpn(got); gcw(" want=" as *u8); gpn(want)
14 if got==want { gcw(" PASS\n" as *u8) } else { gcw(" FAIL\n" as *u8); f[0]=f[0]+1 }
15 return 0
16}
17func main() -> i64 {
18 let f: *i64 = sys_mmap(8) as *i64; f[0]=0
19 let b: *u8 = sys_mmap(512)
20 // _cv_der_len KATs (DER SEQUENCE 0x30=48, length forms)
21 b[0]=48 as u8; b[1]=5 as u8; chk("der_len short(5)" as *u8, _cv_der_len(b), 7, f) // 2+5
22 b[0]=48 as u8; b[1]=129 as u8; b[2]=128 as u8; chk("der_len long1(128)" as *u8, _cv_der_len(b), 131, f) // 2+1+128
23 b[0]=48 as u8; b[1]=130 as u8; b[2]=1 as u8; b[3]=44 as u8; chk("der_len long2(300)" as *u8, _cv_der_len(b), 304, f) // 2+2+300
24 b[0]=49 as u8; b[1]=5 as u8; chk("der_len not-seq->0" as *u8, _cv_der_len(b), 0, f) // 0x31 not SEQUENCE
25 b[0]=48 as u8; b[1]=133 as u8; chk("der_len nlen>4->0" as *u8, _cv_der_len(b), 0, f) // nlen=5 refused
26 // _cv_key_eq KATs (32-byte compare)
27 let k1: *u8 = sys_mmap(64); let k2: *u8 = sys_mmap(32)
28 var i: i64 = 0; while i<32 { k1[i]=(i & 255) as u8; k2[i]=(i & 255) as u8; i=i+1 }
29 chk("key_eq identical->1" as *u8, _cv_key_eq(k1, 0, k2), 1, f)
30 k2[17]=255 as u8
31 chk("key_eq 1-byte-diff->0" as *u8, _cv_key_eq(k1, 0, k2), 0, f)
32 if f[0]==0 { gcw("NX-X509-CHAIN-CACHE-GATE 7/7 verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
33 gcw("NX-X509-CHAIN-CACHE-GATE FAIL count=" as *u8); gpn(f[0]); gcw("\n" as *u8); sys_exit(1); return 1
34}