gitee.com/lh-her-team/common@v1.5.1/crypto/tls/gm_handshake_client.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tls
     6  
     7  import (
     8  	"bytes"
     9  	"crypto"
    10  	"crypto/ecdsa"
    11  	"crypto/rsa"
    12  	"crypto/subtle"
    13  	"errors"
    14  	"fmt"
    15  	"io"
    16  	"strconv"
    17  	"sync/atomic"
    18  
    19  	gox509 "crypto/x509"
    20  
    21  	"gitee.com/lh-her-team/common/crypto/x509"
    22  	"github.com/tjfoc/gmsm/sm2"
    23  )
    24  
    25  type clientHandshakeStateGM struct {
    26  	c            *Conn
    27  	serverHello  *serverHelloMsg
    28  	hello        *clientHelloMsg
    29  	suite        *cipherSuite
    30  	finishedHash finishedHash
    31  	masterSecret []byte
    32  	session      *ClientSessionState
    33  }
    34  
    35  func makeClientHelloGM(config *Config) (*clientHelloMsg, error) {
    36  	if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
    37  		return nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
    38  	}
    39  	nextProtosLength := 0
    40  	for _, proto := range config.NextProtos {
    41  		if l := len(proto); l == 0 || l > 255 {
    42  			return nil, errors.New("tls: invalid NextProtos value")
    43  		} else {
    44  			nextProtosLength += 1 + l
    45  		}
    46  	}
    47  	if nextProtosLength > 0xffff {
    48  		return nil, errors.New("tls: NextProtos values too large")
    49  	}
    50  	hello := &clientHelloMsg{
    51  		vers:               config.GMSupport.GetVersion(),
    52  		compressionMethods: []uint8{compressionNone},
    53  		random:             make([]byte, 32),
    54  		alpnProtocols:      config.NextProtos,
    55  	}
    56  	possibleCipherSuites := getCipherSuites(config)
    57  	hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
    58  NextCipherSuite:
    59  	for _, suiteId := range possibleCipherSuites {
    60  		for _, suite := range config.GMSupport.cipherSuites() {
    61  			if suite.id != suiteId {
    62  				continue
    63  			}
    64  			hello.cipherSuites = append(hello.cipherSuites, suiteId)
    65  			continue NextCipherSuite
    66  		}
    67  	}
    68  	_, err := io.ReadFull(config.rand(), hello.random)
    69  	if err != nil {
    70  		return nil, errors.New("tls: short read from Rand: " + err.Error())
    71  	}
    72  	return hello, nil
    73  }
    74  
    75  // Does the handshake, either a full one or resumes old session.
    76  // Requires hs.c, hs.hello, and, optionally, hs.session to be set.
    77  func (hs *clientHandshakeStateGM) handshake() error {
    78  	c := hs.c
    79  	// send ClientHello
    80  	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
    81  		return err
    82  	}
    83  	msg, err := c.readHandshake()
    84  	if err != nil {
    85  		return err
    86  	}
    87  	var ok bool
    88  	if hs.serverHello, ok = msg.(*serverHelloMsg); !ok {
    89  		c.sendAlert(alertUnexpectedMessage)
    90  		return unexpectedMessageError(hs.serverHello, msg)
    91  	}
    92  	if hs.serverHello.vers != VersionGMSSL {
    93  		hs.c.sendAlert(alertProtocolVersion)
    94  		return fmt.Errorf("tls: server selected unsupported protocol version %x, while expecting %x", hs.serverHello.vers, VersionGMSSL)
    95  	}
    96  	c.vers = hs.serverHello.vers
    97  	c.haveVers = true
    98  	c.in.version = hs.serverHello.vers
    99  	c.out.version = hs.serverHello.vers
   100  	if err = hs.pickCipherSuite(); err != nil {
   101  		return err
   102  	}
   103  	isResume, err := hs.processServerHello()
   104  	if err != nil {
   105  		return err
   106  	}
   107  	hs.finishedHash = newFinishedHashGM(hs.suite)
   108  	// No signatures of the handshake are needed in a resumption.
   109  	// Otherwise, in a full handshake, if we don't have any certificates
   110  	// configured then we will never send a CertificateVerify message and
   111  	// thus no signatures are needed in that case either.
   112  	if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) {
   113  		hs.finishedHash.discardHandshakeBuffer()
   114  	}
   115  	hs.finishedHash.Write(hs.hello.marshal())
   116  	hs.finishedHash.Write(hs.serverHello.marshal())
   117  	c.buffering = true
   118  	if isResume {
   119  		if err := hs.establishKeys(); err != nil {
   120  			return err
   121  		}
   122  		if err := hs.readSessionTicket(); err != nil {
   123  			return err
   124  		}
   125  		if err := hs.readFinished(c.serverFinished[:]); err != nil {
   126  			return err
   127  		}
   128  		c.clientFinishedIsFirst = false
   129  		if err := hs.sendFinished(c.clientFinished[:]); err != nil {
   130  			return err
   131  		}
   132  		if _, err := c.flush(); err != nil {
   133  			return err
   134  		}
   135  	} else {
   136  		if err := hs.doFullHandshake(); err != nil {
   137  			return err
   138  		}
   139  		if err := hs.establishKeys(); err != nil {
   140  			return err
   141  		}
   142  		if err := hs.sendFinished(c.clientFinished[:]); err != nil {
   143  			return err
   144  		}
   145  		if _, err := c.flush(); err != nil {
   146  			return err
   147  		}
   148  		c.clientFinishedIsFirst = true
   149  		if err := hs.readSessionTicket(); err != nil {
   150  			return err
   151  		}
   152  		if err := hs.readFinished(c.serverFinished[:]); err != nil {
   153  			return err
   154  		}
   155  	}
   156  	c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
   157  	c.didResume = isResume
   158  	atomic.StoreUint32(&c.handshakeStatus, 1)
   159  	return nil
   160  }
   161  
   162  func (hs *clientHandshakeStateGM) pickCipherSuite() error {
   163  	if hs.suite = mutualCipherSuiteGM(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
   164  		hs.c.sendAlert(alertHandshakeFailure)
   165  		return errors.New("tls: server chose an unconfigured cipher suite")
   166  	}
   167  	hs.c.cipherSuite = hs.suite.id
   168  	return nil
   169  }
   170  
   171  func (hs *clientHandshakeStateGM) doFullHandshake() error {
   172  	c := hs.c
   173  	msg, err := c.readHandshake()
   174  	if err != nil {
   175  		return err
   176  	}
   177  	certMsg, ok := msg.(*certificateMsg)
   178  	if !ok || len(certMsg.certificates) == 0 {
   179  		c.sendAlert(alertUnexpectedMessage)
   180  		return unexpectedMessageError(certMsg, msg)
   181  	}
   182  	// mod by syl only one cert
   183  	// Thanks to dual certificates mechanism, length of certificates in GMT0024 must great than 2
   184  	if c.config.GMSupport.EncCertEnable {
   185  		if len(certMsg.certificates) < 2 {
   186  			c.sendAlert(alertInsufficientSecurity)
   187  			return fmt.Errorf("tls: length of certificates in GMT0024 must great than 2")
   188  		}
   189  	}
   190  	hs.finishedHash.Write(certMsg.marshal())
   191  	if c.handshakes == 0 {
   192  		// If this is the first handshake on a connection, process and
   193  		// (optionally) verify the server's certificates.
   194  		certs := make([]*x509.Certificate, len(certMsg.certificates))
   195  		for i, asn1Data := range certMsg.certificates {
   196  			cert, err := x509.ParseCertificate(asn1Data)
   197  			if err != nil {
   198  				c.sendAlert(alertBadCertificate)
   199  				return errors.New("tls: failed to parse certificate from server: " + err.Error())
   200  			}
   201  			_, ok := cert.PublicKey.ToStandardKey().(*sm2.PublicKey)
   202  			if !ok {
   203  				c.sendAlert(alertUnsupportedCertificate)
   204  				return fmt.Errorf("tls: pubkey type of cert is error, expect sm2.publicKey")
   205  			}
   206  			if c.config.GMSupport.EncCertEnable {
   207  				//cert[0] is for signature while cert[1] is for encipher, refer to  GMT0024
   208  				//check key usage
   209  				switch i {
   210  				case 0:
   211  					if cert.KeyUsage == 0 || (cert.KeyUsage&(gox509.KeyUsageDigitalSignature|cert.KeyUsage&gox509.KeyUsageContentCommitment)) == 0 {
   212  						c.sendAlert(alertInsufficientSecurity)
   213  						return fmt.Errorf("tls: the keyusage of cert[0] does not exist or is not for KeyUsageDigitalSignature/KeyUsageContentCommitment, value:%d", cert.KeyUsage)
   214  					}
   215  				case len(certs) - 1:
   216  					if cert.KeyUsage == 0 || (cert.KeyUsage&(gox509.KeyUsageDataEncipherment|gox509.KeyUsageKeyEncipherment|gox509.KeyUsageKeyAgreement)) == 0 {
   217  						c.sendAlert(alertInsufficientSecurity)
   218  						return fmt.Errorf("tls: the keyusage of cert[1] does not exist or is not for KeyUsageDataEncipherment/KeyUsageKeyEncipherment/KeyUsageKeyAgreement, value:%d", cert.KeyUsage)
   219  					}
   220  				}
   221  			}
   222  			certs[i] = cert
   223  		}
   224  		if !c.config.InsecureSkipVerify {
   225  			opts := x509.VerifyOptions{
   226  				Roots:         c.config.RootCAs,
   227  				CurrentTime:   c.config.time(),
   228  				DNSName:       c.config.ServerName,
   229  				Intermediates: x509.NewCertPool(),
   230  			}
   231  			if opts.Roots == nil {
   232  				opts.Roots = x509.NewCertPool()
   233  			}
   234  			for _, rootca := range getCAs() {
   235  				opts.Roots.AddCert(rootca)
   236  			}
   237  			/**
   238  			TASSL certificate chain:
   239  			1. signCert + rootCA + encCert
   240  			**/
   241  			for i, cert := range certs {
   242  				if c.config.GMSupport.EncCertEnable {
   243  					if i == 0 || i == len(certs)-1 {
   244  						c.verifiedChains, err = certs[i].Verify(opts)
   245  						if err != nil {
   246  							_ = c.sendAlert(alertBadCertificate)
   247  							return err
   248  						}
   249  						continue
   250  					}
   251  				} else {
   252  					if i == 0 {
   253  						c.verifiedChains, err = certs[i].Verify(opts)
   254  						if err != nil {
   255  							_ = c.sendAlert(alertBadCertificate)
   256  							return err
   257  						}
   258  						continue
   259  					}
   260  				}
   261  				opts.Intermediates.AddCert(cert)
   262  			}
   263  		}
   264  		if c.config.VerifyPeerCertificate != nil {
   265  			if err := c.config.VerifyPeerCertificate(certMsg.certificates, c.verifiedChains); err != nil {
   266  				c.sendAlert(alertBadCertificate)
   267  				return err
   268  			}
   269  		}
   270  		pubKey := certs[0].PublicKey.ToStandardKey()
   271  		switch pubKey.(type) {
   272  		case *sm2.PublicKey, *ecdsa.PublicKey, *rsa.PublicKey:
   273  			break
   274  		default:
   275  			c.sendAlert(alertUnsupportedCertificate)
   276  			return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
   277  		}
   278  		c.peerCertificates = certs
   279  	} else {
   280  		// This is a renegotiation handshake. We require that the
   281  		// server's identity (i.e. leaf certificate) is unchanged and
   282  		// thus any previous trust decision is still valid.
   283  		//
   284  		// See https://mitls.org/pages/attacks/3SHAKE for the
   285  		// motivation behind this requirement.
   286  		if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
   287  			c.sendAlert(alertBadCertificate)
   288  			return errors.New("tls: server's identity changed during renegotiation")
   289  		}
   290  	}
   291  	msg, err = c.readHandshake()
   292  	if err != nil {
   293  		return err
   294  	}
   295  	keyAgreement := hs.suite.ka(c.vers)
   296  	if ka, ok := keyAgreement.(*eccKeyAgreementGM); ok {
   297  		if c.config.GMSupport.EncCertEnable {
   298  			encCert := c.peerCertificates[len(c.peerCertificates)-1]
   299  			ka.encipherCert = encCert
   300  		} else {
   301  			ka.encipherCert = c.peerCertificates[0]
   302  		}
   303  	}
   304  	skx, ok := msg.(*serverKeyExchangeMsg)
   305  	if ok {
   306  		hs.finishedHash.Write(skx.marshal())
   307  		err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
   308  		if err != nil {
   309  			c.sendAlert(alertUnexpectedMessage)
   310  			return err
   311  		}
   312  		msg, err = c.readHandshake()
   313  		if err != nil {
   314  			return err
   315  		}
   316  	}
   317  	var chainToSend *Certificate
   318  	var certRequested bool
   319  	certReq, ok := msg.(*certificateRequestMsgGM)
   320  	if ok {
   321  		certRequested = true
   322  		hs.finishedHash.Write(certReq.marshal())
   323  		if chainToSend, err = hs.getCertificate(certReq); err != nil || chainToSend.Certificate == nil {
   324  			c.sendAlert(alertInternalError)
   325  			return err
   326  		}
   327  		msg, err = c.readHandshake()
   328  		if err != nil {
   329  			return err
   330  		}
   331  	}
   332  	shd, ok := msg.(*serverHelloDoneMsg)
   333  	if !ok {
   334  		c.sendAlert(alertUnexpectedMessage)
   335  		return unexpectedMessageError(shd, msg)
   336  	}
   337  	hs.finishedHash.Write(shd.marshal())
   338  	// If the server requested a certificate then we have to send a
   339  	// Certificate message, even if it's empty because we don't have a
   340  	// certificate to send.
   341  	if certRequested {
   342  		certMsg = new(certificateMsg)
   343  		certMsg.certificates = chainToSend.Certificate
   344  		hs.finishedHash.Write(certMsg.marshal())
   345  		if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
   346  			return err
   347  		}
   348  	}
   349  	var (
   350  		preMasterSecret []byte
   351  		ckx             *clientKeyExchangeMsg
   352  	)
   353  	if c.config.GMSupport.EncCertEnable {
   354  		preMasterSecret, ckx, err = keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[1])
   355  	} else {
   356  		preMasterSecret, ckx, err = keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
   357  	}
   358  	if err != nil {
   359  		c.sendAlert(alertInternalError)
   360  		return err
   361  	}
   362  	if ckx != nil {
   363  		hs.finishedHash.Write(ckx.marshal())
   364  		if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
   365  			return err
   366  		}
   367  	}
   368  	if chainToSend != nil && len(chainToSend.Certificate) > 0 {
   369  		certVerify := &certificateVerifyMsg{}
   370  		key, ok := chainToSend.PrivateKey.(crypto.Signer)
   371  		if !ok {
   372  			c.sendAlert(alertInternalError)
   373  			return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
   374  		}
   375  		digest := hs.finishedHash.client.Sum(nil)
   376  		certVerify.signature, err = key.Sign(c.config.rand(), digest, nil)
   377  		if err != nil {
   378  			c.sendAlert(alertInternalError)
   379  			return err
   380  		}
   381  		hs.finishedHash.Write(certVerify.marshal())
   382  		if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
   383  			return err
   384  		}
   385  	}
   386  	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
   387  	if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil {
   388  		c.sendAlert(alertInternalError)
   389  		return errors.New("tls: failed to write to key log: " + err.Error())
   390  	}
   391  	hs.finishedHash.discardHandshakeBuffer()
   392  	return nil
   393  }
   394  
   395  func (hs *clientHandshakeStateGM) establishKeys() error {
   396  	c := hs.c
   397  	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
   398  		keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
   399  	var clientCipher, serverCipher interface{}
   400  	var clientHash, serverHash macFunction
   401  	if hs.suite.cipher != nil {
   402  		clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
   403  		clientHash = hs.suite.mac(c.vers, clientMAC)
   404  		serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
   405  		serverHash = hs.suite.mac(c.vers, serverMAC)
   406  	} else {
   407  		clientCipher = hs.suite.aead(clientKey, clientIV)
   408  		serverCipher = hs.suite.aead(serverKey, serverIV)
   409  	}
   410  	c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
   411  	c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
   412  	return nil
   413  }
   414  
   415  func (hs *clientHandshakeStateGM) serverResumedSession() bool {
   416  	// If the server responded with the same sessionId then it means the
   417  	// sessionTicket is being used to resume a TLS session.
   418  	return hs.session != nil && hs.hello.sessionId != nil &&
   419  		bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
   420  }
   421  
   422  func (hs *clientHandshakeStateGM) processServerHello() (bool, error) {
   423  	c := hs.c
   424  	if hs.serverHello.compressionMethod != compressionNone {
   425  		c.sendAlert(alertUnexpectedMessage)
   426  		return false, errors.New("tls: server selected unsupported compression format")
   427  	}
   428  	if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
   429  		c.secureRenegotiation = true
   430  		if len(hs.serverHello.secureRenegotiation) != 0 {
   431  			c.sendAlert(alertHandshakeFailure)
   432  			return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
   433  		}
   434  	}
   435  	if c.handshakes > 0 && c.secureRenegotiation {
   436  		var expectedSecureRenegotiation [24]byte
   437  		copy(expectedSecureRenegotiation[:], c.clientFinished[:])
   438  		copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
   439  		if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
   440  			c.sendAlert(alertHandshakeFailure)
   441  			return false, errors.New("tls: incorrect renegotiation extension contents")
   442  		}
   443  	}
   444  	clientDidALPN := len(hs.hello.alpnProtocols) > 0
   445  	serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
   446  	if !clientDidALPN && serverHasALPN {
   447  		c.sendAlert(alertHandshakeFailure)
   448  		return false, errors.New("tls: server advertised unrequested ALPN extension")
   449  	}
   450  	if serverHasALPN {
   451  		c.clientProtocol = hs.serverHello.alpnProtocol
   452  		c.clientProtocolFallback = false
   453  	}
   454  	c.scts = hs.serverHello.scts
   455  	if !hs.serverResumedSession() {
   456  		return false, nil
   457  	}
   458  	if hs.session.vers != c.vers {
   459  		c.sendAlert(alertHandshakeFailure)
   460  		return false, errors.New("tls: server resumed a session with a different version")
   461  	}
   462  	if hs.session.cipherSuite != hs.suite.id {
   463  		c.sendAlert(alertHandshakeFailure)
   464  		return false, errors.New("tls: server resumed a session with a different cipher suite")
   465  	}
   466  	// Restore masterSecret and peerCerts from previous state
   467  	hs.masterSecret = hs.session.masterSecret
   468  	c.peerCertificates = hs.session.serverCertificates
   469  	c.verifiedChains = hs.session.verifiedChains
   470  	return true, nil
   471  }
   472  
   473  func (hs *clientHandshakeStateGM) readFinished(out []byte) error {
   474  	c := hs.c
   475  	if err := c.readChangeCipherSpec(); err != nil {
   476  		return err
   477  	}
   478  	msg, err := c.readHandshake()
   479  	if err != nil {
   480  		return err
   481  	}
   482  	serverFinished, ok := msg.(*finishedMsg)
   483  	if !ok {
   484  		c.sendAlert(alertUnexpectedMessage)
   485  		return unexpectedMessageError(serverFinished, msg)
   486  	}
   487  	verify := hs.finishedHash.serverSum(hs.masterSecret)
   488  	if len(verify) != len(serverFinished.verifyData) ||
   489  		subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
   490  		c.sendAlert(alertHandshakeFailure)
   491  		return errors.New("tls: server's Finished message was incorrect")
   492  	}
   493  	hs.finishedHash.Write(serverFinished.marshal())
   494  	copy(out, verify)
   495  	return nil
   496  }
   497  
   498  func (hs *clientHandshakeStateGM) readSessionTicket() error {
   499  	if !hs.serverHello.ticketSupported {
   500  		return nil
   501  	}
   502  	c := hs.c
   503  	msg, err := c.readHandshake()
   504  	if err != nil {
   505  		return err
   506  	}
   507  	sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
   508  	if !ok {
   509  		c.sendAlert(alertUnexpectedMessage)
   510  		return unexpectedMessageError(sessionTicketMsg, msg)
   511  	}
   512  	hs.finishedHash.Write(sessionTicketMsg.marshal())
   513  	hs.session = &ClientSessionState{
   514  		sessionTicket:      sessionTicketMsg.ticket,
   515  		vers:               c.vers,
   516  		cipherSuite:        hs.suite.id,
   517  		masterSecret:       hs.masterSecret,
   518  		serverCertificates: c.peerCertificates,
   519  		verifiedChains:     c.verifiedChains,
   520  	}
   521  	return nil
   522  }
   523  
   524  func (hs *clientHandshakeStateGM) sendFinished(out []byte) error {
   525  	c := hs.c
   526  	if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
   527  		return err
   528  	}
   529  	finished := new(finishedMsg)
   530  	finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
   531  	hs.finishedHash.Write(finished.marshal())
   532  	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
   533  		return err
   534  	}
   535  	copy(out, finished.verifyData)
   536  	return nil
   537  }
   538  
   539  func (hs *clientHandshakeStateGM) getCertificate(certReq *certificateRequestMsgGM) (*Certificate, error) {
   540  	c := hs.c
   541  	chainToSend := new(Certificate)
   542  	if c.config.GetClientCertificate != nil {
   543  		var signatureSchemes []SignatureScheme
   544  		return c.config.GetClientCertificate(&CertificateRequestInfo{
   545  			AcceptableCAs:    certReq.certificateAuthorities,
   546  			SignatureSchemes: signatureSchemes,
   547  		})
   548  	}
   549  	// RFC 4346 on the certificateAuthorities field: A list of the
   550  	// distinguished names of acceptable certificate authorities.
   551  	// These distinguished names may specify a desired
   552  	// distinguished name for a root CA or for a subordinate CA;
   553  	// thus, this message can be used to describe both known roots
   554  	// and a desired authorization space. If the
   555  	// certificate_authorities list is empty then the client MAY
   556  	// send any certificate of the appropriate
   557  	// ClientCertificateType, unless there is some external
   558  	// arrangement to the contrary.
   559  
   560  	// We need to search our list of client certs for one
   561  	// where SignatureAlgorithm is acceptable to the server and the
   562  	// Issuer is in certReq.certificateAuthorities
   563  findCert:
   564  	for i, chain := range c.config.Certificates {
   565  		for j, cert := range chain.Certificate {
   566  			x509Cert := chain.Leaf
   567  			// parse the certificate if this isn't the leaf
   568  			// node, or if chain.Leaf was nil
   569  			if j != 0 || x509Cert == nil {
   570  				var err error
   571  				cmCert, err := x509.ParseCertificate(cert)
   572  				if err != nil {
   573  					c.sendAlert(alertInternalError)
   574  					return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
   575  				}
   576  				x509Cert, err = x509.HerbtCertToX509Cert(cmCert)
   577  				if err != nil {
   578  					c.sendAlert(alertInternalError)
   579  					return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
   580  				}
   581  			}
   582  			var isGMCert bool
   583  			if x509Cert.PublicKeyAlgorithm == gox509.ECDSA {
   584  				pubKey, ok := x509Cert.PublicKey.(*ecdsa.PublicKey)
   585  				if ok && pubKey.Curve == sm2.P256Sm2() {
   586  					isGMCert = true
   587  				}
   588  				if _, ok = x509Cert.PublicKey.(*sm2.PublicKey); ok {
   589  					isGMCert = true
   590  				}
   591  			}
   592  			if !isGMCert {
   593  				continue findCert
   594  			}
   595  			if len(certReq.certificateAuthorities) == 0 {
   596  				// they gave us an empty list, so just take the
   597  				// first cert from c.config.Certificates
   598  				// return &chain, nil
   599  				if chainToSend.Certificate == nil {
   600  					chainToSend.Certificate = chain.Certificate
   601  					chainToSend.PrivateKey = chain.PrivateKey
   602  				} else {
   603  					chainToSend.Certificate = append(chainToSend.Certificate, chain.Certificate...)
   604  				}
   605  			}
   606  			for _, ca := range certReq.certificateAuthorities {
   607  				if bytes.Equal(x509Cert.RawIssuer, ca) {
   608  					// return &chain, nil
   609  					if chainToSend.Certificate == nil {
   610  						chainToSend.Certificate = chain.Certificate
   611  						chainToSend.PrivateKey = chain.PrivateKey
   612  					} else {
   613  						chainToSend.Certificate = append(chainToSend.Certificate, chain.Certificate...)
   614  					}
   615  				}
   616  			}
   617  		}
   618  	}
   619  	// No acceptable certificate found. Don't send a certificate.
   620  	// return new(Certificate), nil
   621  	return chainToSend, nil
   622  }