// Copyright 2010 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.

// TLS low level connection and record layer

package tls

import (
	
	
	
	
	
	
	
	
	
	
	
	
	
)

// A Conn represents a secured connection.
// It implements the net.Conn interface.
type Conn struct {
	// constant
	conn        net.Conn
	isClient    bool
	handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
	quic        *quicState                  // nil for non-QUIC connections

	// isHandshakeComplete is true if the connection is currently transferring
	// application data (i.e. is not currently processing a handshake).
	// isHandshakeComplete is true implies handshakeErr == nil.
	isHandshakeComplete atomic.Bool
	// constant after handshake; protected by handshakeMutex
	handshakeMutex sync.Mutex
	handshakeErr   error   // error resulting from handshake
	vers           uint16  // TLS version
	haveVers       bool    // version has been negotiated
	config         *Config // configuration passed to constructor
	// handshakes counts the number of handshakes performed on the
	// connection so far. If renegotiation is disabled then this is either
	// zero or one.
	handshakes       int
	extMasterSecret  bool
	didResume        bool // whether this connection was a session resumption
	cipherSuite      uint16
	ocspResponse     []byte   // stapled OCSP response
	scts             [][]byte // signed certificate timestamps from server
	peerCertificates []*x509.Certificate
	// activeCertHandles contains the cache handles to certificates in
	// peerCertificates that are used to track active references.
	activeCertHandles []*activeCert
	// verifiedChains contains the certificate chains that we built, as
	// opposed to the ones presented by the server.
	verifiedChains [][]*x509.Certificate
	// serverName contains the server name indicated by the client, if any.
	serverName string
	// secureRenegotiation is true if the server echoed the secure
	// renegotiation extension. (This is meaningless as a server because
	// renegotiation is not supported in that case.)
	secureRenegotiation bool
	// ekm is a closure for exporting keying material.
	ekm func(label string, context []byte, length int) ([]byte, error)
	// resumptionSecret is the resumption_master_secret for handling
	// or sending NewSessionTicket messages.
	resumptionSecret []byte

	// ticketKeys is the set of active session ticket keys for this
	// connection. The first one is used to encrypt new tickets and
	// all are tried to decrypt tickets.
	ticketKeys []ticketKey

	// clientFinishedIsFirst is true if the client sent the first Finished
	// message during the most recent handshake. This is recorded because
	// the first transmitted Finished message is the tls-unique
	// channel-binding value.
	clientFinishedIsFirst bool

	// closeNotifyErr is any error from sending the alertCloseNotify record.
	closeNotifyErr error
	// closeNotifySent is true if the Conn attempted to send an
	// alertCloseNotify record.
	closeNotifySent bool

	// clientFinished and serverFinished contain the Finished message sent
	// by the client or server in the most recent handshake. This is
	// retained to support the renegotiation extension and tls-unique
	// channel-binding.
	clientFinished [12]byte
	serverFinished [12]byte

	// clientProtocol is the negotiated ALPN protocol.
	clientProtocol string

	// input/output
	in, out   halfConn
	rawInput  bytes.Buffer // raw input, starting with a record header
	input     bytes.Reader // application data waiting to be read, from rawInput.Next
	hand      bytes.Buffer // handshake data waiting to be read
	buffering bool         // whether records are buffered in sendBuf
	sendBuf   []byte       // a buffer of records waiting to be sent

	// bytesSent counts the bytes of application data sent.
	// packetsSent counts packets.
	bytesSent   int64
	packetsSent int64

	// retryCount counts the number of consecutive non-advancing records
	// received by Conn.readRecord. That is, records that neither advance the
	// handshake, nor deliver application data. Protected by in.Mutex.
	retryCount int

	// activeCall indicates whether Close has been call in the low bit.
	// the rest of the bits are the number of goroutines in Conn.Write.
	activeCall atomic.Int32

	tmp [16]byte
}

// Access to net.Conn methods.
// Cannot just embed net.Conn because that would
// export the struct field too.

// LocalAddr returns the local network address.
func ( *Conn) () net.Addr {
	return .conn.LocalAddr()
}

// RemoteAddr returns the remote network address.
func ( *Conn) () net.Addr {
	return .conn.RemoteAddr()
}

// SetDeadline sets the read and write deadlines associated with the connection.
// A zero value for t means Read and Write will not time out.
// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
func ( *Conn) ( time.Time) error {
	return .conn.SetDeadline()
}

// SetReadDeadline sets the read deadline on the underlying connection.
// A zero value for t means Read will not time out.
func ( *Conn) ( time.Time) error {
	return .conn.SetReadDeadline()
}

// SetWriteDeadline sets the write deadline on the underlying connection.
// A zero value for t means Write will not time out.
// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
func ( *Conn) ( time.Time) error {
	return .conn.SetWriteDeadline()
}

// NetConn returns the underlying connection that is wrapped by c.
// Note that writing to or reading from this connection directly will corrupt the
// TLS session.
func ( *Conn) () net.Conn {
	return .conn
}

// A halfConn represents one direction of the record layer
// connection, either sending or receiving.
type halfConn struct {
	sync.Mutex

	err     error  // first permanent error
	version uint16 // protocol version
	cipher  any    // cipher algorithm
	mac     hash.Hash
	seq     [8]byte // 64-bit sequence number

	scratchBuf [13]byte // to avoid allocs; interface method args escape

	nextCipher any       // next encryption state
	nextMac    hash.Hash // next MAC algorithm

	level         QUICEncryptionLevel // current QUIC encryption level
	trafficSecret []byte              // current TLS 1.3 traffic secret
}

type permanentError struct {
	err net.Error
}

func ( *permanentError) () string   { return .err.Error() }
func ( *permanentError) () error   { return .err }
func ( *permanentError) () bool   { return .err.Timeout() }
func ( *permanentError) () bool { return false }

func ( *halfConn) ( error) error {
	if ,  := .(net.Error);  {
		.err = &permanentError{err: }
	} else {
		.err = 
	}
	return .err
}

// prepareCipherSpec sets the encryption and MAC states
// that a subsequent changeCipherSpec will use.
func ( *halfConn) ( uint16,  any,  hash.Hash) {
	.version = 
	.nextCipher = 
	.nextMac = 
}

