Merge pull request #1200 from lucas-clemente/fix-1174

delete handshake packets from history when receiving a forward-secure packet
This commit is contained in:
Marten Seemann
2018-02-23 22:29:10 +08:00
committed by GitHub
2 changed files with 19 additions and 3 deletions

View File

@@ -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
}

View File

@@ -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)