crypto/tls: detect unexpected leftover handshake data

There should be no data in the Handshake buffer on encryption state
changes (including implicit 1.3 transitions). Checking that also blocks
all Handshake messages fragmented across CCS.

BoGo: PartialClientFinishedWithClientHello
This commit is contained in:
Filippo Valsorda 2017-01-18 17:13:07 +00:00 committed by Peter Wu
parent de613b152d
commit c758567785
2 changed files with 13 additions and 0 deletions

10
13.go
View File

@ -120,6 +120,9 @@ CurvePreferenceLoop:
serverCipher, _ = hs.prepareCipher(handshakeCtx, hs.masterSecret, "server application traffic secret") serverCipher, _ = hs.prepareCipher(handshakeCtx, hs.masterSecret, "server application traffic secret")
c.out.setCipher(c.vers, serverCipher) c.out.setCipher(c.vers, serverCipher)
if c.hand.Len() > 0 {
return c.sendAlert(alertUnexpectedMessage)
}
if hs.hello13Enc.earlyData { if hs.hello13Enc.earlyData {
c.in.setCipher(c.vers, earlyClientCipher) c.in.setCipher(c.vers, earlyClientCipher)
c.phase = readingEarlyData c.phase = readingEarlyData
@ -162,6 +165,9 @@ func (hs *serverHandshakeState) readClientFinished13() error {
hs.finishedHash13.Write(clientFinished.marshal()) hs.finishedHash13.Write(clientFinished.marshal())
c.hs = nil // Discard the server handshake state c.hs = nil // Discard the server handshake state
if c.hand.Len() > 0 {
return c.sendAlert(alertUnexpectedMessage)
}
c.in.setCipher(c.vers, hs.appClientCipher) c.in.setCipher(c.vers, hs.appClientCipher)
c.in.traceErr, c.out.traceErr = nil, nil c.in.traceErr, c.out.traceErr = nil, nil
c.phase = handshakeConfirmed c.phase = handshakeConfirmed
@ -224,6 +230,10 @@ func (c *Conn) handleEndOfEarlyData() {
return return
} }
c.phase = waitingClientFinished c.phase = waitingClientFinished
if c.hand.Len() > 0 {
c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
return
}
c.in.setCipher(c.vers, c.hs.hsClientCipher) c.in.setCipher(c.vers, c.hs.hsClientCipher)
} }

View File

@ -132,6 +132,9 @@ func (c *Conn) serverHandshake() error {
return err return err
} }
} }
if c.hand.Len() > 0 {
return c.sendAlert(alertUnexpectedMessage)
}
c.phase = handshakeConfirmed c.phase = handshakeConfirmed
atomic.StoreInt32(&c.handshakeConfirmed, 1) atomic.StoreInt32(&c.handshakeConfirmed, 1)
c.handshakeComplete = true c.handshakeComplete = true