code wiki / _hdl_build / nx_apistack_mtls_gate.nx

nx_apistack_mtls_gate.nx source

↩ module page · 39 lines · 2497 B

1// nx_apistack_mtls_gate.nx -- hermetic gate for CAP-API-MTLS. Proves pinned fingerprint allowed, unknown denied, 2// empty denied. expect_exit: 0 3import "nx_syscalls.nx" 4import "nx_apistack_mtls.nx" 5import "nx_gate_verdict.nx" 6 7func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 8func gn(v: i64) -> i64 { var t: i64=v; if t<0{sys_write(1,"-" as *u8,1);t=0-t} let tm:*u8=sys_mmap(24); var k:i64=0; if t==0{tm[0]=48 as u8;k=1} while t>0{tm[k]=(48+(t%10)) as u8;t=t/10;k=k+1} let b:*u8=sys_mmap(24); var j:i64=0; while j<k{b[j]=tm[k-1-j];j=j+1} sys_write(1,b,k); return 0 } 9func g_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 10func g_app(buf: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){buf[off+i]=s[i];i=i+1} return off+i } 11 12func main(argc: i64, argv: *i64) -> i64 { 13 gp("=== nx_apistack_mtls_gate (client-cert fingerprint pinning) ===\n" as *u8) 14 let C: *u8 = "/tmp/mtls_pins.conf" as *u8 15 let cf: *u8 = sys_mmap(256); var cn: i64 = 0 16 cn = g_app(cf, cn, "a1b2c3d4e5f60718" as *u8); cf[cn]=10 as u8; cn=cn+1 17 cn = g_app(cf, cn, "ffee112233445566" as *u8); cf[cn]=10 as u8; cn=cn+1 18 let fd: i64 = sys_openat_wr(C, 0x1a4); if fd >= 0 { sys_write(fd, cf, cn); sys_close(fd) } 19 var pass: i64 = 0; var fail: i64 = 0 20 21 let ok: *u8 = "a1b2c3d4e5f60718" as *u8 22 if mt_pinned(C, ok, g_slen(ok)) == 1 { pass=pass+1; gp(" T1 pinned fingerprint -> allowed PASS\n" as *u8) } else { fail=fail+1; gp(" T1 FAIL\n" as *u8) } 23 24 let bad: *u8 = "deadbeefdeadbeef" as *u8 25 if mt_pinned(C, bad, g_slen(bad)) == 0 { pass=pass+1; gp(" T2 unpinned fingerprint -> DENIED (deny-by-default) PASS\n" as *u8) } else { fail=fail+1; gp(" T2 FAIL allowed\n" as *u8) } 26 27 if mt_pinned(C, "" as *u8, 0) == 0 { pass=pass+1; gp(" T3 empty fingerprint -> denied PASS\n" as *u8) } else { fail=fail+1; gp(" T3 FAIL\n" as *u8) } 28 29 gp("RESULT pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail) 30 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 31 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 32 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 33 let ctr__dry: *i64 = gv_ctr() 34 ctr__dry[0] = pass 35 ctr__dry[1] = pass + fail 36 let rc__dry: i64 = gv_verdict("APISTACK-MTLS-GATE" as *u8, ctr__dry, "n" as *u8) 37 sys_exit(rc__dry) 38 return rc__dry 39}