authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-27 23:30:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-02 16:57:16-07:00
log477864dca560b03bb3c3e8e7e1e50362e7ed681f
tree8c2baf47e3c9b478fd38fb5cc2b41edfc797ae8b
parentceb211e65fe6bfe864b1150d08cd5e0383f6c2c2

std.crypto.tls.Client: fix truncation attack vulnerability


2 files changed, 10 insertions(+), 9 deletions(-)

lib/std/crypto/tls/Client.zig+6-3
......@@ -725,8 +725,11 @@ pub fn writeAll(c: *Client, stream: net.Stream, bytes: []const u8) !void {
725725
726726/// Returns number of bytes that have been read, which are now populated inside
727727/// `buffer`. A return value of zero bytes does not necessarily mean end of
728/// stream.
728/// stream. Instead, the `eof` flag is set upon end of stream. The `eof` flag
729/// may be set after any call to `read`, including when greater than zero bytes
730/// are returned, and this function asserts that `eof` is `false`.
729731pub fn read(c: *Client, stream: net.Stream, buffer: []u8) !usize {
732 assert(!c.eof);
730733 const prev_len = c.partially_read_len;
731734 var in_buf: [max_ciphertext_len * 4]u8 = undefined;
732735 mem.copy(u8, &in_buf, c.partially_read_buffer[0..prev_len]);
......@@ -738,8 +741,8 @@ pub fn read(c: *Client, stream: net.Stream, buffer: []u8) !usize {
738741 const actual_read_len = try stream.read(ask_slice);
739742 const frag = in_buf[0 .. prev_len + actual_read_len];
740743 if (frag.len == 0) {
741 c.eof = true;
742 return 0;
744 // This is either a truncation attack, or a bug in the server.
745 return error.TlsConnectionTruncated;
743746 }
744747 var in: usize = 0;
745748 var out: usize = 0;
lib/std/http/Client.zig+4-6
......@@ -66,13 +66,11 @@ pub const Request = struct {
6666 var index: usize = 0;
6767 while (index < len) {
6868 const amt = try req.read(buffer[index..]);
69 if (amt == 0) {
70 switch (req.protocol) {
71 .http => break,
72 .https => if (req.tls_client.eof) break,
73 }
74 }
7569 index += amt;
70 switch (req.protocol) {
71 .http => if (amt == 0) break,
72 .https => if (req.tls_client.eof) break,
73 }
7674 }
7775 return index;
7876 }