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