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}