code wiki / _hdl_build / nx_x509_verify_rsa_gate.nx

nx_x509_verify_rsa_gate.nx source

↩ module page · 120 lines · 7241 B

1// nx_x509_verify_rsa_gate.nx -- DIRECT gate for the x509 RSA-verify family (flagged by the HONESTY SYSTEM 2// 2026-07-16: nx_x509_verify_rsa_pkcs1_sha256 + nx_x509_pubkey_extract_rsa, reach ~479, no DIRECT test edge). 3// A crypto-verify gate CANNOT be fake-greened: it passes only if every DER offset, the issuer-key extraction, 4// and the RSA signature are ALL correct (unlike marker judges). Composition over REAL persistent certs: 5// parse real_leaf.der -> parse the intermediate out of real_fullchain.der -> extract issuer RSA (n,e) -> 6// verify the leaf's TBS signature under the issuer key -> must be OK ; then corrupt one sig byte -> must FAIL. 7// Wrapper-logic tests (verdict validator + sig_len!=256 rejection) hold regardless of the leaf's algorithm. 8// Rich diagnostics: prints parse rc, tbs/sig lens, and the leaf sig-alg OID so a RED is INFORMATIVE, not opaque. 9// license_tier: ORIGINAL expect_exit:0 10import "nx_syscalls.nx" 11import "nx_x509.nx" 12import "nx_x509_pubkey_rsa.nx" 13import "nx_x509_verify_rsa_pkcs1_sha256.nx" 14 15func xw(s: *u8) -> i64 { var n:i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 16func xn(v: i64) -> i64 { let b:*u8=sys_mmap(24); var m:i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var j:i64=0; while j<k{b[j]=t[k-1-j];j=j+1} sys_write(1,b,k); return 0 } 17func xhex(buf: *u8, off: i64, len: i64) -> i64 { 18 let h: *u8 = "0123456789abcdef" as *u8 19 var i: i64 = 0 20 while i < len { 21 let c: i64 = buf[off+i] as i64 22 let o: *u8 = sys_mmap(4) 23 o[0] = h[(c/16)%16]; o[1] = h[c%16]; o[2] = 32 as u8 24 sys_write(1, o, 3) 25 i = i + 1 26 } 27 sys_write(1, "\n" as *u8, 1) 28 return 0 29} 30func rdfile(path: *u8, lenout: *i64) -> *u8 { 31 let lp: *i64 = sys_mmap(16) as *i64 32 lp[0] = 0 33 let b: *u8 = sys_read_file(path, lp) 34 lenout[0] = lp[0] 35 return b 36} 37 38func main() -> i64 { 39 var pass: i64 = 0 40 let total: i64 = 6 41 42 // ---- wrapper-logic tests (algorithm-independent) ---- 43 // T1: verdict validator well-formed (+neg) 44 var ok1: i64 = 1 45 if nx_x509_rsa_pkcs1_sha256_verdict_is_valid(NX_X509_RSA_PKCS1_SHA256_OK) != 1 { ok1 = 0 } 46 if nx_x509_rsa_pkcs1_sha256_verdict_is_valid(NX_X509_RSA_PKCS1_SHA256_BAD_SIG) != 1 { ok1 = 0 } 47 if nx_x509_rsa_pkcs1_sha256_verdict_is_valid(999) != 0 { ok1 = 0 } 48 if ok1 == 1 { pass = pass + 1; xw("T1 verdict-valid PASS\n" as *u8) } else { xw("T1 FAIL verdict validator\n" as *u8) } 49 50 // T2: sig_len != 256 -> BAD_LEN (a dummy pubkey suffices; guard fires before crypto) 51 let dn: *i64 = sys_mmap(40*8) as *i64 52 let dsig: *u8 = sys_mmap(256) 53 let dtbs: *u8 = sys_mmap(16) 54 let r2: i64 = nx_x509_verify_rsa_pkcs1_sha256(dtbs, 6, dsig, 200, dn, 65537) 55 if r2 == NX_X509_RSA_PKCS1_SHA256_BAD_LEN { pass = pass + 1; xw("T2 sig_len-guard PASS\n" as *u8) } else { xw("T2 FAIL got=" as *u8); xn(r2); xw("\n" as *u8) } 56 57 // ---- real-cert composition ---- 58 let ll: *i64 = sys_mmap(16) as *i64 59 let leaf: *u8 = rdfile("/mnt/c/Users/elder/nishi-core/nxc2/knowledge/status/real_leaf.der\x00" as *u8, ll) 60 if ll[0] <= 0 { 61 xw("real_leaf.der ABSENT -> real-cert tests SKIPPED (wrapper tests still enforced)\n" as *u8) 62 xw("NX-X509-VERIFY-RSA GATE " as *u8); xn(pass); xw("/2 (real-cert SKIPPED)\n" as *u8) 63 if pass == 2 { return 0 } 64 return 1 65 } 66 let lc: *X509Cert = sys_mmap(1024) as *X509Cert 67 let prc: i64 = x509_parse(leaf, ll[0], lc) 68 xw(" leaf parse rc=" as *u8); xn(prc); xw(" tbs_len=" as *u8); xn(lc.tbs_len); xw(" sig_len=" as *u8); xn(lc.sig_len); xw("\n" as *u8) 69 xw(" leaf sig-alg OID bytes: " as *u8); xhex(leaf, lc.sig_alg_off, 11) 70 71 // T3: leaf parsed with sane TBS + signature 72 if prc >= 0 { if lc.tbs_len > 0 { if lc.sig_len > 0 { pass = pass + 1; xw("T3 leaf-parse PASS\n" as *u8) } else { xw("T3 FAIL sig_len\n" as *u8) } } else { xw("T3 FAIL tbs_len\n" as *u8) } } else { xw("T3 FAIL parse rc\n" as *u8) } 73 74 // guard: RSA-2048 signature is 256 bytes. If not, this leaf is not RSA-2048 -> honestly report + skip crypto. 75 if lc.sig_len != 256 { 76 xw(" NOTE leaf sig_len=" as *u8); xn(lc.sig_len); xw(" != 256 -> leaf is NOT RSA-2048 (likely ECDSA); RSA-verify N/A for this fixture.\n" as *u8) 77 xw(" -> T4-T6 (real RSA verify) require a COMMITTED RSA leaf+issuer vector; recorded as an honest gap, not faked.\n" as *u8) 78 xw("NX-X509-VERIFY-RSA GATE " as *u8); xn(pass); xw("/3 wrapper+parse (RSA crypto path needs committed vector)\n" as *u8) 79 if pass == 3 { return 0 } 80 return 1 81 } 82 83 // intermediate = 2nd cert in the fullchain. DER cert = 0x30 0x82 hi lo <body>; total = 4 + hi*256+lo. 84 let cl: *i64 = sys_mmap(16) as *i64 85 let chain: *u8 = rdfile("/mnt/c/Users/elder/nishi-core/nxc2/knowledge/status/real_fullchain.der\x00" as *u8, cl) 86 var interoff: i64 = 0 87 if cl[0] > 4 { 88 if (chain[0] & 0xff) == 0x30 { if (chain[1] & 0xff) == 0x82 { 89 interoff = 4 + ((chain[2] & 0xff) * 256 + (chain[3] & 0xff)) 90 } } 91 } 92 xw(" fullchain len=" as *u8); xn(cl[0]); xw(" intermediate off=" as *u8); xn(interoff); xw("\n" as *u8) 93 let ic: *X509Cert = sys_mmap(1024) as *X509Cert 94 let iprc: i64 = x509_parse(((chain as i64)+interoff) as *u8, cl[0]-interoff, ic) 95 let out_n: *i64 = sys_mmap(40*8) as *i64 96 let out_e: *i64 = sys_mmap(16) as *i64 97 let erc: i64 = nx_x509_pubkey_extract_rsa(((chain as i64)+interoff) as *u8, ic, out_n, out_e) 98 xw(" issuer parse rc=" as *u8); xn(iprc); xw(" extract rc=" as *u8); xn(erc); xw(" e=" as *u8); xn(out_e[0]); xw("\n" as *u8) 99 100 // T4: issuer RSA key extracted (e is a sane odd exponent, typically 65537) 101 if erc >= 0 { if out_e[0] >= 3 { pass = pass + 1; xw("T4 issuer-key PASS\n" as *u8) } else { xw("T4 FAIL e too small\n" as *u8) } } else { xw("T4 FAIL extract rc=" as *u8); xn(erc); xw("\n" as *u8) } 102 103 // T5: THE crypto -- leaf TBS signature verifies under issuer key -> OK (self-validating green) 104 let vv: i64 = nx_x509_verify_rsa_pkcs1_sha256(((leaf as i64)+lc.tbs_off) as *u8, lc.tbs_len, ((leaf as i64)+lc.sig_off) as *u8, lc.sig_len, out_n, out_e[0]) 105 xw(" VERIFY verdict=" as *u8); xn(vv); xw(" (OK=" as *u8); xn(NX_X509_RSA_PKCS1_SHA256_OK); xw(")\n" as *u8) 106 if vv == NX_X509_RSA_PKCS1_SHA256_OK { pass = pass + 1; xw("T5 real-verify PASS\n" as *u8) } else { xw("T5 FAIL verify verdict=" as *u8); xn(vv); xw("\n" as *u8) } 107 108 // T6 (NEG): corrupt one signature byte -> must NOT be OK 109 let bad: *u8 = sys_mmap(300) 110 var i: i64 = 0 111 while i < lc.sig_len { bad[i] = leaf[lc.sig_off+i]; i = i + 1 } 112 bad[0] = (bad[0] + 1) & 0xff 113 let vb: i64 = nx_x509_verify_rsa_pkcs1_sha256(((leaf as i64)+lc.tbs_off) as *u8, lc.tbs_len, bad, lc.sig_len, out_n, out_e[0]) 114 if vb != NX_X509_RSA_PKCS1_SHA256_OK { pass = pass + 1; xw("T6 corrupt-sig-rejected PASS\n" as *u8) } else { xw("T6 FAIL corrupt sig accepted\n" as *u8) } 115 116 xw("NX-X509-VERIFY-RSA GATE " as *u8); xn(pass); xw("/" as *u8); xn(total); xw("\n" as *u8) 117 if pass == total { xw("GREEN\n" as *u8); return 0 } 118 xw("RED\n" as *u8) 119 return 1 120}