code wiki / (root) / nx_tls12_parse.nx

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}