Copyright 2018 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package tls

import (
	
	
	
	
	
	
	
	
	
)
maxClientPSKIdentities is the number of client PSK identities the server will attempt to validate. It will ignore the rest not to let cheap ClientHello messages cause too much work in session ticket decryption attempts.
For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
	if  := .processClientHello();  != nil {
		return 
	}
	if  := .checkForResumption();  != nil {
		return 
	}
	if  := .pickCertificate();  != nil {
		return 
	}
	.buffering = true
	if  := .sendServerParameters();  != nil {
		return 
	}
	if  := .sendServerCertificate();  != nil {
		return 
	}
	if  := .sendServerFinished();  != nil {
		return 
Note that at this point we could start sending application data without waiting for the client's second flight, but the application might not expect the lack of replay protection of the ClientHello parameters.
	if ,  := .flush();  != nil {
		return 
	}
	if  := .readClientCertificate();  != nil {
		return 
	}
	if  := .readClientFinished();  != nil {
		return 
	}

	atomic.StoreUint32(&.handshakeStatus, 1)

	return nil
}

func ( *serverHandshakeStateTLS13) () error {
	 := .c

	.hello = new(serverHelloMsg)
TLS 1.3 froze the ServerHello.legacy_version field, and uses supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1.
	.hello.vers = VersionTLS12
	.hello.supportedVersion = .vers

	if len(.clientHello.supportedVersions) == 0 {
		.sendAlert(alertIllegalParameter)
		return errors.New("tls: client used the legacy version field to negotiate TLS 1.3")
	}
Abort if the client is doing a fallback and landing lower than what we support. See RFC 7507, which however does not specify the interaction with supported_versions. The only difference is that with supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4] handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case, it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to TLS 1.2, because a TLS 1.3 server would abort here. The situation before supported_versions was not better because there was just no way to do a TLS 1.4 handshake without risking the server selecting TLS 1.3.
	for ,  := range .clientHello.cipherSuites {
Use c.vers instead of max(supported_versions) because an attacker could defeat this by adding an arbitrary high version otherwise.
			if .vers < .config.maxSupportedVersion() {
				.sendAlert(alertInappropriateFallback)
				return errors.New("tls: client using inappropriate protocol fallback")
			}
			break
		}
	}

	if len(.clientHello.compressionMethods) != 1 ||
		.clientHello.compressionMethods[0] != compressionNone {
		.sendAlert(alertIllegalParameter)
		return errors.New("tls: TLS 1.3 client supports illegal compression methods")
	}

	.hello.random = make([]byte, 32)
	if ,  := io.ReadFull(.config.rand(), .hello.random);  != nil {
		.sendAlert(alertInternalError)
		return 
	}

	if len(.clientHello.secureRenegotiation) != 0 {
		.sendAlert(alertHandshakeFailure)
		return errors.New("tls: initial handshake had non-empty renegotiation extension")
	}

See RFC 8446, Section 4.2.10 for the complicated behavior required here. The scenario is that a different server at our address offered to accept early data in the past, which we can't handle. For now, all 0-RTT enabled session tickets need to expire before a Go server can replace a server or join a pool. That's the same requirement that applies to mixing or replacing with any TLS 1.2 server.
		.sendAlert(alertUnsupportedExtension)
		return errors.New("tls: client sent unexpected early data")
	}

	.hello.sessionId = .clientHello.sessionId
	.hello.compressionMethod = compressionNone

	var ,  []uint16
	if .config.PreferServerCipherSuites {
		 = defaultCipherSuitesTLS13()
		 = .clientHello.cipherSuites
If the client does not seem to have hardware support for AES-GCM, prefer other AEAD ciphers even if we prioritized AES-GCM ciphers by default.
		if !aesgcmPreferred(.clientHello.cipherSuites) {
			 = deprioritizeAES()
		}
	} else {
		 = .clientHello.cipherSuites
		 = defaultCipherSuitesTLS13()
If we don't have hardware support for AES-GCM, prefer other AEAD ciphers even if the client prioritized AES-GCM.
		if !hasAESGCMHardwareSupport {
			 = deprioritizeAES()
		}
	}
	for ,  := range  {
		.suite = mutualCipherSuiteTLS13(, )
		if .suite != nil {
			break
		}
	}
	if .suite == nil {
		.sendAlert(alertHandshakeFailure)
		return errors.New("tls: no cipher suite supported by both client and server")
	}
	.cipherSuite = .suite.id
	.hello.cipherSuite = .suite.id
	.transcript = .suite.hash.New()
