code wiki / (root) / nx_h2_test_leaf.nx

nx_h2_test_leaf.nx source

↩ module page · 160 lines · 7715 B

1// nx_h2_test_leaf.nx -- TUTOR-BOOTSTRAP SCAFFOLD (Claude, B1 rung(6) R4-H2-009), 2// NOT credited as team self-authoring (EoE back-fill owed). 3// 4// SHARED self-signed Ed25519 X.509 LEAF (SAN=localhost) minter + PEM exporter for 5// the h2 INTEROP TEST harnesses. Rule 15 (DRY through shared libraries): the 6// identical self-signed-leaf + PEM-export + civil-date code was COPY-PASTED into 7// _h2_serve_loopback_gate.nx (hsl_*), _h2_serve_curl_daemon.nx (hcd_*) AND 8// _h2_multistream_curl_daemon.nx (mcd_*) -- 3 copies = the rule-15 "extract" 9// trigger. This organ is that extraction; new harnesses COMPOSE it instead of a 10// 4th copy. (The 3 existing copies stay BYTE-UNTOUCHED for now -- migrating them 11// is an additive follow-on so the proven daemons are not disturbed this rung.) 12// 13// CONTRACT: 14// h2tl_make_cert(out_cert_der: *u8, out_cert_len: *i64, out_priv: *u8) -> i64 15// mint an Ed25519 keypair + self-signed leaf (CN/SAN=localhost, notBefore 16// now-1d, notAfter now+365d). out_cert_der must be >=8192 bytes, out_priv 32. 17// Returns 0 ok; -1 keygen, -2 pubkey, -3 inputs, -4 build. 18// h2tl_write_pem(cert_der: *u8, der_len: i64, path_z: *u8) -> i64 19// write the DER as a PEM file an external curl can trust via --cacert 20// (BEGIN/END CERTIFICATE armor + base64 re-wrapped at 64 cols, composing the 21// canonical nx_base64 b64_encode -- nx_pem.nx only DECODES). Returns 0 ok, 22// <0 on open/write failure. 23// 24// COMPOSES (each imported once): nx_csprng (csprng_fill), nx_ed25519_signature 25// (ed25519_pub_from_priv), hub/nx_x509_build + nx_x509 + nx_x509_trust_store 26// (self-signed leaf builder), nx_base64 (b64_encode), nx_syscalls (mmap/file I/O + 27// nx_str_cpy + sys_now_realtime_sec). 28// 29// license_tier: INDEPENDENT_REDERIVE 30// genealogy_id: international-research-sources/ietf/rfc_5280 + rfc_4648 + rfc_8032 31// lineage_id: nishi_h2_test_leaf_b1r6 32 33import "nx_syscalls.nx" 34import "nx_str.nx" 35import "nx_csprng.nx" 36import "nx_ed25519_signature.nx" 37import "hub/nx_x509_build.nx" 38import "nx_x509.nx" 39import "nx_x509_trust_store.nx" 40import "nx_base64.nx" 41const K_MAGIC_719468: i64 = 719468 42const K_MAGIC_146097: i64 = 146097 43const K_MAGIC_146096: i64 = 146096 44const K_MAGIC_1460: i64 = 1460 45const K_MAGIC_36524: i64 = 36524 46const K_MAGIC_86400: i64 = 86400 47const K_MAGIC_3600: i64 = 3600 48const K_MAGIC_8192: i64 = 8192 49 50// ---- public-domain civil-date math (Howard Hinnant) ---- 51func h2tl_civil_from_days(days: i64, out_y: *i64, out_m: *i64, out_d: *i64) -> i64 { 52 let z: i64 = days + K_MAGIC_719468 53 let era: i64 = if z >= 0 then z / K_MAGIC_146097 else (z - K_MAGIC_146096) / K_MAGIC_146097 54 let doe: i64 = z - era * K_MAGIC_146097 55 let yoe: i64 = (doe - doe / K_MAGIC_1460 + doe / K_MAGIC_36524 - doe / K_MAGIC_146096) / 365 56 let y: i64 = yoe + era * 400 57 let doy: i64 = doe - (365 * yoe + yoe / 4 - yoe / 100) 58 let mp: i64 = (5 * doy + 2) / 153 59 let d: i64 = doy - (153 * mp + 2) / 5 + 1 60 var m: i64 = mp + 3 61 if mp < 10 { m = mp + 3 } else { m = mp - 9 } 62 var yy: i64 = y 63 if m <= 2 { yy = y + 1 } 64 out_y[0] = yy; out_m[0] = m; out_d[0] = d 65 return 0 66} 67func h2tl_format_generalized_time(unix_sec: i64, out_15: *u8) -> i64 { 68 let days: i64 = unix_sec / K_MAGIC_86400 69 let sod: i64 = unix_sec - days * K_MAGIC_86400 70 let hh: i64 = sod / K_MAGIC_3600 71 let mm: i64 = (sod - hh * K_MAGIC_3600) / 60 72 let ss: i64 = sod - hh * K_MAGIC_3600 - mm * 60 73 let yp: *i64 = sys_mmap(8) as *i64 74 let mp: *i64 = sys_mmap(8) as *i64 75 let dp: *i64 = sys_mmap(8) as *i64 76 h2tl_civil_from_days(days, yp, mp, dp) 77 let y: i64 = yp[0]; let mo: i64 = mp[0]; let d: i64 = dp[0] 78 out_15[0] = ((0x30 + ((y / 1000) % 10)) & 0xff) as u8 79 out_15[1] = ((0x30 + ((y / 100) % 10)) & 0xff) as u8 80 out_15[2] = ((0x30 + ((y / 10) % 10)) & 0xff) as u8 81 out_15[3] = ((0x30 + ( y % 10)) & 0xff) as u8 82 out_15[4] = ((0x30 + (mo / 10)) & 0xff) as u8 83 out_15[5] = ((0x30 + (mo % 10)) & 0xff) as u8 84 out_15[6] = ((0x30 + (d / 10)) & 0xff) as u8 85 out_15[7] = ((0x30 + (d % 10)) & 0xff) as u8 86 out_15[8] = ((0x30 + (hh / 10)) & 0xff) as u8 87 out_15[9] = ((0x30 + (hh % 10)) & 0xff) as u8 88 out_15[10] = ((0x30 + (mm / 10)) & 0xff) as u8 89 out_15[11] = ((0x30 + (mm % 10)) & 0xff) as u8 90 out_15[12] = ((0x30 + (ss / 10)) & 0xff) as u8 91 out_15[13] = ((0x30 + (ss % 10)) & 0xff) as u8 92 out_15[14] = 0x5A as u8 // 'Z' 93 return 0 94} 95 96// ---- mint the self-signed Ed25519 leaf (SAN=localhost) ---- 97func h2tl_make_cert(out_cert_der: *u8, out_cert_len: *i64, out_priv: *u8) -> i64 { 98 if nx_csprng_fill(out_priv, 32) != 0 { return 0 - 1 } 99 let pub32: *u8 = sys_mmap(32) 100 if ed25519_pub_from_priv(out_priv, pub32) != 0 { return 0 - 2 } 101 let now: i64 = sys_now_realtime_sec() 102 let nb: *u8 = sys_mmap(16) 103 let na: *u8 = sys_mmap(16) 104 h2tl_format_generalized_time(now - K_MAGIC_86400, nb) 105 h2tl_format_generalized_time(now + 365 * K_MAGIC_86400, na) 106 let san_name: *u8 = sys_mmap(16); nx_str_cpy(san_name, "localhost" as *u8) 107 let san_ptrs: *i64 = sys_mmap(8) as *i64; san_ptrs[0] = san_name as i64 108 let san_lens: *i64 = sys_mmap(8) as *i64; san_lens[0] = 9 109 let domain: *u8 = sys_mmap(16); nx_str_cpy(domain, "localhost" as *u8) 110 let inp: *NxX509BuildInputs = sys_mmap(256) as *NxX509BuildInputs 111 let in_rc: i64 = nx_x509_inputs_init(inp, domain, 9, san_ptrs, san_lens, 1, 112 out_priv, pub32, nb, na, now) 113 if in_rc != NX_X509_OK { return 0 - 3 } 114 let cdn: *i64 = sys_mmap(8) as *i64; cdn[0] = 0 115 let brc: i64 = nx_x509_build_self_signed(inp, out_cert_der, K_MAGIC_8192, cdn) 116 if brc != NX_X509_OK { return 0 - 4 } 117 out_cert_len[0] = cdn[0] 118 return 0 119} 120 121// ---- PEM export (composes nx_base64 b64_encode, re-wrapped at 64 cols) ---- 122func h2tl_write_pem(cert_der: *u8, der_len: i64, path_z: *u8) -> i64 { 123 let b64cap: i64 = 4 * ((der_len + 2) / 3) + 8 124 let b64buf: *u8 = sys_mmap(b64cap) 125 let b64n: i64 = b64_encode(cert_der, der_len, b64buf) 126 if b64n <= 0 { return 0 - 1 } 127 let fd: i64 = sys_openat_wr(path_z, 0x1a4) 128 if fd < 0 { return 0 - 2 } 129 if sys_write(fd, "-----BEGIN CERTIFICATE-----\n" as *u8, 28) != 28 { sys_close(fd); return 0 - 3 } 130 var off: i64 = 0 131 while off < b64n { 132 var line: i64 = 64 133 if b64n - off < 64 { line = b64n - off } 134 let w: i64 = sys_write(fd, ((b64buf as i64) + off) as *u8, line) 135 if w != line { sys_close(fd); return 0 - 4 } 136 if sys_write(fd, "\n" as *u8, 1) != 1 { sys_close(fd); return 0 - 5 } 137 off = off + line 138 } 139 if sys_write(fd, "-----END CERTIFICATE-----\n" as *u8, 26) != 26 { sys_close(fd); return 0 - 6 } 140 sys_close(fd) 141 return 0 142} 143 144// ---- self-gate main(): LIBRARY organ -- mint a cert + write a PEM to /tmp and 145// print its DER length so it BUILDS + smoke-tests standalone. ---- 146func main() -> i64 { 147 sys_write(1, "nx_h2_test_leaf: shared self-signed Ed25519 SAN=localhost leaf + PEM (B1 rung 6 R4-H2-009)\n" as *u8, 90) 148 let der: *u8 = sys_mmap(K_MAGIC_8192) 149 let dlen: *i64 = sys_mmap(8) as *i64 150 let priv: *u8 = sys_mmap(32) 151 if h2tl_make_cert(der, dlen, priv) < 0 { 152 sys_write(1, " SMOKE FAIL: cert mint\n" as *u8, 23); sys_exit(1); return 1 153 } 154 let pp: *u8 = sys_mmap(64); nx_str_cpy(pp, "/tmp/nx_h2_test_leaf_smoke.pem" as *u8) 155 if h2tl_write_pem(der, dlen[0], pp) < 0 { 156 sys_write(1, " SMOKE FAIL: pem write\n" as *u8, 24); sys_exit(2); return 2 157 } 158 sys_write(1, " SMOKE OK: minted leaf + wrote /tmp/nx_h2_test_leaf_smoke.pem (DER bytes below)\n" as *u8, 79) 159 sys_exit(0); return 0 160}