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}