Pick the ECDHE group in server preference order, but give priority to groups with a key share, to avoid a HelloRetryRequest round-trip.
	var  CurveID
	var  *keyShare
:
	for ,  := range .config.curvePreferences() {
		for ,  := range .clientHello.keyShares {
			if .group ==  {
				 = .group
				 = &
				break 
			}
		}
		if  != 0 {
			continue
		}
		for ,  := range .clientHello.supportedCurves {
			if  ==  {
				 = 
				break
			}
		}
	}
	if  == 0 {
		.sendAlert(alertHandshakeFailure)
		return errors.New("tls: no ECDHE curve supported by both client and server")
	}
	if  == nil {
		if  := .doHelloRetryRequest();  != nil {
			return 
		}
		 = &.clientHello.keyShares[0]
	}

	if ,  := curveForCurveID();  != X25519 && ! {
		.sendAlert(alertInternalError)
		return errors.New("tls: CurvePreferences includes unsupported curve")
	}
	,  := generateECDHEParameters(.config.rand(), )
	if  != nil {
		.sendAlert(alertInternalError)
		return 
	}
	.hello.serverShare = keyShare{group: , data: .PublicKey()}
	.sharedKey = .SharedKey(.data)
	if .sharedKey == nil {
		.sendAlert(alertIllegalParameter)
		return errors.New("tls: invalid client key share")
	}

	.serverName = .clientHello.serverName
	return nil
}

func ( *serverHandshakeStateTLS13) () error {
	 := .c

	if .config.SessionTicketsDisabled {
		return nil
	}

	 := false
	for ,  := range .clientHello.pskModes {
		if  == pskModeDHE {
			 = true
			break
		}
	}
	if ! {
		return nil
	}

	if len(.clientHello.pskIdentities) != len(.clientHello.pskBinders) {
		.sendAlert(alertIllegalParameter)
		return errors.New("tls: invalid or missing PSK binders")
	}
	if len(.clientHello.pskIdentities) == 0 {
		return nil
	}

	for ,  := range .clientHello.pskIdentities {
		if  >= maxClientPSKIdentities {
			break
		}

		,  := .decryptTicket(.label)
		if  == nil {
			continue
		}
		 := new(sessionStateTLS13)
		if  := .unmarshal(); ! {
			continue
		}

		 := time.Unix(int64(.createdAt), 0)
		if .config.time().Sub() > maxSessionTicketLifetime {
			continue
		}
We don't check the obfuscated ticket age because it's affected by clock skew and it's only a freshness signal useful for shrinking the window for replay attacks, which don't affect us as we don't do 0-RTT.

		 := cipherSuiteTLS13ByID(.cipherSuite)
		if  == nil || .hash != .suite.hash {
			continue
		}
PSK connections don't re-establish client certificates, but carry them over in the session ticket. Ensure the presence of client certs in the ticket is consistent with the configured requirements.
		 := len(.certificate.Certificate) != 0
		 := requiresClientCert(.config.ClientAuth)
		if  && ! {
			continue
		}
		if  && .config.ClientAuth == NoClientCert {
			continue
		}

		 := .suite.expandLabel(.resumptionSecret, "resumption",
			nil, .suite.hash.Size())
		.earlySecret = .suite.extract(, nil)
Clone the transcript in case a HelloRetryRequest was recorded.
		 := cloneHash(.transcript, .suite.hash)
		if  == nil {
			.sendAlert(alertInternalError)
			return errors.New("tls: internal error: failed to clone hash")
		}
		.Write(.clientHello.marshalWithoutBinders())
		 := .suite.finishedHash(, )
		if !hmac.Equal(.clientHello.pskBinders[], ) {
			.sendAlert(alertDecryptError)
			return errors.New("tls: invalid PSK binder")
		}

		.didResume = true
		if  := .processCertsFromClient(.certificate);  != nil {
			return 
		}

		.hello.selectedIdentityPresent = true
		.hello.selectedIdentity = uint16()
		.usingPSK = true
		return nil
	}

	return nil
}
cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler interfaces implemented by standard library hashes to clone the state of in to a new instance of h. It returns nil if the operation fails.
Recreate the interface to avoid importing encoding.
	type  interface {
		() ( []byte,  error)
		( []byte) error
	}
	,  := .()
	if ! {
		return nil
	}
	,  := .()
	if  != nil {
		return nil
	}
	 := .New()
	,  := .()
	if ! {
		return nil
	}
	if  := .();  != nil {
		return nil
	}
	return 
}