// changeCipherSpec changes the encryption and MAC states
// to the ones previously passed to prepareCipherSpec.
func ( *halfConn) () error {
	if .nextCipher == nil || .version == VersionTLS13 {
		return alertInternalError
	}
	.cipher = .nextCipher
	.mac = .nextMac
	.nextCipher = nil
	.nextMac = nil
	for  := range .seq {
		.seq[] = 0
	}
	return nil
}

func ( *halfConn) ( *cipherSuiteTLS13,  QUICEncryptionLevel,  []byte) {
	.trafficSecret = 
	.level = 
	,  := .trafficKey()
	.cipher = .aead(, )
	for  := range .seq {
		.seq[] = 0
	}
}

// incSeq increments the sequence number.
func ( *halfConn) () {
	for  := 7;  >= 0; -- {
		.seq[]++
		if .seq[] != 0 {
			return
		}
	}

	// Not allowed to let sequence number wrap.
	// Instead, must renegotiate before it does.
	// Not likely enough to bother.
	panic("TLS: sequence number wraparound")
}

// explicitNonceLen returns the number of bytes of explicit nonce or IV included
// in each record. Explicit nonces are present only in CBC modes after TLS 1.0
// and in certain AEAD modes in TLS 1.2.
func ( *halfConn) () int {
	if .cipher == nil {
		return 0
	}

	switch c := .cipher.(type) {
	case cipher.Stream:
		return 0
	case aead:
		return .explicitNonceLen()
	case cbcMode:
		// TLS 1.1 introduced a per-record explicit IV to fix the BEAST attack.
		if .version >= VersionTLS11 {
			return .BlockSize()
		}
		return 0
	default:
		panic("unknown cipher type")
	}
}

// extractPadding returns, in constant time, the length of the padding to remove
// from the end of payload. It also returns a byte which is equal to 255 if the
// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2.
func ( []byte) ( int,  byte) {
	if len() < 1 {
		return 0, 0
	}

	 := [len()-1]
	 := uint(len()-1) - uint()
	// if len(payload) >= (paddingLen - 1) then the MSB of t is zero
	 = byte(int32(^) >> 31)

	// The maximum possible padding length plus the actual length field
	 := 256
	// The length of the padded data is public, so we can use an if here
	if  > len() {
		 = len()
	}

	for  := 0;  < ; ++ {
		 := uint() - uint()
		// if i <= paddingLen then the MSB of t is zero
		 := byte(int32(^) >> 31)
		 := [len()-1-]
		 &^= & ^ &
	}

	// We AND together the bits of good and replicate the result across
	// all the bits.
	 &=  << 4
	 &=  << 2
	 &=  << 1
	 = uint8(int8() >> 7)

	// Zero the padding length on error. This ensures any unchecked bytes
	// are included in the MAC. Otherwise, an attacker that could
	// distinguish MAC failures from padding failures could mount an attack
	// similar to POODLE in SSL 3.0: given a good ciphertext that uses a
	// full block's worth of padding, replace the final block with another
	// block. If the MAC check passed but the padding check failed, the
	// last byte of that block decrypted to the block size.
	//
	// See also macAndPaddingGood logic below.
	 &= 

	 = int() + 1
	return
}

func (,  int) int {
	return  + (-%)%
}

// cbcMode is an interface for block ciphers using cipher block chaining.
type cbcMode interface {
	cipher.BlockMode
	SetIV([]byte)
}

// decrypt authenticates and decrypts the record if protection is active at
// this stage. The returned plaintext might overlap with the input.
func ( *halfConn) ( []byte) ([]byte, recordType, error) {
	var  []byte
	 := recordType([0])
	 := [recordHeaderLen:]

	// In TLS 1.3, change_cipher_spec messages are to be ignored without being
	// decrypted. See RFC 8446, Appendix D.4.
	if .version == VersionTLS13 &&  == recordTypeChangeCipherSpec {
		return , , nil
	}

	 := byte(255)
	 := 0

	 := .explicitNonceLen()

	if .cipher != nil {
		switch c := .cipher.(type) {
		case cipher.Stream:
			.XORKeyStream(, )
		case aead:
			if len() <  {
				return nil, 0, alertBadRecordMAC
			}
			 := [:]
			if len() == 0 {
				 = .seq[:]
			}
			 = [:]

			var  []byte
			if .version == VersionTLS13 {
				 = [:recordHeaderLen]
			} else {
				 = append(.scratchBuf[:0], .seq[:]...)
				 = append(, [:3]...)
				 := len() - .Overhead()
				 = append(, byte(>>8), byte())
			}

			var  error
			,  = .Open([:0], , , )
			if  != nil {
				return nil, 0, alertBadRecordMAC
			}
		case cbcMode:
			 := .BlockSize()
			 :=  + roundUp(.mac.Size()+1, )
			if len()% != 0 || len() <  {
				return nil, 0, alertBadRecordMAC
			}

			if  > 0 {
				.SetIV([:])
				 = [:]
			}
			.CryptBlocks(, )

			// In a limited attempt to protect against CBC padding oracles like
			// Lucky13, the data past paddingLen (which is secret) is passed to
			// the MAC function as extra data, to be fed into the HMAC after
			// computing the digest. This makes the MAC roughly constant time as
			// long as the digest computation is constant time and does not
			// affect the subsequent write, modulo cache effects.
			,  = extractPadding()
		default:
			panic("unknown cipher type")
		}

		if .version == VersionTLS13 {
			if  != recordTypeApplicationData {
				return nil, 0, alertUnexpectedMessage
			}
			if len() > maxPlaintext+1 {
				return nil, 0, alertRecordOverflow
			}
			// Remove padding and find the ContentType scanning from the end.
			for  := len() - 1;  >= 0; -- {
				if [] != 0 {
					 = recordType([])
					 = [:]
					break
				}
				if  == 0 {
					return nil, 0, alertUnexpectedMessage
				}
			}
		}
	} else {
		 = 
	}

	if .mac != nil {
		 := .mac.Size()
		if len() <  {
			return nil, 0, alertBadRecordMAC
		}

		 := len() -  - 
		 = subtle.ConstantTimeSelect(int(uint32()>>31), 0, ) // if n < 0 { n = 0 }
		[3] = byte( >> 8)
		[4] = byte()
		 := [ : +]
		 := tls10MAC(.mac, .scratchBuf[:0], .seq[:], [:recordHeaderLen], [:], [+:])

		// This is equivalent to checking the MACs and paddingGood
		// separately, but in constant-time to prevent distinguishing
		// padding failures from MAC failures. Depending on what value
		// of paddingLen was returned on bad padding, distinguishing
		// bad MAC from bad padding can lead to an attack.
		//
		// See also the logic at the end of extractPadding.
		 := subtle.ConstantTimeCompare(, ) & int()
		if  != 1 {
			return nil, 0, alertBadRecordMAC
		}

		 = [:]
	}

	.incSeq()
	return , , nil
}

