code wiki / _hdl_build / nx_cert_registry.nx
nx_cert_registry.nx source
↩ module page · 103 lines · 5080 B
1// nx_cert_registry.nx -- the S-CLASS DATA-DRIVEN CERT REGISTRY (SNI host -> per-domain TLS chain+key). The LOGIC
2// core that RETIRES the hardcoded single cert (NX_SD2_CERT_PATH) AND the per-domain consts. PURE: a cert TABLE
3// (data) + a ClientHello SNI host -> the matched (chain_path, key_path). Semantics: EXACT host beats a '*.domain'
4// WILDCARD beats the '*' DEFAULT; the wildcard is LABEL-SAFE + ANTI-SPOOF (`*.nishifamily.com` matches
5// `www.nishifamily.com` but NEVER `evilnishifamily.com` nor `a.b.nishifamily.com`); case-insensitive (DNS).
6// Consumes the rows nx_domain_forge emits (certs_generated.conf). Operator: "fix the hardcoding ... s-class
7// exceed." Table row (space/TAB-delim; '#'=comment): <host|*.domain|*> <chain_path> <key_path>. license_tier: ORIGINAL
8import "nx_syscalls.nx"
9
10func cr_lc(c: i64) -> i64 { if c >= 65 { if c <= 90 { return c + 32 } } return c }
11func cr_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
12
13func cr_eol(b: *u8, n: i64, st: i64) -> i64 {
14 var i: i64 = st; var f: i64 = 0
15 while f == 0 { if i >= n { f = 1 } else { if (b[i] as i64) == 10 { f = 1 } else { i = i + 1 } } }
16 return i
17}
18func cr_is_sep(c: i64) -> i64 { if c == 32 { return 1 } if c == 9 { return 1 } return 0 }
19func cr_split(b: *u8, ls: i64, le: i64, offs: *i64, lens: *i64, maxf: i64) -> i64 {
20 var nf: i64 = 0; var i: i64 = ls
21 while i < le {
22 var sk: i64 = 1
23 while sk == 1 { if i >= le { sk = 0 } else { if cr_is_sep(b[i] as i64) == 1 { i = i + 1 } else { sk = 0 } } }
24 if i < le {
25 let st: i64 = i; var sc: i64 = 1
26 while sc == 1 { if i >= le { sc = 0 } else { if cr_is_sep(b[i] as i64) == 1 { sc = 0 } else { i = i + 1 } } }
27 if nf < maxf { offs[nf] = st; lens[nf] = i - st; nf = nf + 1 }
28 }
29 }
30 return nf
31}
32func cr_copyz(dst: *u8, src: *u8, off: i64, len: i64) -> i64 { var i: i64 = 0; while i < len { dst[i] = src[off + i]; i = i + 1 } dst[len] = 0 as u8; return len }
33
34// case-insensitive: slice a[ao..ao+al) == null-terminated tok?
35func cr_tok_eq_ci(a: *u8, ao: i64, al: i64, tok: *u8) -> i64 {
36 let tl: i64 = cr_slen(tok)
37 if tl != al { return 0 }
38 var i: i64 = 0
39 while i < al { if cr_lc(a[ao + i] as i64) != cr_lc(tok[i] as i64) { return 0 } i = i + 1 }
40 return 1
41}
42// case-insensitive: slice a[ao..ao+al) == host b[0..bn)?
43func cr_host_eq_ci(a: *u8, ao: i64, al: i64, b: *u8, bn: i64) -> i64 {
44 if al != bn { return 0 }
45 var i: i64 = 0
46 while i < al { if cr_lc(a[ao + i] as i64) != cr_lc(b[i] as i64) { return 0 } i = i + 1 }
47 return 1
48}
49
50// label-safe + anti-spoof wildcard: pattern pat[po..po+pl) is "*.D"; matches host[0..hn) iff host ends with ".D"
51// (case-insensitive) AND the prefix before ".D" is exactly ONE non-empty label (no '.'). So "*.nishifamily.com"
52// matches "www.nishifamily.com" but NOT "evilnishifamily.com" (no dot boundary) nor "a.b.nishifamily.com" (2 labels).
53func cr_wild_match(host: *u8, hn: i64, pat: *u8, po: i64, pl: i64) -> i64 {
54 if pl < 3 { return 0 }
55 if (pat[po] as i64) != 42 { return 0 }
56 if (pat[po + 1] as i64) != 46 { return 0 }
57 let so: i64 = po + 1
58 let sl: i64 = pl - 1
59 if sl >= hn { return 0 }
60 let hoff: i64 = hn - sl
61 var i: i64 = 0
62 while i < sl { if cr_lc(host[hoff + i] as i64) != cr_lc(pat[so + i] as i64) { return 0 } i = i + 1 }
63 if hoff <= 0 { return 0 }
64 var k: i64 = 0
65 while k < hoff { if (host[k] as i64) == 46 { return 0 } k = k + 1 }
66 return 1
67}
68
69// THE MATCHER: best cert for the SNI host. priority EXACT(2) > WILDCARD(1) > DEFAULT '*'(0). copies chain+key
70// (null-terminated) into the caller buffers. returns 1 if matched / 0 if none (caller falls back to its default).
71func cr_match(tab: *u8, n: i64, host: *u8, hn: i64, chainbuf: *u8, keybuf: *u8) -> i64 {
72 let offs: *i64 = sys_mmap(64) as *i64
73 let lens: *i64 = sys_mmap(64) as *i64
74 var best_pri: i64 = 0 - 1
75 var bc_off: i64 = 0; var bc_len: i64 = 0
76 var bk_off: i64 = 0; var bk_len: i64 = 0
77 var cur: i64 = 0
78 while cur < n {
79 let le: i64 = cr_eol(tab, n, cur)
80 var ok_line: i64 = 1
81 if le <= cur { ok_line = 0 }
82 if ok_line == 1 { if (tab[cur] as i64) == 35 { ok_line = 0 } }
83 if ok_line == 1 {
84 let nf: i64 = cr_split(tab, cur, le, offs, lens, 8)
85 if nf >= 3 {
86 var pri: i64 = 0 - 1
87 if cr_host_eq_ci(tab, offs[0], lens[0], host, hn) == 1 { pri = 2 }
88 if pri < 0 { if cr_wild_match(host, hn, tab, offs[0], lens[0]) == 1 { pri = 1 } }
89 if pri < 0 { if cr_tok_eq_ci(tab, offs[0], lens[0], "*" as *u8) == 1 { pri = 0 } }
90 if pri > best_pri {
91 best_pri = pri
92 bc_off = offs[1]; bc_len = lens[1]
93 bk_off = offs[2]; bk_len = lens[2]
94 }
95 }
96 }
97 cur = le + 1
98 }
99 if best_pri < 0 { return 0 }
100 cr_copyz(chainbuf, tab, bc_off, bc_len)
101 cr_copyz(keybuf, tab, bk_off, bk_len)
102 return 1
103}