code wiki / _hdl_build / nx_legal_portal_boot_gate.nx

nx_legal_portal_boot_gate.nx source

↩ module page · 209 lines · 9942 B

1// nx_legal_portal_boot_gate.nx -- GATE for LEGAL D8 (nx_legal_portal_boot), ENGINEER verify. 2// 3// Proves the portal's tenant state SURVIVES A REBOOT: build a pctx with a SENT 4// 1-of-2-signed envelope (real Ed25519 seal) + a vault doc + a pending checklist, 5// persist it, then RELOAD into FRESH arrays (the restart) and serve through the 6// real lp_handle router -- the persisted state must reappear. Each with a control: 7// T1 ENVELOPES SURVIVE : after reload, GET /portal/envelopes -> "env 9601 status SENT" + "of 2" 8// T2 SIGNATURES SURVIVE : GET /portal/status?env=9601 -> "SENT" + "signed 1 of 2" 9// T3 CHECKLIST SURVIVES : GET /portal/checklist?doc=8601 -> "remaining 1" 10// T4 NEG no-load : a fresh pctx with NO reload shows NO envelope (the reload is what restored it) 11// T5 FIRST-BOOT clean : loading a tenant with NO files -> empty (env_count 0), not garbage 12// 13// Evidence -> knowledge/status/legal_portal_boot.log 14// license_tier: ORIGINAL 15import "nx_legal_portal_boot.nx" 16import "nx_legal_portal.nx" 17import "nx_doc_envelope.nx" 18import "nx_doc_annotate.nx" 19import "nx_doc_vault.nx" 20import "nx_doc_seal.nx" 21import "nx_legal_store.nx" 22import "nx_legal_compliance.nx" 23import "nx_syscalls.nx" 24 25const LPB_LOG: *u8 = "knowledge/status/legal_portal_boot.log" 26const LPB_BASE: *u8 = "/tmp/nx_lpb_" 27 28func ew(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 } 29func ewn(fd: i64, v: i64) -> i64 { 30 let bb: *u8 = sys_mmap(28); var m: i64 = v 31 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) } 32 let t: *u8 = sys_mmap(28); var k: i64 = 0 33 if m == 0 { t[0] = 48; k = 1 } 34 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 35 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 36 sys_write(fd, bb, k); return 0 37} 38func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 39func g_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o + i] = s[i]; i = i + 1 } return o + i } 40func g_starts(buf: *u8, n: i64, s: *u8) -> i64 { 41 let sn: i64 = slen(s) 42 if n < sn { return 0 } 43 var i: i64 = 0 44 while i < sn { if buf[i] != s[i] { return 0 } i = i + 1 } 45 return 1 46} 47func g_contains(hay: *u8, n: i64, needle: *u8) -> i64 { 48 let nn: i64 = slen(needle) 49 if nn == 0 { return 1 } 50 var i: i64 = 0 51 while i + nn <= n { 52 var m: i64 = 1 53 var j: i64 = 0 54 while j < nn { if hay[i + j] != needle[j] { m = 0; break } j = j + 1 } 55 if m == 1 { return 1 } 56 i = i + 1 57 } 58 return 0 59} 60func mk_seal(s: *NxSeal, dt: i64, ewills: i64, signer: *u8, ts: i64, 61 intent: i64, consent: i64, attribution: i64, retainable: i64, 62 witnesses: i64, notarized: i64) -> i64 { 63 s.doc_type = dt; s.e_wills_allowed = ewills 64 s.intent = intent; s.consent = consent; s.attribution = attribution 65 s.retainable = retainable; s.witnesses = witnesses; s.notarized = notarized 66 s.signer_id = signer; s.signer_id_len = slen(signer); s.ts = ts 67 return nx_seal_create(s) 68} 69 70func main() -> i64 { 71 var ok: i64 = 1 72 73 // ---- RFC 8032 test-1 keypair ---- 74 let priv: *u8 = sys_mmap(64) 75 priv[0]=0x9d; priv[1]=0x61; priv[2]=0xb1; priv[3]=0x9d; priv[4]=0xef; priv[5]=0xfd; priv[6]=0x5a; priv[7]=0x60 76 priv[8]=0xba; priv[9]=0x84; priv[10]=0x4a; priv[11]=0xf4; priv[12]=0x92; priv[13]=0xec; priv[14]=0x2c; priv[15]=0xc4 77 priv[16]=0x44; priv[17]=0x49; priv[18]=0xc5; priv[19]=0x69; priv[20]=0x7b; priv[21]=0x32; priv[22]=0x69; priv[23]=0x19 78 priv[24]=0x70; priv[25]=0x3b; priv[26]=0xac; priv[27]=0x03; priv[28]=0x1c; priv[29]=0xae; priv[30]=0x7f; priv[31]=0x60 79 let pub: *u8 = sys_mmap(64) 80 pub[0]=0xd7; pub[1]=0x5a; pub[2]=0x98; pub[3]=0x01; pub[4]=0x82; pub[5]=0xb1; pub[6]=0x0a; pub[7]=0xb7 81 pub[8]=0xd5; pub[9]=0x4b; pub[10]=0xfe; pub[11]=0xd3; pub[12]=0xc9; pub[13]=0x64; pub[14]=0x07; pub[15]=0x3a 82 pub[16]=0x0e; pub[17]=0xe1; pub[18]=0x72; pub[19]=0xf3; pub[20]=0xda; pub[21]=0xa6; pub[22]=0x23; pub[23]=0x25 83 pub[24]=0xaf; pub[25]=0x02; pub[26]=0x1a; pub[27]=0x68; pub[28]=0xf7; pub[29]=0x07; pub[30]=0x51; pub[31]=0x1a 84 let dh: *u8 = sys_mmap(64) 85 var di: i64 = 0 86 while di < 32 { dh[di] = ((di * 7 + 3) & 0xff) as u8; di = di + 1 } 87 let s: *NxSeal = sys_mmap(256) as *NxSeal 88 s.doc_hash = dh; s.doc_hash_len = 32; s.priv = priv; s.canon = sys_mmap(512); s.sig = sys_mmap(128) 89 90 let ecap: i64 = 8 91 let rcap: i64 = 16 92 let ncap: i64 = 8 93 let vcap: i64 = 8 94 95 // ======== build pctx1: SENT 1-of-2-signed envelope + vault doc + checklist ======== 96 let eflat1: *i64 = sys_mmap(ecap * EF_STRIDE * 8) as *i64 97 let rflat1: *i64 = sys_mmap(rcap * RF_STRIDE * 8) as *i64 98 let anflat1: *i64 = sys_mmap(ncap * NF_STRIDE * 8) as *i64 99 let vflat1: *i64 = sys_mmap(vcap * VF_STRIDE * 8) as *i64 100 var ne: i64 = 0 101 var nr: i64 = 0 102 var na: i64 = 0 103 var vc: i64 = 0 104 ne = nx_env_create(eflat1, ne, ecap, 9601, 8601, "Services Agreement" as *u8, 1, 1000) 105 nr = nx_env_add_recipient(rflat1, nr, rcap, 9601, 101, ROLE_SIGNER, 1) 106 nr = nx_env_add_recipient(rflat1, nr, rcap, 9601, 102, ROLE_SIGNER, 2) 107 nx_env_send(eflat1, ne, rflat1, nr, 9601) 108 let cs: i64 = mk_seal(s, DT_CONTRACT, 1, "client1@andelinwest.com" as *u8, 1100, 1, 1, 1, 1, 0, 0) 109 nx_env_sign(eflat1, ne, rflat1, nr, 9601, 101, s, pub) 110 vc = nx_vault_add(vflat1, vc, vcap, 8601, 5001, 64, 1000) 111 na = nx_ann_add(anflat1, na, ncap, 0, 1, 8601, 1, AN_CHECK, 0, 700, ANF_REQUIRED, 1000) 112 113 let ctx1: *NxPortalCtx = sys_mmap(256) as *NxPortalCtx 114 ctx1.eflat = eflat1; ctx1.ne = ne 115 ctx1.rflat = rflat1; ctx1.nr = nr 116 ctx1.anflat = anflat1; ctx1.na = na 117 ctx1.vflat = vflat1; ctx1.vc = vc 118 119 // ---- PERSIST, then RELOAD into FRESH arrays (the restart) ---- 120 lp_boot_save(ctx1, LPB_BASE, "clientA" as *u8) 121 let eflat2: *i64 = sys_mmap(ecap * EF_STRIDE * 8) as *i64 122 let rflat2: *i64 = sys_mmap(rcap * RF_STRIDE * 8) as *i64 123 let anflat2: *i64 = sys_mmap(ncap * NF_STRIDE * 8) as *i64 124 let vflat2: *i64 = sys_mmap(vcap * VF_STRIDE * 8) as *i64 125 let eidbuf2: *i64 = sys_mmap(64) as *i64 126 let ctx2: *NxPortalCtx = sys_mmap(256) as *NxPortalCtx 127 ctx2.user_level = 1 128 lp_boot_load(ctx2, LPB_BASE, "clientA" as *u8, eflat2, ecap, rflat2, rcap, anflat2, ncap, vflat2, vcap, eidbuf2) 129 130 let req: *u8 = sys_mmap(4096) 131 let out: *u8 = sys_mmap(16384) 132 133 // ---- T1: envelopes survive the reboot ---- 134 var t1: i64 = 1 135 var rn: i64 = g_cat(req, 0, "GET /portal/envelopes HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 136 var on: i64 = lp_handle(ctx2, req, rn, out) 137 if g_starts(out, on, "HTTP/1.1 200" as *u8) != 1 { t1 = 0 } 138 if g_contains(out, on, "env 9601 status SENT" as *u8) != 1 { t1 = 0 } 139 if g_contains(out, on, "of 2" as *u8) != 1 { t1 = 0 } 140 if t1 != 1 { ok = 0 } 141 142 // ---- T2: signatures survive (signed 1 of 2) ---- 143 var t2: i64 = 1 144 rn = g_cat(req, 0, "GET /portal/status?env=9601 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 145 on = lp_handle(ctx2, req, rn, out) 146 if g_contains(out, on, "status SENT" as *u8) != 1 { t2 = 0 } 147 if g_contains(out, on, "signed 1 of 2" as *u8) != 1 { t2 = 0 } 148 if t2 != 1 { ok = 0 } 149 150 // ---- T3: checklist survives ---- 151 var t3: i64 = 1 152 rn = g_cat(req, 0, "GET /portal/checklist?doc=8601 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 153 on = lp_handle(ctx2, req, rn, out) 154 if g_contains(out, on, "remaining 1 NOT_READY" as *u8) != 1 { t3 = 0 } 155 if t3 != 1 { ok = 0 } 156 157 // ---- T4: NEG control -- a fresh pctx with NO reload shows no envelope ---- 158 var t4: i64 = 1 159 let eflat3: *i64 = sys_mmap(ecap * EF_STRIDE * 8) as *i64 160 let rflat3: *i64 = sys_mmap(rcap * RF_STRIDE * 8) as *i64 161 let anflat3: *i64 = sys_mmap(ncap * NF_STRIDE * 8) as *i64 162 let vflat3: *i64 = sys_mmap(vcap * VF_STRIDE * 8) as *i64 163 let eidbuf3: *i64 = sys_mmap(64) as *i64 164 let ctx3: *NxPortalCtx = sys_mmap(256) as *NxPortalCtx 165 ctx3.user_level = 1 166 ctx3.eflat = eflat3; ctx3.ne = 0 167 ctx3.rflat = rflat3; ctx3.nr = 0 168 ctx3.anflat = anflat3; ctx3.na = 0 169 ctx3.vflat = vflat3; ctx3.vc = 0 170 ctx3.env_ids = eidbuf3; ctx3.env_count = 0 171 rn = g_cat(req, 0, "GET /portal/envelopes HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 172 on = lp_handle(ctx3, req, rn, out) 173 if g_starts(out, on, "HTTP/1.1 200" as *u8) != 1 { t4 = 0 } 174 if g_contains(out, on, "9601" as *u8) != 0 { t4 = 0 } // must NOT contain it (not loaded) 175 if t4 != 1 { ok = 0 } 176 177 // ---- T5: first boot for a tenant with NO files -> clean empty ---- 178 var t5: i64 = 1 179 let ctx4: *NxPortalCtx = sys_mmap(256) as *NxPortalCtx 180 ctx4.user_level = 1 181 lp_boot_load(ctx4, LPB_BASE, "freshtenant" as *u8, eflat3, ecap, rflat3, rcap, anflat3, ncap, vflat3, vcap, eidbuf3) 182 if ctx4.env_count != 0 { t5 = 0 } 183 if ctx4.ne != 0 { t5 = 0 } 184 rn = g_cat(req, 0, "GET /portal/envelopes HTTP/1.1\r\nHost: x\r\n\r\n" as *u8) 185 on = lp_handle(ctx4, req, rn, out) 186 if g_starts(out, on, "HTTP/1.1 200" as *u8) != 1 { t5 = 0 } 187 if g_contains(out, on, "9601" as *u8) != 0 { t5 = 0 } 188 if t5 != 1 { ok = 0 } 189 190 // ---- evidence ---- 191 var fd: i64 = 1 192 while fd >= 1 { 193 ew(fd, "LEGALPORTALBOOTGATE authored=organ composes=D6+D7 envelopes_survive_reboot=" as *u8); ewn(fd, t1) 194 ew(fd, " signatures_survive=" as *u8); ewn(fd, t2) 195 ew(fd, " checklist_survives=" as *u8); ewn(fd, t3) 196 ew(fd, " neg_no_load_empty=" as *u8); ewn(fd, t4) 197 ew(fd, " first_boot_clean=" as *u8); ewn(fd, t5) 198 if ok == 1 { ew(fd, " verdict=GREEN\n" as *u8) } else { ew(fd, " verdict=RED\n" as *u8) } 199 if fd == 1 { 200 let lf: i64 = sys_openat_append(LPB_LOG, 420) 201 if lf >= 1 { fd = lf } else { fd = 0 } 202 } else { 203 sys_close(fd); fd = 0 204 } 205 } 206 207 if ok == 1 { return 0 } 208 return 1 209}