From: David Benjamin Date: Mon, 15 Feb 2016 16:51:54 +0000 (-0500) Subject: crypto/tls: Enforce that version and cipher match on resume. X-Git-Tag: go1.7beta1~758 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=73a0185ad390761f21a3407858fcccc6a11c0858;p=gostls13.git crypto/tls: Enforce that version and cipher match on resume. Per RFC 5246, 7.4.1.3: cipher_suite The single cipher suite selected by the server from the list in ClientHello.cipher_suites. For resumed sessions, this field is the value from the state of the session being resumed. The specifications are not very clearly written about resuming sessions at the wrong version (i.e. is the TLS 1.0 notion of "session" the same type as the TLS 1.1 notion of "session"?). But every other implementation enforces this check and not doing so has some odd semantics. Change-Id: I6234708bd02b636c25139d83b0d35381167e5cad Reviewed-on: https://go-review.googlesource.com/21153 Reviewed-by: Adam Langley --- diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go index f71509b25a..9517320f6c 100644 --- a/src/crypto/tls/handshake_client.go +++ b/src/crypto/tls/handshake_client.go @@ -556,6 +556,16 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) { return false, nil } + if hs.session.vers != c.vers { + c.sendAlert(alertHandshakeFailure) + return false, errors.New("tls: server resumed a session with a different version") + } + + if hs.session.cipherSuite != hs.suite.id { + c.sendAlert(alertHandshakeFailure) + return false, errors.New("tls: server resumed a session with a different cipher suite") + } + // Restore masterSecret and peerCerts from previous state hs.masterSecret = hs.session.masterSecret c.peerCertificates = hs.session.serverCertificates