// 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.
const maxClientPSKIdentities = 5

type serverHandshakeStateTLS13 struct {
	c               *Conn
	ctx             context.Context
	clientHello     *clientHelloMsg
	hello           *serverHelloMsg
	sentDummyCCS    bool
	usingPSK        bool
	earlyData       bool
	suite           *cipherSuiteTLS13
	cert            *Certificate
	sigAlg          SignatureScheme
	earlySecret     []byte
	sharedKey       []byte
	handshakeSecret []byte
	masterSecret    []byte
	trafficSecret   []byte // client_application_traffic_secret_0
	transcript      hash.Hash
	clientFinished  []byte
}

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

	if needFIPS() {
		return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
	}

	// 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 
	}

	.isHandshakeComplete.Store(true)

	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 {
		if  == TLS_FALLBACK_SCSV {
			// 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(roleServer) {
				.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")
	}

	if .clientHello.earlyData && .quic != nil {
		if len(.clientHello.pskIdentities) == 0 {
			.sendAlert(alertIllegalParameter)
			return errors.New("tls: early_data without pre_shared_key")
		}
	} else if .clientHello.earlyData {
		// 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

	 := defaultCipherSuitesTLS13
	if !hasAESGCMHardwareSupport || !aesgcmPreferred(.clientHello.cipherSuites) {
		 = defaultCipherSuitesTLS13NoAES
	}
	for ,  := range  {
		.suite = mutualCipherSuiteTLS13(.clientHello.cipherSuites, )
		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(); ! {
		.sendAlert(alertInternalError)
		return errors.New("tls: CurvePreferences includes unsupported curve")
	}
	,  := generateECDHEKey(.config.rand(), )
	if  != nil {
		.sendAlert(alertInternalError)
		return 
	}
	.hello.serverShare = keyShare{group: , data: .PublicKey().Bytes()}
	,  := .Curve().NewPublicKey(.data)
	if  != nil {
		.sendAlert(alertIllegalParameter)
		return errors.New("tls: invalid client key share")
	}
	.sharedKey,  = .ECDH()
	if  != nil {
		.sendAlert(alertIllegalParameter)
		return errors.New("tls: invalid client key share")
	}

	,  := negotiateALPN(.config.NextProtos, .clientHello.alpnProtocols, .quic != nil)
	if  != nil {
		.sendAlert(alertNoApplicationProtocol)
		return 
	}
	.clientProtocol = 

	if .quic != nil {
		if .clientHello.quicTransportParameters == nil {
			// RFC 9001 Section 8.2.
			.sendAlert(alertMissingExtension)
			return errors.New("tls: client did not send a quic_transport_parameters extension")
		}
		.quicSetTransportParameters(.clientHello.quicTransportParameters)
	} else {
		if .clientHello.quicTransportParameters != nil {
			.sendAlert(alertUnsupportedExtension)
			return errors.New("tls: client sent an unexpected quic_transport_parameters extension")
		}
	}

	.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
		}

		var  *SessionState
		if .config.UnwrapSession != nil {
			var  error
			,  = .config.UnwrapSession(.label, .connectionStateLocked())
			if  != nil {
				return 
			}
			if  == nil {
				continue
			}
		} else {
			 := .config.decryptTicket(.label, .ticketKeys)
			if  == nil {
				continue
			}
			var  error
			,  = ParseSessionState()
			if  != nil {
				continue
			}
		}

		if .version != VersionTLS13 {
			continue
		}

		 := time.Unix(int64(.createdAt), 0)
		if .config.time().Sub() > maxSessionTicketLifetime {
			continue
		}

		 := 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(.peerCertificates) != 0
		 := requiresClientCert(.config.ClientAuth)
		if  && ! {
			continue
		}
		if  && .config.ClientAuth == NoClientCert {
			continue
		}
		if  && .config.time().After(.peerCertificates[0].NotAfter) {
			continue
		}
		if  && .config.ClientAuth >= VerifyClientCertIfGiven &&
			len(.verifiedChains) == 0 {
			continue
		}

		.earlySecret = .suite.extract(.secret, nil)
		 := .suite.deriveSecret(.earlySecret, resumptionBinderLabel, 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")
		}
		,  := .clientHello.marshalWithoutBinders()
		if  != nil {
			.sendAlert(alertInternalError)
			return 
		}
		.Write()
		 := .suite.finishedHash(, )
		if !hmac.Equal(.clientHello.pskBinders[], ) {
			.sendAlert(alertDecryptError)
			return errors.New("tls: invalid PSK binder")
		}

		if .quic != nil && .clientHello.earlyData &&  == 0 &&
			.EarlyData && .cipherSuite == .suite.id &&
			.alpnProtocol == .clientProtocol {
			.earlyData = true

			 := .suite.hash.New()
			if  := transcriptMsg(.clientHello, );  != nil {
				return 
			}
			 := .suite.deriveSecret(.earlySecret, clientEarlyTrafficLabel, )
			.quicSetReadSecret(QUICEncryptionLevelEarly, .suite.id, )
		}

		.didResume = true
		.peerCertificates = .peerCertificates
		.ocspResponse = .ocspResponse
		.scts = .scts
		.verifiedChains = .verifiedChains

		.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.
func ( hash.Hash,  crypto.Hash) hash.Hash {
	// 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.
	if len(.clientHello.supportedSignatureAlgorithms) == 0 {
		return .sendAlert(alertMissingExtension)
	}

	,  := .config.getCertificate(clientHelloInfo(.ctx, , .clientHello))
	if  != nil {
		if  == errNoCertificates {
			.sendAlert(alertUnrecognizedName)
		} else {
			.sendAlert(alertInternalError)
		}
		return 
	}
	.sigAlg,  = selectSignatureScheme(.vers, , .clientHello.supportedSignatureAlgorithms)
	if  != nil {
		// 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.
func ( *serverHandshakeStateTLS13) () error {
	if .c.quic != nil {
		return nil
	}
	if .sentDummyCCS {
		return nil
	}
	.sentDummyCCS = true

	return .c.writeChangeCipherRecord()
}

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

	// The first ClientHello gets double-hashed into the transcript upon a
	// HelloRetryRequest. See RFC 8446, Section 4.4.1.
	if  := transcriptMsg(.clientHello, .transcript);  != nil {
		return 
	}
	 := .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:     ,
	}

	if ,  := .c.writeHandshakeRecord(, .transcript);  != nil {
		return 
	}

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

	// clientHelloMsg is not included in the transcript.
	,  := .readHandshake(nil)
	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

	if  := transcriptMsg(.clientHello, .transcript);  != nil {
		return 
	}
	if ,  := .c.writeHandshakeRecord(.hello, .transcript);  != 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, QUICEncryptionLevelHandshake, )
	 := .suite.deriveSecret(.handshakeSecret,
		serverHandshakeTrafficLabel, .transcript)
	.out.setTrafficSecret(.suite, QUICEncryptionLevelHandshake, )

	if .quic != nil {
		if .hand.Len() != 0 {
			.sendAlert(alertUnexpectedMessage)
		}
		.quicSetWriteSecret(QUICEncryptionLevelHandshake, .suite.id, )
		.quicSetReadSecret(QUICEncryptionLevelHandshake, .suite.id, )
	}

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

	 := new(encryptedExtensionsMsg)
	.alpnProtocol = .clientProtocol

	if .quic != nil {
		,  := .quicGetTransportParameters()
		if  != nil {
			return 
		}
		.quicTransportParameters = 
		.earlyData = .earlyData
	}

	if ,  := .c.writeHandshakeRecord(, .transcript);  != 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
	}

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

		if ,  := .c.writeHandshakeRecord(, .transcript);  != nil {
			return 
		}
	}

	 := new(certificateMsgTLS13)

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

	if ,  := .c.writeHandshakeRecord(, .transcript);  != 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 = 

	if ,  := .c.writeHandshakeRecord(, .transcript);  != nil {
		return 
	}

	return nil
}

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

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

	if ,  := .c.writeHandshakeRecord(, .transcript);  != nil {
		return 
	}

	// Derive secrets that take context through the server Finished.

	.masterSecret = .suite.extract(nil,
		.suite.deriveSecret(.handshakeSecret, "derived", nil))

	.trafficSecret = .suite.deriveSecret(.masterSecret,
		clientApplicationTrafficLabel, .transcript)
	 := .suite.deriveSecret(.masterSecret,
		serverApplicationTrafficLabel, .transcript)
	.out.setTrafficSecret(.suite, QUICEncryptionLevelApplication, )

	if .quic != nil {
		if .hand.Len() != 0 {
			// TODO: Handle this in setTrafficSecret?
			.sendAlert(alertUnexpectedMessage)
		}
		.quicSetWriteSecret(QUICEncryptionLevelApplication, .suite.id, )
	}

	 := .config.writeKeyLog(keyLogLabelClientTraffic, .clientHello.random, .trafficSecret)
	if  != nil {
		.sendAlert(alertInternalError)
		return 
	}
	 = .config.writeKeyLog(keyLogLabelServerTraffic, .clientHello.random, )
	if  != nil {
		.sendAlert(alertInternalError)
		return 
	}

	.ekm = .suite.exportKeyingMaterial(.masterSecret, .transcript)

	// 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
	}

	// QUIC tickets are sent by QUICConn.SendSessionTicket, not automatically.
	if .c.quic != nil {
		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,
	}
	if  := transcriptMsg(, .transcript);  != nil {
		return 
	}

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

	if !.shouldSendSessionTickets() {
		return nil
	}
	return .sendSessionTicket(false)
}

