github.com/Hyperledger-TWGC/tjfoc-gm@v1.4.0/gmtls/gm_handshake_client.go (about)

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