nx_cert_monitor_gate.nx source
↩ module page · 56 lines · 3377 B
1// nx_cert_monitor_gate.nx -- KAT for the cert-expiry monitor. Hand-builds a validity field (two UTCTime
2// TLVs), extracts notAfter via the REUSED x509_validity_get (epoch seconds), and asserts the days-until +
3// verdict across OK / WARN(expiring) / EXPIRED. exit 0 = pass, N = assertion N failed.
4import "nx_cert_monitor.nx"
5import "nx_assert.nx"
6
7// write a UTCTime TLV at off: tag 0x17, len 0x0D (13), value "YYMMDDhhmmssZ". returns next offset.
8func g_time(buf: *u8, off: i64, s: *u8) -> i64 {
9 buf[off] = 0x17 as u8; buf[off+1] = 0x0D as u8
10 var i: i64 = 0; while i < 13 { buf[off+2+i] = s[i]; i = i + 1 }
11 return off + 15
12}
13
14func main() -> i64 {
15 // validity body = notBefore(UTCTime) + notAfter(UTCTime)
16 let v: *u8 = sys_mmap(64); var p: i64 = 0
17 p = g_time(v, p, "200101000000Z" as *u8) // notBefore 2020-01-01
18 p = g_time(v, p, "260914120000Z" as *u8) // notAfter 2026-09-14 12:00:00Z
19 let vlen: i64 = p
20 let cert: *X509Cert = sys_mmap(1024) as *X509Cert
21 cert.validity_off = 0; cert.validity_len = vlen
22
23 let nb: *i64 = sys_mmap(16) as *i64; let na: *i64 = sys_mmap(16) as *i64
24 let rc: i64 = x509_validity_get(v, cert, nb, na)
25 nx_puts_err("validity_get rc="); nx_puti_err(rc)
26 nx_puts_err("notAfter_epoch="); nx_puti_err(na[0])
27 if rc != NX_X509_VALID_OK { return 1 } // NX_X509_VALID_OK == 1 (sealed enum, NOT 0)
28 if na[0] <= 0 { return 2 }
29
30 // verdict KAT: fixed notAfter, varied "now"
31 let now50: i64 = na[0] - 50 * 86400 // 50 days before expiry
32 let now10: i64 = na[0] - 10 * 86400 // 10 days before expiry (< 21d warn window)
33 let nowpast: i64 = na[0] + 2 * 86400 // 2 days AFTER expiry
34 nx_puts_err("days_until(now=na-50d)="); nx_puti_err(cm_days_until(na[0], now50))
35 if cm_verdict(na[0], now50, 21) != CM_OK { return 3 }
36 if cm_verdict(na[0], now10, 21) != CM_WARN { return 4 }
37 if cm_verdict(na[0], nowpast, 21) != CM_EXPIRED { return 5 }
38
39 // --- REAL-CERT KAT (verification doctrine: prove x509_parse on a REAL cert vs the openssl oracle, not
40 // just synthetic validity). Fixture = a real LE leaf pulled from the NAS; openssl says notAfter =
41 // Aug 26 2026 15:35:00 UTC = epoch 1787758500. cm_status exercises the FULL path (x509_parse +
42 // x509_validity_get) the synthetic KAT skipped. Graceful if the fixture is absent. ---
43 let rd: *i64 = sys_mmap(16) as *i64; let rna: *i64 = sys_mmap(16) as *i64
44 let rv: i64 = cm_status("/mnt/c/Users/elder/nishi-core/nxc2/knowledge/status/real_leaf.der" as *u8, rd, rna)
45 if rv == CM_NOCERT {
46 nx_puts_err("real-cert fixture absent -> real-cert KAT SKIPPED (synthetic KATs still enforced)\n" as *u8)
47 } else {
48 nx_puts_err("real-cert x509_parse notAfter_epoch="); nx_puti_err(rna[0]); nx_puts_err(" (openssl oracle Aug26 2026 = 1787758500)\n" as *u8)
49 if rna[0] != 1787758500 { return 6 } // x509_parse on a REAL cert MUST match openssl to-the-second
50 }
51
52 nx_puts_err("--- vs best-in-class (cPanel/CyberPanel/RunCloud auto-renew + expiry alert) ---\n" as *u8)
53 nx_puts_err("expiry alert before the outage: best-in-class fires a WARN+renew ; Nishi was SILENT (no alert) -> now WARN at <21d = gap CLOSED (PARITY)\n" as *u8)
54 nx_puts_err("nx_cert_monitor_gate verdict=GREEN pass=6 (incl REAL-cert parse vs openssl oracle)\n" as *u8)
55 return 0
56}