code wiki / _hdl_build / nx_email_invite_gate.nx

nx_email_invite_gate.nx source

↩ module page · 106 lines · 5145 B

1// nx_email_invite_gate.nx -- MEASURED gate for the invite-mint provisioning seam (nx_email_invite's 2// core = inv_issue composed against the SAME inv_check/inv_consume the live portal registration 3// runs). Proves the full lifecycle offline against a scratch store: 4// T1 mint -> NX_INV_OK + 64 lowercase-hex token 5// T2 accept -> inv_check(same realm, fresh) returns the minted level 6// T3 realm-bind -> inv_check(WRONG realm) = 0 (an andelinwest invite can never register on 7// another domain's portal -- the per-domain delegation boundary) 8// T4 single-use -> inv_consume then inv_check = 0 (no replay) 9// T5 expiry -> ttl=1 token checked at now+5 = 0 (fail-closed) 10// GREEN iff 5/5. Appends knowledge/status/email_invite_gate.log. license_tier: ORIGINAL 11import "nx_invite_token.nx" 12import "nx_g_puts_lib.nx" 13import "nx_syscalls.nx" 14 15func g_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 16func g_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 17func g_putn(v: i64) -> i64 { 18 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 19 var m: i64 = v 20 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 21 let t: *u8 = sys_mmap(24); var k: i64 = 0 22 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 23 let o: *u8 = sys_mmap(24); var w: i64 = 0; var q: i64 = k - 1 24 while q >= 0 { o[w] = t[q]; w = w + 1; q = q - 1 } 25 sys_write(1, o, w); return 0 26} 27 28func main() -> i64 { 29 g_puts("=== EMAIL INVITE GATE: mint->accept->realm-bind->single-use->expiry (the portal's own check path) ===\n" as *u8) 30 let store: *u8 = "knowledge/status/email_invite_gate.invites" as *u8 31 // reset the scratch store (idempotent gate, rule 10) 32 let rfd: i64 = sys_openat_wr(store, 0x1a4) 33 if rfd >= 0 { sys_close(rfd) } 34 let realm: *u8 = "mailgate-realm" as *u8 35 let wrong: *u8 = "other-realm" as *u8 36 let now: i64 = sys_now_realtime_sec() 37 var pass: i64 = 0 38 39 // T1 mint 40 let tok: *u8 = sys_mmap(80) 41 let rc: i64 = inv_issue(store, realm, g_slen(realm), 3, 3600, now, tok) 42 var t1: i64 = 0 43 if rc == NX_INV_OK { 44 var hexok: i64 = 1 45 var i: i64 = 0 46 while i < 64 { 47 let c: i64 = tok[i] as i64 48 var ok: i64 = 0 49 if c >= 48 { if c <= 57 { ok = 1 } } 50 if c >= 97 { if c <= 102 { ok = 1 } } 51 if ok == 0 { hexok = 0 } 52 i = i + 1 53 } 54 if hexok == 1 { t1 = 1 } 55 } 56 pass = pass + t1 57 g_puts(" T1 mint 64-hex: " as *u8); if t1 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 58 59 // T2 accept (same realm, fresh) 60 let lvl: i64 = inv_check(store, tok, 64, realm, g_slen(realm), now + 1) 61 var t2: i64 = 0 62 if lvl == 3 { t2 = 1 } 63 pass = pass + t2 64 g_puts(" T2 accept level==3 (got " as *u8); g_putn(lvl); g_puts("): " as *u8); if t2 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 65 66 // T3 realm binding 67 let lw: i64 = inv_check(store, tok, 64, wrong, g_slen(wrong), now + 1) 68 var t3: i64 = 0 69 if lw == 0 { t3 = 1 } 70 pass = pass + t3 71 g_puts(" T3 wrong-realm rejected: " as *u8); if t3 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 72 73 // T4 single-use 74 inv_consume(store, tok, 64, now + 2) 75 let lc: i64 = inv_check(store, tok, 64, realm, g_slen(realm), now + 3) 76 var t4: i64 = 0 77 if lc == 0 { t4 = 1 } 78 pass = pass + t4 79 g_puts(" T4 consumed no-replay: " as *u8); if t4 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 80 81 // T5 expiry fail-closed 82 let tok2: *u8 = sys_mmap(80) 83 let rc2: i64 = inv_issue(store, realm, g_slen(realm), 1, 1, now, tok2) 84 var t5: i64 = 0 85 if rc2 == NX_INV_OK { 86 let le: i64 = inv_check(store, tok2, 64, realm, g_slen(realm), now + 5) 87 if le == 0 { t5 = 1 } 88 } 89 pass = pass + t5 90 g_puts(" T5 expired rejected: " as *u8); if t5 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 91 92 g_puts("----\nEMAIL-INVITE rows=5 pass=" as *u8); g_putn(pass); g_puts("\n" as *u8) 93 let lg: i64 = sys_openat_append("knowledge/status/email_invite_gate.log" as *u8, 0x1a4) 94 if lg >= 0 { 95 g_w(lg, "INVITEGATE mint_hex=" as *u8); if t1 == 1 { g_w(lg, "1" as *u8) } else { g_w(lg, "0" as *u8) } 96 g_w(lg, " accept=" as *u8); if t2 == 1 { g_w(lg, "1" as *u8) } else { g_w(lg, "0" as *u8) } 97 g_w(lg, " realm_bind=" as *u8); if t3 == 1 { g_w(lg, "1" as *u8) } else { g_w(lg, "0" as *u8) } 98 g_w(lg, " single_use=" as *u8); if t4 == 1 { g_w(lg, "1" as *u8) } else { g_w(lg, "0" as *u8) } 99 g_w(lg, " expiry=" as *u8); if t5 == 1 { g_w(lg, "1" as *u8) } else { g_w(lg, "0" as *u8) } 100 if pass == 5 { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } 101 sys_close(lg) 102 } 103 if pass == 5 { g_puts("EMAIL-INVITE GREEN (the provisioning seam is measured end-to-end)\n" as *u8); sys_exit(0); return 0 } 104 g_puts("EMAIL-INVITE RED\n" as *u8) 105 sys_exit(1); return 1 106}