code wiki / _hdl_build / nx_email_dns_gate.nx
nx_email_dns_gate.nx source
↩ module page · 123 lines · 5577 B
1// nx_email_dns_gate.nx -- generate the jasonewest.com mail DNS artifacts.
2//
3// Generates a REAL ed25519 DKIM keypair (sovereign csprng + ed25519),
4// emits the DNS zone (nx_dns_zone), VERIFIES the key actually signs+
5// verifies (so the published pubkey will validate this signer), checks
6// the zone structure, and writes two artifacts:
7// knowledge/status/jasonewest_dns_zone.txt <- publish these records
8// knowledge/status/jasonewest_dkim_priv.key <- SECRET: keep to sign outbound
9//
10// Evidence -> knowledge/status/email_dns.log (DNSGATE ... verdict=GREEN)
11// license_tier: ORIGINAL
12import "nx_email_dns.nx"
13import "nx_email_auth.nx"
14import "nx_csprng.nx"
15import "nx_base64.nx"
16import "nx_syscalls.nx"
17import "nx_gate_verdict.nx"
18
19const DNS_LOG: *u8 = "knowledge/status/email_dns.log"
20
21func ew(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
22func epf(fd: i64, label: *u8, pass: i64) -> i64 { ew(fd, label); if pass == 1 { ew(fd, "PASS" as *u8) } else { ew(fd, "FAIL" as *u8) } return 0 }
23func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
24func contains(hay: *u8, hlen: i64, needle: *u8) -> i64 {
25 let nl: i64 = slen(needle); var i: i64 = 0
26 while i + nl <= hlen {
27 var k: i64 = 0; var hit: i64 = 1
28 while k < nl { if (hay[i + k] & 0xff) != (needle[k] & 0xff) { hit = 0; k = nl } else { k = k + 1 } }
29 if hit == 1 { return 1 }
30 i = i + 1
31 }
32 return 0
33}
34func writefile(path: *u8, buf: *u8, n: i64) -> i64 {
35 let fd: i64 = sys_openat_wr(path, 420)
36 if fd < 0 { return 0 - 1 }
37 var w: i64 = 0
38 while w < n { let k: i64 = sys_write(fd, (buf as i64 + w) as *u8, n - w); if k <= 0 { w = n } else { w = w + k } }
39 sys_close(fd)
40 return 0
41}
42func hexbyte(out: *u8, oi: i64, b: i64) -> i64 {
43 let hi: i64 = (b >> 4) & 0xf; let lo: i64 = b & 0xf
44 if hi < 10 { out[oi] = (48 + hi) as u8 } else { out[oi] = (97 + hi - 10) as u8 }
45 if lo < 10 { out[oi + 1] = (48 + lo) as u8 } else { out[oi + 1] = (97 + lo - 10) as u8 }
46 return oi + 2
47}
48
49func main() -> i64 {
50 var ok: i64 = 1
51
52 // 1. real ed25519 DKIM keypair
53 let priv: *u8 = sys_mmap(32)
54 nx_csprng_fill(priv, 32)
55 let pub: *u8 = sys_mmap(32)
56 ed25519_pub_from_priv(priv, pub)
57 let pub_b64: *u8 = sys_mmap(128)
58 let bl: i64 = b64_encode(pub, 32, pub_b64)
59 pub_b64[bl] = 0 as u8
60
61 // 2. emit zone
62 let zone: *u8 = sys_mmap(4096)
63 let zlen: i64 = nx_dns_zone("jasonewest.com" as *u8, "mail.jasonewest.com" as *u8, "203.0.113.10" as *u8, "nishi1" as *u8, pub_b64, zone, 4096)
64 zone[zlen] = 0 as u8
65
66 // 3. verify the DKIM key round-trips (the published pubkey validates this signer)
67 let sig: *u8 = sys_mmap(64)
68 ed25519_sign_full(priv, "dkim-test" as *u8, 9, sig)
69 var dkim_rt: i64 = 0
70 if ed25519_verify_full(pub, "dkim-test" as *u8, 9, sig) == 1 { dkim_rt = 1 } else { ok = 0 }
71
72 // 4. zone structure checks
73 var z_mx: i64 = contains(zone, zlen, "MX\t10 mail.jasonewest.com" as *u8)
74 var z_dkim: i64 = contains(zone, zlen, "v=DKIM1; k=ed25519; p=" as *u8)
75 var z_spf: i64 = contains(zone, zlen, "v=spf1 a:mail.jasonewest.com -all" as *u8)
76 var z_dmarc: i64 = contains(zone, zlen, "v=DMARC1; p=quarantine" as *u8)
77 var z_sel: i64 = contains(zone, zlen, "nishi1._domainkey.jasonewest.com" as *u8)
78 if z_mx != 1 || z_dkim != 1 || z_spf != 1 || z_dmarc != 1 || z_sel != 1 { ok = 0 }
79
80 // 5. write artifacts
81 writefile("knowledge/status/jasonewest_dns_zone.txt" as *u8, zone, zlen)
82 let keyf: *u8 = sys_mmap(256)
83 var ko: i64 = 0
84 ko = 0
85 let hdr: *u8 = "# SECRET ed25519 DKIM private key for nishi1._domainkey.jasonewest.com -- keep offline.\n# hex(32):\n" as *u8
86 var hk: i64 = 0
87 while hdr[hk] != (0 as u8) { keyf[ko] = hdr[hk]; ko = ko + 1; hk = hk + 1 }
88 var bi: i64 = 0
89 while bi < 32 { ko = hexbyte(keyf, ko, priv[bi] & 0xff); bi = bi + 1 }
90 keyf[ko] = 10 as u8; ko = ko + 1
91 writefile("knowledge/status/jasonewest_dkim_priv.key" as *u8, keyf, ko)
92 var artifacts: i64 = 1
93
94 // 6. emit marker + the zone for the operator
95 var fd: i64 = 1
96 while fd >= 1 {
97 ew(fd, "DNSGATE authored=organ domain=jasonewest.com dkim=ed25519 selector=nishi1 " as *u8)
98 epf(fd, "dkim_roundtrip=" as *u8, dkim_rt)
99 epf(fd, " zone_mx=" as *u8, z_mx)
100 epf(fd, " zone_dkim=" as *u8, z_dkim)
101 epf(fd, " zone_spf=" as *u8, z_spf)
102 epf(fd, " zone_dmarc=" as *u8, z_dmarc)
103 epf(fd, " zone_selector=" as *u8, z_sel)
104 epf(fd, " artifacts_written=" as *u8, artifacts)
105 if ok == 1 { ew(fd, " verdict=GREEN\n" as *u8) } else { ew(fd, " verdict=RED\n" as *u8) }
106 if fd == 1 {
107 let lf: i64 = sys_openat_append(DNS_LOG, 420)
108 if lf >= 1 { fd = lf } else { fd = 0 }
109 } else { sys_close(fd); fd = 0 }
110 }
111 ew(1, "\n----- DNS records (knowledge/status/jasonewest_dns_zone.txt) -----\n" as *u8)
112 ew(1, zone)
113
114 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
115 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
116 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
117 let ctr__dry: *i64 = gv_ctr()
118 ctr__dry[0] = ok
119 ctr__dry[1] = 1
120 let rc__dry: i64 = gv_verdict("EMAIL-DNS-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
121 sys_exit(rc__dry)
122 return rc__dry
123}