]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/crypto/tls/handshake_client.go
[dev.boringcrypto] all: merge master into dev.boringcrypto
[gostls13.git] / src / crypto / tls / handshake_client.go
index a72555f66e62d83b46e73cf243da8e35a7907b20..e089762b9f9a635ef396fde94afa808075d64bcc 100644 (file)
@@ -149,6 +149,7 @@ func (c *Conn) clientHandshake() (err error) {
        if err != nil {
                return err
        }
+       c.serverName = hello.serverName
 
        cacheKey, session, earlySecret, binderKey := c.loadSession(hello)
        if cacheKey != "" && session != nil {
@@ -391,6 +392,7 @@ func (hs *clientHandshakeState) handshake() error {
        hs.finishedHash.Write(hs.serverHello.marshal())
 
        c.buffering = true
+       c.didResume = isResume
        if isResume {
                if err := hs.establishKeys(); err != nil {
                        return err
@@ -402,6 +404,15 @@ func (hs *clientHandshakeState) handshake() error {
                        return err
                }
                c.clientFinishedIsFirst = false
+               // Make sure the connection is still being verified whether or not this
+               // is a resumption. Resumptions currently don't reverify certificates so
+               // they don't call verifyServerCertificate. See Issue 31641.
+               if c.config.VerifyConnection != nil {
+                       if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+                               c.sendAlert(alertBadCertificate)
+                               return err
+                       }
+               }
                if err := hs.sendFinished(c.clientFinished[:]); err != nil {
                        return err
                }
@@ -431,7 +442,6 @@ func (hs *clientHandshakeState) handshake() error {
        }
 
        c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
-       c.didResume = isResume
        atomic.StoreUint32(&c.handshakeStatus, 1)
 
        return nil
@@ -461,25 +471,6 @@ func (hs *clientHandshakeState) doFullHandshake() error {
        }
        hs.finishedHash.Write(certMsg.marshal())
 
-       if c.handshakes == 0 {
-               // If this is the first handshake on a connection, process and
-               // (optionally) verify the server's certificates.
-               if err := c.verifyServerCertificate(certMsg.certificates); err != nil {
-                       return err
-               }
-       } else {
-               // This is a renegotiation handshake. We require that the
-               // server's identity (i.e. leaf certificate) is unchanged and
-               // thus any previous trust decision is still valid.
-               //
-               // See https://mitls.org/pages/attacks/3SHAKE for the
-               // motivation behind this requirement.
-               if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
-                       c.sendAlert(alertBadCertificate)
-                       return errors.New("tls: server's identity changed during renegotiation")
-               }
-       }
-
        msg, err = c.readHandshake()
        if err != nil {
                return err
@@ -508,6 +499,25 @@ func (hs *clientHandshakeState) doFullHandshake() error {
                }
        }
 
+       if c.handshakes == 0 {
+               // If this is the first handshake on a connection, process and
+               // (optionally) verify the server's certificates.
+               if err := c.verifyServerCertificate(certMsg.certificates); err != nil {
+                       return err
+               }
+       } else {
+               // This is a renegotiation handshake. We require that the
+               // server's identity (i.e. leaf certificate) is unchanged and
+               // thus any previous trust decision is still valid.
+               //
+               // See https://mitls.org/pages/attacks/3SHAKE for the
+               // motivation behind this requirement.
+               if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
+                       c.sendAlert(alertBadCertificate)
+                       return errors.New("tls: server's identity changed during renegotiation")
+               }
+       }
+
        keyAgreement := hs.suite.ka(c.vers)
 
        skx, ok := msg.(*serverKeyExchangeMsg)
@@ -721,10 +731,17 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
                return false, errors.New("tls: server resumed a session with a different cipher suite")
        }
 
-       // Restore masterSecret and peerCerts from previous state
+       // Restore masterSecret, peerCerts, and ocspResponse from previous state
        hs.masterSecret = hs.session.masterSecret
        c.peerCertificates = hs.session.serverCertificates
        c.verifiedChains = hs.session.verifiedChains
+       c.ocspResponse = hs.session.ocspResponse
+       // Let the ServerHello SCTs override the session SCTs from the original
+       // connection, if any are provided
+       if len(c.scts) == 0 && len(hs.session.scts) != 0 {
+               c.scts = hs.session.scts
+       }
+
        return true, nil
 }
 
@@ -781,6 +798,8 @@ func (hs *clientHandshakeState) readSessionTicket() error {
                serverCertificates: c.peerCertificates,
                verifiedChains:     c.verifiedChains,
                receivedAt:         c.config.time(),
+               ocspResponse:       c.ocspResponse,
+               scts:               c.scts,
        }
 
        return nil
@@ -836,13 +855,6 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
                }
        }
 
-       if c.config.VerifyPeerCertificate != nil {
-               if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
-                       c.sendAlert(alertBadCertificate)
-                       return err
-               }
-       }
-
        switch certs[0].PublicKey.(type) {
        case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
                break
@@ -853,6 +865,20 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
 
        c.peerCertificates = certs
 
+       if c.config.VerifyPeerCertificate != nil {
+               if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
+                       c.sendAlert(alertBadCertificate)
+                       return err
+               }
+       }
+
+       if c.config.VerifyConnection != nil {
+               if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+                       c.sendAlert(alertBadCertificate)
+                       return err
+               }
+       }
+
        return nil
 }