From 8fd7219bfc1542239e377e40b9621ef382103eaa Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 23 Feb 2018 19:08:53 +0800 Subject: [PATCH] delete handshake packets from history when receiving a forward-secure packet --- internal/ackhandler/sent_packet_handler.go | 7 +++++++ session.go | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index 08b4ee5a3..11fa2f911 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -101,6 +101,13 @@ func (h *sentPacketHandler) SetHandshakeComplete() { queue = append(queue, packet) } } + for el := h.packetHistory.Front(); el != nil; { + next := el.Next() + if el.Value.EncryptionLevel != protocol.EncryptionForwardSecure { + h.packetHistory.Remove(el) + } + el = next + } h.retransmissionQueue = queue h.handshakeComplete = true } diff --git a/session.go b/session.go index 681444976..1acfdc82f 100644 --- a/session.go +++ b/session.go @@ -111,8 +111,9 @@ type session struct { handshakeChan chan error handshakeComplete bool - receivedFirstPacket bool // since packet numbers start at 0, we can't use largestRcvdPacketNumber != 0 for this - lastRcvdPacketNumber protocol.PacketNumber + receivedFirstPacket bool // since packet numbers start at 0, we can't use largestRcvdPacketNumber != 0 for this + receivedFirstForwardSecurePacket bool + lastRcvdPacketNumber protocol.PacketNumber // Used to calculate the next packet number from the truncated wire // representation, and sent back in public reset packets largestRcvdPacketNumber protocol.PacketNumber @@ -401,7 +402,6 @@ runLoop: if !ok { // the aeadChanged chan was closed. This means that the handshake is completed. s.handshakeComplete = true handshakeEvent = nil // prevent this case from ever being selected again - s.sentPacketHandler.SetHandshakeComplete() if !s.version.UsesTLS() && s.perspective == protocol.PerspectiveClient { // In gQUIC, there's no equivalent to the Finished message in TLS // The server knows that the handshake is complete when it receives the first forward-secure packet sent by the client. @@ -537,6 +537,15 @@ func (s *session) handlePacketImpl(p *receivedPacket) error { return err } + // In TLS 1.3, the client considers the handshake complete as soon as + // it received the server's Finished message and sent its Finished. + // We have to wait for the first forward-secure packet from the server before + // deleting all handshake packets from the history. + if !s.receivedFirstForwardSecurePacket && packet.encryptionLevel == protocol.EncryptionForwardSecure { + s.receivedFirstForwardSecurePacket = true + s.sentPacketHandler.SetHandshakeComplete() + } + s.lastRcvdPacketNumber = hdr.PacketNumber // Only do this after decrypting, so we are sure the packet is not attacker-controlled s.largestRcvdPacketNumber = utils.MaxPacketNumber(s.largestRcvdPacketNumber, hdr.PacketNumber)