// sliceForAppend extends the input slice by n bytes. head is the full extended
// slice, while tail is the appended part. If the original slice has sufficient
// capacity no allocation is performed.
func ( []byte,  int) (,  []byte) {
	if  := len() + ; cap() >=  {
		 = [:]
	} else {
		 = make([]byte, )
		copy(, )
	}
	 = [len():]
	return
}

// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and
// appends it to record, which must already contain the record header.
func ( *halfConn) (,  []byte,  io.Reader) ([]byte, error) {
	if .cipher == nil {
		return append(, ...), nil
	}

	var  []byte
	if  := .explicitNonceLen();  > 0 {
		,  = sliceForAppend(, )
		if ,  := .cipher.(cbcMode); ! &&  < 16 {
			// The AES-GCM construction in TLS has an explicit nonce so that the
			// nonce can be random. However, the nonce is only 8 bytes which is
			// too small for a secure, random nonce. Therefore we use the
			// sequence number as the nonce. The 3DES-CBC construction also has
			// an 8 bytes nonce but its nonces must be unpredictable (see RFC
			// 5246, Appendix F.3), forcing us to use randomness. That's not
			// 3DES' biggest problem anyway because the birthday bound on block
			// collision is reached first due to its similarly small block size
			// (see the Sweet32 attack).
			copy(, .seq[:])
		} else {
			if ,  := io.ReadFull(, );  != nil {
				return nil, 
			}
		}
	}

	var  []byte
	switch c := .cipher.(type) {
	case cipher.Stream:
		 := tls10MAC(.mac, .scratchBuf[:0], .seq[:], [:recordHeaderLen], , nil)
		,  = sliceForAppend(, len()+len())
		.XORKeyStream([:len()], )
		.XORKeyStream([len():], )
	case aead:
		 := 
		if len() == 0 {
			 = .seq[:]
		}

		if .version == VersionTLS13 {
			 = append(, ...)

			// Encrypt the actual ContentType and replace the plaintext one.
			 = append(, [0])
			[0] = byte(recordTypeApplicationData)

			 := len() + 1 + .Overhead()
			[3] = byte( >> 8)
			[4] = byte()

			 = .Seal([:recordHeaderLen],
				, [recordHeaderLen:], [:recordHeaderLen])
		} else {
			 := append(.scratchBuf[:0], .seq[:]...)
			 = append(, [:recordHeaderLen]...)
			 = .Seal(, , , )
		}
	case cbcMode:
		 := tls10MAC(.mac, .scratchBuf[:0], .seq[:], [:recordHeaderLen], , nil)
		 := .BlockSize()
		 := len() + len()
		 :=  - %
		,  = sliceForAppend(, +)
		copy(, )
		copy([len():], )
		for  := ;  < len(); ++ {
			[] = byte( - 1)
		}
		if len() > 0 {
			.SetIV()
		}
		.CryptBlocks(, )
	default:
		panic("unknown cipher type")
	}

	// Update length to include nonce, MAC and any block padding needed.
	 := len() - recordHeaderLen
	[3] = byte( >> 8)
	[4] = byte()
	.incSeq()

	return , nil
}

// RecordHeaderError is returned when a TLS record header is invalid.
type RecordHeaderError struct {
	// Msg contains a human readable string that describes the error.
	Msg string
	// RecordHeader contains the five bytes of TLS record header that
	// triggered the error.
	RecordHeader [5]byte
	// Conn provides the underlying net.Conn in the case that a client
	// sent an initial handshake that didn't look like TLS.
	// It is nil if there's already been a handshake or a TLS alert has
	// been written to the connection.
	Conn net.Conn
}

func ( RecordHeaderError) () string { return "tls: " + .Msg }

func ( *Conn) ( net.Conn,  string) ( RecordHeaderError) {
	.Msg = 
	.Conn = 
	copy(.RecordHeader[:], .rawInput.Bytes())
	return 
}

func ( *Conn) () error {
	return .readRecordOrCCS(false)
}

func ( *Conn) () error {
	return .readRecordOrCCS(true)
}

