code wiki / (root) / nx_session_mint_lib.nx

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}