Update to TLS 1.3 draft 18.

This is the squash of the following CLs:
https://boringssl-review.googlesource.com/c/12021/9
https://boringssl-review.googlesource.com/c/12022/9
https://boringssl-review.googlesource.com/c/12107/19
https://boringssl-review.googlesource.com/c/12141/22
https://boringssl-review.googlesource.com/c/12181/33

The Go portions were written by Nick Harper

BUG=112

Change-Id: I375a1fcead493ec3e0282e231ccc8d7c4dde5063
Reviewed-on: https://boringssl-review.googlesource.com/12300
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index 4b3df2d..1e0d313 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -16,6 +16,7 @@
 	"fmt"
 	"io"
 	"math/big"
+	"time"
 )
 
 // serverHandshakeState contains details of a server handshake in progress.
@@ -404,78 +405,75 @@
 	}
 
 	pskIdentities := hs.clientHello.pskIdentities
+	pskKEModes := hs.clientHello.pskKEModes
+
 	if len(pskIdentities) == 0 && len(hs.clientHello.sessionTicket) > 0 && c.config.Bugs.AcceptAnySession {
 		psk := pskIdentity{
-			keModes:   []byte{pskDHEKEMode},
-			authModes: []byte{pskAuthMode},
-			ticket:    hs.clientHello.sessionTicket,
+			ticket: hs.clientHello.sessionTicket,
 		}
 		pskIdentities = []pskIdentity{psk}
+		pskKEModes = []byte{pskDHEKEMode}
 	}
