code wiki / (root) / nx_compare_capture_scope_lib.nx

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}