gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/gmtls/handshake_server_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 "io" 28 "sync/atomic" 29 "time" 30 31 "gitee.com/ks-custle/core-gm/x509" 32 ) 33 34 // maxClientPSKIdentities is the number of client PSK identities the server will 35 // attempt to validate. It will ignore the rest not to let cheap ClientHello 36 // messages cause too much work in session ticket decryption attempts. 37 const maxClientPSKIdentities = 5 38 39 type serverHandshakeStateTLS13 struct { 40 c *Conn 41 ctx context.Context 42 clientHello *clientHelloMsg 43 hello *serverHelloMsg 44 sentDummyCCS bool 45 usingPSK bool 46 suite *cipherSuiteTLS13 47 cert *Certificate 48 sigAlg SignatureScheme 49 earlySecret []byte 50 sharedKey []byte 51 handshakeSecret []byte 52 masterSecret []byte 53 trafficSecret []byte // client_application_traffic_secret_0 54 transcript hash.Hash 55 clientFinished []byte 56 } 57 58 // tls1.3在接收到ClientHello之后的握手过程 59 func (hs *serverHandshakeStateTLS13) handshake() error { 60 c := hs.c 61 62 // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2. 63 64 // 处理ClientHello,协商密码套件,计算共享密钥 65 if err := hs.processClientHello(); err != nil { 66 return err 67 } 68 // 检查会话恢复 69 if err := hs.checkForResumption(); err != nil { 70 return err 71 } 72 // 选择服务端证书 73 if err := hs.pickCertificate(); err != nil { 74 return err 75 } 76 c.buffering = true 77 // 发送 ServerHello,DummyChangeCipherSpec,EncryptedExtensions 78 if err := hs.sendServerParameters(); err != nil { 79 return err 80 } 81 // 发送 certificateRequestMsgTLS13,certificateMsgTLS13,certificateVerifyMsg 82 if err := hs.sendServerCertificate(); err != nil { 83 return err 84 } 85 // 发送 ServerFinished 86 if err := hs.sendServerFinished(); err != nil { 87 return err 88 } 89 // Note that at this point we could start sending application data without 90 // waiting for the client's second flight, but the application might not 91 // expect the lack of replay protection of the ClientHello parameters. 92 if _, err := c.flush(); err != nil { 93 return err 94 } 95 // 读取客户端证书,验证后发送 sessionTicket 96 if err := hs.readClientCertificate(); err != nil { 97 return err 98 } 99 // 读取 ClientFinished 100 if err := hs.readClientFinished(); err != nil { 101 return err 102 } 103 104 atomic.StoreUint32(&c.handshakeStatus, 1) 105 106 return nil 107 } 108 109 // 对 ClientHello 进行处理, 协商密码套件并计算共享密钥 110 func (hs *serverHandshakeStateTLS13) processClientHello() error { 111 c := hs.c 112 113 hs.hello = new(serverHelloMsg) 114 // 兼容性对应 115 // TLS 1.3 froze the ServerHello.legacy_version field, and uses 116 // supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1. 117 hs.hello.vers = VersionTLS12 118 // 扩展信息 supportedVersion 使用之前协商好的tls协议版本 119 hs.hello.supportedVersion = c.vers 120 121 if len(hs.clientHello.supportedVersions) == 0 { 122 _ = c.sendAlert(alertIllegalParameter) 123 return errors.New("gmtls: client used the legacy version field to negotiate TLS 1.3") 124 } 125 126 // Abort if the client is doing a fallback and landing lower than what we 127 // support. See RFC 7507, which however does not specify the interaction 128 // with supported_versions. The only difference is that with 129 // supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4] 130 // handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case, 131 // it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to 132 // TLS 1.2, because a TLS 1.3 server would abort here. The situation before 133 // supported_versions was not better because there was just no way to do a 134 // TLS 1.4 handshake without risking the server selecting TLS 1.3. 135 for _, id := range hs.clientHello.cipherSuites { 136 if id == TLS_FALLBACK_SCSV { 137 // Use c.vers instead of max(supported_versions) because an attacker 138 // could defeat this by adding an arbitrary high version otherwise. 139 if c.vers < c.config.maxSupportedVersion() { 140 _ = c.sendAlert(alertInappropriateFallback) 141 return errors.New("gmtls: client using inappropriate protocol fallback") 142 } 143 break 144 } 145 } 146 147 if len(hs.clientHello.compressionMethods) != 1 || 148 hs.clientHello.compressionMethods[0] != compressionNone { 149 _ = c.sendAlert(alertIllegalParameter) 150 return errors.New("gmtls: TLS 1.3 client supports illegal compression methods") 151 } 152 153 hs.hello.random = make([]byte, 32) 154 if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil { 155 _ = c.sendAlert(alertInternalError) 156 return err 157 } 158 159 if len(hs.clientHello.secureRenegotiation) != 0 { 160 _ = c.sendAlert(alertHandshakeFailure) 161 return errors.New("gmtls: initial handshake had non-empty renegotiation extension") 162 } 163 164 if hs.clientHello.earlyData { 165 // See RFC 8446, Section 4.2.10 for the complicated behavior required 166 // here. The scenario is that a different server at our address offered 167 // to accept early data in the past, which we can't handle. For now, all 168 // 0-RTT enabled session tickets need to expire before a Go server can 169 // replace a server or join a pool. That's the same requirement that 170 // applies to mixing or replacing with any TLS 1.2 server. 171 _ = c.sendAlert(alertUnsupportedExtension) 172 return errors.New("gmtls: client sent unexpected early data") 173 } 174 175 hs.hello.sessionId = hs.clientHello.sessionId 176 hs.hello.compressionMethod = compressionNone 177 // 协商密码套件 178 preferenceList := defaultCipherSuitesTLS13 179 if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) { 180 preferenceList = defaultCipherSuitesTLS13NoAES 181 } 182 // 改为优先满足客户端的密码套件 183 //for _, suiteID := range preferenceList { 184 // hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID) 185 // if hs.suite != nil { 186 // break 187 // } 188 //} 189 for _, suiteID := range hs.clientHello.cipherSuites { 190 hs.suite = mutualCipherSuiteTLS13(preferenceList, suiteID) 191 if hs.suite != nil { 192 break 193 } 194 } 195 196 if hs.suite == nil { 197 _ = c.sendAlert(alertHandshakeFailure) 198 return errors.New("gmtls: no cipher suite supported by both client and server") 199 } 200 c.cipherSuite = hs.suite.id 201 hs.hello.cipherSuite = hs.suite.id 202 fmt.Println("===== 服务端协商密码套件: %s", CipherSuiteName(hs.suite.id)) 203 // 使用密码套件的散列函数作为握手数据摘要函数 204 hs.transcript = hs.suite.hash.New() 205 206 // Pick the ECDHE group in server preference order, but give priority to 207 // groups with a key share, to avoid a HelloRetryRequest round-trip. 208 var selectedGroup CurveID 209 var clientKeyShare *keyShare 210 GroupSelection: 211 for _, preferredGroup := range c.config.curvePreferences() { 212 for _, ks := range hs.clientHello.keyShares { 213 if ks.group == preferredGroup { 214 selectedGroup = ks.group 215 clientKeyShare = &ks 216 break GroupSelection 217 } 218 } 219 if selectedGroup != 0 { 220 continue 221 } 222 for _, group := range hs.clientHello.supportedCurves { 223 if group == preferredGroup { 224 selectedGroup = group 225 break 226 } 227 } 228 } 229 if selectedGroup == 0 { 230 _ = c.sendAlert(alertHandshakeFailure) 231 return errors.New("gmtls: no ECDHE curve supported by both client and server") 232 } 233 // 未能获取客户端共享密钥 234 if clientKeyShare == nil { 235 // 请求客户端重新发送ClientHello以获取共享密钥 236 if err := hs.doHelloRetryRequest(selectedGroup); err != nil { 237 return err 238 } 239 clientKeyShare = &hs.clientHello.keyShares[0] 240 } 241 // var curve elliptic.Curve 242 var curveOk bool 243 //var curveName string 244 if _, curveOk = CheckCurveNameById(selectedGroup); !curveOk { 245 _ = c.sendAlert(alertInternalError) 246 return errors.New("gmtls: CurvePreferences includes unsupported curve") 247 } 248 // 生成服务端的密钥交换算法参数,即对应曲线的公私钥 249 params, err := generateECDHEParameters(c.config.rand(), selectedGroup) 250 if err != nil { 251 _ = c.sendAlert(alertInternalError) 252 return err 253 } 254 //fmt.Println("===== 服务端使用曲线 %s 生成密钥交换算法参数", curveName) 255 // 设置服务端密钥交换算法参数(曲线ID + 服务端公钥) 256 hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()} 257 // 根据客户端公钥与服务端公钥计算预主密钥 258 //fmt.Println("===== 服务端使用曲线 %s 与客户端公钥计算预主密钥", curveName) 259 hs.sharedKey = params.SharedKey(clientKeyShare.data) 260 if hs.sharedKey == nil { 261 _ = c.sendAlert(alertIllegalParameter) 262 return errors.New("gmtls: invalid client key share") 263 } 264 265 c.serverName = hs.clientHello.serverName 266 return nil 267 } 268 269 // 检查会话恢复 270 func (hs *serverHandshakeStateTLS13) checkForResumption() error { 271 c := hs.c 272 273 if c.config.SessionTicketsDisabled { 274 return nil 275 } 276 277 modeOK := false 278 for _, mode := range hs.clientHello.pskModes { 279 if mode == pskModeDHE { 280 modeOK = true 281 break 282 } 283 } 284 if !modeOK { 285 return nil 286 } 287 288 if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) { 289 _ = c.sendAlert(alertIllegalParameter) 290 return errors.New("gmtls: invalid or missing PSK binders") 291 } 292 if len(hs.clientHello.pskIdentities) == 0 { 293 return nil 294 } 295 // 尝试从 ClientHello的pskid集合中选取一个作为本次会话的公钥密钥。 296 // 如果客户端就是本代码实现的客户端,那么pskIdentities中最多只会有一个 pskIdentitie 297 for i, identity := range hs.clientHello.pskIdentities { 298 if i >= maxClientPSKIdentities { 299 break 300 } 301 // 对pskIdentitie的label解密得到sessionStateTLS13的序列化明文 302 plaintext, _ := c.decryptTicket(identity.label) 303 if plaintext == nil { 304 continue 305 } 306 // 反序列化为sessionStateTLS13 307 sessionState := new(sessionStateTLS13) 308 if ok := sessionState.unmarshal(plaintext); !ok { 309 continue 310 } 311 // 检查sessionTicket最大存活时间 312 createdAt := time.Unix(int64(sessionState.createdAt), 0) 313 if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { 314 continue 315 } 316 317 // We don't check the obfuscated ticket age because it's affected by 318 // clock skew and it's only a freshness signal useful for shrinking the 319 // window for replay attacks, which don't affect us as we don't do 0-RTT. 320 321 // 选取该会话的密码套件 322 pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite) 323 if pskSuite == nil || pskSuite.hash != hs.suite.hash { 324 continue 325 } 326 327 // PSK connections don't re-establish client certificates, but carry 328 // them over in the session ticket. Ensure the presence of client certs 329 // in the ticket is consistent with the configured requirements. 330 sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0 331 needClientCerts := requiresClientCert(c.config.ClientAuth) 332 if needClientCerts && !sessionHasClientCerts { 333 continue 334 } 335 if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { 336 continue 337 } 338 // 使用会话状态中保存的恢复用密钥扩展为psk 339 psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption", 340 nil, hs.suite.hash.Size()) 341 // 再基于psk派生早期密钥 342 hs.earlySecret = hs.suite.extract(psk, nil) 343 // 再基于早期密钥派生绑定者密钥 344 binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil) 345 // 复制一个转录散列函数 346 // Clone the transcript in case a HelloRetryRequest was recorded. 347 transcript := cloneHash(hs.transcript, hs.suite.hash) 348 if transcript == nil { 349 _ = c.sendAlert(alertInternalError) 350 return errors.New("gmtls: internal error: failed to clone hash") 351 } 352 // 向转录散列写入不带pskBinders的ClientHello 353 transcript.Write(hs.clientHello.marshalWithoutBinders()) 354 // 生成pskBinders: 使用绑定者密钥和转录散列生成的Finished消息散列 355 pskBinder := hs.suite.finishedHash(binderKey, transcript) 356 // 检查clientHello与服务端计算出的pskBinder的认证码是否一致 357 if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) { 358 _ = c.sendAlert(alertDecryptError) 359 return errors.New("gmtls: invalid PSK binder") 360 } 361 // 向连接写入会话恢复标识 362 c.didResume = true 363 // 检查客户端短证书 364 if err := c.processCertsFromClient(sessionState.certificate); err != nil { 365 return err 366 } 367 // 在ServerHello中填写会话恢复相关字段 368 hs.hello.selectedIdentityPresent = true 369 hs.hello.selectedIdentity = uint16(i) 370 hs.usingPSK = true 371 return nil 372 } 373 374 return nil 375 } 376 377 // cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler 378 // interfaces implemented by standard library hashes to clone the state of in 379 // to a new instance of h. It returns nil if the operation fails. 380 func cloneHash(in hash.Hash, h x509.Hash) hash.Hash { 381 // Recreate the interface to avoid importing encoding. 382 type binaryMarshaler interface { 383 MarshalBinary() (data []byte, err error) 384 UnmarshalBinary(data []byte) error 385 } 386 marshaler, ok := in.(binaryMarshaler) 387 if !ok { 388 return nil 389 } 390 state, err := marshaler.MarshalBinary() 391 if err != nil { 392 return nil 393 } 394 out := h.New() 395 unmarshaler, ok := out.(binaryMarshaler) 396 if !ok { 397 return nil 398 } 399 if err := unmarshaler.UnmarshalBinary(state); err != nil { 400 return nil 401 } 402 return out 403 } 404 405 // 选择服务端证书 406 func (hs *serverHandshakeStateTLS13) pickCertificate() error { 407 c := hs.c 408 409 // Only one of PSK and certificates are used at a time. 410 if hs.usingPSK { 411 return nil 412 } 413 414 // signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3. 415 if len(hs.clientHello.supportedSignatureAlgorithms) == 0 { 416 return c.sendAlert(alertMissingExtension) 417 } 418 // 根据clientHello与服务端config选择服务端证书 419 certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello)) 420 if err != nil { 421 if err == errNoCertificates { 422 _ = c.sendAlert(alertUnrecognizedName) 423 } else { 424 _ = c.sendAlert(alertInternalError) 425 } 426 return err 427 } 428 hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms) 429 if err != nil { 430 // getCertificate returned a certificate that is unsupported or 431 // incompatible with the client's signature algorithms. 432 _ = c.sendAlert(alertHandshakeFailure) 433 return err 434 } 435 hs.cert = certificate 436 437 return nil 438 } 439 440 // sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility 441 // with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. 442 func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error { 443 if hs.sentDummyCCS { 444 return nil 445 } 446 hs.sentDummyCCS = true 447 448 _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) 449 return err 450 } 451 452 // 向客户端发送 HelloRetryRequest , 请求重新发送 ClientHello 453 func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error { 454 c := hs.c 455 // 将ClientHello散列后重新写入握手数据摘要 456 // The first ClientHello gets double-hashed into the transcript upon a 457 // HelloRetryRequest. See RFC 8446, Section 4.4.1. 458 hs.transcript.Write(hs.clientHello.marshal()) 459 chHash := hs.transcript.Sum(nil) 460 hs.transcript.Reset() 461 hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) 462 hs.transcript.Write(chHash) 463 // 创建 HelloRetryRequest 464 helloRetryRequest := &serverHelloMsg{ 465 vers: hs.hello.vers, 466 random: helloRetryRequestRandom, // 客户端通过该random值判断是否HelloRetryRequest 467 sessionId: hs.hello.sessionId, 468 cipherSuite: hs.hello.cipherSuite, 469 compressionMethod: hs.hello.compressionMethod, 470 supportedVersion: hs.hello.supportedVersion, 471 selectedGroup: selectedGroup, 472 } 473 // 将HelloRetryRequest写入握手数据摘要 474 hs.transcript.Write(helloRetryRequest.marshal()) 475 if _, err := c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal()); err != nil { 476 return err 477 } 478 fmt.Println("===== 服务端发送 HelloRetryRequest") 479 if err := hs.sendDummyChangeCipherSpec(); err != nil { 480 return err 481 } 482 // 读取下一条消息, 客户端重新发送的 ClientHello 483 msg, err := c.readHandshake() 484 if err != nil { 485 return err 486 } 487 clientHello, ok := msg.(*clientHelloMsg) 488 if !ok { 489 _ = c.sendAlert(alertUnexpectedMessage) 490 return unexpectedMessageError(clientHello, msg) 491 } 492 fmt.Println("===== 服务端读取到客户端重新发送的 ClientHello") 493 if len(clientHello.keyShares) != 1 || clientHello.keyShares[0].group != selectedGroup { 494 _ = c.sendAlert(alertIllegalParameter) 495 return errors.New("gmtls: client sent invalid key share in second ClientHello") 496 } 497 498 if clientHello.earlyData { 499 _ = c.sendAlert(alertIllegalParameter) 500 return errors.New("gmtls: client indicated early data in second ClientHello") 501 } 502 503 if illegalClientHelloChange(clientHello, hs.clientHello) { 504 _ = c.sendAlert(alertIllegalParameter) 505 return errors.New("gmtls: client illegally modified second ClientHello") 506 } 507 508 hs.clientHello = clientHello 509 return nil 510 } 511 512 // illegalClientHelloChange reports whether the two ClientHello messages are 513 // different, with the exception of the changes allowed before and after a 514 // HelloRetryRequest. See RFC 8446, Section 4.1.2. 515 func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool { 516 if len(ch.supportedVersions) != len(ch1.supportedVersions) || 517 len(ch.cipherSuites) != len(ch1.cipherSuites) || 518 len(ch.supportedCurves) != len(ch1.supportedCurves) || 519 len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) || 520 len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) || 521 len(ch.alpnProtocols) != len(ch1.alpnProtocols) { 522 return true 523 } 524 for i := range ch.supportedVersions { 525 if ch.supportedVersions[i] != ch1.supportedVersions[i] { 526 return true 527 } 528 } 529 for i := range ch.cipherSuites { 530 if ch.cipherSuites[i] != ch1.cipherSuites[i] { 531 return true 532 } 533 } 534 for i := range ch.supportedCurves { 535 if ch.supportedCurves[i] != ch1.supportedCurves[i] { 536 return true 537 } 538 } 539 for i := range ch.supportedSignatureAlgorithms { 540 if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] { 541 return true 542 } 543 } 544 for i := range ch.supportedSignatureAlgorithmsCert { 545 if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] { 546 return true 547 } 548 } 549 for i := range ch.alpnProtocols { 550 if ch.alpnProtocols[i] != ch1.alpnProtocols[i] { 551 return true 552 } 553 } 554 return ch.vers != ch1.vers || 555 !bytes.Equal(ch.random, ch1.random) || 556 !bytes.Equal(ch.sessionId, ch1.sessionId) || 557 !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) || 558 ch.serverName != ch1.serverName || 559 ch.ocspStapling != ch1.ocspStapling || 560 !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) || 561 ch.ticketSupported != ch1.ticketSupported || 562 !bytes.Equal(ch.sessionTicket, ch1.sessionTicket) || 563 ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported || 564 !bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) || 565 ch.scts != ch1.scts || 566 !bytes.Equal(ch.cookie, ch1.cookie) || 567 !bytes.Equal(ch.pskModes, ch1.pskModes) 568 } 569 570 // 发送 ServerHello,DummyChangeCipherSpec,EncryptedExtensions 571 func (hs *serverHandshakeStateTLS13) sendServerParameters() error { 572 c := hs.c 573 // 向握手数据摘要写入ClientHello与ServerHello 574 hs.transcript.Write(hs.clientHello.marshal()) 575 hs.transcript.Write(hs.hello.marshal()) 576 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 577 return err 578 } 579 fmt.Println("===== 服务端发送 ServerHello") 580 if err := hs.sendDummyChangeCipherSpec(); err != nil { 581 return err 582 } 583 fmt.Println("===== 服务端发送 DummyChangeCipherSpec") 584 // 如果是会话恢复,这里已经存在早期密钥,如果不存在,则初始化早期密钥 585 earlySecret := hs.earlySecret 586 if earlySecret == nil { 587 earlySecret = hs.suite.extract(nil, nil) 588 } 589 // 使用 HKDF-Extract, 根据之前计算出的预主密钥与早期密钥计算出握手阶段密钥。 590 // hs.sharedKey 是预主密钥; 591 // 用deriveSecret函数从earlySecret、"derived"派生出盐值。 592 hs.handshakeSecret = hs.suite.extract(hs.sharedKey, 593 hs.suite.deriveSecret(earlySecret, "derived", nil)) 594 // 使用 HKDF-Expand, 根据握手阶段密钥与目前的握手数据摘要计算出客户端会话密钥,并设置到连接通道 595 clientSecret := hs.suite.deriveSecret(hs.handshakeSecret, 596 clientHandshakeTrafficLabel, hs.transcript) 597 c.in.setTrafficSecret(hs.suite, clientSecret) 598 // 使用 HKDF-Expand, 根据握手阶段密钥与目前的握手数据摘要计算出服务端会话密钥,并设置到连接通道 599 serverSecret := hs.suite.deriveSecret(hs.handshakeSecret, 600 serverHandshakeTrafficLabel, hs.transcript) 601 c.out.setTrafficSecret(hs.suite, serverSecret) 602 603 err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret) 604 if err != nil { 605 _ = c.sendAlert(alertInternalError) 606 return err 607 } 608 err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret) 609 if err != nil { 610 _ = c.sendAlert(alertInternalError) 611 return err 612 } 613 // 生成加密扩展信息 614 encryptedExtensions := new(encryptedExtensionsMsg) 615 // 协商ALPN协议 616 selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols) 617 if err != nil { 618 _ = c.sendAlert(alertNoApplicationProtocol) 619 return err 620 } 621 encryptedExtensions.alpnProtocol = selectedProto 622 c.clientProtocol = selectedProto 623 // 向握手数据摘要写入加密扩展信息 624 hs.transcript.Write(encryptedExtensions.marshal()) 625 if _, err := c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal()); err != nil { 626 return err 627 } 628 fmt.Println("===== 服务端发送 EncryptedExtensions") 629 630 return nil 631 } 632 633 func (hs *serverHandshakeStateTLS13) requestClientCert() bool { 634 return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK 635 } 636 637 // 发送 certificateRequestMsgTLS13,certificateMsgTLS13,certificateVerifyMsg 638 func (hs *serverHandshakeStateTLS13) sendServerCertificate() error { 639 c := hs.c 640 641 // Only one of PSK and certificates are used at a time. 642 if hs.usingPSK { 643 return nil 644 } 645 646 if hs.requestClientCert() { 647 // Request a client certificate 648 certReq := new(certificateRequestMsgTLS13) 649 certReq.ocspStapling = true 650 certReq.scts = true 651 certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms 652 if c.config.ClientCAs != nil { 653 certReq.certificateAuthorities = c.config.ClientCAs.Subjects() 654 } 655 // 向握手数据摘要写入 certificateRequestMsgTLS13 656 hs.transcript.Write(certReq.marshal()) 657 if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { 658 return err 659 } 660 fmt.Println("===== 服务端发送 certificateRequestMsgTLS13") 661 } 662 663 certMsg := new(certificateMsgTLS13) 664 665 certMsg.certificate = *hs.cert 666 certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0 667 certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 668 // 向握手数据摘要写入 certificateMsgTLS13 669 hs.transcript.Write(certMsg.marshal()) 670 if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { 671 return err 672 } 673 fmt.Println("===== 服务端发送 certificateMsgTLS13") 674 certVerifyMsg := new(certificateVerifyMsg) 675 certVerifyMsg.hasSignatureAlgorithm = true 676 certVerifyMsg.signatureAlgorithm = hs.sigAlg 677 678 sigType, sigHash, err := typeAndHashFromSignatureScheme(hs.sigAlg) 679 fmt.Println("sigHash: %s", sigHash.String()) 680 if err != nil { 681 return c.sendAlert(alertInternalError) 682 } 683 684 signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) 685 signOpts := crypto.SignerOpts(sigHash) 686 switch sigType { 687 case signatureRSAPSS: 688 signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash.HashFunc()} 689 case signatureSM2: 690 signOpts = sm2.DefaultSM2SignerOption() 691 case signatureECDSAEXT: 692 signOpts = ecbase.CreateEcSignerOpts(sigHash.HashFunc(), true) 693 } 694 // TODO 需要确认sign的处理有没有对ecdsaext做特殊处理 695 sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts) 696 if err != nil { 697 public := hs.cert.PrivateKey.(crypto.Signer).Public() 698 if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS && 699 rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS 700 _ = c.sendAlert(alertHandshakeFailure) 701 } else { 702 _ = c.sendAlert(alertInternalError) 703 } 704 return errors.New("gmtls: failed to sign handshake: " + err.Error()) 705 } 706 certVerifyMsg.signature = sig 707 // 向握手数据摘要写入 certificateVerifyMsg 708 hs.transcript.Write(certVerifyMsg.marshal()) 709 if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { 710 return err 711 } 712 fmt.Println("===== 服务端发送 certificateVerifyMsg") 713 return nil 714 } 715 716 // 发送 ServerFinished 717 func (hs *serverHandshakeStateTLS13) sendServerFinished() error { 718 c := hs.c 719 720 finished := &finishedMsg{ 721 verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), 722 } 723 // 向握手数据摘要写入 ServerFinished 724 hs.transcript.Write(finished.marshal()) 725 if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { 726 return err 727 } 728 fmt.Println("===== 服务端发送 ServerFinished") 729 // Derive secrets that take context through the server Finished. 730 // 从握手阶段密钥派生新的预主密钥并提取出主密钥 731 hs.masterSecret = hs.suite.extract(nil, 732 hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil)) 733 // 重新派生客户端通信密钥,但暂时不设置到连接通道 734 hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, 735 clientApplicationTrafficLabel, hs.transcript) 736 // 重新派生服务端通信密钥,并设置到连接通道 737 serverSecret := hs.suite.deriveSecret(hs.masterSecret, 738 serverApplicationTrafficLabel, hs.transcript) 739 c.out.setTrafficSecret(hs.suite, serverSecret) 740 741 err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret) 742 if err != nil { 743 _ = c.sendAlert(alertInternalError) 744 return err 745 } 746 err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret) 747 if err != nil { 748 _ = c.sendAlert(alertInternalError) 749 return err 750 } 751 752 c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) 753 754 // If we did not request client certificates, at this point we can 755 // precompute the client finished and roll the transcript forward to send 756 // session tickets in our first flight. 757 if !hs.requestClientCert() { 758 if err := hs.sendSessionTickets(); err != nil { 759 return err 760 } 761 } 762 763 return nil 764 } 765 766 func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool { 767 if hs.c.config.SessionTicketsDisabled { 768 fmt.Println("===== config.SessionTicketsDisabled is true") 769 return false 770 } 771 772 // Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9. 773 for _, pskMode := range hs.clientHello.pskModes { 774 if pskMode == pskModeDHE { 775 return true 776 } 777 } 778 return false 779 } 780 781 // 发送 newSessionTicketMsgTLS13 782 func (hs *serverHandshakeStateTLS13) sendSessionTickets() error { 783 c := hs.c 784 785 hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) 786 finishedMsg := &finishedMsg{ 787 verifyData: hs.clientFinished, 788 } 789 hs.transcript.Write(finishedMsg.marshal()) 790 791 if !hs.shouldSendSessionTickets() { 792 fmt.Println("===== shouldSendSessionTickets is false") 793 return nil 794 } 795 // 派生会话恢复用密钥 796 resumptionSecret := hs.suite.deriveSecret(hs.masterSecret, 797 resumptionLabel, hs.transcript) 798 // 创建 newSessionTicketMsgTLS13 799 m := new(newSessionTicketMsgTLS13) 800 var certsFromClient [][]byte 801 for _, cert := range c.peerCertificates { 802 certsFromClient = append(certsFromClient, cert.Raw) 803 } 804 state := sessionStateTLS13{ 805 cipherSuite: hs.suite.id, 806 createdAt: uint64(c.config.time().Unix()), 807 resumptionSecret: resumptionSecret, 808 certificate: Certificate{ 809 Certificate: certsFromClient, 810 OCSPStaple: c.ocspResponse, 811 SignedCertificateTimestamps: c.scts, 812 }, 813 } 814 var err error 815 // 序列化 newSessionTicketMsgTLS13 并加密 816 m.label, err = c.encryptTicket(state.marshal()) 817 if err != nil { 818 return err 819 } 820 m.lifetime = uint32(maxSessionTicketLifetime / time.Second) 821 if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { 822 return err 823 } 824 fmt.Println("===== 服务端发出 newSessionTicketMsgTLS13") 825 return nil 826 } 827 828 // 读取并验证客户端证书,并发送本次会话票据信息给客户端。 829 func (hs *serverHandshakeStateTLS13) readClientCertificate() error { 830 c := hs.c 831 832 if !hs.requestClientCert() { 833 // Make sure the connection is still being verified whether or not 834 // the server requested a client certificate. 835 if c.config.VerifyConnection != nil { 836 if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { 837 _ = c.sendAlert(alertBadCertificate) 838 return err 839 } 840 } 841 return nil 842 } 843 844 // If we requested a client certificate, then the client must send a 845 // certificate message. If it's empty, no CertificateVerify is sent. 846 // 读取 ClientCertificate 847 msg, err := c.readHandshake() 848 if err != nil { 849 return err 850 } 851 certMsg, ok := msg.(*certificateMsgTLS13) 852 if !ok { 853 _ = c.sendAlert(alertUnexpectedMessage) 854 return unexpectedMessageError(certMsg, msg) 855 } 856 fmt.Println("===== 服务端读取到 ClientCertificate") 857 hs.transcript.Write(certMsg.marshal()) 858 // 检查客户端证书 859 if err := c.processCertsFromClient(certMsg.certificate); err != nil { 860 return err 861 } 862 863 if c.config.VerifyConnection != nil { 864 if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { 865 _ = c.sendAlert(alertBadCertificate) 866 return err 867 } 868 } 869 870 if len(certMsg.certificate.Certificate) != 0 { 871 // 读取 ClientCertVerify 872 msg, err = c.readHandshake() 873 if err != nil { 874 return err 875 } 876 certVerify, ok := msg.(*certificateVerifyMsg) 877 if !ok { 878 _ = c.sendAlert(alertUnexpectedMessage) 879 return unexpectedMessageError(certVerify, msg) 880 } 881 fmt.Println("===== 服务端读取到 ClientCertVerify") 882 // See RFC 8446, Section 4.4.3. 883 if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { 884 _ = c.sendAlert(alertIllegalParameter) 885 return errors.New("gmtls: client certificate used with invalid signature algorithm") 886 } 887 sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) 888 fmt.Println("sigHash: %s", sigHash.String()) 889 if err != nil { 890 return c.sendAlert(alertInternalError) 891 } 892 if sigType == signaturePKCS1v15 || sigHash == x509.SHA1 { 893 _ = c.sendAlert(alertIllegalParameter) 894 return errors.New("gmtls: client certificate used with invalid signature algorithm") 895 } 896 signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) 897 // TODO 需要确认sign的处理有没有对ecdsaext做特殊处理 898 if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, 899 sigHash, signed, certVerify.signature); err != nil { 900 _ = c.sendAlert(alertDecryptError) 901 return errors.New("gmtls: invalid signature by the client certificate: " + err.Error()) 902 } 903 904 hs.transcript.Write(certVerify.marshal()) 905 } 906 // 在需求验证客户端证书且验证Ok之后,向客户端发送本次会话新创建的票据信息。 907 // 该消息属于握手消息,但是在客户端完成握手之后才会接收。 908 // PS : 如果要使用会话恢复功能,服务端就必须验证客户端身份。 909 // If we waited until the client certificates to send session tickets, we 910 // are ready to do it now. 911 if err := hs.sendSessionTickets(); err != nil { 912 return err 913 } 914 915 return nil 916 } 917 918 // 读取 ClientFinished 919 func (hs *serverHandshakeStateTLS13) readClientFinished() error { 920 c := hs.c 921 // 读取 ClientFinished 922 msg, err := c.readHandshake() 923 if err != nil { 924 return err 925 } 926 finished, ok := msg.(*finishedMsg) 927 if !ok { 928 _ = c.sendAlert(alertUnexpectedMessage) 929 return unexpectedMessageError(finished, msg) 930 } 931 fmt.Println("===== 服务端读取到 ClientFinished") 932 if !hmac.Equal(hs.clientFinished, finished.verifyData) { 933 _ = c.sendAlert(alertDecryptError) 934 return errors.New("gmtls: invalid client finished hash") 935 } 936 // 将之前重新生成的客户端通信密钥设置到连接in通道 937 c.in.setTrafficSecret(hs.suite, hs.trafficSecret) 938 939 return nil 940 }