code wiki / (root) / nx_tls13_server_full_handshake_test.nx

nx_tls13_server_full_handshake_test.nx source

↩ module page · 225 lines · 9084 B

1// nx_tls13_server_full_handshake_test.nx -- end-to-end integration 2// smoke composing ALL 10 TLS server stones in ONE authenticated 3// handshake. Proves the substrate's complete TLS 1.3 server-side 4// pipeline works in pure NishiLang. 5// 6// The 10-stone authenticated flow: 7// 8// client ClientHello bytes 9// -> [stone 2] recv_ch state INIT -> CH_RECEIVED 10// [stone 3] emit_sh -> SH_SENT 11// [stone 4] derive_hs_secrets -> EE_SENT (placeholder) 12// [stone 5] derive_traffic (no state change) 13// [stone 6] emit_ee -> CERT_SENT 14// [stone 6.5] emit_certificate (state stays CERT_SENT) 15// [stone 7.5] emit_cv -> CV_SENT 16// [stone 7] emit_sf -> SF_SENT 17// <- client Finished bytes (constructed using shared keys) 18// [stone 8] recv_cf + derive_app -> CONNECTED 19// 20// Asserts at every step: 21// - State transition correct 22// - server_seq / client_seq tracking correct 23// - Each emit returns positive byte count + 0x17 (app_data) header 24// - Final state CONNECTED + master_secret + 6 app-traffic buffers 25// 26// expect_exit: 0 27// license_tier: ORIGINAL 28 29import "nx_syscalls.nx" 30import "nx_x25519.nx" 31import "nx_x25519_ephemeral.nx" 32import "nx_hmac.nx" 33import "nx_tls13.nx" 34import "nx_tls13_hello.nx" 35import "nx_tls13_kdf.nx" 36import "nx_tls13_record.nx" 37import "nx_tls13_transcript.nx" 38import "nx_tls13_server_session.nx" 39import "nx_tls13_server_session_recv_ch.nx" 40import "nx_tls13_server_session_emit_sh.nx" 41import "nx_tls13_server_session_derive_hs.nx" 42import "nx_tls13_server_session_derive_traffic.nx" 43import "nx_tls13_server_session_emit_ee.nx" 44import "nx_tls13_server_session_emit_certificate.nx" 45import "nx_tls13_server_session_emit_cv.nx" 46import "nx_tls13_server_session_emit_sf.nx" 47import "nx_tls13_server_session_recv_cf.nx" 48 49// Helper from recv_cf_test pattern: build client Finished record 50// using the shared c_hs_traffic_key + iv + transcript. 51func build_client_finished( 52 cli_hs_key: *u8, cli_hs_iv: *u8, cli_seq: i64, 53 verify_data: *u8, 54 out: *u8, out_cap: i64 55) -> i64 { 56 let inner_len: i64 = 36 57 let inner: *u8 = sys_mmap(inner_len) 58 inner[0] = HT_FINISHED & 0xff 59 inner[1] = 0 60 inner[2] = 0 61 inner[3] = 32 62 var i: i64 = 0 63 while i < 32 { inner[4 + i] = verify_data[i]; i = i + 1 } 64 let header: *u8 = sys_mmap(5) 65 let ct: *u8 = sys_mmap(inner_len + 17) 66 let tag: *u8 = sys_mmap(16) 67 let rv: i64 = nx_tls13_record_encrypt( 68 cli_hs_key, cli_hs_iv, cli_seq, 69 inner, inner_len, 70 CT_HANDSHAKE, 0, 71 header, ct, tag) 72 if rv != NX_TLS13_REC_VERDICT_OK { return -1 } 73 let total: i64 = 5 + inner_len + 1 + 16 74 if total > out_cap { return -1 } 75 var w: i64 = 0 76 var hi: i64 = 0 77 while hi < 5 { out[w + hi] = header[hi]; hi = hi + 1 } 78 w = w + 5 79 var ci: i64 = 0 80 while ci < inner_len + 1 { out[w + ci] = ct[ci]; ci = ci + 1 } 81 w = w + inner_len + 1 82 var ti: i64 = 0 83 while ti < 16 { out[w + ti] = tag[ti]; ti = ti + 1 } 84 return w + 16 85} 86 87func main() -> i64 { 88 // ========== CLIENT SETUP ========== 89 let cli_priv: *u8 = sys_mmap(32) 90 let cli_pub: *u8 = sys_mmap(32) 91 let cli_rand: *u8 = sys_mmap(32) 92 var i: i64 = 0 93 while i < 32 { 94 cli_priv[i] = ((i + 17) & 0xff) as u8 95 cli_rand[i] = ((i + 50) & 0xff) as u8 96 i = i + 1 97 } 98 x25519_keypair_public(cli_priv, cli_pub) 99 100 let ch_buf: *u8 = sys_mmap(1024) 101 let ch_n: i64 = tls13_client_hello_emit( 102 cli_rand, "nishifamily.com", 15, cli_pub, ch_buf, 1024) 103 if ch_n <= 0 { return 5 } 104 105 // ========== SERVER SETUP ========== 106 let srv_priv: *u8 = sys_mmap(32) 107 let srv_rand: *u8 = sys_mmap(32) 108 let srv_ecdsa: *u8 = sys_mmap(32) 109 var k: i64 = 0 110 while k < 32 { 111 srv_priv[k] = ((k + 80) & 0xff) as u8 112 srv_rand[k] = ((k + 70) & 0xff) as u8 113 srv_ecdsa[k] = ((k + 100) & 0xff) as u8 114 k = k + 1 115 } 116 let s: *Tls13ServerSession = nx_tls13_server_session_new(srv_rand, srv_priv) 117 if (s as i64) == 0 { return 10 } 118 if s.state != NX_TLS13_SSTATE_INIT { return 11 } 119 120 // ========== STONE 2: recv_ch ========== 121 let r2: i64 = nx_tls13_server_session_recv_ch(s, ch_buf, ch_n) 122 if r2 != NX_TLS13_SSESSION_OK { return 20 } 123 if s.state != NX_TLS13_SSTATE_CH_RECEIVED { return 21 } 124 if (s.client_x25519_pub as i64) == 0 { return 22 } 125 126 // ========== STONE 3: emit_sh ========== 127 let sh_buf: *u8 = sys_mmap(512) 128 let n_sh: i64 = nx_tls13_server_session_emit_sh(s, sh_buf, 512) 129 if n_sh <= 0 { return 30 } 130 if s.state != NX_TLS13_SSTATE_SH_SENT { return 31 } 131 // STALE-TEST HEAL 2026-06-10: emit_sh writes record header (5B) 132 // then body; HT_SERVER_HELLO is at offset 5, record type 22 at 0. 133 if sh_buf[0] != (22 as u8) { return 33 } // record: Handshake 134 if sh_buf[5] != 0x02 { return 32 } // HT_SERVER_HELLO 135 136 // ========== STONE 4: derive_hs_secrets ========== 137 let r4: i64 = nx_tls13_server_session_derive_hs_secrets(s) 138 if r4 != NX_TLS13_SSESSION_OK { return 40 } 139 if s.state != NX_TLS13_SSTATE_EE_SENT { return 41 } 140 if (s.handshake_secret as i64) == 0 { return 42 } 141 142 // ========== STONE 5: derive_traffic ========== 143 let r5: i64 = nx_tls13_server_session_derive_traffic(s) 144 if r5 != NX_TLS13_SSESSION_OK { return 50 } 145 if (s.client_hs_traffic_secret as i64) == 0 { return 51 } 146 if (s.server_hs_traffic_secret as i64) == 0 { return 52 } 147 if (s.client_hs_traffic_key as i64) == 0 { return 53 } 148 if (s.server_hs_traffic_key as i64) == 0 { return 54 } 149 if (s.client_hs_iv as i64) == 0 { return 55 } 150 if (s.server_hs_iv as i64) == 0 { return 56 } 151 152 // ========== STONE 6: emit_ee ========== 153 let ee_buf: *u8 = sys_mmap(256) 154 let n_ee: i64 = nx_tls13_server_session_emit_ee(s, ee_buf, 256) 155 if n_ee <= 0 { return 60 } 156 if s.state != NX_TLS13_SSTATE_CERT_SENT { return 61 } 157 if ee_buf[0] != 0x17 { return 62 } 158 if s.server_seq != 1 { return 63 } 159 160 // ========== STONE 6.5: emit_certificate ========== 161 let fake_cert: *u8 = sys_mmap(96) 162 var ci: i64 = 0 163 while ci < 96 { 164 fake_cert[ci] = ((ci + 50) & 0xff) as u8 165 ci = ci + 1 166 } 167 let cert_buf: *u8 = sys_mmap(512) 168 let n_cert: i64 = nx_tls13_server_session_emit_certificate(s, fake_cert, 96, cert_buf, 512) 169 if n_cert <= 0 { return 65 } 170 if s.state != NX_TLS13_SSTATE_CERT_SENT { return 66 } // unchanged 171 if cert_buf[0] != 0x17 { return 67 } 172 if s.server_seq != 2 { return 68 } 173 174 // ========== STONE 7.5: emit_cv ========== 175 let cv_buf: *u8 = sys_mmap(512) 176 let n_cv: i64 = nx_tls13_server_session_emit_cv(s, srv_ecdsa, cv_buf, 512) 177 if n_cv <= 0 { return 70 } 178 if s.state != NX_TLS13_SSTATE_CV_SENT { return 71 } 179 if cv_buf[0] != 0x17 { return 72 } 180 if s.server_seq != 3 { return 73 } 181 182 // ========== STONE 7: emit_sf ========== 183 let sf_buf: *u8 = sys_mmap(256) 184 let n_sf: i64 = nx_tls13_server_session_emit_sf(s, sf_buf, 256) 185 if n_sf <= 0 { return 80 } 186 if s.state != NX_TLS13_SSTATE_SF_SENT { return 81 } 187 if sf_buf[0] != 0x17 { return 82 } 188 if s.server_seq != 4 { return 83 } 189 190 // ========== CONSTRUCT CLIENT FINISHED ========== 191 let finished_label: *u8 = "finished" 192 let empty: *u8 = sys_mmap(1) 193 let finished_key_c: *u8 = sys_mmap(32) 194 tls13_hkdf_expand_label( 195 s.client_hs_traffic_secret, 196 finished_label, 8, empty, 0, 197 32, finished_key_c) 198 let th: *u8 = sys_mmap(32) 199 nx_tls13_transcript_snapshot(s.transcript, th) 200 let verify_data: *u8 = sys_mmap(32) 201 hmac_sha256(finished_key_c, 32, th, 32, verify_data) 202 203 let cf_rec: *u8 = sys_mmap(256) 204 let n_cf: i64 = build_client_finished( 205 s.client_hs_traffic_key, s.client_hs_iv, s.client_seq, 206 verify_data, cf_rec, 256) 207 if n_cf <= 0 { return 90 } 208 209 // ========== STONE 8: recv_cf + derive_app ========== 210 let r8: i64 = nx_tls13_server_session_recv_cf(s, cf_rec, n_cf) 211 if r8 != NX_TLS13_SSESSION_OK { return 100 } 212 if s.state != NX_TLS13_SSTATE_CONNECTED { return 101 } 213 if s.client_seq != 1 { return 102 } 214 215 // App keys derived 216 if (s.master_secret as i64) == 0 { return 110 } 217 if (s.client_app_traffic_secret as i64) == 0 { return 111 } 218 if (s.server_app_traffic_secret as i64) == 0 { return 112 } 219 if (s.client_app_traffic_key as i64) == 0 { return 113 } 220 if (s.server_app_traffic_key as i64) == 0 { return 114 } 221 if (s.client_app_iv as i64) == 0 { return 115 } 222 if (s.server_app_iv as i64) == 0 { return 116 } 223 224 return 0 225}