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