// readRecordOrCCS reads one or more TLS records from the connection and
// updates the record layer state. Some invariants:
//   - c.in must be locked
//   - c.input must be empty
//
// During the handshake one and only one of the following will happen:
//   - c.hand grows
//   - c.in.changeCipherSpec is called
//   - an error is returned
//
// After the handshake one and only one of the following will happen:
//   - c.hand grows
//   - c.input is set
//   - an error is returned
func ( *Conn) ( bool) error {
	if .in.err != nil {
		return .in.err
	}
	 := .isHandshakeComplete.Load()

	// This function modifies c.rawInput, which owns the c.input memory.
	if .input.Len() != 0 {
		return .in.setErrorLocked(errors.New("tls: internal error: attempted to read record with pending application data"))
	}
	.input.Reset(nil)

	if .quic != nil {
		return .in.setErrorLocked(errors.New("tls: internal error: attempted to read record with QUIC transport"))
	}

	// Read header, payload.
	if  := .readFromUntil(.conn, recordHeaderLen);  != nil {
		// RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify
		// is an error, but popular web sites seem to do this, so we accept it
		// if and only if at the record boundary.
		if  == io.ErrUnexpectedEOF && .rawInput.Len() == 0 {
			 = io.EOF
		}
		if ,  := .(net.Error); ! || !.Temporary() {
			.in.setErrorLocked()
		}
		return 
	}
	 := .rawInput.Bytes()[:recordHeaderLen]
	 := recordType([0])

	// No valid TLS record has a type of 0x80, however SSLv2 handshakes
	// start with a uint16 length where the MSB is set and the first record
	// is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
	// an SSLv2 client.
	if ! &&  == 0x80 {
		.sendAlert(alertProtocolVersion)
		return .in.setErrorLocked(.newRecordHeaderError(nil, "unsupported SSLv2 handshake received"))
	}

	 := uint16([1])<<8 | uint16([2])
	 := .vers
	if  == VersionTLS13 {
		// All TLS 1.3 records are expected to have 0x0303 (1.2) after
		// the initial hello (RFC 8446 Section 5.1).
		 = VersionTLS12
	}
	 := int([3])<<8 | int([4])
	if .haveVers &&  !=  {
		.sendAlert(alertProtocolVersion)
		 := fmt.Sprintf("received record with version %x when expecting version %x", , )
		return .in.setErrorLocked(.newRecordHeaderError(nil, ))
	}
	if !.haveVers {
		// First message, be extra suspicious: this might not be a TLS
		// client. Bail out before reading a full 'body', if possible.
		// The current max version is 3.3 so if the version is >= 16.0,
		// it's probably not real.
		if ( != recordTypeAlert &&  != recordTypeHandshake) ||  >= 0x1000 {
			return .in.setErrorLocked(.newRecordHeaderError(.conn, "first record does not look like a TLS handshake"))
		}
	}
	if .vers == VersionTLS13 &&  > maxCiphertextTLS13 ||  > maxCiphertext {
		.sendAlert(alertRecordOverflow)
		 := fmt.Sprintf("oversized record received with length %d", )
		return .in.setErrorLocked(.newRecordHeaderError(nil, ))
	}
	if  := .readFromUntil(.conn, recordHeaderLen+);  != nil {
		if ,  := .(net.Error); ! || !.Temporary() {
			.in.setErrorLocked()
		}
		return 
	}

	// Process message.
	 := .rawInput.Next(recordHeaderLen + )
	, ,  := .in.decrypt()
	if  != nil {
		return .in.setErrorLocked(.sendAlert(.(alert)))
	}
	if len() > maxPlaintext {
		return .in.setErrorLocked(.sendAlert(alertRecordOverflow))
	}

	// Application Data messages are always protected.
	if .in.cipher == nil &&  == recordTypeApplicationData {
		return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
	}

	if  != recordTypeAlert &&  != recordTypeChangeCipherSpec && len() > 0 {
		// This is a state-advancing message: reset the retry count.
		.retryCount = 0
	}

	// Handshake messages MUST NOT be interleaved with other record types in TLS 1.3.
	if .vers == VersionTLS13 &&  != recordTypeHandshake && .hand.Len() > 0 {
		return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
	}

	switch  {
	default:
		return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))

	case recordTypeAlert:
		if .quic != nil {
			return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
		}
		if len() != 2 {
			return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
		}
		if alert([1]) == alertCloseNotify {
			return .in.setErrorLocked(io.EOF)
		}
		if .vers == VersionTLS13 {
			return .in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert([1])})
		}
		switch [0] {
		case alertLevelWarning:
			// Drop the record on the floor and retry.
			return .retryReadRecord()
		case alertLevelError:
			return .in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert([1])})
		default:
			return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
		}

	case recordTypeChangeCipherSpec:
		if len() != 1 || [0] != 1 {
			return .in.setErrorLocked(.sendAlert(alertDecodeError))
		}
		// Handshake messages are not allowed to fragment across the CCS.
		if .hand.Len() > 0 {
			return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
		}
		// In TLS 1.3, change_cipher_spec records are ignored until the
		// Finished. See RFC 8446, Appendix D.4. Note that according to Section
		// 5, a server can send a ChangeCipherSpec before its ServerHello, when
		// c.vers is still unset. That's not useful though and suspicious if the
		// server then selects a lower protocol version, so don't allow that.
		if .vers == VersionTLS13 {
			return .retryReadRecord()
		}
		if ! {
			return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
		}
		if  := .in.changeCipherSpec();  != nil {
			return .in.setErrorLocked(.sendAlert(.(alert)))
		}

	case recordTypeApplicationData:
		if ! ||  {
			return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
		}
		// Some OpenSSL servers send empty records in order to randomize the
		// CBC IV. Ignore a limited number of empty records.
		if len() == 0 {
			return .retryReadRecord()
		}
		// Note that data is owned by c.rawInput, following the Next call above,
		// to avoid copying the plaintext. This is safe because c.rawInput is
		// not read from or written to until c.input is drained.
		.input.Reset()

	case recordTypeHandshake:
		if len() == 0 ||  {
			return .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
		}
		.hand.Write()
	}

	return nil
}

// retryReadRecord recurs into readRecordOrCCS to drop a non-advancing record, like
// a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3.
func ( *Conn) ( bool) error {
	.retryCount++
	if .retryCount > maxUselessRecords {
		.sendAlert(alertUnexpectedMessage)
		return .in.setErrorLocked(errors.New("tls: too many ignored records"))
	}
	return .readRecordOrCCS()
}

// atLeastReader reads from R, stopping with EOF once at least N bytes have been
// read. It is different from an io.LimitedReader in that it doesn't cut short
// the last Read call, and in that it considers an early EOF an error.
type atLeastReader struct {
	R io.Reader
	N int64
}

func ( *atLeastReader) ( []byte) (int, error) {
	if .N <= 0 {
		return 0, io.EOF
	}
	,  := .R.Read()
	.N -= int64() // won't underflow unless len(p) >= n > 9223372036854775809
	if .N > 0 &&  == io.EOF {
		return , io.ErrUnexpectedEOF
	}
	if .N <= 0 &&  == nil {
		return , io.EOF
	}
	return , 
}