func ( *serverHandshakeStateTLS13) () error {
	 := .c
Only one of PSK and certificates are used at a time.
	if .usingPSK {
		return nil
	}
signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3.
getCertificate returned a certificate that is unsupported or incompatible with the client's signature algorithms.
		.sendAlert(alertHandshakeFailure)
		return 
	}
	.cert = 

	return nil
}
sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
The first ClientHello gets double-hashed into the transcript upon a HelloRetryRequest. See RFC 8446, Section 4.4.1.
	.transcript.Write(.clientHello.marshal())
	 := .transcript.Sum(nil)
	.transcript.Reset()
	.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len())})
	.transcript.Write()

	 := &serverHelloMsg{
		vers:              .hello.vers,
		random:            helloRetryRequestRandom,
		sessionId:         .hello.sessionId,
		cipherSuite:       .hello.cipherSuite,
		compressionMethod: .hello.compressionMethod,
		supportedVersion:  .hello.supportedVersion,
		selectedGroup:     ,
	}

	.transcript.Write(.marshal())
	if ,  := .writeRecord(recordTypeHandshake, .marshal());  != nil {
		return 
	}

	if  := .sendDummyChangeCipherSpec();  != nil {
		return 
	}

	,  := .readHandshake()
	if  != nil {
		return 
	}

	,  := .(*clientHelloMsg)
	if ! {
		.sendAlert(alertUnexpectedMessage)
		return unexpectedMessageError(, )
	}

	if len(.keyShares) != 1 || .keyShares[0].group !=  {
		.sendAlert(alertIllegalParameter)
		return errors.New("tls: client sent invalid key share in second ClientHello")
	}

	if .earlyData {
		.sendAlert(alertIllegalParameter)
		return errors.New("tls: client indicated early data in second ClientHello")
	}

	if illegalClientHelloChange(, .clientHello) {
		.sendAlert(alertIllegalParameter)
		return errors.New("tls: client illegally modified second ClientHello")
	}

	.clientHello = 
	return nil
}
illegalClientHelloChange reports whether the two ClientHello messages are different, with the exception of the changes allowed before and after a HelloRetryRequest. See RFC 8446, Section 4.1.2.
func (,  *clientHelloMsg) bool {
	if len(.supportedVersions) != len(.supportedVersions) ||
		len(.cipherSuites) != len(.cipherSuites) ||
		len(.supportedCurves) != len(.supportedCurves) ||
		len(.supportedSignatureAlgorithms) != len(.supportedSignatureAlgorithms) ||
		len(.supportedSignatureAlgorithmsCert) != len(.supportedSignatureAlgorithmsCert) ||
		len(.alpnProtocols) != len(.alpnProtocols) {
		return true
	}
	for  := range .supportedVersions {
		if .supportedVersions[] != .supportedVersions[] {
			return true
		}
	}
	for  := range .cipherSuites {
		if .cipherSuites[] != .cipherSuites[] {
			return true
		}
	}
	for  := range .supportedCurves {
		if .supportedCurves[] != .supportedCurves[] {
			return true
		}
	}
	for  := range .supportedSignatureAlgorithms {
		if .supportedSignatureAlgorithms[] != .supportedSignatureAlgorithms[] {
			return true
		}
	}
	for  := range .supportedSignatureAlgorithmsCert {
		if .supportedSignatureAlgorithmsCert[] != .supportedSignatureAlgorithmsCert[] {
			return true
		}
	}
	for  := range .alpnProtocols {
		if .alpnProtocols[] != .alpnProtocols[] {
			return true
		}
	}
	return .vers != .vers ||
		!bytes.Equal(.random, .random) ||
		!bytes.Equal(.sessionId, .sessionId) ||
		!bytes.Equal(.compressionMethods, .compressionMethods) ||
		.serverName != .serverName ||
		.ocspStapling != .ocspStapling ||
		!bytes.Equal(.supportedPoints, .supportedPoints) ||
		.ticketSupported != .ticketSupported ||
		!bytes.Equal(.sessionTicket, .sessionTicket) ||
		.secureRenegotiationSupported != .secureRenegotiationSupported ||
		!bytes.Equal(.secureRenegotiation, .secureRenegotiation) ||
		.scts != .scts ||
		!bytes.Equal(.cookie, .cookie) ||
		!bytes.Equal(.pskModes, .pskModes)
}

