Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions src/quic/tls13.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1827,19 +1827,21 @@ pub const Tls13Handshake = struct {

// Decrypt ticket identity to get PSK
if (identity_len < 16 + 1) return; // at least tag + 1 byte
var decrypted: [64]u8 = undefined;
var ct_copy: [decrypted.len + 16]u8 = undefined;
if (identity_len > ct_copy.len) return;
const ciphertext_len = identity_len - 16;
if (ciphertext_len > decrypted.len) return;

// Reconstruct nonce from ticket (we use the last 4 bytes of identity as hint)
var ticket_nonce: [12]u8 = .{0} ** 12;
// Use zeros as nonce — server encrypts with incrementing nonce_buf in [8..12]
// We need to try nonce counter values. For simplicity, try a few.
var decrypted: [64]u8 = undefined;
var psk_found = false;
var found_psk: [32]u8 = undefined;

for (0..256) |nonce_try| {
std.mem.writeInt(u32, ticket_nonce[8..12], @intCast(nonce_try), .big);
var ct_copy: [80]u8 = undefined;
@memcpy(ct_copy[0..identity_len], identity[0..identity_len]);
const tag_start = ciphertext_len;
const tag: [16]u8 = ct_copy[tag_start..][0..16].*;
Expand Down Expand Up @@ -3104,6 +3106,33 @@ test "loopback PSK resumption: two handshakes with session ticket" {
);
}

test "tryProcessPsk rejects oversized ticket identity before decrypt" {
const tp = transport_params.TransportParams{
.initial_max_data = 1048576,
.initial_max_streams_bidi = 100,
};

const server_config = TlsConfig{
.cert_chain_der = &.{},
.private_key_bytes = &.{},
.alpn = &[_][]const u8{"h3"},
.ticket_key = .{0xA5} ** 16,
};

var handshake = Tls13Handshake.initServer(server_config, tp);

var psk_ext: [124]u8 = .{0} ** 124;
std.mem.writeInt(u16, psk_ext[0..2], 87, .big);
std.mem.writeInt(u16, psk_ext[2..4], 81, .big);
std.mem.writeInt(u32, psk_ext[85..89], 0, .big);
std.mem.writeInt(u16, psk_ext[89..91], 33, .big);
psk_ext[91] = 32;

handshake.tryProcessPsk("", "", 0, &psk_ext, 0, psk_ext.len);

try std.testing.expect(!handshake.using_psk);
}

// NewSessionTicket roundtrip test
test "NewSessionTicket: build and parse roundtrip" {
const psk: [32]u8 = .{0x55} ** 32;
Expand Down