// readFromUntil reads from r into c.rawInput until c.rawInput contains
// at least n bytes or else returns an error.
func ( *Conn) ( io.Reader,  int) error {
	if .rawInput.Len() >=  {
		return nil
	}
	 :=  - .rawInput.Len()
	// There might be extra input waiting on the wire. Make a best effort
	// attempt to fetch it so that it can be used in (*Conn).Read to
	// "predict" closeNotify alerts.
	.rawInput.Grow( + bytes.MinRead)
	,  := .rawInput.ReadFrom(&atLeastReader{, int64()})
	return 
}

// sendAlertLocked sends a TLS alert message.
func ( *Conn) ( alert) error {
	if .quic != nil {
		return .out.setErrorLocked(&net.OpError{Op: "local error", Err: })
	}

	switch  {
	case alertNoRenegotiation, alertCloseNotify:
		.tmp[0] = alertLevelWarning
	default:
		.tmp[0] = alertLevelError
	}
	.tmp[1] = byte()

	,  := .writeRecordLocked(recordTypeAlert, .tmp[0:2])
	if  == alertCloseNotify {
		// closeNotify is a special case in that it isn't an error.
		return 
	}

	return .out.setErrorLocked(&net.OpError{Op: "local error", Err: })
}

// sendAlert sends a TLS alert message.
func ( *Conn) ( alert) error {
	.out.Lock()
	defer .out.Unlock()
	return .sendAlertLocked()
}

const (
	// tcpMSSEstimate is a conservative estimate of the TCP maximum segment
	// size (MSS). A constant is used, rather than querying the kernel for
	// the actual MSS, to avoid complexity. The value here is the IPv6
	// minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40
	// bytes) and a TCP header with timestamps (32 bytes).
	tcpMSSEstimate = 1208

	// recordSizeBoostThreshold is the number of bytes of application data
	// sent after which the TLS record size will be increased to the
	// maximum.
	recordSizeBoostThreshold = 128 * 1024
)

// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the
// next application data record. There is the following trade-off:
//
//   - For latency-sensitive applications, such as web browsing, each TLS
//     record should fit in one TCP segment.
//   - For throughput-sensitive applications, such as large file transfers,
//     larger TLS records better amortize framing and encryption overheads.
//
// A simple heuristic that works well in practice is to use small records for
// the first 1MB of data, then use larger records for subsequent data, and
// reset back to smaller records after the connection becomes idle. See "High
// Performance Web Networking", Chapter 4, or:
// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/
//
// In the interests of simplicity and determinism, this code does not attempt
// to reset the record size once the connection is idle, however.
func ( *Conn) ( recordType) int {
	if .config.DynamicRecordSizingDisabled ||  != recordTypeApplicationData {
		return maxPlaintext
	}

	if .bytesSent >= recordSizeBoostThreshold {
		return maxPlaintext
	}

	// Subtract TLS overheads to get the maximum payload size.
	 := tcpMSSEstimate - recordHeaderLen - .out.explicitNonceLen()
	if .out.cipher != nil {
		switch ciph := .out.cipher.(type) {
		case cipher.Stream:
			 -= .out.mac.Size()
		case cipher.AEAD:
			 -= .Overhead()
		case cbcMode:
			 := .BlockSize()
			// The payload must fit in a multiple of blockSize, with
			// room for at least one padding byte.
			 = ( & ^( - 1)) - 1
			// The MAC is appended before padding so affects the
			// payload size directly.
			 -= .out.mac.Size()
		default:
			panic("unknown cipher type")
		}
	}
	if .vers == VersionTLS13 {
		-- // encrypted ContentType
	}

	// Allow packet growth in arithmetic progression up to max.
	 := .packetsSent
	.packetsSent++
	if  > 1000 {
		return maxPlaintext // avoid overflow in multiply below
	}

	 :=  * int(+1)
	if  > maxPlaintext {
		 = maxPlaintext
	}
	return 
}

func ( *Conn) ( []byte) (int, error) {
	if .buffering {
		.sendBuf = append(.sendBuf, ...)
		return len(), nil
	}

	,  := .conn.Write()
	.bytesSent += int64()
	return , 
}

func ( *Conn) () (int, error) {
	if len(.sendBuf) == 0 {
		return 0, nil
	}

	,  := .conn.Write(.sendBuf)
	.bytesSent += int64()
	.sendBuf = nil
	.buffering = false
	return , 
}

// outBufPool pools the record-sized scratch buffers used by writeRecordLocked.
var outBufPool = sync.Pool{
	New: func() any {
		return new([]byte)
	},
}

// writeRecordLocked writes a TLS record with the given type and payload to the
// connection and updates the record layer state.
func ( *Conn) ( recordType,  []byte) (int, error) {
	if .quic != nil {
		if  != recordTypeHandshake {
			return 0, errors.New("tls: internal error: sending non-handshake message to QUIC transport")
		}
		.quicWriteCryptoData(.out.level, )
		if !.buffering {
			if ,  := .flush();  != nil {
				return 0, 
			}
		}
		return len(), nil
	}

	 := outBufPool.Get().(*[]byte)
	 := *
	defer func() {
		// You might be tempted to simplify this by just passing &outBuf to Put,
		// but that would make the local copy of the outBuf slice header escape
		// to the heap, causing an allocation. Instead, we keep around the
		// pointer to the slice header returned by Get, which is already on the
		// heap, and overwrite and return that.
		* = 
		outBufPool.Put()
	}()

	var  int
	for len() > 0 {
		 := len()
		if  := .maxPayloadSizeForWrite();  >  {
			 = 
		}

		_,  = sliceForAppend([:0], recordHeaderLen)
		[0] = byte()
		 := .vers
		if  == 0 {
			// Some TLS servers fail if the record version is
			// greater than TLS 1.0 for the initial ClientHello.
			 = VersionTLS10
		} else if  == VersionTLS13 {
			// TLS 1.3 froze the record layer version to 1.2.
			// See RFC 8446, Section 5.1.
			 = VersionTLS12
		}
		[1] = byte( >> 8)
		[2] = byte()
		[3] = byte( >> 8)
		[4] = byte()

		var  error
		,  = .out.encrypt(, [:], .config.rand())
		if  != nil {
			return , 
		}
		if ,  := .write();  != nil {
			return , 
		}
		 += 
		 = [:]
	}

	if  == recordTypeChangeCipherSpec && .vers != VersionTLS13 {
		if  := .out.changeCipherSpec();  != nil {
			return , .sendAlertLocked(.(alert))
		}
	}

	return , nil
}

