nx_session_mint_lib.nx source
↩ module page · 68 lines · 3911 B
1// nx_session_mint_lib.nx -- LIBRARY (no main): mint an M5 no-cookie session token directly from a server key bundle,
2// without the OPAQUE passphrase. Shared by the CLI (nx_mgmt_session_mint) and the mgmt driver (nx_mgmt_call). See
3// nx_mgmt_session_mint.nx header for the full rationale + token/keyfile layout. Operator-authorized 2026-07-08.
4import "hub/nx_no_cookie_session.nx" // nx_ncs_derive_user_id_hash / _realm_id_hash / mint_token ; NX_NCS_OK ; sha256/ed25519/csprng
5
6func msm_slen(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i }
7func msm_atoi(s: *u8) -> i64 { var v: i64 = 0; var i: i64 = 0; while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c >= 0x30 { if c <= 0x39 { v = v * 10 + (c - 0x30) } } i = i + 1 } return v }
8func msm_hexval(c: i64) -> i64 { if c >= 0x30 { if c <= 0x39 { return c - 0x30 } } if c >= 0x61 { if c <= 0x66 { return c - 0x61 + 10 } } if c >= 0x41 { if c <= 0x46 { return c - 0x41 + 10 } } return 0 }
9
10// self-contained standard base64 (daemon b64_decode accepts +/ and -_); avoids any imported-b64 symbol conflict.
11func msm_b64_enc(inb: *u8, n: i64, out: *u8) -> i64 {
12 let a: *u8 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" as *u8
13 var pos: i64 = 0; var o: i64 = 0
14 while pos + 3 <= n {
15 let b0: i64 = inb[pos] as i64; let b1: i64 = inb[pos + 1] as i64; let b2: i64 = inb[pos + 2] as i64
16 out[o] = a[(b0 >> 2) & 0x3F]; out[o + 1] = a[((b0 << 4) | (b1 >> 4)) & 0x3F]; out[o + 2] = a[((b1 << 2) | (b2 >> 6)) & 0x3F]; out[o + 3] = a[b2 & 0x3F]
17 pos = pos + 3; o = o + 4
18 }
19 let rem: i64 = n - pos
20 if rem == 1 {
21 let b0: i64 = inb[pos] as i64
22 out[o] = a[(b0 >> 2) & 0x3F]; out[o + 1] = a[(b0 << 4) & 0x3F]; out[o + 2] = 0x3D as u8; out[o + 3] = 0x3D as u8; o = o + 4
23 }
24 if rem == 2 {
25 let b0: i64 = inb[pos] as i64; let b1: i64 = inb[pos + 1] as i64
26 out[o] = a[(b0 >> 2) & 0x3F]; out[o + 1] = a[((b0 << 4) | (b1 >> 4)) & 0x3F]; out[o + 2] = a[(b1 << 2) & 0x3F]; out[o + 3] = 0x3D as u8; o = o + 4
27 }
28 return o
29}
30
31// extract the 32-byte Ed25519 private key at hex offset 200 of an nx_uas key bundle. Returns 0 OK, negative on error.
32func msm_load_edpriv(keysfile: *u8, out32: *u8) -> i64 {
33 let lb: *i64 = sys_mmap(16) as *i64
34 let data: *u8 = sys_read_file(keysfile, lb)
35 if (data as i64) == 0 { return 0 - 1 }
36 if lb[0] < 327 { return 0 - 2 }
37 if (data[0] as i64) != 0x4B { return 0 - 3 } // 'K' -- bundle magic
38 var i: i64 = 0
39 while i < 32 {
40 let hi: i64 = msm_hexval(data[200 + i * 2] as i64)
41 let lo: i64 = msm_hexval(data[200 + i * 2 + 1] as i64)
42 out32[i] = ((hi << 4) | lo) as u8
43 i = i + 1
44 }
45 return 0
46}
47
48// mint the RAW 152-byte token. Returns 0 OK, negative on failure.
49func msm_mint_raw(keysfile: *u8, realm: *u8, realm_n: i64, handle: *u8, handle_n: i64, now_s: i64, ttl_s: i64, out_tok: *u8) -> i64 {
50 let edp: *u8 = sys_mmap(32)
51 if msm_load_edpriv(keysfile, edp) != 0 { return 0 - 10 }
52 let uid: *u8 = sys_mmap(32)
53 if nx_ncs_derive_user_id_hash(realm, realm_n, handle, handle_n, uid) != NX_NCS_OK { return 0 - 11 }
54 let rh: *u8 = sys_mmap(32)
55 if nx_ncs_derive_realm_id_hash(realm, realm_n, rh) != NX_NCS_OK { return 0 - 12 }
56 if nx_ncs_mint_token(edp, uid, rh, now_s, ttl_s, out_tok) != NX_NCS_OK { return 0 - 13 }
57 return 0
58}
59
60// convenience: mint straight to base64 (out_b64 NUL-terminated). Returns b64 length, or negative on failure.
61func msm_mint_b64(keysfile: *u8, realm: *u8, realm_n: i64, handle: *u8, handle_n: i64, now_s: i64, ttl_s: i64, out_b64: *u8) -> i64 {
62 let tok: *u8 = sys_mmap(152)
63 let mrc: i64 = msm_mint_raw(keysfile, realm, realm_n, handle, handle_n, now_s, ttl_s, tok)
64 if mrc != 0 { return mrc }
65 let blen: i64 = msm_b64_enc(tok, 152, out_b64)
66 out_b64[blen] = 0 as u8
67 return blen
68}