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 }