code wiki / (root) / nx_pem_loader.nx

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}