-	for i, pskIdentity := range pskIdentities {
-		foundKE := false
-		foundAuth := false
 
-		for _, keMode := range pskIdentity.keModes {
-			if keMode == pskDHEKEMode {
-				foundKE = true
-			}
-		}
-
-		for _, authMode := range pskIdentity.authModes {
-			if authMode == pskAuthMode {
-				foundAuth = true
-			}
-		}
-
-		if !foundKE || !foundAuth {
-			continue
-		}
-
-		sessionState, ok := c.decryptTicket(pskIdentity.ticket)
-		if !ok {
-			continue
-		}
-		if config.Bugs.AcceptAnySession {
-			// Replace the cipher suite with one known to work, to
-			// test cross-version resumption attempts.
-			sessionState.cipherSuite = TLS_AES_128_GCM_SHA256
-		} else {
-			if sessionState.vers != c.vers && c.config.Bugs.AcceptAnySession {
-				continue
-			}
-			if sessionState.ticketExpiration.Before(c.config.time()) {
+	var pskIndex int
+	foundKEMode := bytes.IndexByte(pskKEModes, pskDHEKEMode) >= 0
+	if foundKEMode {
+		for i, pskIdentity := range pskIdentities {
+			// TODO(svaldez): Check the obfuscatedTicketAge before accepting 0-RTT.
+			sessionState, ok := c.decryptTicket(pskIdentity.ticket)
+			if !ok {
 				continue
 			}
 
-			cipherSuiteOk := false
-			// Check that the client is still offering the ciphersuite in the session.
-			for _, id := range hs.clientHello.cipherSuites {
-				if id == sessionState.cipherSuite {
-					cipherSuiteOk = true
-					break
+			if config.Bugs.AcceptAnySession {
+				// Replace the cipher suite with one known to work, to
+				// test cross-version resumption attempts.
+				sessionState.cipherSuite = TLS_AES_128_GCM_SHA256
+			} else {
+				if sessionState.vers != c.vers && c.config.Bugs.AcceptAnySession {
+					continue
 				}
+				if sessionState.ticketExpiration.Before(c.config.time()) {
+					continue
+				}
+
+				clientTicketAge := time.Duration(uint32(pskIdentity.obfuscatedTicketAge-sessionState.ticketAgeAdd)) * time.Millisecond
+				if config.Bugs.ExpectTicketAge != 0 && clientTicketAge != config.Bugs.ExpectTicketAge {
+					c.sendAlert(alertHandshakeFailure)
+					return errors.New("tls: invalid ticket age")
+				}
+
+				cipherSuiteOk := false
+				// Check that the client is still offering the ciphersuite in the session.
+				for _, id := range hs.clientHello.cipherSuites {
+					if id == sessionState.cipherSuite {
+						cipherSuiteOk = true
+						break
+					}
+				}
+				if !cipherSuiteOk {
+					continue
+				}
+
 			}
-			if !cipherSuiteOk {
+
+			// Check that we also support the ciphersuite from the session.
+			suite := c.tryCipherSuite(sessionState.cipherSuite, c.config.cipherSuites(), c.vers, true, true)
+			if suite == nil {
 				continue
 			}
-		}
 
-		// Check that we also support the ciphersuite from the session.
-		suite := c.tryCipherSuite(sessionState.cipherSuite, c.config.cipherSuites(), c.vers, true, true)
-		if suite == nil {
-			continue
+			hs.sessionState = sessionState
+			hs.suite = suite
+			hs.hello.hasPSKIdentity = true
+			hs.hello.pskIdentity = uint16(i)
+			pskIndex = i
+			if config.Bugs.SelectPSKIdentityOnResume != 0 {
+				hs.hello.pskIdentity = config.Bugs.SelectPSKIdentityOnResume
+			}
+			c.didResume = true
+			break
 		}
-
-		hs.sessionState = sessionState
-		hs.suite = suite
-		hs.hello.hasPSKIdentity = true
-		hs.hello.pskIdentity = uint16(i)
-		if config.Bugs.SelectPSKIdentityOnResume != 0 {
-			hs.hello.pskIdentity = config.Bugs.SelectPSKIdentityOnResume
-		}
-		c.didResume = true
-		break
 	}
 
 	if config.Bugs.AlwaysSelectPSKIdentity {
@@ -483,6 +481,15 @@
 		hs.hello.pskIdentity = 0
 	}
 
+	// Verify the PSK binder. Note there may not be a PSK binder if
+	// AcceptAnyBinder is set. See https://crbug.com/boringssl/115.
+	if hs.sessionState != nil && !config.Bugs.AcceptAnySession {
+		binderToVerify := hs.clientHello.pskBinders[pskIndex]
+		if err := verifyPSKBinder(hs.clientHello, hs.sessionState, binderToVerify, []byte{}); err != nil {
+			return err
+		}
+	}
+
 	// If not resuming, select the cipher suite.
 	if hs.suite == nil {
 		var preferenceList, supportedList []uint16
@@ -515,26 +522,16 @@
 	hs.finishedHash.discardHandshakeBuffer()
 	hs.writeClientHash(hs.clientHello.marshal())
 
-	hs.hello.useCertAuth = hs.sessionState == nil
-
 	// Resolve PSK and compute the early secret.
 	var psk []byte
 	if hs.sessionState != nil {
-		psk = deriveResumptionPSK(hs.suite, hs.sessionState.masterSecret)
-		hs.finishedHash.setResumptionContext(deriveResumptionContext(hs.suite, hs.sessionState.masterSecret))
+		psk = hs.sessionState.masterSecret
 	} else {
 		psk = hs.finishedHash.zeroSecret()
-		hs.finishedHash.setResumptionContext(hs.finishedHash.zeroSecret())
 	}
 
 	earlySecret := hs.finishedHash.extractKey(hs.finishedHash.zeroSecret(), psk)
 
-	if config.Bugs.OmitServerHelloSignatureAlgorithms {
-		hs.hello.useCertAuth = false
-	} else if config.Bugs.IncludeServerHelloSignatureAlgorithms {
-		hs.hello.useCertAuth = true
-	}
-
 	hs.hello.hasKeyShare = true
 	if hs.sessionState != nil && config.Bugs.NegotiatePSKResumption {
 		hs.hello.hasKeyShare = false
@@ -598,6 +595,7 @@
 	}
 
 	if sendHelloRetryRequest {
+		oldClientHelloBytes := hs.clientHello.marshal()
 		hs.writeServerHash(helloRetryRequest.marshal())
 		c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal())
 		c.flushHandshake()
@@ -627,11 +625,11 @@
 
 		if helloRetryRequest.hasSelectedGroup {
 			newKeyShares := newClientHelloCopy.keyShares
-			if len(newKeyShares) == 0 || newKeyShares[len(newKeyShares)-1].group != helloRetryRequest.selectedGroup {
-				return errors.New("tls: KeyShare from HelloRetryRequest not present in new ClientHello")
+			if len(newKeyShares) != 1 || newKeyShares[0].group != helloRetryRequest.selectedGroup {
+				return errors.New("tls: KeyShare from HelloRetryRequest not in new ClientHello")
 			}
-			selectedKeyShare = &newKeyShares[len(newKeyShares)-1]
-			newClientHelloCopy.keyShares = newKeyShares[:len(newKeyShares)-1]
+			selectedKeyShare = &newKeyShares[0]
+			newClientHelloCopy.keyShares = oldClientHelloCopy.keyShares
 		}
 
 		if len(helloRetryRequest.cookie) > 0 {
@@ -640,6 +638,7 @@
 			}
 			newClientHelloCopy.tls13Cookie = nil
 		}
+		newClientHelloCopy.pskBinders = oldClientHelloCopy.pskBinders
 
 		if !oldClientHelloCopy.equal(&newClientHelloCopy) {
 			return errors.New("tls: new ClientHello does not match")
@@ -649,6 +648,16 @@
 			firstHelloRetryRequest = false
 			goto ResendHelloRetryRequest
 		}
+
+		// Verify the PSK binder. Note there may not be a PSK binder if
+		// AcceptAnyBinder is set. See https://crbug.com/115.
+		if hs.sessionState != nil && !config.Bugs.AcceptAnySession {
+			binderToVerify := newClientHello.pskBinders[pskIndex]
+			err := verifyPSKBinder(newClientHello, hs.sessionState, binderToVerify, append(oldClientHelloBytes, helloRetryRequest.marshal()...))
+			if err != nil {
+				return err
+			}
+		}
 	}
 
 	// Resolve ECDHE and compute the handshake secret.
@@ -728,25 +737,9 @@
 
 	// Switch to handshake traffic keys.
 	serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(handshakeSecret, serverHandshakeTrafficLabel)
-	c.out.useTrafficSecret(c.vers, hs.suite, serverHandshakeTrafficSecret, handshakePhase, serverWrite)
+	c.out.useTrafficSecret(c.vers, hs.suite, serverHandshakeTrafficSecret, serverWrite)
 	clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(handshakeSecret, clientHandshakeTrafficLabel)
-	c.in.useTrafficSecret(c.vers, hs.suite, clientHandshakeTrafficSecret, handshakePhase, clientWrite)
-
-	if hs.hello.useCertAuth {
-		if hs.clientHello.ocspStapling {
-			encryptedExtensions.extensions.ocspResponse = hs.cert.OCSPStaple
-		}
-		if hs.clientHello.sctListSupported {
-			encryptedExtensions.extensions.sctList = hs.cert.SignedCertificateTimestampList
-		}
-	} else {
-		if config.Bugs.SendOCSPResponseOnResume != nil {
-			encryptedExtensions.extensions.ocspResponse = config.Bugs.SendOCSPResponseOnResume
-		}
-		if config.Bugs.SendSCTListOnResume != nil {
-			encryptedExtensions.extensions.sctList = config.Bugs.SendSCTListOnResume
-		}
-	}
+	c.in.useTrafficSecret(c.vers, hs.suite, clientHandshakeTrafficSecret, clientWrite)
 
 	// Send EncryptedExtensions.
 	hs.writeServerHash(encryptedExtensions.marshal())
@@ -757,7 +750,7 @@
 		c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal())
 	}
 
-	if hs.hello.useCertAuth {
+	if hs.sessionState == nil {
 		if config.ClientAuth >= RequestClientCert {
 			// Request a client certificate
 			certReq := &certificateRequestMsg{
@@ -785,7 +778,29 @@
 			hasRequestContext: true,
 		}
 		if !config.Bugs.EmptyCertificateList {
-			certMsg.certificates = hs.cert.Certificate
+			for i, certData := range hs.cert.Certificate {
+				cert := certificateEntry{
+					data: certData,
+				}
+				if i == 0 {
+					if hs.clientHello.ocspStapling {
+						cert.ocspResponse = hs.cert.OCSPStaple
+					}
+					if hs.clientHello.sctListSupported {
+						cert.sctList = hs.cert.SignedCertificateTimestampList
+					}
+					cert.duplicateExtensions = config.Bugs.SendDuplicateCertExtensions
+					cert.extraExtension = config.Bugs.SendExtensionOnCertificate
+				} else {
+					if config.Bugs.SendOCSPOnIntermediates != nil {
+						cert.ocspResponse = config.Bugs.SendOCSPOnIntermediates
+					}
+					if config.Bugs.SendSCTOnIntermediates != nil {
+						cert.sctList = config.Bugs.SendSCTOnIntermediates
+					}
+				}
+				certMsg.certificates = append(certMsg.certificates, cert)
+			}
 		}
 		certMsgBytes := certMsg.marshal()
 		hs.writeServerHash(certMsgBytes)
@@ -844,10 +859,11 @@
 	masterSecret := hs.finishedHash.extractKey(handshakeSecret, hs.finishedHash.zeroSecret())
 	clientTrafficSecret := hs.finishedHash.deriveSecret(masterSecret, clientApplicationTrafficLabel)
 	serverTrafficSecret := hs.finishedHash.deriveSecret(masterSecret, serverApplicationTrafficLabel)
+	c.exporterSecret = hs.finishedHash.deriveSecret(masterSecret, exporterLabel)
 
 	// Switch to application data keys on write. In particular, any alerts
 	// from the client certificate are sent over these keys.
-	c.out.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, applicationPhase, serverWrite)
+	c.out.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, serverWrite)
 
 	// If we requested a client certificate, then the client must send a
 	// certificate message, even if it's empty.
@@ -873,7 +889,17 @@
 			}
 		}
 
-		pub, err := hs.processCertsFromClient(certMsg.certificates)
+		var certs [][]byte
+		for _, cert := range certMsg.certificates {
+			certs = append(certs, cert.data)
+			// OCSP responses and SCT lists are not negotiated in
+			// client certificates.
+			if cert.ocspResponse != nil || cert.sctList != nil {
+				c.sendAlert(alertUnsupportedExtension)
+				return errors.New("tls: unexpected extensions in the client certificate")
+			}
+		}
+		pub, err := hs.processCertsFromClient(certs)
 		if err != nil {
 			return err
 		}
@@ -941,15 +967,14 @@
 	hs.writeClientHash(clientFinished.marshal())
 
 	// Switch to application data keys on read.
-	c.in.useTrafficSecret(c.vers, hs.suite, clientTrafficSecret, applicationPhase, clientWrite)
+	c.in.useTrafficSecret(c.vers, hs.suite, clientTrafficSecret, clientWrite)
 
 	c.cipherSuite = hs.suite
-	c.exporterSecret = hs.finishedHash.deriveSecret(masterSecret, exporterLabel)
 	c.resumptionSecret = hs.finishedHash.deriveSecret(masterSecret, resumptionLabel)
 
 	// TODO(davidben): Allow configuring the number of tickets sent for
 	// testing.
-	if !c.config.SessionTicketsDisabled {
+	if !c.config.SessionTicketsDisabled && foundKEMode {
 		ticketCount := 2
 		for i := 0; i < ticketCount; i++ {
 			c.SendNewSessionTicket()
@@ -1134,7 +1159,7 @@
 			if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 {
 				serverExtensions.nextProtoNeg = true
 				serverExtensions.nextProtos = config.NextProtos
-				serverExtensions.npnLast = config.Bugs.SwapNPNAndALPN
+				serverExtensions.npnAfterAlpn = config.Bugs.SwapNPNAndALPN
 			}
 		}
 	}
@@ -1340,7 +1365,11 @@
 	if !isPSK {
 		certMsg := new(certificateMsg)
 		if !config.Bugs.EmptyCertificateList {
-			certMsg.certificates = hs.cert.Certificate
+			for _, certData := range hs.cert.Certificate {
+				certMsg.certificates = append(certMsg.certificates, certificateEntry{
+					data: certData,
+				})
+			}
 		}
 		if !config.Bugs.UnauthenticatedECDH {
 			certMsgBytes := certMsg.marshal()
@@ -1428,7 +1457,9 @@
 			}
 
 			hs.writeClientHash(certMsg.marshal())
-			certificates = certMsg.certificates
+			for _, cert := range certMsg.certificates {
+				certificates = append(certificates, cert.data)
+			}
 		} else if c.vers != VersionSSL30 {
 			// In TLS, the Certificate message is required. In SSL
 			// 3.0, the peer skips it when sending no certificates.
@@ -1876,3 +1907,24 @@
 func isGREASEValue(val uint16) bool {
 	return val&0x0f0f == 0x0a0a && val&0xff == val>>8
 }
+
+func verifyPSKBinder(clientHello *clientHelloMsg, sessionState *sessionState, binderToVerify, transcript []byte) error {
+	binderLen := 2
+	for _, binder := range clientHello.pskBinders {
+		binderLen += 1 + len(binder)
+	}
+
+	truncatedHello := clientHello.marshal()
+	truncatedHello = truncatedHello[:len(truncatedHello)-binderLen]
+	pskCipherSuite := cipherSuiteFromID(sessionState.cipherSuite)
+	if pskCipherSuite == nil {
+		return errors.New("tls: Unknown cipher suite for PSK in session")
+	}
+
+	binder := computePSKBinder(sessionState.masterSecret, resumptionPSKBinderLabel, pskCipherSuite, transcript, truncatedHello)
+	if !bytes.Equal(binder, binderToVerify) {
+		return errors.New("tls: PSK binder does not verify")
+	}
+
+	return nil
+}