| ... | @@ -1202,6 +1202,7 @@ fn readIndirect(c: *Client) Reader.Error!usize { | ... | @@ -1202,6 +1202,7 @@ fn readIndirect(c: *Client) Reader.Error!usize { |
| 1202 | .tls_1_2 => { | 1202 | .tls_1_2 => { |
| 1203 | const pv = &p.tls_1_2; | 1203 | const pv = &p.tls_1_2; |
| 1204 | const P = @TypeOf(p.*); | 1204 | const P = @TypeOf(p.*); |
| | 1205 | if (record_len < P.record_iv_length + P.mac_length) return failRead(c, error.TlsRecordOverflow); |
| 1205 | const message_len: u16 = record_len - P.record_iv_length - P.mac_length; | 1206 | const message_len: u16 = record_len - P.record_iv_length - P.mac_length; |
| 1206 | const ad_header = input.take(tls.record_header_len) catch unreachable; // already peeked | 1207 | const ad_header = input.take(tls.record_header_len) catch unreachable; // already peeked |
| 1207 | const ad = mem.toBytes(big(c.read_seq)) ++ | 1208 | const ad = mem.toBytes(big(c.read_seq)) ++ |
| ... | @@ -1674,7 +1675,7 @@ else | ... | @@ -1674,7 +1675,7 @@ else |
| 1674 | .ECDHE_RSA_WITH_AES_256_GCM_SHA384, | 1675 | .ECDHE_RSA_WITH_AES_256_GCM_SHA384, |
| 1675 | }); | 1676 | }); |
| 1676 | | 1677 | |
| 1677 | fn testReadError(input_buf: []const u8, cipher: tls.ApplicationCipher) ReadError { | 1678 | fn testReadError(input_buf: []const u8, tls_version: tls.ProtocolVersion, cipher: tls.ApplicationCipher) ReadError { |
| 1678 | var input_reader: Reader = .fixed(input_buf); | 1679 | var input_reader: Reader = .fixed(input_buf); |
| 1679 | var read_buf: [tls.max_ciphertext_record_len]u8 = undefined; | 1680 | var read_buf: [tls.max_ciphertext_record_len]u8 = undefined; |
| 1680 | var c: Client = .{ | 1681 | var c: Client = .{ |
| ... | @@ -1687,7 +1688,7 @@ fn testReadError(input_buf: []const u8, cipher: tls.ApplicationCipher) ReadError | ... | @@ -1687,7 +1688,7 @@ fn testReadError(input_buf: []const u8, cipher: tls.ApplicationCipher) ReadError |
| 1687 | }, | 1688 | }, |
| 1688 | .output = undefined, | 1689 | .output = undefined, |
| 1689 | .writer = undefined, | 1690 | .writer = undefined, |
| 1690 | .tls_version = .tls_1_3, | 1691 | .tls_version = tls_version, |
| 1691 | .read_seq = 0, | 1692 | .read_seq = 0, |
| 1692 | .write_seq = 0, | 1693 | .write_seq = 0, |
| 1693 | .received_close_notify = false, | 1694 | .received_close_notify = false, |
| ... | @@ -1715,6 +1716,7 @@ test "empty inner plaintext" { | ... | @@ -1715,6 +1716,7 @@ test "empty inner plaintext" { |
| 1715 | | 1716 | |
| 1716 | try std.testing.expectEqual(error.TlsDecodeError, testReadError( | 1717 | try std.testing.expectEqual(error.TlsDecodeError, testReadError( |
| 1717 | &record_header ++ ciphertext ++ tag, | 1718 | &record_header ++ ciphertext ++ tag, |
| | 1719 | .tls_1_3, |
| 1718 | .{ .CHACHA20_POLY1305_SHA256 = .{ .tls_1_3 = .{ | 1720 | .{ .CHACHA20_POLY1305_SHA256 = .{ .tls_1_3 = .{ |
| 1719 | .server_key = key, | 1721 | .server_key = key, |
| 1720 | .server_iv = iv, | 1722 | .server_iv = iv, |
| ... | @@ -1734,6 +1736,7 @@ test "record shorter than tag" { | ... | @@ -1734,6 +1736,7 @@ test "record shorter than tag" { |
| 1734 | | 1736 | |
| 1735 | try std.testing.expectEqual(error.TlsRecordOverflow, testReadError( | 1737 | try std.testing.expectEqual(error.TlsRecordOverflow, testReadError( |
| 1736 | &wire, | 1738 | &wire, |
| | 1739 | .tls_1_3, |
| 1737 | .{ .CHACHA20_POLY1305_SHA256 = .{ .tls_1_3 = .{ | 1740 | .{ .CHACHA20_POLY1305_SHA256 = .{ .tls_1_3 = .{ |
| 1738 | .server_key = undefined, | 1741 | .server_key = undefined, |
| 1739 | .server_iv = undefined, | 1742 | .server_iv = undefined, |
| ... | @@ -1744,3 +1747,15 @@ test "record shorter than tag" { | ... | @@ -1744,3 +1747,15 @@ test "record shorter than tag" { |
| 1744 | } } }, | 1747 | } } }, |
| 1745 | )); | 1748 | )); |
| 1746 | } | 1749 | } |
| | 1750 | |
| | 1751 | test "TLS 1.2 record shorter than IV plus tag" { |
| | 1752 | const P = tls.ApplicationCipherT(crypto.aead.aes_gcm.Aes128Gcm, crypto.hash.sha2.Sha256, 8); |
| | 1753 | const record_len: u16 = P.record_iv_length + P.mac_length - 1; |
| | 1754 | const header = [_]u8{ 0x17, 0x03, 0x03 } ++ mem.toBytes(big(record_len)); |
| | 1755 | |
| | 1756 | try std.testing.expectEqual(error.TlsRecordOverflow, testReadError( |
| | 1757 | &(header ++ @as([record_len]u8, @splat(0))), |
| | 1758 | .tls_1_2, |
| | 1759 | .{ .AES_128_GCM_SHA256 = .{ .tls_1_2 = mem.zeroes(P.Tls_1_2) } }, |
| | 1760 | )); |
| | 1761 | } |