authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-04-20 12:10:24+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-07-12 13:38:23+02:00
log3221389b28ed03ae372b43ac04a9c11e94534128
tree5f1ccb402da0ec4977f125de2049728ec97af2f9
parent452ec646f90e43d516768d43cf8581d68a9ba776

std.crypto.tls.Client: reject KeyUpdate with invalid body length

We were reading `handshake[0]` without checking the body length. A TLS 1.3 KeyUpdate handshake message must contain exactly one byte.

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

lib/std/crypto/tls/Client.zig+23
...@@ -1267,6 +1267,7 @@ fn readIndirect(c: *Client) Reader.Error!usize {...@@ -1267,6 +1267,7 @@ fn readIndirect(c: *Client) Reader.Error!usize {
1267 // This client implementation ignores new session tickets.1267 // This client implementation ignores new session tickets.
1268 },1268 },
1269 .key_update => {1269 .key_update => {
1270 if (handshake.len != 1) return failRead(c, error.TlsDecodeError);
1270 switch (c.application_cipher) {1271 switch (c.application_cipher) {
1271 inline else => |*p| {1272 inline else => |*p| {
1272 const pv = &p.tls_1_3;1273 const pv = &p.tls_1_3;
...@@ -1759,3 +1760,25 @@ test "TLS 1.2 record shorter than IV plus tag" {...@@ -1759,3 +1760,25 @@ test "TLS 1.2 record shorter than IV plus tag" {
1759 .{ .AES_128_GCM_SHA256 = .{ .tls_1_2 = mem.zeroes(P.Tls_1_2) } },1760 .{ .AES_128_GCM_SHA256 = .{ .tls_1_2 = mem.zeroes(P.Tls_1_2) } },
1760 ));1761 ));
1761}1762}
1763
1764test "zero-length key_update body" {
1765 const Chacha = crypto.aead.chacha_poly.ChaCha20Poly1305;
1766 const plaintext = [_]u8{ 0x18, 0x00, 0x00, 0x00, 0x16 };
1767 const header = [_]u8{ 0x17, 0x03, 0x03 } ++ mem.toBytes(big(@as(u16, plaintext.len + Chacha.tag_length)));
1768 var ct: [plaintext.len]u8 = undefined;
1769 var tag: [Chacha.tag_length]u8 = undefined;
1770 Chacha.encrypt(&ct, &tag, &plaintext, &header, @splat(0), @splat(0));
1771 const wire = header ++ ct ++ tag;
1772 try std.testing.expectEqual(error.TlsDecodeError, testReadError(
1773 &wire,
1774 .tls_1_3,
1775 .{ .CHACHA20_POLY1305_SHA256 = .{ .tls_1_3 = .{
1776 .server_key = @splat(0),
1777 .server_iv = @splat(0),
1778 .client_secret = undefined,
1779 .server_secret = undefined,
1780 .client_key = undefined,
1781 .client_iv = undefined,
1782 } } },
1783 ));
1784}