nx_compare_capture_scope_lib.nx source
↩ module page · 99 lines · 4415 B
1// Compare capture authorization; selected scope binds one reviewed artifact and render call.
2import "nx_tabrec.nx"
3import "nx_rank_refresh_lib.nx"
4const CCS_PATH_CAP: i64 = 512
5const CCS_HEX_BYTES: i64 = 64
6const CCS_I64_MAX: i64 = 9223372036854775807
7const CCS_FIELD_COUNT: i64 = 5
8const CCS_LF: i64 = 10
9const CCS_CR: i64 = 13
10const CCS_HASH_COL: i64 = 4
11const CCS_REFUSED: i64 = 0
12func ccs_len(p: *u8) -> i64 { var n: i64=0; while p[n]!=(0 as u8) { n=n+1 }; return n }
13func ccs_identifier(p: *u8,maximum: i64) -> i64 {
14 var n: i64=0
15 while p[n]!=(0 as u8) {
16 if n>=maximum { return 0 }
17 let c: i64=p[n] as i64; var ok: i64=0
18 if c>=97 { if c<=122 { ok=1 } }
19 if c>=48 { if c<=57 { ok=1 } }
20 if c==95 { ok=1 }; if c==45 { ok=1 }
21 if ok==0 { return 0 }; n=n+1
22 }
23 return (n>0) as i64
24}
25func ccs_target(p: *u8) -> i64 {
26 let family: *u8="nx_swcompare_" as *u8
27 if ccs_identifier(p,CCS_PATH_CAP-ccs_len("_build/.sov.elf" as *u8)-1)!=1 { return 0 }
28 let n: i64=ccs_len(family); var i: i64=0
29 while i<n { if p[i]!=family[i] { return 0 }; i=i+1 }
30 return (p[n]!=(0 as u8)) as i64
31}
32// Full regular-file capture from one descriptor; short read or growth refuses rather than accepting a prefix.
33func ccs_read(path: *u8,outlen: *i64) -> *u8 {
34 outlen[0]=0
35 let fd: i64=sys_openat_rd(path); if fd<0 { return 0 as *u8 }
36 let size: i64=sys_lseek(fd,0,2)
37 if size<=0 { sys_close(fd); return 0 as *u8 }
38 if size>=CCS_I64_MAX { sys_close(fd); return 0 as *u8 }
39 if sys_lseek(fd,0,0)!=0 { sys_close(fd); return 0 as *u8 }
40 let b: *u8=sys_mmap(size+1)
41 if (b as i64)<=0 { sys_close(fd); return 0 as *u8 }
42 var n: i64=0
43 while n<size {
44 let got: i64=sys_read(fd,(b as i64+n) as *u8,size-n)
45 if got<=0 { sys_close(fd); sys_munmap(b,size+1); return 0 as *u8 }
46 n=n+got
47 }
48 let probe: *u8=sys_mmap(1); let extra: i64=sys_read(fd,probe,1)
49 sys_munmap(probe,1)
50 let closed: i64=sys_close(fd)
51 if extra!=0 { sys_munmap(b,size+1); return 0 as *u8 }
52 if closed!=0 { sys_munmap(b,size+1); return 0 as *u8 }
53 b[size]=0 as u8; outlen[0]=size; return b
54}
55// Schema: scope TAB target TAB domain TAB mode TAB lowercase-sha256 LF.
56// A scope ID selects exactly one row. Duplicate, malformed or mismatched selected rows refuse.
57func ccs_scope_digest(buf: *u8,n: i64,scope: *u8,target: *u8,domain: *u8,mode: *u8,digest: *u8) -> i64 {
58 if n<=0 { return 0 }
59 if buf[n-1]!=(CCS_LF as u8) { return 0 }
60 let field: *i64=sys_mmap(16) as *i64
61 var start: i64=0; var p: i64=0; var found: i64=0
62 while p<n {
63 if buf[p]==(CCS_LF as u8) {
64 var end: i64=p
65 if end>start { if buf[end-1]==(CCS_CR as u8) { end=end-1 } }
66 if end>start { if buf[start]!=(35 as u8) {
67 let row: *u8=(buf as i64+start) as *u8; let length: i64=end-start
68 if tr_field_eq(row,length,0,scope,field)==1 {
69 found=found+1; if found>1 { return 0 }
70 if tr_field_eq(row,length,1,target,field)!=1 { return 0 }
71 if tr_field_eq(row,length,2,domain,field)!=1 { return 0 }
72 if tr_field_eq(row,length,3,mode,field)!=1 { return 0 }
73 if tr_field(row,0,length,CCS_FIELD_COUNT,field)!=0 { return 0 }
74 if tr_field(row,0,length,CCS_HASH_COL,field)!=1 { return 0 }
75 if field[1]!=CCS_HEX_BYTES { return 0 }
76 var i: i64=0
77 while i<CCS_HEX_BYTES {
78 let c: i64=row[field[0]+i] as i64; var valid: i64=0
79 if c>=48 { if c<=57 { valid=1 } }; if c>=97 { if c<=102 { valid=1 } }
80 if valid!=1 { return 0 }; digest[i]=c as u8; i=i+1
81 }
82 digest[CCS_HEX_BYTES]=0 as u8
83 }
84 } }
85 start=p+1
86 }
87 p=p+1
88 }
89 return (found==1) as i64
90}
91func ccs_authorize(scope: *u8,target: *u8,domain: *u8,mode: *u8,executable: *u8,digest: *u8) -> i64 {
92 let n: *i64=sys_mmap(8) as *i64
93 let b: *u8=ccs_read("knowledge/compare/capture.scope" as *u8,n)
94 if (b as i64)==0 { return 0 }
95 let selected: i64=ccs_scope_digest(b,n[0],scope,target,domain,mode,digest)
96 sys_munmap(b,n[0]+1)
97 if selected!=1 { return 0 }
98 return rrf_file_hash_matches(executable,digest)
99}