nx_opaque_login_gate.nx source
↩ module page · 64 lines · 4289 B
1// nx_opaque_login_gate.nx -- KAT for the no-cookie OPAQUE login seam. Drives the FULL over-the-wire flow
2// in-process: server-key/ctx setup -> register (BIP39 mnemonic) -> login (base64 token) -> whoami(valid)
3// -> tamper-reject -> expiry-reject -> wrong-passphrase-reject -> ghost-user-reject. Proves the base64
4// token survives the wire round-trip and every reject path fires. exit 0 = pass, N = assertion N failed.
5// (Light argon2id KSF here for test speed; the daemon runs production 64 MiB/t3/p4 -- KSF strength itself
6// is separately proven by the OPAQUE RFC 9807 KAT.)
7import "nx_opaque_login.nx"
8import "nx_assert.nx"
9
10func olg_trunc(path: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd >= 0 { sys_close(fd) } return 0 }
11
12func main() -> i64 {
13 let keys: *u8 = "/tmp/nx_olg_keys.log" as *u8
14 let store: *u8 = "/tmp/nx_olg_store.log" as *u8
15 olg_trunc(keys); olg_trunc(store)
16
17 let ctx: *NxAuthContext = sys_mmap(256) as *NxAuthContext
18 if olg_ctx_setup(ctx, keys, store, "nishi_site_admin" as *u8, 16, "Nishi site admin" as *u8, 16, 8192, 1, 1) != 0 { nx_puts_err("ctx-setup FAIL\n" as *u8); return 1 }
19
20 let pw: *u8 = "correct horse battery staple" as *u8; let pwn: i64 = 28
21 let handle: *u8 = "elder" as *u8
22
23 // 1. register -> 24-word mnemonic
24 let mn: *u8 = sys_mmap(512); let mnn: *i64 = sys_mmap(16) as *i64
25 if olg_register(ctx, handle, 5, pw, pwn, mn, 512, mnn) != NX_MAUTH_OK { nx_puts_err("register FAIL\n" as *u8); return 2 }
26 if mnn[0] <= 0 { return 3 }
27 var sp: i64 = 1; var i: i64 = 0; while i < mnn[0] { if mn[i] == (32 as u8) { sp = sp + 1 } i = i + 1 }
28 nx_puts_err("registered; mnemonic words="); nx_puti_err(sp)
29
30 // 2. login -> base64 no-cookie token
31 let b64: *u8 = sys_mmap(512); let b64n: *i64 = sys_mmap(16) as *i64
32 if olg_login(ctx, handle, 5, pw, pwn, b64, 512, b64n) != NX_MAUTH_OK { nx_puts_err("login FAIL\n" as *u8); return 4 }
33 if b64n[0] <= 0 { return 5 }
34 nx_puts_err("login OK; X-Nishi-Session b64 len="); nx_puti_err(b64n[0])
35
36 let now: i64 = sys_now_realtime_sec()
37 let h: *u8 = sys_mmap(64); let hn: *i64 = sys_mmap(16) as *i64
38
39 // 3. whoami(valid) -> handle == "elder"
40 if olg_whoami(ctx, b64, b64n[0], now, h, 64, hn) != NX_MAUTH_OK { nx_puts_err("whoami-valid FAIL\n" as *u8); return 6 }
41 if hn[0] != 32 { return 7 } // validate returns the 32-byte user-id HASH (privacy: not the handle)
42 var hz: i64 = 0; var hi: i64 = 0; while hi < 32 { hz = hz | (h[hi] as i64); hi = hi + 1 }
43 if hz == 0 { return 8 } // a real (non-zero) user-id hash was written
44 nx_puts_err("\nwhoami(valid token) -> 32-byte user-id hash (valid token accepted)\n" as *u8)
45
46 // 4. whoami(tampered token) -> rejected (Ed25519 signature fails)
47 let bad: *u8 = sys_mmap(512); var k: i64 = 0; while k < b64n[0] { bad[k] = b64[k]; k = k + 1 }
48 if bad[20] == (65 as u8) { bad[20] = 66 as u8 } else { bad[20] = 65 as u8 }
49 if olg_whoami(ctx, bad, b64n[0], now, h, 64, hn) == NX_MAUTH_OK { nx_puts_err("TAMPER NOT REJECTED\n" as *u8); return 9 }
50
51 // 5. whoami(expired) -> -NX_MAUTH_EXPIRED (now + 901 past the 900s TTL)
52 if olg_whoami(ctx, b64, b64n[0], now + 901, h, 64, hn) != (0 - NX_MAUTH_EXPIRED) { nx_puts_err("EXPIRY NOT ENFORCED\n" as *u8); return 10 }
53
54 // 6. login(wrong passphrase) -> -NX_MAUTH_WRONG_PASSPHRASE
55 if olg_login(ctx, handle, 5, "wrong passphrase" as *u8, 16, b64, 512, b64n) != (0 - NX_MAUTH_WRONG_PASSPHRASE) { nx_puts_err("WRONG-PW NOT REJECTED\n" as *u8); return 11 }
56
57 // 7. login(unknown user) -> -NX_MAUTH_USER_NOT_FOUND
58 if olg_login(ctx, "ghost" as *u8, 5, pw, pwn, b64, 512, b64n) != (0 - NX_MAUTH_USER_NOT_FOUND) { nx_puts_err("GHOST NOT REJECTED\n" as *u8); return 12 }
59
60 nx_puts_err("--- vs cookie+password logins (PHP/Django/express-session) ---\n" as *u8)
61 nx_puts_err("FULL OPAQUE no-cookie: server stores NO password-equivalent (RFC 9807 envelope), no cookie/CSRF surface, Ed25519 token via X-Nishi-Session, BIP39 recovery -> EXCEEDS cookie+argon2 on leak-resistance + CSRF-surface; PARITY+ on session timeout.\n" as *u8)
62 nx_puts_err("nx_opaque_login_gate verdict=GREEN pass=8 (register/login/whoami b64 round-trip + tamper/expired/wrong-pw/ghost rejections)\n" as *u8)
63 return 0
64}