authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-18 18:14:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-02 16:57:15-07:00
log7a2377838414157fb65850aa045c2112a0bbd006
tree9a8ec80e992e08b24787d1bb6586cee6cf28fb78
parente2efba76aa0e1566da65721db64537d94fea69df

std.crypto.tls: send a legacy session id

To support middlebox compatibility mode.

1 files changed, 34 insertions(+), 23 deletions(-)

lib/std/crypto/tls/Client.zig+34-23
...@@ -36,9 +36,11 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {...@@ -36,9 +36,11 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {
36 error.IdentityElement => return error.InsufficientEntropy,36 error.IdentityElement => return error.InsufficientEntropy,
37 };37 };
3838
39 // random (u32)39 // This is used both for the random bytes and for the legacy session id.
40 var rand_buf: [32]u8 = undefined;40 var random_buffer: [64]u8 = undefined;
41 crypto.random.bytes(&rand_buf);41 crypto.random.bytes(&random_buffer);
42 const hello_rand = random_buffer[0..32].*;
43 const legacy_session_id = random_buffer[32..64].*;
4244
43 const extensions_payload =45 const extensions_payload =
44 tls.extension(.supported_versions, [_]u8{46 tls.extension(.supported_versions, [_]u8{
...@@ -86,8 +88,8 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {...@@ -86,8 +88,8 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {
8688
87 const client_hello =89 const client_hello =
88 int2(@enumToInt(tls.ProtocolVersion.tls_1_2)) ++90 int2(@enumToInt(tls.ProtocolVersion.tls_1_2)) ++
89 rand_buf ++91 hello_rand ++
90 [1]u8{0} ++92 [1]u8{32} ++ legacy_session_id ++
91 cipher_suites ++93 cipher_suites ++
92 int2(legacy_compression_methods) ++94 int2(legacy_compression_methods) ++
93 extensions_header;95 extensions_header;
...@@ -152,46 +154,55 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {...@@ -152,46 +154,55 @@ pub fn init(stream: net.Stream, host: []const u8) !Client {
152 }154 }
153 const length = mem.readIntBig(u24, frag[1..4]);155 const length = mem.readIntBig(u24, frag[1..4]);
154 if (4 + length != frag.len) return error.TlsBadLength;156 if (4 + length != frag.len) return error.TlsBadLength;
155 const hello = frag[4..];157 var i: usize = 4;
156 const legacy_version = mem.readIntBig(u16, hello[0..2]);158 const legacy_version = mem.readIntBig(u16, frag[i..][0..2]);
157 const random = hello[2..34].*;159 i += 2;
160 const random = frag[i..][0..32].*;
161 i += 32;
158 if (mem.eql(u8, &random, &tls.hello_retry_request_sequence)) {162 if (mem.eql(u8, &random, &tls.hello_retry_request_sequence)) {
159 @panic("TODO handle HelloRetryRequest");163 @panic("TODO handle HelloRetryRequest");
160 }164 }
161 const legacy_session_id_echo_len = hello[34];165 const legacy_session_id_echo_len = frag[i];
162 if (legacy_session_id_echo_len != 0) return error.TlsIllegalParameter;166 i += 1;
163 const cipher_suite_int = mem.readIntBig(u16, hello[35..37]);167 if (legacy_session_id_echo_len != 32) return error.TlsIllegalParameter;
168 const legacy_session_id_echo = frag[i..][0..32];
169 if (!mem.eql(u8, legacy_session_id_echo, &legacy_session_id))
170 return error.TlsIllegalParameter;
171 i += 32;
172 const cipher_suite_int = mem.readIntBig(u16, frag[i..][0..2]);
173 i += 2;
164 const cipher_suite_tag = @intToEnum(CipherSuite, cipher_suite_int);174 const cipher_suite_tag = @intToEnum(CipherSuite, cipher_suite_int);
165 std.debug.print("server wants cipher suite {any}\n", .{cipher_suite_tag});175 std.debug.print("server wants cipher suite {any}\n", .{cipher_suite_tag});
166 const legacy_compression_method = hello[37];176 const legacy_compression_method = frag[i];
177 i += 1;
167 _ = legacy_compression_method;178 _ = legacy_compression_method;
168 const extensions_size = mem.readIntBig(u16, hello[38..40]);179 const extensions_size = mem.readIntBig(u16, frag[i..][0..2]);
169 if (40 + extensions_size != hello.len) return error.TlsBadLength;180 i += 2;
170 var i: usize = 40;181 if (i + extensions_size != frag.len) return error.TlsBadLength;
171 var supported_version: u16 = 0;182 var supported_version: u16 = 0;
172 var opt_x25519_server_pub_key: ?*[32]u8 = null;183 var opt_x25519_server_pub_key: ?*[32]u8 = null;
173 while (i < hello.len) {184 while (i < frag.len) {
174 const et = mem.readIntBig(u16, hello[i..][0..2]);185 const et = mem.readIntBig(u16, frag[i..][0..2]);
175 i += 2;186 i += 2;
176 const ext_size = mem.readIntBig(u16, hello[i..][0..2]);187 const ext_size = mem.readIntBig(u16, frag[i..][0..2]);
177 i += 2;188 i += 2;
178 const next_i = i + ext_size;189 const next_i = i + ext_size;
179 if (next_i > hello.len) return error.TlsBadLength;190 if (next_i > frag.len) return error.TlsBadLength;
180 switch (et) {191 switch (et) {
181 @enumToInt(tls.ExtensionType.supported_versions) => {192 @enumToInt(tls.ExtensionType.supported_versions) => {
182 if (supported_version != 0) return error.TlsIllegalParameter;193 if (supported_version != 0) return error.TlsIllegalParameter;
183 supported_version = mem.readIntBig(u16, hello[i..][0..2]);194 supported_version = mem.readIntBig(u16, frag[i..][0..2]);
184 },195 },
185 @enumToInt(tls.ExtensionType.key_share) => {196 @enumToInt(tls.ExtensionType.key_share) => {
186 if (opt_x25519_server_pub_key != null) return error.TlsIllegalParameter;197 if (opt_x25519_server_pub_key != null) return error.TlsIllegalParameter;
187 const named_group = mem.readIntBig(u16, hello[i..][0..2]);198 const named_group = mem.readIntBig(u16, frag[i..][0..2]);
188 i += 2;199 i += 2;
189 switch (named_group) {200 switch (named_group) {
190 @enumToInt(tls.NamedGroup.x25519) => {201 @enumToInt(tls.NamedGroup.x25519) => {
191 const key_size = mem.readIntBig(u16, hello[i..][0..2]);202 const key_size = mem.readIntBig(u16, frag[i..][0..2]);
192 i += 2;203 i += 2;
193 if (key_size != 32) return error.TlsBadLength;204 if (key_size != 32) return error.TlsBadLength;
194 opt_x25519_server_pub_key = hello[i..][0..32];205 opt_x25519_server_pub_key = frag[i..][0..32];
195 },206 },
196 else => {207 else => {
197 std.debug.print("named group: {x}\n", .{named_group});208 std.debug.print("named group: {x}\n", .{named_group});