func ( *serverHandshakeStateTLS13) () error {
	 := .c

	.transcript.Write(.clientHello.marshal())
	.transcript.Write(.hello.marshal())
	if ,  := .writeRecord(recordTypeHandshake, .hello.marshal());  != nil {
		return 
	}

	if  := .sendDummyChangeCipherSpec();  != nil {
		return 
	}

	 := .earlySecret
	if  == nil {
		 = .suite.extract(nil, nil)
	}
	.handshakeSecret = .suite.extract(.sharedKey,
		.suite.deriveSecret(, "derived", nil))

	 := .suite.deriveSecret(.handshakeSecret,
		clientHandshakeTrafficLabel, .transcript)
	.in.setTrafficSecret(.suite, )
	 := .suite.deriveSecret(.handshakeSecret,
		serverHandshakeTrafficLabel, .transcript)
	.out.setTrafficSecret(.suite, )

	 := .config.writeKeyLog(keyLogLabelClientHandshake, .clientHello.random, )
	if  != nil {
		.sendAlert(alertInternalError)
		return 
	}
	 = .config.writeKeyLog(keyLogLabelServerHandshake, .clientHello.random, )
	if  != nil {
		.sendAlert(alertInternalError)
		return 
	}

	 := new(encryptedExtensionsMsg)

	if len(.clientHello.alpnProtocols) > 0 {
		if  := mutualProtocol(.clientHello.alpnProtocols, .config.NextProtos);  != "" {
			.alpnProtocol = 
			.clientProtocol = 
		}
	}

	.transcript.Write(.marshal())
	if ,  := .writeRecord(recordTypeHandshake, .marshal());  != nil {
		return 
	}

	return nil
}

func ( *serverHandshakeStateTLS13) () bool {
	return .c.config.ClientAuth >= RequestClientCert && !.usingPSK
}

func ( *serverHandshakeStateTLS13) () error {
	 := .c
Only one of PSK and certificates are used at a time.
	if .usingPSK {
		return nil
	}

Request a client certificate
		 := new(certificateRequestMsgTLS13)
		.ocspStapling = true
		.scts = true
		.supportedSignatureAlgorithms = supportedSignatureAlgorithms
		if .config.ClientCAs != nil {
			.certificateAuthorities = .config.ClientCAs.Subjects()
		}

		.transcript.Write(.marshal())
		if ,  := .writeRecord(recordTypeHandshake, .marshal());  != nil {
			return 
		}
	}

	 := new(certificateMsgTLS13)

	.certificate = *.cert
	.scts = .clientHello.scts && len(.cert.SignedCertificateTimestamps) > 0
	.ocspStapling = .clientHello.ocspStapling && len(.cert.OCSPStaple) > 0

	.transcript.Write(.marshal())
	if ,  := .writeRecord(recordTypeHandshake, .marshal());  != nil {
		return 
	}

	 := new(certificateVerifyMsg)
	.hasSignatureAlgorithm = true
	.signatureAlgorithm = .sigAlg

	, ,  := typeAndHashFromSignatureScheme(.sigAlg)
	if  != nil {
		return .sendAlert(alertInternalError)
	}

	 := signedMessage(, serverSignatureContext, .transcript)
	 := crypto.SignerOpts()
	if  == signatureRSAPSS {
		 = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: }
	}
	,  := .cert.PrivateKey.(crypto.Signer).Sign(.config.rand(), , )
	if  != nil {
		 := .cert.PrivateKey.(crypto.Signer).Public()
		if ,  := .(*rsa.PublicKey);  &&  == signatureRSAPSS &&
			.N.BitLen()/8 < .Size()*2+2 { // key too small for RSA-PSS
			.sendAlert(alertHandshakeFailure)
		} else {
			.sendAlert(alertInternalError)
		}
		return errors.New("tls: failed to sign handshake: " + .Error())
	}
	.signature = 

	.transcript.Write(.marshal())
	if ,  := .writeRecord(recordTypeHandshake, .marshal());  != nil {
		return 
	}

	return nil
}

func ( *serverHandshakeStateTLS13) () error {
	 := .c

	 := &finishedMsg{
		verifyData: .suite.finishedHash(.out.trafficSecret, .transcript),
	}

	.transcript.Write(.marshal())
	if ,  := .writeRecord(recordTypeHandshake, .marshal());  != nil {
		return 
	}
Derive secrets that take context through the server Finished.
If we did not request client certificates, at this point we can precompute the client finished and roll the transcript forward to send session tickets in our first flight.
	if !.requestClientCert() {
		if  := .sendSessionTickets();  != nil {
			return 
		}
	}

	return nil
}