func ( *Conn) ( bool) error {
	 := cipherSuiteTLS13ByID(.cipherSuite)
	if  == nil {
		return errors.New("tls: internal error: unknown cipher suite")
	}
	// ticket_nonce, which must be unique per connection, is always left at
	// zero because we only ever send one ticket per connection.
	 := .expandLabel(.resumptionSecret, "resumption",
		nil, .hash.Size())

	 := new(newSessionTicketMsgTLS13)

	,  := .sessionState()
	if  != nil {
		return 
	}
	.secret = 
	.EarlyData = 
	if .config.WrapSession != nil {
		.label,  = .config.WrapSession(.connectionStateLocked(), )
		if  != nil {
			return 
		}
	} else {
		,  := .Bytes()
		if  != nil {
			.sendAlert(alertInternalError)
			return 
		}
		.label,  = .config.encryptTicket(, .ticketKeys)
		if  != nil {
			return 
		}
	}
	.lifetime = uint32(maxSessionTicketLifetime / time.Second)

	// ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1
	// The value is not stored anywhere; we never need to check the ticket age
	// because 0-RTT is not supported.
	 := make([]byte, 4)
	_,  = .config.rand().Read()
	if  != nil {
		return 
	}
	.ageAdd = binary.LittleEndian.Uint32()

	if  {
		// RFC 9001, Section 4.6.1
		.maxEarlyData = 0xffffffff
	}

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

	return nil
}

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

	if !.requestClientCert() {
		// 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(.transcript)
	if  != nil {
		return 
	}

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

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

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

	if len(.certificate.Certificate) != 0 {
		// certificateVerifyMsg is included in the transcript, but not until
		// after we verify the handshake signature, since the state before
		// this message was sent is used.
		,  = .readHandshake(nil)
		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())
		}

		if  := transcriptMsg(, .transcript);  != nil {
			return 
		}
	}

	// 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

	// finishedMsg is not included in the transcript.
	,  := .readHandshake(nil)
	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, QUICEncryptionLevelApplication, .trafficSecret)

	return nil
}