gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/gmtls/handshake_client_tls13.go (about)

     1  // Copyright (c) 2022 zhaochun
     2  // core-gm is licensed under Mulan PSL v2.
     3  // You can use this software according to the terms and conditions of the Mulan PSL v2.
     4  // You may obtain a copy of Mulan PSL v2 at:
     5  //          http://license.coscl.org.cn/MulanPSL2
     6  // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
     7  // See the Mulan PSL v2 for more details.
     8  
     9  /*
    10  gmtls是基于`golang/go`的`tls`包实现的国密改造版本。
    11  对应版权声明: thrid_licenses/github.com/golang/go/LICENSE
    12  */
    13  
    14  package gmtls
    15  
    16  import (
    17  	"bytes"
    18  	"context"
    19  	"crypto"
    20  	"crypto/hmac"
    21  	"crypto/rsa"
    22  	"errors"
    23  	"fmt"
    24  	"gitee.com/ks-custle/core-gm/ecbase"
    25  	"gitee.com/ks-custle/core-gm/sm2"
    26  	"hash"
    27  	"sync/atomic"
    28  	"time"
    29  
    30  	"gitee.com/ks-custle/core-gm/x509"
    31  )
    32  
    33  // tls1.3客户端握手状态
    34  // GMSSL目前也使用tls1.3的处理
    35  type clientHandshakeStateTLS13 struct {
    36  	c           *Conn
    37  	ctx         context.Context
    38  	serverHello *serverHelloMsg
    39  	hello       *clientHelloMsg
    40  	ecdheParams ecdheParameters
    41  
    42  	session     *ClientSessionState
    43  	earlySecret []byte
    44  	binderKey   []byte
    45  
    46  	certReq       *certificateRequestMsgTLS13
    47  	usingPSK      bool
    48  	sentDummyCCS  bool
    49  	suite         *cipherSuiteTLS13
    50  	transcript    hash.Hash
    51  	masterSecret  []byte
    52  	trafficSecret []byte // client_application_traffic_secret_0
    53  }
    54  
    55  // tls1.3在收到ServerHello之后的握手过程
    56  // handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and,
    57  // optionally, hs.session, hs.earlySecret and hs.binderKey to be set.
    58  func (hs *clientHandshakeStateTLS13) handshake() error {
    59  	c := hs.c
    60  
    61  	// The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
    62  	// sections 4.1.2 and 4.1.3.
    63  	if c.handshakes > 0 {
    64  		_ = c.sendAlert(alertProtocolVersion)
    65  		return errors.New("gmtls: server selected TLS 1.3 in a renegotiation")
    66  	}
    67  
    68  	// Consistency check on the presence of a keyShare and its parameters.
    69  	if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 {
    70  		_ = c.sendAlert(alertInternalError)
    71  		return nil
    72  	}
    73  	// 检查ServerHello或HelloRetryRequest,并设置协商好的密码套件
    74  	if err := hs.checkServerHelloOrHRR(); err != nil {
    75  		return err
    76  	}
    77  	// 使用协商好的密码套件中的散列函数作为握手数据摘要的计算函数
    78  	hs.transcript = hs.suite.hash.New()
    79  	// 将ClientHello的序列化结果写入握手数据摘要
    80  	hs.transcript.Write(hs.hello.marshal())
    81  	// 检查是ServerHello还是HelloRetryRequest
    82  	if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
    83  		// 出于兼容性考虑,发出一个假的ChangeCipherSpec消息。
    84  		// 实际不会现在改变c.out的加密和MAC状态。
    85  		if err := hs.sendDummyChangeCipherSpec(); err != nil {
    86  			return err
    87  		}
    88  		// 应服务端的 HelloRetryRequest 请求,修改ClientHello,重新发送ClientHello,重新接收并检查ServerHello。
    89  		if err := hs.processHelloRetryRequest(); err != nil {
    90  			return err
    91  		}
    92  	}
    93  	// 将ServerHello写入握手数据摘要
    94  	hs.transcript.Write(hs.serverHello.marshal())
    95  
    96  	c.buffering = true
    97  	// 检查ServerHello
    98  	if err := hs.processServerHello(); err != nil {
    99  		return err
   100  	}
   101  	if err := hs.sendDummyChangeCipherSpec(); err != nil {
   102  		return err
   103  	}
   104  	// 根据ServerHello的服务端公钥生成共享密钥,进一步生成握手密钥与对应的客户端/服务端会话密钥。
   105  	// 因为tls1.3中,ServerHello之后的通信都是加密的,必须在这里就完成密钥协商,生成对应的会话密钥。
   106  	if err := hs.establishHandshakeKeys(); err != nil {
   107  		return err
   108  	}
   109  	// 读取服务端加密扩展信息
   110  	if err := hs.readServerParameters(); err != nil {
   111  		return err
   112  	}
   113  	// 读取证书请求/服务端证书/certificateVerifyMsg
   114  	if err := hs.readServerCertificate(); err != nil {
   115  		return err
   116  	}
   117  	// 读取 ServerFinished 并重新派生会话密钥
   118  	if err := hs.readServerFinished(); err != nil {
   119  		return err
   120  	}
   121  	// 发送客户端证书与客户端证书验证消息
   122  	if err := hs.sendClientCertificate(); err != nil {
   123  		return err
   124  	}
   125  	// 发送 ClientFinished
   126  	if err := hs.sendClientFinished(); err != nil {
   127  		return err
   128  	}
   129  	if _, err := c.flush(); err != nil {
   130  		return err
   131  	}
   132  	// 将握手状态改为1
   133  	atomic.StoreUint32(&c.handshakeStatus, 1)
   134  
   135  	return nil
   136  }
   137  
   138  // 检查ServerHello或HelloRetryRequest。
   139  // checkServerHelloOrHRR does validity checks that apply to both ServerHello and
   140  // HelloRetryRequest messages. It sets hs.suite.
   141  func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
   142  	c := hs.c
   143  
   144  	if hs.serverHello.supportedVersion == 0 {
   145  		_ = c.sendAlert(alertMissingExtension)
   146  		return errors.New("gmtls: server selected TLS 1.3 using the legacy version field")
   147  	}
   148  	// GMSSL采取相同处理
   149  	if hs.serverHello.supportedVersion != VersionTLS13 && hs.serverHello.supportedVersion != VersionGMSSL {
   150  		_ = c.sendAlert(alertIllegalParameter)
   151  		return errors.New("gmtls: server selected an invalid version after a HelloRetryRequest")
   152  	}
   153  	// 出于兼容性原因,vers只能写VersionTLS12
   154  	if hs.serverHello.vers != VersionTLS12 {
   155  		_ = c.sendAlert(alertIllegalParameter)
   156  		return errors.New("gmtls: server sent an incorrect legacy version")
   157  	}
   158  	// 检查ServerHello是否包含tls1.3禁用的扩展信息
   159  	if hs.serverHello.ocspStapling ||
   160  		hs.serverHello.ticketSupported ||
   161  		hs.serverHello.secureRenegotiationSupported ||
   162  		len(hs.serverHello.secureRenegotiation) != 0 ||
   163  		len(hs.serverHello.alpnProtocol) != 0 ||
   164  		len(hs.serverHello.scts) != 0 {
   165  		_ = c.sendAlert(alertUnsupportedExtension)
   166  		return errors.New("gmtls: server sent a ServerHello extension forbidden in TLS 1.3")
   167  	}
   168  	// 检查双方sessionID是否一致
   169  	if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
   170  		_ = c.sendAlert(alertIllegalParameter)
   171  		return errors.New("gmtls: server did not echo the legacy session ID")
   172  	}
   173  	// 检查是否不支持压缩,tls1.3不再支持压缩
   174  	if hs.serverHello.compressionMethod != compressionNone {
   175  		_ = c.sendAlert(alertIllegalParameter)
   176  		return errors.New("gmtls: server selected unsupported compression format")
   177  	}
   178  	// 协商tls1.3密码套件
   179  	selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite)
   180  	if hs.suite != nil && selectedSuite != hs.suite {
   181  		_ = c.sendAlert(alertIllegalParameter)
   182  		return errors.New("gmtls: server changed cipher suite after a HelloRetryRequest")
   183  	}
   184  	if selectedSuite == nil {
   185  		_ = c.sendAlert(alertIllegalParameter)
   186  		return errors.New("gmtls: server chose an unconfigured cipher suite")
   187  	}
   188  	//fmt.Println("===== 客户端确认协商好的密码套件: %s", CipherSuiteName(selectedSuite.id))
   189  	// 设置协商好的密码套件
   190  	hs.suite = selectedSuite
   191  	c.cipherSuite = hs.suite.id
   192  
   193  	return nil
   194  }
   195  
   196  // sendDummyChangeCipherSpec 发送 ChangeCipherSpec 记录,用来与未正确实现TLS的中间件兼容。
   197  // sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
   198  // with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
   199  func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
   200  	if hs.sentDummyCCS {
   201  		return nil
   202  	}
   203  	hs.sentDummyCCS = true
   204  
   205  	_, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
   206  	//fmt.Println("===== 客户端发送 DummyChangeCipherSpec")
   207  	return err
   208  }
   209  
   210  // processHelloRetryRequest handles the HRR in hs.serverHello, modifies and
   211  // resends hs.hello, and reads the new ServerHello into hs.serverHello.
   212  func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
   213  	c := hs.c
   214  
   215  	// 对已经写入握手数据摘要的ClientHello进行散列,并重新写入握手数据摘要,然后写入ServerHellod的序列化结果。
   216  	// 即,发生HelloRetryRequest的话,握手数据摘要中的ClientHello会被重复散列。
   217  	// The first ClientHello gets double-hashed into the transcript upon a
   218  	// HelloRetryRequest. (The idea is that the server might offload transcript
   219  	// storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
   220  	chHash := hs.transcript.Sum(nil)
   221  	hs.transcript.Reset()
   222  	hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
   223  	hs.transcript.Write(chHash)
   224  	hs.transcript.Write(hs.serverHello.marshal())
   225  
   226  	// The only HelloRetryRequest extensions we support are key_share and
   227  	// cookie, and clients must abort the handshake if the HRR would not result
   228  	// in any change in the ClientHello.
   229  	if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil {
   230  		_ = c.sendAlert(alertIllegalParameter)
   231  		return errors.New("gmtls: server sent an unnecessary HelloRetryRequest message")
   232  	}
   233  
   234  	if hs.serverHello.cookie != nil {
   235  		hs.hello.cookie = hs.serverHello.cookie
   236  	}
   237  
   238  	if hs.serverHello.serverShare.group != 0 {
   239  		_ = c.sendAlert(alertDecodeError)
   240  		return errors.New("gmtls: server sent a malformed key_share extension")
   241  	}
   242  
   243  	// 如果ServerHello中有key_share,那么检查是否与之前发出的ClientHello中的key_share相同,
   244  	// 并重新生成一个key_share。
   245  	// If the server sent a key_share extension selecting a group, ensure it's
   246  	// a group we advertised but did not send a key share for, and send a key
   247  	// share for it this time.
   248  	if curveID := hs.serverHello.selectedGroup; curveID != 0 {
   249  		curveOK := false
   250  		for _, id := range hs.hello.supportedCurves {
   251  			if id == curveID {
   252  				curveOK = true
   253  				break
   254  			}
   255  		}
   256  		if !curveOK {
   257  			_ = c.sendAlert(alertIllegalParameter)
   258  			return errors.New("gmtls: server selected unsupported group")
   259  		}
   260  		if hs.ecdheParams.CurveID() == curveID {
   261  			_ = c.sendAlert(alertIllegalParameter)
   262  			return errors.New("gmtls: server sent an unnecessary HelloRetryRequest key_share")
   263  		}
   264  		if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
   265  			_ = c.sendAlert(alertInternalError)
   266  			return errors.New("gmtls: CurvePreferences includes unsupported curve")
   267  		}
   268  		// 再次生成密钥交换参数
   269  		params, err := generateECDHEParameters(c.config.rand(), curveID)
   270  		if err != nil {
   271  			_ = c.sendAlert(alertInternalError)
   272  			return fmt.Errorf("gmtls: ECDHE密钥协商失败: %s", err)
   273  		}
   274  		hs.ecdheParams = params
   275  		hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
   276  	}
   277  
   278  	hs.hello.raw = nil
   279  	if len(hs.hello.pskIdentities) > 0 {
   280  		pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
   281  		if pskSuite == nil {
   282  			_ = c.sendAlert(alertInternalError)
   283  			return nil
   284  		}
   285  		if pskSuite.hash == hs.suite.hash {
   286  			// Update binders and obfuscated_ticket_age.
   287  			ticketAge := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond)
   288  			hs.hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + hs.session.ageAdd
   289  
   290  			transcript := hs.suite.hash.New()
   291  			transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
   292  			transcript.Write(chHash)
   293  			transcript.Write(hs.serverHello.marshal())
   294  			transcript.Write(hs.hello.marshalWithoutBinders())
   295  			pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)}
   296  			hs.hello.updateBinders(pskBinders)
   297  		} else {
   298  			// Server selected a cipher suite incompatible with the PSK.
   299  			hs.hello.pskIdentities = nil
   300  			hs.hello.pskBinders = nil
   301  		}
   302  	}
   303  	// 将ServerHello写入握手数据摘要
   304  	hs.transcript.Write(hs.hello.marshal())
   305  	// 再次发送ClientHello
   306  	fmt.Println("===== 客户端再次发出ClientHello(HelloRetryRequest)")
   307  	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
   308  		return err
   309  	}
   310  	// 读取下一条握手信息
   311  	msg, err := c.readHandshake()
   312  	if err != nil {
   313  		return err
   314  	}
   315  	serverHello, ok := msg.(*serverHelloMsg)
   316  	if !ok {
   317  		_ = c.sendAlert(alertUnexpectedMessage)
   318  		return unexpectedMessageError(serverHello, msg)
   319  	}
   320  	hs.serverHello = serverHello
   321  	fmt.Println("===== 客户端再次读取到ServerHello(HelloRetryRequest)")
   322  
   323  	if err := hs.checkServerHelloOrHRR(); err != nil {
   324  		return err
   325  	}
   326  
   327  	return nil
   328  }
   329  
   330  // 对ServerHello做检查处理
   331  func (hs *clientHandshakeStateTLS13) processServerHello() error {
   332  	c := hs.c
   333  	// 服务端只能请求一次 HelloRetryRequest
   334  	if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
   335  		_ = c.sendAlert(alertUnexpectedMessage)
   336  		return errors.New("gmtls: server sent two HelloRetryRequest messages")
   337  	}
   338  
   339  	if len(hs.serverHello.cookie) != 0 {
   340  		_ = c.sendAlert(alertUnsupportedExtension)
   341  		return errors.New("gmtls: server sent a cookie in a normal ServerHello")
   342  	}
   343  
   344  	if hs.serverHello.selectedGroup != 0 {
   345  		_ = c.sendAlert(alertDecodeError)
   346  		return errors.New("gmtls: malformed key_share extension")
   347  	}
   348  
   349  	if hs.serverHello.serverShare.group == 0 {
   350  		_ = c.sendAlert(alertIllegalParameter)
   351  		return errors.New("gmtls: server did not send a key share")
   352  	}
   353  	// 检查服务端的密钥协商参数的曲线是否与客户端的对应曲线ID一致
   354  	if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() {
   355  		_ = c.sendAlert(alertIllegalParameter)
   356  		return errors.New("gmtls: server selected unsupported group")
   357  	}
   358  	// ServerHello没有选择会话恢复用的ID时,处理结束。
   359  	if !hs.serverHello.selectedIdentityPresent {
   360  		return nil
   361  	}
   362  
   363  	if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) {
   364  		_ = c.sendAlert(alertIllegalParameter)
   365  		return errors.New("gmtls: server selected an invalid PSK")
   366  	}
   367  
   368  	if len(hs.hello.pskIdentities) != 1 || hs.session == nil {
   369  		return c.sendAlert(alertInternalError)
   370  	}
   371  	pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
   372  	if pskSuite == nil {
   373  		return c.sendAlert(alertInternalError)
   374  	}
   375  	if pskSuite.hash != hs.suite.hash {
   376  		_ = c.sendAlert(alertIllegalParameter)
   377  		return errors.New("gmtls: server selected an invalid PSK and cipher suite pair")
   378  	}
   379  	// 会话恢复场景的属性设置
   380  	hs.usingPSK = true
   381  	c.didResume = true
   382  	c.peerCertificates = hs.session.serverCertificates
   383  	c.verifiedChains = hs.session.verifiedChains
   384  	c.ocspResponse = hs.session.ocspResponse
   385  	c.scts = hs.session.scts
   386  	return nil
   387  }
   388  
   389  // 创建握手密钥
   390  func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
   391  	c := hs.c
   392  	// 根据服务端公钥计算预主密钥
   393  	//fmt.Println("===== 利用服务端公钥计算预主密钥")
   394  	sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data)
   395  	if sharedKey == nil {
   396  		_ = c.sendAlert(alertIllegalParameter)
   397  		return errors.New("gmtls: invalid server key share")
   398  	}
   399  	// 获取之前的密钥
   400  	earlySecret := hs.earlySecret
   401  	if !hs.usingPSK {
   402  		// 不是会话恢复场景时,初始化 earlySecret
   403  		earlySecret = hs.suite.extract(nil, nil)
   404  	}
   405  	// 生成本次会话的握手阶段密钥
   406  	handshakeSecret := hs.suite.extract(sharedKey,
   407  		hs.suite.deriveSecret(earlySecret, "derived", nil))
   408  	// 派生握手阶段的客户端会话密钥,后续还要根据最新的握手数据摘要重新派生
   409  	clientSecret := hs.suite.deriveSecret(handshakeSecret,
   410  		clientHandshakeTrafficLabel, hs.transcript)
   411  	c.out.setTrafficSecret(hs.suite, clientSecret)
   412  	// 派生握手阶段的服务端会话密钥,后续还要根据最新的握手数据摘要重新派生
   413  	serverSecret := hs.suite.deriveSecret(handshakeSecret,
   414  		serverHandshakeTrafficLabel, hs.transcript)
   415  	c.in.setTrafficSecret(hs.suite, serverSecret)
   416  
   417  	err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
   418  	if err != nil {
   419  		_ = c.sendAlert(alertInternalError)
   420  		return fmt.Errorf("gmtls: 写入clientSecret日志时发生错误: %s", err)
   421  	}
   422  	err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret)
   423  	if err != nil {
   424  		_ = c.sendAlert(alertInternalError)
   425  		return fmt.Errorf("gmtls: 写入serverSecret日志时发生错误: %s", err)
   426  	}
   427  	// 根据握手阶段密钥派生新的预主密钥并提取出主密钥
   428  	// tls1.3的密钥协商算法不再需要使用 ClientRadom与ServerRandom
   429  	hs.masterSecret = hs.suite.extract(nil,
   430  		hs.suite.deriveSecret(handshakeSecret, "derived", nil))
   431  
   432  	return nil
   433  }
   434  
   435  // 读取服务端发送的加密扩展信息
   436  func (hs *clientHandshakeStateTLS13) readServerParameters() error {
   437  	c := hs.c
   438  	// 读取服务端发送的加密扩展信息
   439  	msg, err := c.readHandshake()
   440  	if err != nil {
   441  		return err
   442  	}
   443  	encryptedExtensions, ok := msg.(*encryptedExtensionsMsg)
   444  	if !ok {
   445  		_ = c.sendAlert(alertUnexpectedMessage)
   446  		return unexpectedMessageError(encryptedExtensions, msg)
   447  	}
   448  	hs.transcript.Write(encryptedExtensions.marshal())
   449  	//fmt.Println("===== 客户端读取到 encryptedExtensionsMsg")
   450  	// 检查ALPN协议设置
   451  	if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil {
   452  		_ = c.sendAlert(alertUnsupportedExtension)
   453  		return err
   454  	}
   455  	c.clientProtocol = encryptedExtensions.alpnProtocol
   456  
   457  	return nil
   458  }
   459  
   460  // 读取服务端证书
   461  func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
   462  	c := hs.c
   463  
   464  	// Either a PSK or a certificate is always used, but not both.
   465  	// See RFC 8446, Section 4.1.1.
   466  	if hs.usingPSK {
   467  		// Make sure the connection is still being verified whether or not this
   468  		// is a resumption. Resumptions currently don't reverify certificates so
   469  		// they don't call verifyServerCertificate. See Issue 31641.
   470  		if c.config.VerifyConnection != nil {
   471  			if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
   472  				_ = c.sendAlert(alertBadCertificate)
   473  				return err
   474  			}
   475  		}
   476  		return nil
   477  	}
   478  	// 从tls连接读取下一条消息
   479  	msg, err := c.readHandshake()
   480  	if err != nil {
   481  		return err
   482  	}
   483  	// 检查是否证书请求消息
   484  	certReq, ok := msg.(*certificateRequestMsgTLS13)
   485  	if ok {
   486  		hs.transcript.Write(certReq.marshal())
   487  		//fmt.Println("===== 客户端读取到 certificateRequestMsgTLS13")
   488  		hs.certReq = certReq
   489  		// 从tls连接读取下一条消息
   490  		msg, err = c.readHandshake()
   491  		if err != nil {
   492  			return err
   493  		}
   494  	}
   495  	certMsg, ok := msg.(*certificateMsgTLS13)
   496  	if !ok {
   497  		err := unexpectedMessageError(certMsg, msg)
   498  		_ = c.sendAlert(alertUnexpectedMessage)
   499  		return err
   500  	}
   501  	//fmt.Println("===== 客户端读取到 certificateMsgTLS13")
   502  	if len(certMsg.certificate.Certificate) == 0 {
   503  		_ = c.sendAlert(alertDecodeError)
   504  		return errors.New("gmtls: received empty certificates message")
   505  	}
   506  	hs.transcript.Write(certMsg.marshal())
   507  
   508  	c.scts = certMsg.certificate.SignedCertificateTimestamps
   509  	c.ocspResponse = certMsg.certificate.OCSPStaple
   510  	// 验证服务端证书
   511  	if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil {
   512  		return err
   513  	}
   514  
   515  	msg, err = c.readHandshake()
   516  	if err != nil {
   517  		return err
   518  	}
   519  	certVerify, ok := msg.(*certificateVerifyMsg)
   520  	if !ok {
   521  		_ = c.sendAlert(alertUnexpectedMessage)
   522  		return unexpectedMessageError(certVerify, msg)
   523  	}
   524  	//fmt.Println("===== 客户端读取到 certificateVerifyMsg")
   525  
   526  	// See RFC 8446, Section 4.4.3.
   527  	if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) {
   528  		_ = c.sendAlert(alertIllegalParameter)
   529  		return errors.New("gmtls: certificate used with unsupported signature algorithm")
   530  	}
   531  	sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
   532  	//fmt.Println("sigHash: " +  sigHash.String())
   533  	if err != nil {
   534  		return c.sendAlert(alertInternalError)
   535  	}
   536  	if sigType == signaturePKCS1v15 || sigHash == x509.SHA1 {
   537  		_ = c.sendAlert(alertIllegalParameter)
   538  		return errors.New("gmtls: certificate used with obsolete signature algorithm")
   539  	}
   540  	// 生成签名内容: 握手数据摘要混入一些固定的值
   541  	signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
   542  	// 对certificateVerifyMsg中的签名进行验签
   543  	// TODO 需要确认sign的处理有没有对ecdsaext做特殊处理
   544  	if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,
   545  		sigHash, signed, certVerify.signature); err != nil {
   546  		_ = c.sendAlert(alertDecryptError)
   547  		fmt.Println("客户端对服务端证书验签失败")
   548  		return errors.New("gmtls: invalid signature by the server certificate: " + err.Error())
   549  	}
   550  	// 将服务端 certVerify 写入握手数据摘要
   551  	hs.transcript.Write(certVerify.marshal())
   552  
   553  	return nil
   554  }
   555  
   556  // 读取ServerFinished
   557  func (hs *clientHandshakeStateTLS13) readServerFinished() error {
   558  	c := hs.c
   559  	// 读取ServerFinished
   560  	msg, err := c.readHandshake()
   561  	if err != nil {
   562  		return err
   563  	}
   564  	finished, ok := msg.(*finishedMsg)
   565  	if !ok {
   566  		_ = c.sendAlert(alertUnexpectedMessage)
   567  		return unexpectedMessageError(finished, msg)
   568  	}
   569  	//fmt.Println("===== 客户端读取到 ServerFinished")
   570  	// 计算期望的finished散列并与接收的值比较
   571  	expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
   572  	if !hmac.Equal(expectedMAC, finished.verifyData) {
   573  		_ = c.sendAlert(alertDecryptError)
   574  		return errors.New("gmtls: invalid server finished hash")
   575  	}
   576  	// 将finished消息写入握手数据摘要
   577  	hs.transcript.Write(finished.marshal())
   578  
   579  	// Derive secrets that take context through the server Finished.
   580  	// 根据主密钥与最新的握手数据摘要重新派生客户端与服务端会话密钥
   581  	// 注意,此时并没有将重新生成的客户端会话密钥设置到连接通道上,只更新了连接通道上的服务端会话密钥。
   582  	// 新的客户端会话密钥要等到 ClientFinished 发送给服务端之后才能配置到连接通道上。
   583  	hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
   584  		clientApplicationTrafficLabel, hs.transcript)
   585  	serverSecret := hs.suite.deriveSecret(hs.masterSecret,
   586  		serverApplicationTrafficLabel, hs.transcript)
   587  	c.in.setTrafficSecret(hs.suite, serverSecret)
   588  
   589  	err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
   590  	if err != nil {
   591  		_ = c.sendAlert(alertInternalError)
   592  		return fmt.Errorf("gmtls: 写入trafficSecret日志时发生错误: %s", err)
   593  	}
   594  	err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret)
   595  	if err != nil {
   596  		_ = c.sendAlert(alertInternalError)
   597  		return fmt.Errorf("gmtls: 写入serverSecret日志时发生错误: %s", err)
   598  	}
   599  
   600  	c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
   601  
   602  	return nil
   603  }
   604  
   605  // 根据服务端是否发出证书请求决定是否发出客户端证书
   606  func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
   607  	c := hs.c
   608  
   609  	if hs.certReq == nil {
   610  		return nil
   611  	}
   612  
   613  	cert, err := c.getClientCertificate(&CertificateRequestInfo{
   614  		AcceptableCAs:    hs.certReq.certificateAuthorities,
   615  		SignatureSchemes: hs.certReq.supportedSignatureAlgorithms,
   616  		Version:          c.vers,
   617  		ctx:              hs.ctx,
   618  	})
   619  	if err != nil {
   620  		return err
   621  	}
   622  
   623  	certMsg := new(certificateMsgTLS13)
   624  
   625  	certMsg.certificate = *cert
   626  	certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0
   627  	certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0
   628  	// 向握手数据摘要写入客户端证书,并向服务端发送客户端证书
   629  	hs.transcript.Write(certMsg.marshal())
   630  	if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
   631  		return err
   632  	}
   633  	//fmt.Println("===== 客户端发出 ClientCertificate")
   634  
   635  	// If we sent an empty certificate message, skip the CertificateVerify.
   636  	if len(cert.Certificate) == 0 {
   637  		return nil
   638  	}
   639  
   640  	certVerifyMsg := new(certificateVerifyMsg)
   641  	certVerifyMsg.hasSignatureAlgorithm = true
   642  	// 获取签名算法
   643  	certVerifyMsg.signatureAlgorithm, err = selectSignatureScheme(c.vers, cert, hs.certReq.supportedSignatureAlgorithms)
   644  	if err != nil {
   645  		// getClientCertificate returned a certificate incompatible with the
   646  		// CertificateRequestInfo supported signature algorithms.
   647  		_ = c.sendAlert(alertHandshakeFailure)
   648  		return err
   649  	}
   650  	// 获取签名算法与散列算法
   651  	sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm)
   652  	fmt.Println("sigHash: %s", sigHash.String())
   653  	if err != nil {
   654  		return c.sendAlert(alertInternalError)
   655  	}
   656  	// 生成签名内容: 当前握手数据摘要混入一些固定值后散列
   657  	signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
   658  	signOpts := crypto.SignerOpts(sigHash)
   659  	//if sigType == signatureRSAPSS {
   660  	//	signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash.HashFunc()}
   661  	//}
   662  	switch sigType {
   663  	case signatureRSAPSS:
   664  		signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash.HashFunc()}
   665  	case signatureSM2:
   666  		signOpts = sm2.DefaultSM2SignerOption()
   667  	case signatureECDSAEXT:
   668  		signOpts = ecbase.CreateEcSignerOpts(sigHash.HashFunc(), true)
   669  	}
   670  	// 使用证书私钥进行签名
   671  	// TODO 需要确认sign的处理有没有对ecdsaext做特殊处理
   672  	sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
   673  	if err != nil {
   674  		_ = c.sendAlert(alertInternalError)
   675  		return errors.New("gmtls: failed to sign handshake: " + err.Error())
   676  	}
   677  	certVerifyMsg.signature = sig
   678  	// 向握手数据摘要写入证书认证消息并发送给服务端
   679  	hs.transcript.Write(certVerifyMsg.marshal())
   680  	if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil {
   681  		return err
   682  	}
   683  	fmt.Println("===== 客户端发出 ClientCertVerify")
   684  
   685  	return nil
   686  }
   687  
   688  // 发送 ClientFinished
   689  func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
   690  	c := hs.c
   691  
   692  	finished := &finishedMsg{
   693  		verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
   694  	}
   695  	// 向握手数据摘要写入 ClientFinished 并向服务端发送
   696  	hs.transcript.Write(finished.marshal())
   697  	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
   698  		return err
   699  	}
   700  	//fmt.Println("===== 客户端发出 ClientFinished")
   701  	// 注意,此时才将重新生成的客户端会话密钥设置到连接通道上。
   702  	c.out.setTrafficSecret(hs.suite, hs.trafficSecret)
   703  
   704  	if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
   705  		c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
   706  			resumptionLabel, hs.transcript)
   707  	}
   708  
   709  	return nil
   710  }
   711  
   712  // 处理来自服务端的 newSessionTicketMsgTLS13
   713  func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
   714  	if !c.isClient {
   715  		_ = c.sendAlert(alertUnexpectedMessage)
   716  		return errors.New("gmtls: received new session ticket from a client")
   717  	}
   718  
   719  	if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
   720  		return nil
   721  	}
   722  
   723  	// See RFC 8446, Section 4.6.1.
   724  	if msg.lifetime == 0 {
   725  		return nil
   726  	}
   727  	lifetime := time.Duration(msg.lifetime) * time.Second
   728  	if lifetime > maxSessionTicketLifetime {
   729  		_ = c.sendAlert(alertIllegalParameter)
   730  		return errors.New("gmtls: received a session ticket with invalid lifetime")
   731  	}
   732  
   733  	cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
   734  	if cipherSuite == nil || c.resumptionSecret == nil {
   735  		_ = c.sendAlert(alertInternalError)
   736  		return nil
   737  	}
   738  
   739  	// Save the resumption_master_secret and nonce instead of deriving the PSK
   740  	// to do the least amount of work on NewSessionTicket messages before we
   741  	// know if the ticket will be used. Forward secrecy of resumed connections
   742  	// is guaranteed by the requirement for pskModeDHE.
   743  	session := &ClientSessionState{
   744  		sessionTicket:      msg.label, // 这里的label是在服务端经过序列化并加密的sessionStateTLS13
   745  		vers:               c.vers,
   746  		cipherSuite:        c.cipherSuite,
   747  		masterSecret:       c.resumptionSecret,
   748  		serverCertificates: c.peerCertificates,
   749  		verifiedChains:     c.verifiedChains,
   750  		receivedAt:         c.config.time(),
   751  		nonce:              msg.nonce,
   752  		useBy:              c.config.time().Add(lifetime),
   753  		ageAdd:             msg.ageAdd,
   754  		ocspResponse:       c.ocspResponse,
   755  		scts:               c.scts,
   756  	}
   757  
   758  	cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
   759  	c.config.ClientSessionCache.Put(cacheKey, session)
   760  
   761  	return nil
   762  }