func ( *serverHandshakeStateTLS13) () bool {
	if .c.config.SessionTicketsDisabled {
		return false
	}
Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9.
	for ,  := range .clientHello.pskModes {
		if  == pskModeDHE {
			return true
		}
	}
	return false
}

func ( *serverHandshakeStateTLS13) () error {
	 := .c

	.clientFinished = .suite.finishedHash(.in.trafficSecret, .transcript)
	 := &finishedMsg{
		verifyData: .clientFinished,
	}
	.transcript.Write(.marshal())

	if !.shouldSendSessionTickets() {
		return nil
	}

	 := .suite.deriveSecret(.masterSecret,
		resumptionLabel, .transcript)

	 := new(newSessionTicketMsgTLS13)

	var  [][]byte
	for ,  := range .peerCertificates {
		 = append(, .Raw)
	}
	 := sessionStateTLS13{
		cipherSuite:      .suite.id,
		createdAt:        uint64(.config.time().Unix()),
		resumptionSecret: ,
		certificate: Certificate{
			Certificate:                 ,
			OCSPStaple:                  .ocspResponse,
			SignedCertificateTimestamps: .scts,
		},
	}
	var  error
	.label,  = .encryptTicket(.marshal())
	if  != nil {
		return 
	}
	.lifetime = uint32(maxSessionTicketLifetime / time.Second)

	if ,  := .writeRecord(recordTypeHandshake, .marshal());  != nil {
		return 
	}

	return nil
}

func ( *serverHandshakeStateTLS13) () error {
	 := .c

Make sure the connection is still being verified whether or not the server requested a client certificate.
		if .config.VerifyConnection != nil {
			if  := .config.VerifyConnection(.connectionStateLocked());  != nil {
				.sendAlert(alertBadCertificate)
				return 
			}
		}
		return nil
	}
If we requested a client certificate, then the client must send a certificate message. If it's empty, no CertificateVerify is sent.

	,  := .readHandshake()
	if  != nil {
		return 
	}

	,  := .(*certificateMsgTLS13)
	if ! {
		.sendAlert(alertUnexpectedMessage)
		return unexpectedMessageError(, )
	}
	.transcript.Write(.marshal())

	if  := .processCertsFromClient(.certificate);  != nil {
		return 
	}

	if .config.VerifyConnection != nil {
		if  := .config.VerifyConnection(.connectionStateLocked());  != nil {
			.sendAlert(alertBadCertificate)
			return 
		}
	}

	if len(.certificate.Certificate) != 0 {
		,  = .readHandshake()
		if  != nil {
			return 
		}

		,  := .(*certificateVerifyMsg)
		if ! {
			.sendAlert(alertUnexpectedMessage)
			return unexpectedMessageError(, )
		}
See RFC 8446, Section 4.4.3.
		if !isSupportedSignatureAlgorithm(.signatureAlgorithm, supportedSignatureAlgorithms) {
			.sendAlert(alertIllegalParameter)
			return errors.New("tls: client certificate used with invalid signature algorithm")
		}
		, ,  := typeAndHashFromSignatureScheme(.signatureAlgorithm)
		if  != nil {
			return .sendAlert(alertInternalError)
		}
		if  == signaturePKCS1v15 ||  == crypto.SHA1 {
			.sendAlert(alertIllegalParameter)
			return errors.New("tls: client certificate used with invalid signature algorithm")
		}
		 := signedMessage(, clientSignatureContext, .transcript)
		if  := verifyHandshakeSignature(, .peerCertificates[0].PublicKey,
			, , .signature);  != nil {
			.sendAlert(alertDecryptError)
			return errors.New("tls: invalid signature by the client certificate: " + .Error())
		}

		.transcript.Write(.marshal())
	}
If we waited until the client certificates to send session tickets, we are ready to do it now.
	if  := .sendSessionTickets();  != nil {
		return 
	}

	return nil
}

func ( *serverHandshakeStateTLS13) () error {
	 := .c

	,  := .readHandshake()
	if  != nil {
		return 
	}

	,  := .(*finishedMsg)
	if ! {
		.sendAlert(alertUnexpectedMessage)
		return unexpectedMessageError(, )
	}

	if !hmac.Equal(.clientFinished, .verifyData) {
		.sendAlert(alertDecryptError)
		return errors.New("tls: invalid client finished hash")
	}

	.in.setTrafficSecret(.suite, .trafficSecret)

	return nil