code wiki / (root) / nx_tls13_client_test.nx

nx_tls13_client_test.nx source

↩ module page · 231 lines · 9518 B

1// nx_tls13_client_test.nx -- in-memory end-to-end handshake dispatch. 2// 3// Synthesises an entire server-handshake message stream 4// (EncryptedExtensions + Certificate + CertificateVerify + server 5// Finished) and walks it through the state machine. Uses the 6// shipped handshake-key orchestrator (RFC 8448 §3 inputs) to derive 7// real AEAD keys + finished_keys, so the server_Finished MAC is 8// computed correctly and the dispatcher must accept it. 9// 10// Then runs: 11// - tampered SF MAC -> SF_BAD_MAC verdict 12// - wrong message type at each state -> BAD_MSG_TYPE verdict 13// - client_Finished structure + emit 14// - record-layer encrypt/decrypt round-trip on our emitted bytes 15// 16// expect_exit: 0 17// license_tier: ORIGINAL 18 19import "nx_syscalls.nx" 20import "nx_tls13.nx" 21import "nx_tls13_record.nx" 22import "nx_tls13_finished.nx" 23import "nx_tls13_transcript.nx" 24import "nx_tls13_handshake.nx" 25import "nx_tls13_client.nx" 26 27func main() -> i64 { 28 // ---- Set up RFC 8448 §3 keys via the orchestrator ---- 29 let cpriv: *u8 = sys_mmap(64) 30 cpriv[0]=0x49; cpriv[1]=0xaf; cpriv[2]=0x42; cpriv[3]=0xba 31 cpriv[4]=0x7f; cpriv[5]=0x99; cpriv[6]=0x94; cpriv[7]=0x85 32 cpriv[8]=0x2d; cpriv[9]=0x71; cpriv[10]=0x3e; cpriv[11]=0xf2 33 cpriv[12]=0x78; cpriv[13]=0x4b; cpriv[14]=0xcb; cpriv[15]=0xca 34 cpriv[16]=0xa7; cpriv[17]=0x91; cpriv[18]=0x1d; cpriv[19]=0xe2 35 cpriv[20]=0x6a; cpriv[21]=0xdc; cpriv[22]=0x56; cpriv[23]=0x42 36 cpriv[24]=0xcb; cpriv[25]=0x63; cpriv[26]=0x45; cpriv[27]=0x40 37 cpriv[28]=0xe7; cpriv[29]=0xea; cpriv[30]=0x50; cpriv[31]=0x05 38 39 let spub: *u8 = sys_mmap(64) 40 spub[0]=0xc9; spub[1]=0x82; spub[2]=0x88; spub[3]=0x76 41 spub[4]=0x11; spub[5]=0x20; spub[6]=0x95; spub[7]=0xfe 42 spub[8]=0x66; spub[9]=0x76; spub[10]=0x2b; spub[11]=0xdb 43 spub[12]=0xf7; spub[13]=0xc6; spub[14]=0x72; spub[15]=0xe1 44 spub[16]=0x56; spub[17]=0xd6; spub[18]=0xcc; spub[19]=0x25 45 spub[20]=0x3b; spub[21]=0x83; spub[22]=0x3d; spub[23]=0xf1 46 spub[24]=0xdd; spub[25]=0x69; spub[26]=0xb1; spub[27]=0xb0 47 spub[28]=0x4e; spub[29]=0x75; spub[30]=0x1f; spub[31]=0x0f 48 49 let empty_hash: *u8 = sys_mmap(64) 50 empty_hash[0]=0xe3; empty_hash[1]=0xb0; empty_hash[2]=0xc4; empty_hash[3]=0x42 51 empty_hash[4]=0x98; empty_hash[5]=0xfc; empty_hash[6]=0x1c; empty_hash[7]=0x14 52 empty_hash[8]=0x9a; empty_hash[9]=0xfb; empty_hash[10]=0xf4; empty_hash[11]=0xc8 53 empty_hash[12]=0x99; empty_hash[13]=0x6f; empty_hash[14]=0xb9; empty_hash[15]=0x24 54 empty_hash[16]=0x27; empty_hash[17]=0xae; empty_hash[18]=0x41; empty_hash[19]=0xe4 55 empty_hash[20]=0x64; empty_hash[21]=0x9b; empty_hash[22]=0x93; empty_hash[23]=0x4c 56 empty_hash[24]=0xa4; empty_hash[25]=0x95; empty_hash[26]=0x99; empty_hash[27]=0x1b 57 empty_hash[28]=0x78; empty_hash[29]=0x52; empty_hash[30]=0xb8; empty_hash[31]=0x55 58 59 let th_after_sh: *u8 = sys_mmap(64) 60 th_after_sh[0]=0x86; th_after_sh[1]=0x0c; th_after_sh[2]=0x06; th_after_sh[3]=0xed 61 th_after_sh[4]=0xc0; th_after_sh[5]=0x78; th_after_sh[6]=0x58; th_after_sh[7]=0xee 62 th_after_sh[8]=0x8e; th_after_sh[9]=0x78; th_after_sh[10]=0xf0; th_after_sh[11]=0xe7 63 th_after_sh[12]=0x42; th_after_sh[13]=0x8c; th_after_sh[14]=0x58; th_after_sh[15]=0xed 64 th_after_sh[16]=0xd6; th_after_sh[17]=0xb4; th_after_sh[18]=0x3f; th_after_sh[19]=0x2c 65 th_after_sh[20]=0xa3; th_after_sh[21]=0xe6; th_after_sh[22]=0xe9; th_after_sh[23]=0x5f 66 th_after_sh[24]=0x02; th_after_sh[25]=0xed; th_after_sh[26]=0x06; th_after_sh[27]=0x3c 67 th_after_sh[28]=0xf0; th_after_sh[29]=0xe1; th_after_sh[30]=0xca; th_after_sh[31]=0xd8 68 69 let hs_secret: *u8 = sys_mmap(64) 70 let chts: *u8 = sys_mmap(64) 71 let shts: *u8 = sys_mmap(64) 72 let cks: *u8 = sys_mmap(64) 73 let civ: *u8 = sys_mmap(64) 74 let sks: *u8 = sys_mmap(64) 75 let siv: *u8 = sys_mmap(64) 76 tls13_handshake_compute_handshake_keys( 77 cpriv, spub, th_after_sh, empty_hash, 78 hs_secret, chts, shts, cks, civ, sks, siv 79 ) 80 81 // ---- Synthesise EE / Cert / CV messages ---- 82 // EE: HT=8, body_len=2, ext_list_len=0 -> 6 bytes total 83 let ee: *u8 = sys_mmap(64) 84 ee[0] = HT_ENCRYPTED_EXTENSIONS & 0xff 85 ee[1] = 0; ee[2] = 0; ee[3] = 2 86 ee[4] = 0; ee[5] = 0 87 let ee_len: i64 = 6 88 89 // Cert: HT=11, body=19; ctx_len=0; chain_len=15; cert_len=10; cert(10); cert_exts_len=0 90 let cert: *u8 = sys_mmap(64) 91 cert[0] = HT_CERTIFICATE & 0xff 92 cert[1] = 0; cert[2] = 0; cert[3] = 19 93 cert[4] = 0 94 cert[5] = 0; cert[6] = 0; cert[7] = 15 95 cert[8] = 0; cert[9] = 0; cert[10] = 10 96 var i: i64 = 0 97 while i < 10 { 98 cert[11 + i] = 0x30 + i 99 i = i + 1 100 } 101 cert[21] = 0; cert[22] = 0 102 let cert_len: i64 = 23 103 104 // CV: HT=15, body=68; scheme=ed25519 (0x0807); sig_len=64; sig(64) 105 let cv: *u8 = sys_mmap(128) 106 cv[0] = HT_CERTIFICATE_VERIFY & 0xff 107 cv[1] = 0; cv[2] = 0; cv[3] = 68 108 cv[4] = 0x08; cv[5] = 0x07 109 cv[6] = 0; cv[7] = 64 110 i = 0 111 while i < 64 { 112 cv[8 + i] = 0x90 + (i & 0x0f) 113 i = i + 1 114 } 115 let cv_len: i64 = 72 116 117 // ---- Walk dispatcher EE -> Cert -> CV ---- 118 let tx: *u8 = nx_tls13_transcript_new() 119 var state: i64 = NX_TLS13_CSTATE_WAIT_EE 120 let out_state: *i64 = sys_mmap(16) as *i64 121 122 let v1: i64 = tls13_client_dispatch_handshake_message(state, ee, ee_len, shts, tx, out_state) 123 if v1 != NX_TLS13_CLIENT_VERDICT_OK { return 1 } 124 state = *out_state 125 if state != NX_TLS13_CSTATE_WAIT_CERT { return 2 } 126 127 let v2: i64 = tls13_client_dispatch_handshake_message(state, cert, cert_len, shts, tx, out_state) 128 if v2 != NX_TLS13_CLIENT_VERDICT_OK { return 3 } 129 state = *out_state 130 if state != NX_TLS13_CSTATE_WAIT_CV { return 4 } 131 132 let v3: i64 = tls13_client_dispatch_handshake_message(state, cv, cv_len, shts, tx, out_state) 133 if v3 != NX_TLS13_CLIENT_VERDICT_OK { return 5 } 134 state = *out_state 135 if state != NX_TLS13_CSTATE_WAIT_SF { return 6 } 136 137 // ---- Build a VALID SF: compute MAC with server's finished_key over snapshot ---- 138 let th_before_sf: *u8 = sys_mmap(64) 139 nx_tls13_transcript_snapshot(tx, th_before_sf) 140 let s_fk: *u8 = sys_mmap(64) 141 tls13_finished_key(shts, 32, s_fk) 142 let server_mac: *u8 = sys_mmap(64) 143 nx_tls13_finished_compute(s_fk, 32, th_before_sf, 32, server_mac) 144 145 let sf: *u8 = sys_mmap(64) 146 sf[0] = HT_FINISHED & 0xff 147 sf[1] = 0; sf[2] = 0; sf[3] = 32 148 i = 0 149 while i < 32 { 150 sf[4 + i] = server_mac[i] 151 i = i + 1 152 } 153 let sf_len: i64 = 36 154 155 let v4: i64 = tls13_client_dispatch_handshake_message(state, sf, sf_len, shts, tx, out_state) 156 if v4 != NX_TLS13_CLIENT_VERDICT_OK { return 7 } 157 state = *out_state 158 if state != NX_TLS13_CSTATE_CONNECTED { return 8 } 159 160 // ---- Tampered SF MAC rejected: rebuild fresh state on a separate transcript ---- 161 let bad_tx: *u8 = nx_tls13_transcript_new() 162 nx_tls13_transcript_update(bad_tx, ee, ee_len) 163 nx_tls13_transcript_update(bad_tx, cert, cert_len) 164 nx_tls13_transcript_update(bad_tx, cv, cv_len) 165 let bad_sf: *u8 = sys_mmap(64) 166 var j: i64 = 0 167 while j < sf_len { 168 bad_sf[j] = sf[j] 169 j = j + 1 170 } 171 bad_sf[10] = bad_sf[10] ^ 0x40 // flip a MAC byte 172 let bad_state: i64 = NX_TLS13_CSTATE_WAIT_SF 173 let v5: i64 = tls13_client_dispatch_handshake_message(bad_state, bad_sf, sf_len, shts, bad_tx, out_state) 174 if v5 != NX_TLS13_CLIENT_VERDICT_SF_BAD_MAC { return 20 } 175 176 // ---- Wrong msg_type at WAIT_EE state rejected ---- 177 let bogus_tx: *u8 = nx_tls13_transcript_new() 178 let v_wrong: i64 = tls13_client_dispatch_handshake_message( 179 NX_TLS13_CSTATE_WAIT_EE, cv, cv_len, shts, bogus_tx, out_state 180 ) 181 if v_wrong != NX_TLS13_CLIENT_VERDICT_BAD_MSG_TYPE { return 30 } 182 183 // ---- Emit our client_Finished ---- 184 let cf: *u8 = sys_mmap(64) 185 let cf_len: i64 = tls13_client_emit_finished(chts, tx, cf) 186 if cf_len != 36 { return 40 } 187 if (cf[0] & 0xff) != HT_FINISHED { return 41 } 188 if (cf[1] & 0xff) != 0 { return 42 } 189 if (cf[2] & 0xff) != 0 { return 43 } 190 if (cf[3] & 0xff) != 32 { return 44 } 191 192 // ---- Record-layer round-trip: encrypt CF under client_hs key, decrypt back ---- 193 let header: *u8 = sys_mmap(16) 194 let ct: *u8 = sys_mmap(128) 195 let tag: *u8 = sys_mmap(32) 196 let v_enc: i64 = nx_tls13_record_encrypt( 197 cks, civ, 0, 198 cf, cf_len, 199 NX_TLS13_CT_HANDSHAKE, 200 0, 201 header, ct, tag 202 ) 203 if v_enc != NX_TLS13_REC_VERDICT_OK { return 50 } 204 205 let inner_buf: *u8 = sys_mmap(128) 206 let ct_type_out: *i64 = sys_mmap(16) as *i64 207 let ct_len_out: *i64 = sys_mmap(16) as *i64 208 let v_dec: i64 = nx_tls13_record_decrypt( 209 cks, civ, 0, 210 header, 211 ct, cf_len + 1, 212 tag, 213 inner_buf, ct_type_out, ct_len_out 214 ) 215 if v_dec != NX_TLS13_REC_VERDICT_OK { return 51 } 216 if *ct_type_out != NX_TLS13_CT_HANDSHAKE { return 52 } 217 if *ct_len_out != cf_len { return 53 } 218 var k: i64 = 0 219 while k < cf_len { 220 if (inner_buf[k] & 0xff) != (cf[k] & 0xff) { return 60 + (k & 0x1f) } 221 k = k + 1 222 } 223 224 // ---- Verdict + state gates ---- 225 if nx_tls13_client_verdict_is_valid(NX_TLS13_CLIENT_VERDICT_OK) != 1 { return 100 } 226 if nx_tls13_client_verdict_is_valid(NX_TLS13_CLIENT_VERDICT_N) != 0 { return 101 } 227 if nx_tls13_cstate_is_valid(NX_TLS13_CSTATE_CONNECTED) != 1 { return 102 } 228 if nx_tls13_cstate_is_valid(NX_TLS13_CSTATE_N) != 0 { return 103 } 229 230 return 0 231}