// writeHandshakeRecord writes a handshake message to the connection and updates
// the record layer state. If transcript is non-nil the marshalled message is
// written to it.
func ( *Conn) ( handshakeMessage,  transcriptHash) (int, error) {
	.out.Lock()
	defer .out.Unlock()

	,  := .marshal()
	if  != nil {
		return 0, 
	}
	if  != nil {
		.Write()
	}

	return .writeRecordLocked(recordTypeHandshake, )
}

// writeChangeCipherRecord writes a ChangeCipherSpec message to the connection and
// updates the record layer state.
func ( *Conn) () error {
	.out.Lock()
	defer .out.Unlock()
	,  := .writeRecordLocked(recordTypeChangeCipherSpec, []byte{1})
	return 
}

// readHandshakeBytes reads handshake data until c.hand contains at least n bytes.
func ( *Conn) ( int) error {
	if .quic != nil {
		return .quicReadHandshakeBytes()
	}
	for .hand.Len() <  {
		if  := .readRecord();  != nil {
			return 
		}
	}
	return nil
}

// readHandshake reads the next handshake message from
// the record layer. If transcript is non-nil, the message
// is written to the passed transcriptHash.
func ( *Conn) ( transcriptHash) (any, error) {
	if  := .readHandshakeBytes(4);  != nil {
		return nil, 
	}
	 := .hand.Bytes()
	 := int([1])<<16 | int([2])<<8 | int([3])
	if  > maxHandshake {
		.sendAlertLocked(alertInternalError)
		return nil, .in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", , maxHandshake))
	}
	if  := .readHandshakeBytes(4 + );  != nil {
		return nil, 
	}
	 = .hand.Next(4 + )
	return .unmarshalHandshakeMessage(, )
}

func ( *Conn) ( []byte,  transcriptHash) (handshakeMessage, error) {
	var  handshakeMessage
	switch [0] {
	case typeHelloRequest:
		 = new(helloRequestMsg)
	case typeClientHello:
		 = new(clientHelloMsg)
	case typeServerHello:
		 = new(serverHelloMsg)
	case typeNewSessionTicket:
		if .vers == VersionTLS13 {
			 = new(newSessionTicketMsgTLS13)
		} else {
			 = new(newSessionTicketMsg)
		}
	case typeCertificate:
		if .vers == VersionTLS13 {
			 = new(certificateMsgTLS13)
		} else {
			 = new(certificateMsg)
		}
	case typeCertificateRequest:
		if .vers == VersionTLS13 {
			 = new(certificateRequestMsgTLS13)
		} else {
			 = &certificateRequestMsg{
				hasSignatureAlgorithm: .vers >= VersionTLS12,
			}
		}
	case typeCertificateStatus:
		 = new(certificateStatusMsg)
	case typeServerKeyExchange:
		 = new(serverKeyExchangeMsg)
	case typeServerHelloDone:
		 = new(serverHelloDoneMsg)
	case typeClientKeyExchange:
		 = new(clientKeyExchangeMsg)
	case typeCertificateVerify:
		 = &certificateVerifyMsg{
			hasSignatureAlgorithm: .vers >= VersionTLS12,
		}
	case typeFinished:
		 = new(finishedMsg)
	case typeEncryptedExtensions:
		 = new(encryptedExtensionsMsg)
	case typeEndOfEarlyData:
		 = new(endOfEarlyDataMsg)
	case typeKeyUpdate:
		 = new(keyUpdateMsg)
	default:
		return nil, .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
	}

	// The handshake message unmarshalers
	// expect to be able to keep references to data,
	// so pass in a fresh copy that won't be overwritten.
	 = append([]byte(nil), ...)

	if !.unmarshal() {
		return nil, .in.setErrorLocked(.sendAlert(alertUnexpectedMessage))
	}

	if  != nil {
		.Write()
	}

	return , nil
}

var (
	errShutdown = errors.New("tls: protocol is shutdown")
)

// Write writes data to the connection.
//
// As Write calls Handshake, in order to prevent indefinite blocking a deadline
// must be set for both Read and Write before Write is called when the handshake
// has not yet completed. See SetDeadline, SetReadDeadline, and
// SetWriteDeadline.
func ( *Conn) ( []byte) (int, error) {
	// interlock with Close below
	for {
		 := .activeCall.Load()
		if &1 != 0 {
			return 0, net.ErrClosed
		}
		if .activeCall.CompareAndSwap(, +2) {
			break
		}
	}
	defer .activeCall.Add(-2)

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

	.out.Lock()
	defer .out.Unlock()

	if  := .out.err;  != nil {
		return 0, 
	}

	if !.isHandshakeComplete.Load() {
		return 0, alertInternalError
	}

	if .closeNotifySent {
		return 0, errShutdown
	}

	// TLS 1.0 is susceptible to a chosen-plaintext
	// attack when using block mode ciphers due to predictable IVs.
	// This can be prevented by splitting each Application Data
	// record into two records, effectively randomizing the IV.
	//
	// https://www.openssl.org/~bodo/tls-cbc.txt
	// https://bugzilla.mozilla.org/show_bug.cgi?id=665814
	// https://www.imperialviolet.org/2012/01/15/beastfollowup.html

	var  int
	if len() > 1 && .vers == VersionTLS10 {
		if ,  := .out.cipher.(cipher.BlockMode);  {
			,  := .writeRecordLocked(recordTypeApplicationData, [:1])
			if  != nil {
				return , .out.setErrorLocked()
			}
			,  = 1, [1:]
		}
	}

	,  := .writeRecordLocked(recordTypeApplicationData, )
	return  + , .out.setErrorLocked()
}

