nx_tls12_parse.nx source
↩ module page · 65 lines · 3083 B
1// nx_tls12_parse.nx -- TLS 1.2 handshake parsers (rung 2 of the sovereign TLS 1.2 client).
2// Parses the server's 1.2 handshake messages so we can derive keys (rung 3):
3// tls12_parse_server_hello -> server_random(32) + chosen cipher suite
4// tls12_parse_server_key_exchange -> ECDHE named_curve + server pubkey + signature(alg+bytes)
5// (Certificate parsing/validation reuses the existing X.509 pipeline.) Pure byte parsing, no network --
6// KAT'd by round-trip against a synthetic blob in nx_tls12_parse_test. license_tier: ORIGINAL
7import "nx_syscalls.nx"
8
9func _t12_u16(buf: *u8, off: i64) -> i64 { return ((buf[off] as i64) << 8) | (buf[off + 1] as i64) }
10
11// ServerHello body (after the 4-byte handshake header):
12// version(2) + random(32) + session_id_len(1) + session_id(var) + cipher_suite(2) + compression(1) + ext...
13// Returns 1 + fills out_random(32) + out_cipher[0]; 0 on malformed.
14func tls12_parse_server_hello(buf: *u8, len: i64, out_random: *u8, out_cipher: *i64) -> i64 {
15 if len < 38 { return 0 }
16 var i: i64 = 0
17 while i < 32 { out_random[i] = buf[2 + i]; i = i + 1 }
18 let sid_len: i64 = buf[34] as i64
19 let p: i64 = 35 + sid_len
20 if p + 3 > len { return 0 }
21 out_cipher[0] = _t12_u16(buf, p)
22 return 1
23}
24
25// ServerKeyExchange body (ECDHE), after the 4-byte handshake header:
26// ECParameters: curve_type(1)=named_curve(3) + named_curve(2)
27// public: point_len(1) + point(point_len)
28// signature: sig_alg(2) + sig_len(2) + sig(sig_len)
29// Returns 1 + fills out_curve/out_pub/out_pub_len/out_sigalg/out_sig/out_sig_len; 0 on malformed.
30func tls12_parse_server_key_exchange(buf: *u8, len: i64,
31 out_curve: *i64, out_pub: *u8, out_pub_len: *i64,
32 out_sigalg: *i64, out_sig: *u8, out_sig_len: *i64) -> i64 {
33 if len < 4 { return 0 }
34 if (buf[0] as i64) != 3 { return 0 } // 3 = named_curve
35 out_curve[0] = _t12_u16(buf, 1)
36 let pkl: i64 = buf[3] as i64
37 if 4 + pkl + 4 > len { return 0 }
38 var i: i64 = 0
39 while i < pkl { out_pub[i] = buf[4 + i]; i = i + 1 }
40 out_pub_len[0] = pkl
41 var p: i64 = 4 + pkl
42 out_sigalg[0] = _t12_u16(buf, p)
43 p = p + 2
44 let sl: i64 = _t12_u16(buf, p)
45 p = p + 2
46 if p + sl > len { return 0 }
47 var j: i64 = 0
48 while j < sl { out_sig[j] = buf[p + j]; j = j + 1 }
49 out_sig_len[0] = sl
50 return 1
51}
52
53// The data the server signs in a 1.2 ECDHE ServerKeyExchange = client_random || server_random || ECDHE params
54// (the ECParameters+public bytes, i.e. SKX body up to the signature). Assembled here for rung-3 sig verify.
55// Returns the assembled length.
56func tls12_skx_signed_data(client_random: *u8, server_random: *u8, skx_body: *u8, params_len: i64, out: *u8) -> i64 {
57 var o: i64 = 0
58 var i: i64 = 0
59 while i < 32 { out[o] = client_random[i]; o = o + 1; i = i + 1 }
60 i = 0
61 while i < 32 { out[o] = server_random[i]; o = o + 1; i = i + 1 }
62 i = 0
63 while i < params_len { out[o] = skx_body[i]; o = o + 1; i = i + 1 }
64 return o
65}