nx_pem_loader.nx source
↩ module page · 89 lines · 3447 B
1// nx_pem_loader.nx -- load a PEM CA bundle into a TrustStore, bits-up.
2//
3// module: nishi-core.search.pem_loader
4// depends: nx_str, nx_syscalls, nx_base64 (b64_decode), nx_x509 (x509_parse),
5// nx_x509_trust_store (trust_store_add)
6// capability: CORE_IO
7// wired_status: FULLY_WIRED
8//
9// The missing piece for validated live HTTPS: turn the system PEM bundle
10// (/etc/ssl/certs/ca-certificates.crt -- concatenated -----BEGIN CERTIFICATE--
11// blocks) into a populated TrustStore. For each block: strip whitespace from
12// the base64, OUR b64_decode -> DER, OUR x509_parse -> X509Cert, trust_store_add.
13// Every step sovereign (our base64 + our X.509 parser). Pairs with nx_https_get
14// so the crawler can fetch + VALIDATE real HTTPS hosts.
15
16import "nx_str.nx"
17import "nx_syscalls.nx"
18import "nx_base64.nx"
19import "nx_x509.nx"
20import "nx_x509_trust_store.nx"
21
22// index of `needle` in hay[from..haylen), or -1.
23func _pem_find(hay: *u8, haylen: i64, from: i64, needle: *u8) -> i64 {
24 let nl: i64 = nx_str_len(needle)
25 if nl == 0 { return from }
26 var i: i64 = from
27 while i <= haylen - nl {
28 var j: i64 = 0
29 var ok: i64 = 1
30 while j < nl { if (hay[i + j] as i64) != (needle[j] as i64) { ok = 0; j = nl } else { j = j + 1 } }
31 if ok == 1 { return i }
32 i = i + 1
33 }
34 return 0 - 1
35}
36
37// Load every PEM CERTIFICATE block from pem[0..n) into store. Returns the
38// number of roots successfully parsed + added.
39func nx_pem_trust_load(pem: *u8, n: i64, store: *TrustStore) -> i64 {
40 let BEGIN: *u8 = "-----BEGIN CERTIFICATE-----"
41 let END: *u8 = "-----END CERTIFICATE-----"
42 let blen: i64 = nx_str_len(BEGIN)
43 let elen: i64 = nx_str_len(END)
44 var added: i64 = 0
45 var i: i64 = 0
46 var run: i64 = 1
47 while run == 1 {
48 run = 0
49 let bs: i64 = _pem_find(pem, n, i, BEGIN)
50 if bs >= 0 {
51 let b64s: i64 = bs + blen
52 let be: i64 = _pem_find(pem, n, b64s, END)
53 if be >= 0 {
54 // collect the base64 body, stripping CR/LF/space/tab
55 let clean: *u8 = sys_mmap(be - b64s + 8)
56 var cn: i64 = 0
57 var p: i64 = b64s
58 while p < be {
59 let c: i64 = pem[p] as i64
60 if c != 0x0A { if c != 0x0D { if c != 0x20 { if c != 0x09 { clean[cn] = c; cn = cn + 1 } } } }
61 p = p + 1
62 }
63 if cn > 0 {
64 let der: *u8 = sys_mmap(cn)
65 let derlen: i64 = b64_decode(clean, cn, der)
66 if derlen > 0 {
67 let cert: *u8 = sys_mmap(256)
68 let cc: *X509Cert = cert as *X509Cert
69 if x509_parse(der, derlen, cc) >= 0 {
70 if trust_store_add(store, der, cc) == NX_TRUST_STORE_OK { added = added + 1 }
71 }
72 }
73 }
74 i = be + elen
75 run = 1
76 }
77 }
78 }
79 return added
80}
81
82// Convenience: read a PEM bundle file from disk and load it into store.
83// Returns roots added, or -1 if the file could not be read.
84func nx_pem_trust_load_file(path: *u8, store: *TrustStore) -> i64 {
85 let lenbox: *i64 = sys_mmap(8) as *i64
86 let buf: *u8 = sys_read_file(path, lenbox)
87 if buf == 0 as *u8 { return 0 - 1 }
88 return nx_pem_trust_load(buf, lenbox[0], store)
89}