// handleRenegotiation processes a HelloRequest handshake message.
func ( *Conn) () error {
	if .vers == VersionTLS13 {
		return errors.New("tls: internal error: unexpected renegotiation")
	}

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

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

	if !.isClient {
		return .sendAlert(alertNoRenegotiation)
	}

	switch .config.Renegotiation {
	case RenegotiateNever:
		return .sendAlert(alertNoRenegotiation)
	case RenegotiateOnceAsClient:
		if .handshakes > 1 {
			return .sendAlert(alertNoRenegotiation)
		}
	case RenegotiateFreelyAsClient:
		// Ok.
	default:
		.sendAlert(alertInternalError)
		return errors.New("tls: unknown Renegotiation value")
	}

	.handshakeMutex.Lock()
	defer .handshakeMutex.Unlock()

	.isHandshakeComplete.Store(false)
	if .handshakeErr = .clientHandshake(context.Background()); .handshakeErr == nil {
		.handshakes++
	}
	return .handshakeErr
}

// handlePostHandshakeMessage processes a handshake message arrived after the
// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation.
func ( *Conn) () error {
	if .vers != VersionTLS13 {
		return .handleRenegotiation()
	}

	,  := .readHandshake(nil)
	if  != nil {
		return 
	}
	.retryCount++
	if .retryCount > maxUselessRecords {
		.sendAlert(alertUnexpectedMessage)
		return .in.setErrorLocked(errors.New("tls: too many non-advancing records"))
	}

	switch msg := .(type) {
	case *newSessionTicketMsgTLS13:
		return .handleNewSessionTicket()
	case *keyUpdateMsg:
		return .handleKeyUpdate()
	}
	// The QUIC layer is supposed to treat an unexpected post-handshake CertificateRequest
	// as a QUIC-level PROTOCOL_VIOLATION error (RFC 9001, Section 4.4). Returning an
	// unexpected_message alert here doesn't provide it with enough information to distinguish
	// this condition from other unexpected messages. This is probably fine.
	.sendAlert(alertUnexpectedMessage)
	return fmt.Errorf("tls: received unexpected handshake message of type %T", )
}

func ( *Conn) ( *keyUpdateMsg) error {
	if .quic != nil {
		.sendAlert(alertUnexpectedMessage)
		return .in.setErrorLocked(errors.New("tls: received unexpected key update message"))
	}

	 := cipherSuiteTLS13ByID(.cipherSuite)
	if  == nil {
		return .in.setErrorLocked(.sendAlert(alertInternalError))
	}

	 := .nextTrafficSecret(.in.trafficSecret)
	.in.setTrafficSecret(, QUICEncryptionLevelInitial, )

	if .updateRequested {
		.out.Lock()
		defer .out.Unlock()

		 := &keyUpdateMsg{}
		,  := .marshal()
		if  != nil {
			return 
		}
		_,  = .writeRecordLocked(recordTypeHandshake, )
		if  != nil {
			// Surface the error at the next write.
			.out.setErrorLocked()
			return nil
		}

		 := .nextTrafficSecret(.out.trafficSecret)
		.out.setTrafficSecret(, QUICEncryptionLevelInitial, )
	}

	return nil
}

// Read reads data from the connection.
//
// As Read calls Handshake, in order to prevent indefinite blocking a deadline
// must be set for both Read and Write before Read is called when the handshake
// has not yet completed. See SetDeadline, SetReadDeadline, and
// SetWriteDeadline.
func ( *Conn) ( []byte) (int, error) {
	if  := .Handshake();  != nil {
		return 0, 
	}
	if len() == 0 {
		// Put this after Handshake, in case people were calling
		// Read(nil) for the side effect of the Handshake.
		return 0, nil
	}

	.in.Lock()
	defer .in.Unlock()

	for .input.Len() == 0 {
		if  := .readRecord();  != nil {
			return 0, 
		}
		for .hand.Len() > 0 {
			if  := .handlePostHandshakeMessage();  != nil {
				return 0, 
			}
		}
	}

	,  := .input.Read()

	// If a close-notify alert is waiting, read it so that we can return (n,
	// EOF) instead of (n, nil), to signal to the HTTP response reading
	// goroutine that the connection is now closed. This eliminates a race
	// where the HTTP response reading goroutine would otherwise not observe
	// the EOF until its next read, by which time a client goroutine might
	// have already tried to reuse the HTTP connection for a new request.
	// See https://golang.org/cl/76400046 and https://golang.org/issue/3514
	if  != 0 && .input.Len() == 0 && .rawInput.Len() > 0 &&
		recordType(.rawInput.Bytes()[0]) == recordTypeAlert {
		if  := .readRecord();  != nil {
			return ,  // will be io.EOF on closeNotify
		}
	}

	return , nil
}

