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 }