| ... | @@ -320,6 +320,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client | ... | @@ -320,6 +320,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client |
| 320 | var handshake_state: HandshakeState = .hello; | 320 | var handshake_state: HandshakeState = .hello; |
| 321 | var handshake_cipher: tls.HandshakeCipher = undefined; | 321 | var handshake_cipher: tls.HandshakeCipher = undefined; |
| 322 | var main_cert_pub_key: CertificatePublicKey = undefined; | 322 | var main_cert_pub_key: CertificatePublicKey = undefined; |
| | 323 | var tls12_negotiated_group: ?tls.NamedGroup = null; |
| 323 | const now_sec = std.time.timestamp(); | 324 | const now_sec = std.time.timestamp(); |
| 324 | | 325 | |
| 325 | var cleartext_fragment_start: usize = 0; | 326 | var cleartext_fragment_start: usize = 0; |
| ... | @@ -679,6 +680,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client | ... | @@ -679,6 +680,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client |
| 679 | const curve_type = hsd.decode(u8); | 680 | const curve_type = hsd.decode(u8); |
| 680 | if (curve_type != 0x03) return error.TlsIllegalParameter; // named_curve | 681 | if (curve_type != 0x03) return error.TlsIllegalParameter; // named_curve |
| 681 | const named_group = hsd.decode(tls.NamedGroup); | 682 | const named_group = hsd.decode(tls.NamedGroup); |
| | 683 | tls12_negotiated_group = named_group; |
| 682 | const key_size = hsd.decode(u8); | 684 | const key_size = hsd.decode(u8); |
| 683 | try hsd.ensure(key_size); | 685 | try hsd.ensure(key_size); |
| 684 | const server_pub_key = hsd.slice(key_size); | 686 | const server_pub_key = hsd.slice(key_size); |
| ... | @@ -691,10 +693,19 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client | ... | @@ -691,10 +693,19 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client |
| 691 | if (cipher_state != .cleartext) return error.TlsUnexpectedMessage; | 693 | if (cipher_state != .cleartext) return error.TlsUnexpectedMessage; |
| 692 | if (handshake_state != .server_hello_done) return error.TlsUnexpectedMessage; | 694 | if (handshake_state != .server_hello_done) return error.TlsUnexpectedMessage; |
| 693 | | 695 | |
| 694 | const client_key_exchange_msg = .{@intFromEnum(tls.ContentType.handshake)} ++ | 696 | const public_key_bytes: []const u8 = switch (tls12_negotiated_group orelse .secp256r1) { |
| | 697 | .secp256r1 => &key_share.secp256r1_kp.public_key.toUncompressedSec1(), |
| | 698 | .secp384r1 => &key_share.secp384r1_kp.public_key.toUncompressedSec1(), |
| | 699 | .x25519 => &key_share.x25519_kp.public_key, |
| | 700 | else => return error.TlsIllegalParameter, |
| | 701 | }; |
| | 702 | |
| | 703 | const client_key_exchange_prefix = .{@intFromEnum(tls.ContentType.handshake)} ++ |
| 695 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ | 704 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 696 | array(u16, u8, .{@intFromEnum(tls.HandshakeType.client_key_exchange)} ++ | 705 | int(u16, @intCast(public_key_bytes.len + 5)) ++ // record length |
| 697 | array(u24, u8, array(u8, u8, key_share.secp256r1_kp.public_key.toUncompressedSec1()))); | 706 | .{@intFromEnum(tls.HandshakeType.client_key_exchange)} ++ |
| | 707 | int(u24, @intCast(public_key_bytes.len + 1)) ++ // handshake message length |
| | 708 | .{@as(u8, @intCast(public_key_bytes.len))}; // public key length |
| 698 | const client_change_cipher_spec_msg = .{@intFromEnum(tls.ContentType.change_cipher_spec)} ++ | 709 | const client_change_cipher_spec_msg = .{@intFromEnum(tls.ContentType.change_cipher_spec)} ++ |
| 699 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ | 710 | int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++ |
| 700 | array(u16, tls.ChangeCipherSpecType, .{.change_cipher_spec}); | 711 | array(u16, tls.ChangeCipherSpecType, .{.change_cipher_spec}); |
| ... | @@ -703,7 +714,8 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client | ... | @@ -703,7 +714,8 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client |
| 703 | inline else => |*p| { | 714 | inline else => |*p| { |
| 704 | const P = @TypeOf(p.*).A; | 715 | const P = @TypeOf(p.*).A; |
| 705 | p.transcript_hash.update(wrapped_handshake); | 716 | p.transcript_hash.update(wrapped_handshake); |
| 706 | p.transcript_hash.update(client_key_exchange_msg[tls.record_header_len..]); | 717 | p.transcript_hash.update(client_key_exchange_prefix[tls.record_header_len..]); |
| | 718 | p.transcript_hash.update(public_key_bytes); |
| 707 | const master_secret = hmacExpandLabel(P.Hmac, pre_master_secret, &.{ | 719 | const master_secret = hmacExpandLabel(P.Hmac, pre_master_secret, &.{ |
| 708 | "master secret", | 720 | "master secret", |
| 709 | &client_hello_rand, | 721 | &client_hello_rand, |
| ... | @@ -757,8 +769,9 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client | ... | @@ -757,8 +769,9 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client |
| 757 | nonce, | 769 | nonce, |
| 758 | pv.app_cipher.client_write_key, | 770 | pv.app_cipher.client_write_key, |
| 759 | ); | 771 | ); |
| 760 | var all_msgs_vec: [3][]const u8 = .{ | 772 | var all_msgs_vec: [4][]const u8 = .{ |
| 761 | &client_key_exchange_msg, | 773 | &client_key_exchange_prefix, |
| | 774 | public_key_bytes, |
| 762 | &client_change_cipher_spec_msg, | 775 | &client_change_cipher_spec_msg, |
| 763 | &client_verify_msg, | 776 | &client_verify_msg, |
| 764 | }; | 777 | }; |