package tls
import (
)
type clientHandshakeState struct {
c *Conn
ctx context.Context
serverHello *serverHelloMsg
hello *clientHelloMsg
suite *cipherSuite
finishedHash finishedHash
masterSecret []byte
session *SessionState
ticket []byte
}
var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
func ( *Conn) () (*clientHelloMsg, *keySharePrivateKeys, *echClientContext, error) {
:= .config
if len(.ServerName) == 0 && !.InsecureSkipVerify {
return nil, nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
}
:= 0
for , := range .NextProtos {
if := len(); == 0 || > 255 {
return nil, nil, nil, errors.New("tls: invalid NextProtos value")
} else {
+= 1 +
}
}
if > 0xffff {
return nil, nil, nil, errors.New("tls: NextProtos values too large")
}
:= .supportedVersions(roleClient)
if len() == 0 {
return nil, nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
}
:= .maxSupportedVersion(roleClient)
:= &clientHelloMsg{
vers: ,
compressionMethods: []uint8{compressionNone},
random: make([]byte, 32),
extendedMasterSecret: true,
ocspStapling: true,
scts: true,
serverName: hostnameInSNI(.ServerName),
supportedCurves: .curvePreferences(),
supportedPoints: []uint8{pointFormatUncompressed},
secureRenegotiationSupported: true,
alpnProtocols: .NextProtos,
supportedVersions: ,
}
if .vers > VersionTLS12 {
.vers = VersionTLS12
}
if .handshakes > 0 {
.secureRenegotiation = .clientFinished[:]
}
:= cipherSuitesPreferenceOrder
if !hasAESGCMHardwareSupport {
= cipherSuitesPreferenceOrderNoAES
}
:= .cipherSuites()
.cipherSuites = make([]uint16, 0, len())
for , := range {
:= mutualCipherSuite(, )
if == nil {
continue
}
if < VersionTLS12 && .flags&suiteTLS12 != 0 {
continue
}
.cipherSuites = append(.cipherSuites, )
}
, := io.ReadFull(.rand(), .random)
if != nil {
return nil, nil, nil, errors.New("tls: short read from Rand: " + .Error())
}
if .quic == nil {
.sessionId = make([]byte, 32)
if , := io.ReadFull(.rand(), .sessionId); != nil {
return nil, nil, nil, errors.New("tls: short read from Rand: " + .Error())
}
}
if >= VersionTLS12 {
.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
}
if testingOnlyForceClientHelloSignatureAlgorithms != nil {
.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
}
var *keySharePrivateKeys
if .supportedVersions[0] == VersionTLS13 {
if len(.supportedVersions) == 1 {
.cipherSuites = nil
}
if fips140tls.Required() {
.cipherSuites = append(.cipherSuites, defaultCipherSuitesTLS13FIPS...)
} else if hasAESGCMHardwareSupport {
.cipherSuites = append(.cipherSuites, defaultCipherSuitesTLS13...)
} else {
.cipherSuites = append(.cipherSuites, defaultCipherSuitesTLS13NoAES...)
}
if len(.supportedCurves) == 0 {
return nil, nil, nil, errors.New("tls: no supported elliptic curves for ECDHE")
}
:= .supportedCurves[0]
= &keySharePrivateKeys{curveID: }
if == X25519MLKEM768 {
.ecdhe, = generateECDHEKey(.rand(), X25519)
if != nil {
return nil, nil, nil,
}
:= make([]byte, mlkem.SeedSize)
if , := io.ReadFull(.rand(), ); != nil {
return nil, nil, nil,
}
.mlkem, = mlkem.NewDecapsulationKey768()
if != nil {
return nil, nil, nil,
}
:= .mlkem.EncapsulationKey().Bytes()
:= .ecdhe.PublicKey().Bytes()
.keyShares = []keyShare{
{group: X25519MLKEM768, data: append(, ...)},
}
if slices.Contains(.supportedCurves, X25519) {
.keyShares = append(.keyShares, keyShare{group: X25519, data: })
}
} else {
if , := curveForCurveID(); ! {
return nil, nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
}
.ecdhe, = generateECDHEKey(.rand(), )
if != nil {
return nil, nil, nil,
}
.keyShares = []keyShare{{group: , data: .ecdhe.PublicKey().Bytes()}}
}
}
if .quic != nil {
, := .quicGetTransportParameters()
if != nil {
return nil, nil, nil,
}
if == nil {
= []byte{}
}
.quicTransportParameters =
}
var *echClientContext
if .config.EncryptedClientHelloConfigList != nil {
if .config.MinVersion != 0 && .config.MinVersion < VersionTLS13 {
return nil, nil, nil, errors.New("tls: MinVersion must be >= VersionTLS13 if EncryptedClientHelloConfigList is populated")
}
if .config.MaxVersion != 0 && .config.MaxVersion <= VersionTLS12 {
return nil, nil, nil, errors.New("tls: MaxVersion must be >= VersionTLS13 if EncryptedClientHelloConfigList is populated")
}
, := parseECHConfigList(.config.EncryptedClientHelloConfigList)
if != nil {
return nil, nil, nil,
}
:= pickECHConfig()
if == nil {
return nil, nil, nil, errors.New("tls: EncryptedClientHelloConfigList contains no valid configs")
}
= &echClientContext{config: }
.encryptedClientHello = []byte{1}
.supportedPoints = nil
.ticketSupported = false
.secureRenegotiationSupported = false
.extendedMasterSecret = false
, := hpke.ParseHPKEPublicKey(.config.KemID, .config.PublicKey)
if != nil {
return nil, nil, nil,
}
, := pickECHCipherSuite(.config.SymmetricCipherSuite)
if != nil {
return nil, nil, nil,
}
.kdfID, .aeadID = .KDFID, .AEADID
:= append([]byte("tls ech\x00"), .config.raw...)
.encapsulatedKey, .hpkeContext, = hpke.SetupSender(.config.KemID, .KDFID, .AEADID, , )
if != nil {
return nil, nil, nil,
}
}
return , , , nil
}
type echClientContext struct {
config *echConfig
hpkeContext *hpke.Sender
encapsulatedKey []byte
innerHello *clientHelloMsg
innerTranscript hash.Hash
kdfID uint16
aeadID uint16
echRejected bool
retryConfigs []byte
}
func ( *Conn) ( context.Context) ( error) {
if .config == nil {
.config = defaultConfig()
}
.didResume = false
, , , := .makeClientHello()
if != nil {
return
}
, , , := .loadSession()
if != nil {
return
}
if != nil {
defer func() {
if != nil {
if := .clientSessionCacheKey(); != "" {
.config.ClientSessionCache.Put(, nil)
}
}
}()
}
if != nil {
.innerHello = .clone()
.serverName = string(.config.PublicName)
.random = make([]byte, 32)
_, = io.ReadFull(.config.rand(), .random)
if != nil {
return errors.New("tls: short read from Rand: " + .Error())
}
if := computeAndUpdateOuterECHExtension(, .innerHello, , true); != nil {
return
}
}
.serverName = .serverName
if , := .writeHandshakeRecord(, nil); != nil {
return
}
if .earlyData {
:= cipherSuiteTLS13ByID(.cipherSuite)
:= .hash.New()
if := transcriptMsg(, ); != nil {
return
}
:= .ClientEarlyTrafficSecret()
.quicSetWriteSecret(QUICEncryptionLevelEarly, .id, )
}
, := .readHandshake(nil)
if != nil {
return
}
, := .(*serverHelloMsg)
if ! {
.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(, )
}
if := .pickTLSVersion(); != nil {
return
}
:= .config.maxSupportedVersion(roleClient)
:= string(.random[24:]) == downgradeCanaryTLS12
:= string(.random[24:]) == downgradeCanaryTLS11
if == VersionTLS13 && .vers <= VersionTLS12 && ( || ) ||
== VersionTLS12 && .vers <= VersionTLS11 && {
.sendAlert(alertIllegalParameter)
return errors.New("tls: downgrade attempt detected, possibly due to a MitM attack or a broken middlebox")
}
if .vers == VersionTLS13 {
:= &clientHandshakeStateTLS13{
c: ,
ctx: ,
serverHello: ,
hello: ,
keyShareKeys: ,
session: ,
earlySecret: ,
binderKey: ,
echContext: ,
}
return .handshake()
}
:= &clientHandshakeState{
c: ,
ctx: ,
serverHello: ,
hello: ,
session: ,
}
return .handshake()
}
func ( *Conn) ( *clientHelloMsg) (
*SessionState, *tls13.EarlySecret, []byte, error) {
if .config.SessionTicketsDisabled || .config.ClientSessionCache == nil {
return nil, nil, nil, nil
}
:= bytes.Equal(.encryptedClientHello, []byte{1})
.ticketSupported = true && !
if .supportedVersions[0] == VersionTLS13 {
.pskModes = []uint8{pskModeDHE}
}
if .handshakes != 0 {
return nil, nil, nil, nil
}
:= .clientSessionCacheKey()
if == "" {
return nil, nil, nil, nil
}
, := .config.ClientSessionCache.Get()
if ! || == nil {
return nil, nil, nil, nil
}
= .session
:= false
for , := range .supportedVersions {
if == .version {
= true
break
}
}
if ! {
return nil, nil, nil, nil
}
if .config.time().After(.peerCertificates[0].NotAfter) {
.config.ClientSessionCache.Put(, nil)
return nil, nil, nil, nil
}
if !.config.InsecureSkipVerify {
if len(.verifiedChains) == 0 {
return nil, nil, nil, nil
}
if := .peerCertificates[0].VerifyHostname(.config.ServerName); != nil {
return nil, nil, nil, nil
}
}
if .version != VersionTLS13 {
if mutualCipherSuite(.cipherSuites, .cipherSuite) == nil {
return nil, nil, nil, nil
}
.sessionTicket = .ticket
return
}
if .config.time().After(time.Unix(int64(.useBy), 0)) {
.config.ClientSessionCache.Put(, nil)
return nil, nil, nil, nil
}
:= cipherSuiteTLS13ByID(.cipherSuite)
if == nil {
return nil, nil, nil, nil
}
:= false
for , := range .cipherSuites {
:= cipherSuiteTLS13ByID()
if != nil && .hash == .hash {
= true
break
}
}
if ! {
return nil, nil, nil, nil
}
if .quic != nil {
if .quic.enableSessionEvents {
.quicResumeSession()
}
if .EarlyData && mutualCipherSuiteTLS13(.cipherSuites, .cipherSuite) != nil {
for , := range .alpnProtocols {
if == .alpnProtocol {
.earlyData = true
break
}
}
}
}
:= .config.time().Sub(time.Unix(int64(.createdAt), 0))
:= pskIdentity{
label: .ticket,
obfuscatedTicketAge: uint32(/time.Millisecond) + .ageAdd,
}
.pskIdentities = []pskIdentity{}
.pskBinders = [][]byte{make([]byte, .hash.Size())}
= tls13.NewEarlySecret(.hash.New, .secret)
= .ResumptionBinderKey()
:= .hash.New()
if := computeAndUpdatePSK(, , , .finishedHash); != nil {
return nil, nil, nil,
}
return
}
func ( *Conn) ( *serverHelloMsg) error {
:= .vers
if .supportedVersion != 0 {
= .supportedVersion
}
, := .config.mutualVersion(roleClient, []uint16{})
if ! {
.sendAlert(alertProtocolVersion)
return fmt.Errorf("tls: server selected unsupported protocol version %x", )
}
.vers =
.haveVers = true
.in.version =
.out.version =
return nil
}
func ( *clientHandshakeState) () error {
:= .c
, := .processServerHello()
if != nil {
return
}
.finishedHash = newFinishedHash(.vers, .suite)
if || (len(.config.Certificates) == 0 && .config.GetClientCertificate == nil) {
.finishedHash.discardHandshakeBuffer()
}
if := transcriptMsg(.hello, &.finishedHash); != nil {
return
}
if := transcriptMsg(.serverHello, &.finishedHash); != nil {
return
}
.buffering = true
.didResume =
if {
if := .establishKeys(); != nil {
return
}
if := .readSessionTicket(); != nil {
return
}
if := .readFinished(.serverFinished[:]); != nil {
return
}
.clientFinishedIsFirst = false
if .config.VerifyConnection != nil {
if := .config.VerifyConnection(.connectionStateLocked()); != nil {
.sendAlert(alertBadCertificate)
return
}
}
if := .sendFinished(.clientFinished[:]); != nil {
return
}
if , := .flush(); != nil {
return
}
} else {
if := .doFullHandshake(); != nil {
return
}
if := .establishKeys(); != nil {
return
}
if := .sendFinished(.clientFinished[:]); != nil {
return
}
if , := .flush(); != nil {
return
}
.clientFinishedIsFirst = true
if := .readSessionTicket(); != nil {
return
}
if := .readFinished(.serverFinished[:]); != nil {
return
}
}
if := .saveSessionTicket(); != nil {
return
}
.ekm = ekmFromMasterSecret(.vers, .suite, .masterSecret, .hello.random, .serverHello.random)
.isHandshakeComplete.Store(true)
return nil
}
func ( *clientHandshakeState) () error {
if .suite = mutualCipherSuite(.hello.cipherSuites, .serverHello.cipherSuite); .suite == nil {
.c.sendAlert(alertHandshakeFailure)
return errors.New("tls: server chose an unconfigured cipher suite")
}
if .c.config.CipherSuites == nil && !fips140tls.Required() && rsaKexCiphers[.suite.id] {
tlsrsakex.Value()
tlsrsakex.IncNonDefault()
}
if .c.config.CipherSuites == nil && !fips140tls.Required() && tdesCiphers[.suite.id] {
tls3des.Value()
tls3des.IncNonDefault()
}
.c.cipherSuite = .suite.id
return nil
}
func ( *clientHandshakeState) () error {
:= .c
, := .readHandshake(&.finishedHash)
if != nil {
return
}
, := .(*certificateMsg)
if ! || len(.certificates) == 0 {
.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(, )
}
, = .readHandshake(&.finishedHash)
if != nil {
return
}
, := .(*certificateStatusMsg)
if {
if !.serverHello.ocspStapling {
.sendAlert(alertUnexpectedMessage)
return errors.New("tls: received unexpected CertificateStatus message")
}
.ocspResponse = .response
, = .readHandshake(&.finishedHash)
if != nil {
return
}
}
if .handshakes == 0 {
if := .verifyServerCertificate(.certificates); != nil {
return
}
} else {
if !bytes.Equal(.peerCertificates[0].Raw, .certificates[0]) {
.sendAlert(alertBadCertificate)
return errors.New("tls: server's identity changed during renegotiation")
}
}
:= .suite.ka(.vers)
, := .(*serverKeyExchangeMsg)
if {
= .processServerKeyExchange(.config, .hello, .serverHello, .peerCertificates[0], )
if != nil {
.sendAlert(alertIllegalParameter)
return
}
if len(.key) >= 3 && .key[0] == 3 {
.curveID = CurveID(byteorder.BEUint16(.key[1:]))
}
, = .readHandshake(&.finishedHash)
if != nil {
return
}
}
var *Certificate
var bool
, := .(*certificateRequestMsg)
if {
= true
:= certificateRequestInfoFromMsg(.ctx, .vers, )
if , = .getClientCertificate(); != nil {
.sendAlert(alertInternalError)
return
}
, = .readHandshake(&.finishedHash)
if != nil {
return
}
}
, := .(*serverHelloDoneMsg)
if ! {
.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(, )
}
if {
= new(certificateMsg)
.certificates = .Certificate
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
}
, , := .generateClientKeyExchange(.config, .hello, .peerCertificates[0])
if != nil {
.sendAlert(alertInternalError)
return
}
if != nil {
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
}
if .serverHello.extendedMasterSecret {
.extMasterSecret = true
.masterSecret = extMasterFromPreMasterSecret(.vers, .suite, ,
.finishedHash.Sum())
} else {
.masterSecret = masterFromPreMasterSecret(.vers, .suite, ,
.hello.random, .serverHello.random)
}
if := .config.writeKeyLog(keyLogLabelTLS12, .hello.random, .masterSecret); != nil {
.sendAlert(alertInternalError)
return errors.New("tls: failed to write to key log: " + .Error())
}
if != nil && len(.Certificate) > 0 {
:= &certificateVerifyMsg{}
, := .PrivateKey.(crypto.Signer)
if ! {
.sendAlert(alertInternalError)
return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", .PrivateKey)
}
var uint8
var crypto.Hash
if .vers >= VersionTLS12 {
, := selectSignatureScheme(.vers, , .supportedSignatureAlgorithms)
if != nil {
.sendAlert(alertIllegalParameter)
return
}
, , = typeAndHashFromSignatureScheme()
if != nil {
return .sendAlert(alertInternalError)
}
.hasSignatureAlgorithm = true
.signatureAlgorithm =
} else {
, , = legacyTypeAndHashFromPublicKey(.Public())
if != nil {
.sendAlert(alertIllegalParameter)
return
}
}
:= .finishedHash.hashForClientCertificate(, )
:= crypto.SignerOpts()
if == signatureRSAPSS {
= &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: }
}
.signature, = .Sign(.config.rand(), , )
if != nil {
.sendAlert(alertInternalError)
return
}
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
}
.finishedHash.discardHandshakeBuffer()
return nil
}
func ( *clientHandshakeState) () error {
:= .c
, , , , , :=
keysFromMasterSecret(.vers, .suite, .masterSecret, .hello.random, .serverHello.random, .suite.macLen, .suite.keyLen, .suite.ivLen)
var , any
var , hash.Hash
if .suite.cipher != nil {
= .suite.cipher(, , false )
= .suite.mac()
= .suite.cipher(, , true )
= .suite.mac()
} else {
= .suite.aead(, )
= .suite.aead(, )
}
.in.prepareCipherSpec(.vers, , )
.out.prepareCipherSpec(.vers, , )
return nil
}
func ( *clientHandshakeState) () bool {
return .session != nil && .hello.sessionId != nil &&
bytes.Equal(.serverHello.sessionId, .hello.sessionId)
}
func ( *clientHandshakeState) () (bool, error) {
:= .c
if := .pickCipherSuite(); != nil {
return false,
}
if .serverHello.compressionMethod != compressionNone {
.sendAlert(alertUnexpectedMessage)
return false, errors.New("tls: server selected unsupported compression format")
}
if .handshakes == 0 && .serverHello.secureRenegotiationSupported {
.secureRenegotiation = true
if len(.serverHello.secureRenegotiation) != 0 {
.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
}
}
if .handshakes > 0 && .secureRenegotiation {
var [24]byte
copy([:], .clientFinished[:])
copy([12:], .serverFinished[:])
if !bytes.Equal(.serverHello.secureRenegotiation, [:]) {
.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: incorrect renegotiation extension contents")
}
}
if := checkALPN(.hello.alpnProtocols, .serverHello.alpnProtocol, false); != nil {
.sendAlert(alertUnsupportedExtension)
return false,
}
.clientProtocol = .serverHello.alpnProtocol
.scts = .serverHello.scts
if !.serverResumedSession() {
return false, nil
}
if .session.version != .vers {
.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: server resumed a session with a different version")
}
if .session.cipherSuite != .suite.id {
.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: server resumed a session with a different cipher suite")
}
if .session.extMasterSecret != .serverHello.extendedMasterSecret {
.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: server resumed a session with a different EMS extension")
}
.masterSecret = .session.secret
.extMasterSecret = .session.extMasterSecret
.peerCertificates = .session.peerCertificates
.activeCertHandles = .c.activeCertHandles
.verifiedChains = .session.verifiedChains
.ocspResponse = .session.ocspResponse
if len(.scts) == 0 && len(.session.scts) != 0 {
.scts = .session.scts
}
return true, nil
}
func ( []string, string, bool) error {
if == "" {
if && len() > 0 {
return errors.New("tls: server did not select an ALPN protocol")
}
return nil
}
if len() == 0 {
return errors.New("tls: server advertised unrequested ALPN extension")
}
for , := range {
if == {
return nil
}
}
return errors.New("tls: server selected unadvertised ALPN protocol")
}
func ( *clientHandshakeState) ( []byte) error {
:= .c
if := .readChangeCipherSpec(); != nil {
return
}
, := .readHandshake(nil)
if != nil {
return
}
, := .(*finishedMsg)
if ! {
.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(, )
}
:= .finishedHash.serverSum(.masterSecret)
if len() != len(.verifyData) ||
subtle.ConstantTimeCompare(, .verifyData) != 1 {
.sendAlert(alertHandshakeFailure)
return errors.New("tls: server's Finished message was incorrect")
}
if := transcriptMsg(, &.finishedHash); != nil {
return
}
copy(, )
return nil
}
func ( *clientHandshakeState) () error {
if !.serverHello.ticketSupported {
return nil
}
:= .c
if !.hello.ticketSupported {
.sendAlert(alertIllegalParameter)
return errors.New("tls: server sent unrequested session ticket")
}
, := .readHandshake(&.finishedHash)
if != nil {
return
}
, := .(*newSessionTicketMsg)
if ! {
.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(, )
}
.ticket = .ticket
return nil
}
func ( *clientHandshakeState) () error {
if .ticket == nil {
return nil
}
:= .c
:= .clientSessionCacheKey()
if == "" {
return nil
}
:= .sessionState()
.secret = .masterSecret
.ticket = .ticket
:= &ClientSessionState{session: }
.config.ClientSessionCache.Put(, )
return nil
}
func ( *clientHandshakeState) ( []byte) error {
:= .c
if := .writeChangeCipherRecord(); != nil {
return
}
:= new(finishedMsg)
.verifyData = .finishedHash.clientSum(.masterSecret)
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
copy(, .verifyData)
return nil
}
const defaultMaxRSAKeySize = 8192
var tlsmaxrsasize = godebug.New("tlsmaxrsasize")
func ( int) ( int, bool) {
if := tlsmaxrsasize.Value(); != "" {
if , := strconv.Atoi(); == nil {
if ( <= ) != ( <= defaultMaxRSAKeySize) {
tlsmaxrsasize.IncNonDefault()
}
return , <=
}
}
return defaultMaxRSAKeySize, <= defaultMaxRSAKeySize
}
func ( *Conn) ( [][]byte) error {
:= make([]*activeCert, len())
:= make([]*x509.Certificate, len())
for , := range {
, := globalCertCache.newCert()
if != nil {
.sendAlert(alertBadCertificate)
return errors.New("tls: failed to parse certificate from server: " + .Error())
}
if .cert.PublicKeyAlgorithm == x509.RSA {
:= .cert.PublicKey.(*rsa.PublicKey).N.BitLen()
if , := checkKeySize(); ! {
.sendAlert(alertBadCertificate)
return fmt.Errorf("tls: server sent certificate containing RSA key larger than %d bits", )
}
}
[] =
[] = .cert
}
:= .config.EncryptedClientHelloConfigList != nil && !.echAccepted
if {
if .config.EncryptedClientHelloRejectionVerify != nil {
if := .config.EncryptedClientHelloRejectionVerify(.connectionStateLocked()); != nil {
.sendAlert(alertBadCertificate)
return
}
} else {
:= x509.VerifyOptions{
Roots: .config.RootCAs,
CurrentTime: .config.time(),
DNSName: .serverName,
Intermediates: x509.NewCertPool(),
}
for , := range [1:] {
.Intermediates.AddCert()
}
, := [0].Verify()
if != nil {
.sendAlert(alertBadCertificate)
return &CertificateVerificationError{UnverifiedCertificates: , Err: }
}
.verifiedChains, = fipsAllowedChains()
if != nil {
.sendAlert(alertBadCertificate)
return &CertificateVerificationError{UnverifiedCertificates: , Err: }
}
}
} else if !.config.InsecureSkipVerify {
:= x509.VerifyOptions{
Roots: .config.RootCAs,
CurrentTime: .config.time(),
DNSName: .config.ServerName,
Intermediates: x509.NewCertPool(),
}
for , := range [1:] {
.Intermediates.AddCert()
}
, := [0].Verify()
if != nil {
.sendAlert(alertBadCertificate)
return &CertificateVerificationError{UnverifiedCertificates: , Err: }
}
.verifiedChains, = fipsAllowedChains()
if != nil {
.sendAlert(alertBadCertificate)
return &CertificateVerificationError{UnverifiedCertificates: , Err: }
}
}
switch [0].PublicKey.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
break
default:
.sendAlert(alertUnsupportedCertificate)
return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", [0].PublicKey)
}
.activeCertHandles =
.peerCertificates =
if .config.VerifyPeerCertificate != nil && ! {
if := .config.VerifyPeerCertificate(, .verifiedChains); != nil {
.sendAlert(alertBadCertificate)
return
}
}
if .config.VerifyConnection != nil && ! {
if := .config.VerifyConnection(.connectionStateLocked()); != nil {
.sendAlert(alertBadCertificate)
return
}
}
return nil
}
func ( context.Context, uint16, *certificateRequestMsg) *CertificateRequestInfo {
:= &CertificateRequestInfo{
AcceptableCAs: .certificateAuthorities,
Version: ,
ctx: ,
}
var , bool
for , := range .certificateTypes {
switch {
case certTypeRSASign:
= true
case certTypeECDSASign:
= true
}
}
if !.hasSignatureAlgorithm {
switch {
case && :
.SignatureSchemes = []SignatureScheme{
ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
}
case :
.SignatureSchemes = []SignatureScheme{
PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
}
case :
.SignatureSchemes = []SignatureScheme{
ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
}
}
return
}
.SignatureSchemes = make([]SignatureScheme, 0, len(.supportedSignatureAlgorithms))
for , := range .supportedSignatureAlgorithms {
, , := typeAndHashFromSignatureScheme()
if != nil {
continue
}
switch {
case signatureECDSA, signatureEd25519:
if {
.SignatureSchemes = append(.SignatureSchemes, )
}
case signatureRSAPSS, signaturePKCS1v15:
if {
.SignatureSchemes = append(.SignatureSchemes, )
}
}
}
return
}
func ( *Conn) ( *CertificateRequestInfo) (*Certificate, error) {
if .config.GetClientCertificate != nil {
return .config.GetClientCertificate()
}
for , := range .config.Certificates {
if := .SupportsCertificate(&); != nil {
continue
}
return &, nil
}
return new(Certificate), nil
}
func ( *Conn) () string {
if len(.config.ServerName) > 0 {
return .config.ServerName
}
if .conn != nil {
return .conn.RemoteAddr().String()
}
return ""
}
func ( string) string {
:=
if len() > 0 && [0] == '[' && [len()-1] == ']' {
= [1 : len()-1]
}
if := strings.LastIndex(, "%"); > 0 {
= [:]
}
if net.ParseIP() != nil {
return ""
}
for len() > 0 && [len()-1] == '.' {
= [:len()-1]
}
return
}
func ( *clientHelloMsg, []byte, hash.Hash, func([]byte, hash.Hash) []byte) error {
, := .marshalWithoutBinders()
if != nil {
return
}
.Write()
:= [][]byte{(, )}
return .updateBinders()
}