// Close closes the connection.
func ( *Conn) () error {
	// Interlock with Conn.Write above.
	var  int32
	for {
		 = .activeCall.Load()
		if &1 != 0 {
			return net.ErrClosed
		}
		if .activeCall.CompareAndSwap(, |1) {
			break
		}
	}
	if  != 0 {
		// io.Writer and io.Closer should not be used concurrently.
		// If Close is called while a Write is currently in-flight,
		// interpret that as a sign that this Close is really just
		// being used to break the Write and/or clean up resources and
		// avoid sending the alertCloseNotify, which may block
		// waiting on handshakeMutex or the c.out mutex.
		return .conn.Close()
	}

	var  error
	if .isHandshakeComplete.Load() {
		if  := .closeNotify();  != nil {
			 = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", )
		}
	}

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

var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake complete")

// CloseWrite shuts down the writing side of the connection. It should only be
// called once the handshake has completed and does not call CloseWrite on the
// underlying connection. Most callers should just use Close.
func ( *Conn) () error {
	if !.isHandshakeComplete.Load() {
		return errEarlyCloseWrite
	}

	return .closeNotify()
}

func ( *Conn) () error {
	.out.Lock()
	defer .out.Unlock()

	if !.closeNotifySent {
		// Set a Write Deadline to prevent possibly blocking forever.
		.SetWriteDeadline(time.Now().Add(time.Second * 5))
		.closeNotifyErr = .sendAlertLocked(alertCloseNotify)
		.closeNotifySent = true
		// Any subsequent writes will fail.
		.SetWriteDeadline(time.Now())
	}
	return .closeNotifyErr
}

// Handshake runs the client or server handshake
// protocol if it has not yet been run.
//
// Most uses of this package need not call Handshake explicitly: the
// first Read or Write will call it automatically.
//
// For control over canceling or setting a timeout on a handshake, use
// HandshakeContext or the Dialer's DialContext method instead.
//
// In order to avoid denial of service attacks, the maximum RSA key size allowed
// in certificates sent by either the TLS server or client is limited to 8192
// bits. This limit can be overridden by setting tlsmaxrsasize in the GODEBUG
// environment variable (e.g. GODEBUG=tlsmaxrsasize=4096).
func ( *Conn) () error {
	return .HandshakeContext(context.Background())
}

// HandshakeContext runs the client or server handshake
// protocol if it has not yet been run.
//
// The provided Context must be non-nil. If the context is canceled before
// the handshake is complete, the handshake is interrupted and an error is returned.
// Once the handshake has completed, cancellation of the context will not affect the
// connection.
//
// Most uses of this package need not call HandshakeContext explicitly: the
// first Read or Write will call it automatically.
func ( *Conn) ( context.Context) error {
	// Delegate to unexported method for named return
	// without confusing documented signature.
	return .handshakeContext()
}

func ( *Conn) ( context.Context) ( error) {
	// Fast sync/atomic-based exit if there is no handshake in flight and the
	// last one succeeded without an error. Avoids the expensive context setup
	// and mutex for most Read and Write calls.
	if .isHandshakeComplete.Load() {
		return nil
	}

	,  := context.WithCancel()
	// Note: defer this before starting the "interrupter" goroutine
	// so that we can tell the difference between the input being canceled and
	// this cancellation. In the former case, we need to close the connection.
	defer ()

	if .quic != nil {
		.quic.cancelc = .Done()
		.quic.cancel = 
	} else if .Done() != nil {
		// Start the "interrupter" goroutine, if this context might be canceled.
		// (The background context cannot).
		//
		// The interrupter goroutine waits for the input context to be done and
		// closes the connection if this happens before the function returns.
		 := make(chan struct{})
		 := make(chan error, 1)
		defer func() {
			close()
			if  := <-;  != nil {
				// Return context error to user.
				 = 
			}
		}()
		go func() {
			select {
			case <-.Done():
				// Close the connection, discarding the error
				_ = .conn.Close()
				 <- .Err()
			case <-:
				 <- nil
			}
		}()
	}

	.handshakeMutex.Lock()
	defer .handshakeMutex.Unlock()

	if  := .handshakeErr;  != nil {
		return 
	}
	if .isHandshakeComplete.Load() {
		return nil
	}

	.in.Lock()
	defer .in.Unlock()

	.handshakeErr = .handshakeFn()
	if .handshakeErr == nil {
		.handshakes++
	} else {
		// If an error occurred during the handshake try to flush the
		// alert that might be left in the buffer.
		.flush()
	}

	if .handshakeErr == nil && !.isHandshakeComplete.Load() {
		.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
	}
	if .handshakeErr != nil && .isHandshakeComplete.Load() {
		panic("tls: internal error: handshake returned an error but is marked successful")
	}

	if .quic != nil {
		if .handshakeErr == nil {
			.quicHandshakeComplete()
			// Provide the 1-RTT read secret now that the handshake is complete.
			// The QUIC layer MUST NOT decrypt 1-RTT packets prior to completing
			// the handshake (RFC 9001, Section 5.7).
			.quicSetReadSecret(QUICEncryptionLevelApplication, .cipherSuite, .in.trafficSecret)
		} else {
			var  alert
			.out.Lock()
			if !errors.As(.out.err, &) {
				 = alertInternalError
			}
			.out.Unlock()
			// Return an error which wraps both the handshake error and
			// any alert error we may have sent, or alertInternalError
			// if we didn't send an alert.
			// Truncate the text of the alert to 0 characters.
			.handshakeErr = fmt.Errorf("%w%.0w", .handshakeErr, AlertError())
		}
		close(.quic.blockedc)
		close(.quic.signalc)
	}

	return .handshakeErr
}

// ConnectionState returns basic TLS details about the connection.
func ( *Conn) () ConnectionState {
	.handshakeMutex.Lock()
	defer .handshakeMutex.Unlock()
	return .connectionStateLocked()
}

func ( *Conn) () ConnectionState {
	var  ConnectionState
	.HandshakeComplete = .isHandshakeComplete.Load()
	.Version = .vers
	.NegotiatedProtocol = .clientProtocol
	.DidResume = .didResume
	.NegotiatedProtocolIsMutual = true
	.ServerName = .serverName
	.CipherSuite = .cipherSuite
	.PeerCertificates = .peerCertificates
	.VerifiedChains = .verifiedChains
	.SignedCertificateTimestamps = .scts
	.OCSPResponse = .ocspResponse
	if (!.didResume || .extMasterSecret) && .vers != VersionTLS13 {
		if .clientFinishedIsFirst {
			.TLSUnique = .clientFinished[:]
		} else {
			.TLSUnique = .serverFinished[:]
		}
	}
	if .config.Renegotiation != RenegotiateNever {
		.ekm = noExportedKeyingMaterial
	} else {
		.ekm = .ekm
	}
	return 
}

// OCSPResponse returns the stapled OCSP response from the TLS server, if
// any. (Only valid for client connections.)
func ( *Conn) () []byte {
	.handshakeMutex.Lock()
	defer .handshakeMutex.Unlock()

	return .ocspResponse
}

// VerifyHostname checks that the peer certificate chain is valid for
// connecting to host. If so, it returns nil; if not, it returns an error
// describing the problem.
func ( *Conn) ( string) error {
	.handshakeMutex.Lock()
	defer .handshakeMutex.Unlock()
	if !.isClient {
		return errors.New("tls: VerifyHostname called on TLS server connection")
	}
	if !.isHandshakeComplete.Load() {
		return errors.New("tls: handshake has not yet been performed")
	}
	if len(.verifiedChains) == 0 {
		return errors.New("tls: handshake did not verify certificate chain")
	}
	return .peerCertificates[0].VerifyHostname()
}