code wiki / (root) / nx_cap_keygen_gate.nx

nx_cap_keygen_gate.nx source

↩ module page · 67 lines · 4635 B

1// nx_cap_keygen_gate.nx -- proves nx_cap_keygen provisions a REAL CSPRNG signing secret that (a) is 256-bit hex, 2// (b) lands on disk 0600 byte-exact with no trailing newline, (c) has real entropy (two draws differ), (d) is 3// fail-safe (refuses a silent overwrite), and -- the composition that matters -- (e) actually WORKS as an HMAC 4// signing key: a capability minted with it VERIFIES, and (f) is independent: a token signed by one key is DENIED 5// under another (unforgeable across keys). Closes GAP 2 of the MCP grant and ties it to GAP 1 (mint) + verify. 6// license_tier: ORIGINAL expect_exit: 0 7import "nx_cap_keygen.nx" // ck_provision + CK_* (+ transitive nx_csprng, nx_syscalls) 8import "nx_cap_token.nx" // capt_issue / capt_verify / CAPT_OK / CAPT_DENY_MAC 9import "nx_gate.nx" // gw / gn 10 11const KG_PATH: *u8 = "/tmp/nx_capkeygen_gate.key" as *u8 12 13func kg_is_hex(c: i64) -> i64 { if c >= 48 { if c <= 57 { return 1 } } if c >= 97 { if c <= 102 { return 1 } } return 0 } 14func kg_all_hex(s: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { if kg_is_hex(s[i] as i64) == 0 { return 0 } i = i + 1 } return 1 } 15func kg_eqn(a: *u8, b: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { if a[i] != b[i] { return 0 } i = i + 1 } return 1 } 16 17func kg_expect(actual: i64, expected: i64, pass: *i64, tot: *i64, label: *u8) -> i64 { 18 tot[0] = tot[0] + 1 19 if actual == expected { pass[0] = pass[0] + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL got=" as *u8); gn(actual); gw(" want=" as *u8); gn(expected); gw("] " as *u8) } 20 gw(label); gw("\n" as *u8) 21 return 0 22} 23 24func main() -> i64 { 25 gw("=== nx_cap_keygen_gate: CSPRNG signing-secret provisioning (GAP 2), proven to sign valid caps ===\n" as *u8) 26 __syscall(87, KG_PATH, 0, 0, 0, 0, 0) // unlink any stale file (ignore result) 27 let pbox: *i64 = sys_mmap(16) as *i64; pbox[0] = 0 28 let tbox: *i64 = sys_mmap(16) as *i64; tbox[0] = 0 29 30 // T1: provision a fresh keyfile 31 let k1: *u8 = sys_mmap(128); let l1: *i64 = sys_mmap(16) as *i64 32 let r1: i64 = ck_provision(KG_PATH, 1, k1, l1) 33 kg_expect(r1, CK_OK, pbox, tbox, "T1a provision (fresh) -> CK_OK" as *u8) 34 kg_expect(l1[0], 64, pbox, tbox, "T1b secret is 64 hex chars (256-bit)" as *u8) 35 kg_expect(kg_all_hex(k1, 64), 1, pbox, tbox, "T1c all chars are lowercase hex [0-9a-f]" as *u8) 36 37 // T2: the on-disk file is byte-exact to the returned key (64 bytes, no trailing newline) 38 let szp: *i64 = sys_mmap(16) as *i64 39 let disk: *u8 = sys_read_file(KG_PATH, szp) 40 var t2: i64 = 0 41 if (disk as i64) != 0 { if szp[0] == 64 { if kg_eqn(disk, k1, 64) == 1 { t2 = 1 } } } 42 kg_expect(t2, 1, pbox, tbox, "T2 keyfile on disk == returned secret, exactly 64 bytes (no newline)" as *u8) 43 44 // T3: entropy -- a second forced draw differs from the first (not a constant) 45 let k2: *u8 = sys_mmap(128); let l2: *i64 = sys_mmap(16) as *i64 46 let r3: i64 = ck_provision(KG_PATH, 1, k2, l2) 47 var differ: i64 = 0 48 if r3 == CK_OK { if kg_eqn(k1, k2, 64) == 0 { differ = 1 } } 49 kg_expect(differ, 1, pbox, tbox, "T3 second draw differs from the first (real entropy, not constant)" as *u8) 50 51 // T4: fail-safe -- provisioning over an existing file WITHOUT --force is refused (no silent rotate) 52 let k3: *u8 = sys_mmap(128); let l3: *i64 = sys_mmap(16) as *i64 53 let r4: i64 = ck_provision(KG_PATH, 0, k3, l3) 54 kg_expect(r4, CK_EXISTS, pbox, tbox, "T4 no-force over existing keyfile -> CK_EXISTS (no silent rotate)" as *u8) 55 56 // T5: COMPOSITION -- a capability minted with the GENERATED key verifies (the secret really is a working HMAC key) 57 let tok: *u8 = sys_mmap(1024) 58 let tn: i64 = capt_issue(k1, l1[0], "nx_mgmt_client" as *u8, 14, 9999999999, 7, tok, 1024) 59 kg_expect(capt_verify(k1, l1[0], tok, tn, "nx_mgmt_client" as *u8, 14, 1782000000), CAPT_OK, pbox, tbox, "T5 cap minted with the generated key VERIFIES (GAP2 secret drives GAP1 mint)" as *u8) 60 61 // T6: independence -- the SAME token does NOT verify under a DIFFERENT generated key (unforgeable across keys) 62 kg_expect(capt_verify(k2, l2[0], tok, tn, "nx_mgmt_client" as *u8, 14, 1782000000), CAPT_DENY_MAC, pbox, tbox, "T6 token from key#1 is DENIED under key#2 (keys independent, unforgeable)" as *u8) 63 64 gw("\n=== nx_cap_keygen_gate " as *u8); gn(pbox[0]); gw("/" as *u8); gn(tbox[0]); gw(" ===\n" as *u8) 65 if pbox[0] == tbox[0] { gw("CAP-KEYGEN GREEN -- CSPRNG 256-bit secret, 0600 byte-exact, real entropy, fail-safe, PROVEN to sign+verify caps (GAP 2 closed offline)\n" as *u8); sys_exit(0); return 0 } 66 gw("CAP-KEYGEN RED\n" as *u8); sys_exit(1); return 1 67}