| ... | @@ -21,12 +21,7 @@ const array = tls.array; | ... | @@ -21,12 +21,7 @@ const array = tls.array; |
| 21 | /// here via `reader`. | 21 | /// here via `reader`. |
| 22 | /// | 22 | /// |
| 23 | /// The buffer is asserted to have capacity at least `min_buffer_len`. | 23 | /// 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. | | |
| 27 | input: *std.io.BufferedReader, | 24 | input: *std.io.BufferedReader, |
| 28 | /// Tells how many bytes inside `input` have already been decrypted. | | |
| 29 | remaining_cleartext_len: u15, | | |
| 30 | | 25 | |
| 31 | /// The encrypted stream from the client to the server. Bytes are pushed here | 26 | /// The encrypted stream from the client to the server. Bytes are pushed here |
| 32 | /// via `writer`. | 27 | /// via `writer`. |
| ... | @@ -68,6 +63,9 @@ pub const ReadError = error{ | ... | @@ -68,6 +63,9 @@ pub const ReadError = error{ |
| 68 | TlsUnexpectedMessage, | 63 | TlsUnexpectedMessage, |
| 69 | TlsIllegalParameter, | 64 | TlsIllegalParameter, |
| 70 | TlsSequenceOverflow, | 65 | TlsSequenceOverflow, |
| | 66 | /// The buffer provided to the read function was not at least |
| | 67 | /// `min_buffer_len`. |
| | 68 | OutputBufferUndersize, |
| 71 | }; | 69 | }; |
| 72 | | 70 | |
| 73 | pub const SslKeyLog = struct { | 71 | pub const SslKeyLog = struct { |
| ... | @@ -868,7 +866,6 @@ pub fn init( | ... | @@ -868,7 +866,6 @@ pub fn init( |
| 868 | .tls_1_2 => write_seq, | 866 | .tls_1_2 => write_seq, |
| 869 | else => unreachable, | 867 | else => unreachable, |
| 870 | }, | 868 | }, |
| 871 | .remaining_cleartext_len = 0, | | |
| 872 | .received_close_notify = false, | 869 | .received_close_notify = false, |
| 873 | .allow_truncation_attacks = false, | 870 | .allow_truncation_attacks = false, |
| 874 | .application_cipher = app_cipher, | 871 | .application_cipher = app_cipher, |
| ... | @@ -1047,18 +1044,13 @@ fn prepareCiphertextRecord( | ... | @@ -1047,18 +1044,13 @@ fn prepareCiphertextRecord( |
| 1047 | } | 1044 | } |
| 1048 | | 1045 | |
| 1049 | pub fn eof(c: Client) bool { | 1046 | pub fn eof(c: Client) bool { |
| 1050 | return c.received_close_notify and c.remaining_cleartext_len == 0; | 1047 | return c.received_close_notify; |
| 1051 | } | 1048 | } |
| 1052 | | 1049 | |
| 1053 | fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: Reader.Limit) Reader.RwError!usize { | 1050 | fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: Reader.Limit) Reader.RwError!usize { |
| 1054 | const c: *Client = @ptrCast(@alignCast(context)); | 1051 | const c: *Client = @ptrCast(@alignCast(context)); |
| 1055 | if (c.eof()) return error.EndOfStream; | 1052 | if (c.eof()) return error.EndOfStream; |
| 1056 | const input = c.input; | 1053 | 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 | } | | |
| 1062 | // If at least one full encrypted record is not buffered, read once. | 1054 | // If at least one full encrypted record is not buffered, read once. |
| 1063 | const record_header = input.peek(tls.record_header_len) catch |err| switch (err) { | 1055 | const record_header = input.peek(tls.record_header_len) catch |err| switch (err) { |
| 1064 | error.EndOfStream => { | 1056 | error.EndOfStream => { |
| ... | @@ -1225,13 +1217,9 @@ fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: Reader.Limit) R | ... | @@ -1225,13 +1217,9 @@ fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: Reader.Limit) R |
| 1225 | return 0; | 1217 | return 0; |
| 1226 | }, | 1218 | }, |
| 1227 | .application_data => { | 1219 | .application_data => { |
| 1228 | const n = try bw.write(limit.sliceConst(cleartext)); | 1220 | if (@intFromEnum(limit) < cleartext.len) return failRead(c, error.OutputBufferUndersize); |
| 1229 | if (n < cleartext.len) { | 1221 | try bw.writeAll(cleartext); |
| 1230 | const remainder = cleartext[n..]; | 1222 | return cleartext.len; |
| 1231 | input.unread(remainder); | | |
| 1232 | c.remaining_cleartext_len = @intCast(remainder.len); | | |
| 1233 | } | | |
| 1234 | return n; | | |
| 1235 | }, | 1223 | }, |
| 1236 | else => return failRead(c, error.TlsUnexpectedMessage), | 1224 | else => return failRead(c, error.TlsUnexpectedMessage), |
| 1237 | } | 1225 | } |