gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/gmtls/handshake_client_tls13.go (about)

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