code wiki / _hdl_build / nx_room_invite.nx
nx_room_invite.nx source
↩ module page · 72 lines · 3512 B
1// nx_room_invite.nx -- mint a ROOM CAPABILITY LINK (task #41 room tokens). Usage:
2// nx_room_invite <room> [secretfile] (secretfile default knowledge/room_secret.txt)
3// Prints: https://nishifamily.com/video/?room=<room>#k=<token> (token = same SSOT organ as the relay)
4// The operator arms a room by (1) adding it to knowledge/rooms_protected.txt, (2) sharing this link.
5// #k= (hash) keeps the token out of server logs/referers; the client accepts ?k= too. license_tier: ORIGINAL
6import "nx_syscalls.nx"
7import "nx_room_key.nx" // token + sha256 (transitively); the E2EE ekey is minted here via sha256 too
8const K_MAGIC_4096: i64 = 4096
9
10func iw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
11
12func main(argc: i64, argv: *i64) -> i64 {
13 if argc < 2 {
14 iw("usage: nx_room_invite <room> [secretfile]\n" as *u8)
15 return 2
16 }
17 let room: *u8 = (argv[1]) as *u8
18 var rlen: i64 = 0
19 while room[rlen] != (0 as u8) { rlen = rlen + 1 }
20 var secpath: *u8 = "knowledge/room_secret.txt" as *u8
21 if argc > 2 { secpath = (argv[2]) as *u8 }
22 let slp: *i64 = sys_mmap(16) as *i64
23 let sec: *u8 = sys_read_file(secpath, slp)
24 if (sec as i64) == 0 {
25 iw("nx_room_invite: no secret at " as *u8); iw(secpath)
26 iw(" (create it first -- one line of high-entropy text; keep it OFF the repo)\n" as *u8)
27 return 1
28 }
29 var slen: i64 = slp[0]
30 var trimming: i64 = 1 // match the relay's trailing CR/LF trim exactly
31 while trimming == 1 {
32 if slen <= 0 { trimming = 0 }
33 else {
34 let lc: i64 = sec[slen - 1] & 0xff
35 if lc == 10 { slen = slen - 1 } else { if lc == 13 { slen = slen - 1 } else { trimming = 0 } }
36 }
37 }
38 let base: i64 = rk_base_len(room, rlen) // strip any accidental lane suffix
39 let tok: *u8 = sys_mmap(32)
40 rk_token(room, base, sec, slen, tok)
41 iw("https://nishifamily.com/video/?room=" as *u8)
42 sys_write(1, room, rlen)
43 iw("#k=" as *u8)
44 sys_write(1, tok, RK_TOK_LEN)
45 // E2EE fragment: if knowledge/e2ee_secret.txt exists (a DIFFERENT secret the relay never receives),
46 // append &e=<ekey>. ekey = hex(sha256(base_room || e2ee_secret)). Lives in the hash -> never sent to
47 // any server. The relay has room_secret (checks ?k=) but NOT e2ee_secret -> genuinely relay-blind.
48 let elp: *i64 = sys_mmap(16) as *i64
49 let esec: *u8 = sys_read_file("knowledge/e2ee_secret.txt" as *u8, elp)
50 if (esec as i64) != 0 {
51 var elen: i64 = elp[0]
52 var etr: i64 = 1
53 while etr == 1 {
54 if elen <= 0 { etr = 0 }
55 else { let lc: i64 = esec[elen-1] & 0xff
56 if lc == 10 { elen = elen - 1 } else { if lc == 13 { elen = elen - 1 } else { etr = 0 } } }
57 }
58 if elen > 0 {
59 // ekey = 64 hex chars of sha256(base_room || e2ee_secret) -> a 256-bit key in the link
60 let c: *Sha256 = sys_mmap(K_MAGIC_4096) as *Sha256
61 sha256_init(c); sha256_update(c, room, base); sha256_update(c, esec, elen)
62 let dg: *u8 = sys_mmap(64); sha256_final(c, dg)
63 let hx: *u8 = "0123456789abcdef" as *u8
64 let ek: *u8 = sys_mmap(80)
65 var di: i64 = 0
66 while di < 32 { ek[di*2] = hx[(dg[di] >> 4) & 15]; ek[di*2+1] = hx[dg[di] & 15]; di = di + 1 }
67 iw("&e=" as *u8)
68 sys_write(1, ek, 64)
69 }
70 }
71 iw("\n" as *u8)
72 return 0 }