authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-05-02 17:31:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:28-07:00
log5ac895c82066ad02e8d9232077d43fbb9bc5a6d9
tree17c0507c0d03b9dd064a36a7f61e0d5de591d9d9
parentbb7af21d6fbd056309d474b27f7f6639287e9e5d

std.crypto.tls.Client: give all cleartext in read


2 files changed, 7 insertions(+), 25 deletions(-)

lib/std/crypto/tls/Client.zig+7-19
......@@ -21,12 +21,7 @@ const array = tls.array;
2121/// here via `reader`.
2222///
2323/// The buffer is asserted to have capacity at least `min_buffer_len`.
24///
25/// `remaining_cleartext_len` tells how many bytes inside this buffer have
26/// already been decrypted.
2724input: *std.io.BufferedReader,
28/// Tells how many bytes inside `input` have already been decrypted.
29remaining_cleartext_len: u15,
3025
3126/// The encrypted stream from the client to the server. Bytes are pushed here
3227/// via `writer`.
......@@ -68,6 +63,9 @@ pub const ReadError = error{
6863 TlsUnexpectedMessage,
6964 TlsIllegalParameter,
7065 TlsSequenceOverflow,
66 /// The buffer provided to the read function was not at least
67 /// `min_buffer_len`.
68 OutputBufferUndersize,
7169};
7270
7371pub const SslKeyLog = struct {
......@@ -868,7 +866,6 @@ pub fn init(
868866 .tls_1_2 => write_seq,
869867 else => unreachable,
870868 },
871 .remaining_cleartext_len = 0,
872869 .received_close_notify = false,
873870 .allow_truncation_attacks = false,
874871 .application_cipher = app_cipher,
......@@ -1047,18 +1044,13 @@ fn prepareCiphertextRecord(
10471044}
10481045
10491046pub fn eof(c: Client) bool {
1050 return c.received_close_notify and c.remaining_cleartext_len == 0;
1047 return c.received_close_notify;
10511048}
10521049
10531050fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: Reader.Limit) Reader.RwError!usize {
10541051 const c: *Client = @ptrCast(@alignCast(context));
10551052 if (c.eof()) return error.EndOfStream;
10561053 const input = c.input;
1057 if (c.remaining_cleartext_len > 0) {
1058 const n = try bw.write(input.bufferContents()[0..c.remaining_cleartext_len]);
1059 c.remaining_cleartext_len = @intCast(c.remaining_cleartext_len - n);
1060 return n;
1061 }
10621054 // If at least one full encrypted record is not buffered, read once.
10631055 const record_header = input.peek(tls.record_header_len) catch |err| switch (err) {
10641056 error.EndOfStream => {
......@@ -1225,13 +1217,9 @@ fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: Reader.Limit) R
12251217 return 0;
12261218 },
12271219 .application_data => {
1228 const n = try bw.write(limit.sliceConst(cleartext));
1229 if (n < cleartext.len) {
1230 const remainder = cleartext[n..];
1231 input.unread(remainder);
1232 c.remaining_cleartext_len = @intCast(remainder.len);
1233 }
1234 return n;
1220 if (@intFromEnum(limit) < cleartext.len) return failRead(c, error.OutputBufferUndersize);
1221 try bw.writeAll(cleartext);
1222 return cleartext.len;
12351223 },
12361224 else => return failRead(c, error.TlsUnexpectedMessage),
12371225 }
lib/std/io/BufferedReader.zig-6
......@@ -252,12 +252,6 @@ pub fn toss(br: *BufferedReader, n: usize) void {
252252 assert(br.seek <= br.end);
253253}
254254
255pub fn unread(noalias br: *BufferedReader, noalias data: []const u8) void {
256 _ = br;
257 _ = data;
258 @panic("TODO");
259}
260
261255/// Equivalent to `peek` followed by `toss`.
262256///
263257/// The data returned is invalidated by the next call to `take`, `peek`,