github.com/fisco-bcos/crypto@v0.0.0-20200202032121-bd8ab0b5d4f1/tls/handshake_client_tls13.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tls 6 7 import ( 8 "bytes" 9 "crypto" 10 "crypto/hmac" 11 "crypto/rsa" 12 "errors" 13 "hash" 14 "sync/atomic" 15 "time" 16 ) 17 18 type clientHandshakeStateTLS13 struct { 19 c *Conn 20 serverHello *serverHelloMsg 21 hello *clientHelloMsg 22 ecdheParams ecdheParameters 23 24 session *ClientSessionState 25 earlySecret []byte 26 binderKey []byte 27 28 certReq *certificateRequestMsgTLS13 29 usingPSK bool 30 sentDummyCCS bool 31 suite *cipherSuiteTLS13 32 transcript hash.Hash 33 masterSecret []byte 34 trafficSecret []byte // client_application_traffic_secret_0 35 } 36 37 // handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and, 38 // optionally, hs.session, hs.earlySecret and hs.binderKey to be set. 39 func (hs *clientHandshakeStateTLS13) handshake() error { 40 c := hs.c 41 42 // The server must not select TLS 1.3 in a renegotiation. See RFC 8446, 43 // sections 4.1.2 and 4.1.3. 44 if c.handshakes > 0 { 45 c.sendAlert(alertProtocolVersion) 46 return errors.New("tls: server selected TLS 1.3 in a renegotiation") 47 } 48 49 // Consistency check on the presence of a keyShare and its parameters. 50 if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 { 51 return c.sendAlert(alertInternalError) 52 } 53 54 if err := hs.checkServerHelloOrHRR(); err != nil { 55 return err 56 } 57 58 hs.transcript = hs.suite.hash.New() 59 hs.transcript.Write(hs.hello.marshal()) 60 61 if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { 62 if err := hs.sendDummyChangeCipherSpec(); err != nil { 63 return err 64 } 65 if err := hs.processHelloRetryRequest(); err != nil { 66 return err 67 } 68 } 69 70 hs.transcript.Write(hs.serverHello.marshal()) 71 72 c.buffering = true 73 if err := hs.processServerHello(); err != nil { 74 return err 75 } 76 if err := hs.sendDummyChangeCipherSpec(); err != nil { 77 return err 78 } 79 if err := hs.establishHandshakeKeys(); err != nil { 80 return err 81 } 82 if err := hs.readServerParameters(); err != nil { 83 return err 84 } 85 if err := hs.readServerCertificate(); err != nil { 86 return err 87 } 88 if err := hs.readServerFinished(); err != nil { 89 return err 90 } 91 if err := hs.sendClientCertificate(); err != nil { 92 return err 93 } 94 if err := hs.sendClientFinished(); err != nil { 95 return err 96 } 97 if _, err := c.flush(); err != nil { 98 return err 99 } 100 101 atomic.StoreUint32(&c.handshakeStatus, 1) 102 103 return nil 104 } 105 106 // checkServerHelloOrHRR does validity checks that apply to both ServerHello and 107 // HelloRetryRequest messages. It sets hs.suite. 108 func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error { 109 c := hs.c 110 111 if hs.serverHello.supportedVersion == 0 { 112 c.sendAlert(alertMissingExtension) 113 return errors.New("tls: server selected TLS 1.3 using the legacy version field") 114 } 115 116 if hs.serverHello.supportedVersion != VersionTLS13 { 117 c.sendAlert(alertIllegalParameter) 118 return errors.New("tls: server selected an invalid version after a HelloRetryRequest") 119 } 120 121 if hs.serverHello.vers != VersionTLS12 { 122 c.sendAlert(alertIllegalParameter) 123 return errors.New("tls: server sent an incorrect legacy version") 124 } 125 126 if hs.serverHello.nextProtoNeg || 127 len(hs.serverHello.nextProtos) != 0 || 128 hs.serverHello.ocspStapling || 129 hs.serverHello.ticketSupported || 130 hs.serverHello.secureRenegotiationSupported || 131 len(hs.serverHello.secureRenegotiation) != 0 || 132 len(hs.serverHello.alpnProtocol) != 0 || 133 len(hs.serverHello.scts) != 0 { 134 c.sendAlert(alertUnsupportedExtension) 135 return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3") 136 } 137 138 if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) { 139 c.sendAlert(alertIllegalParameter) 140 return errors.New("tls: server did not echo the legacy session ID") 141 } 142 143 if hs.serverHello.compressionMethod != compressionNone { 144 c.sendAlert(alertIllegalParameter) 145 return errors.New("tls: server selected unsupported compression format") 146 } 147 148 selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite) 149 if hs.suite != nil && selectedSuite != hs.suite { 150 c.sendAlert(alertIllegalParameter) 151 return errors.New("tls: server changed cipher suite after a HelloRetryRequest") 152 } 153 if selectedSuite == nil { 154 c.sendAlert(alertIllegalParameter) 155 return errors.New("tls: server chose an unconfigured cipher suite") 156 } 157 hs.suite = selectedSuite 158 c.cipherSuite = hs.suite.id 159 160 return nil 161 } 162 163 // sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility 164 // with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. 165 func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error { 166 if hs.sentDummyCCS { 167 return nil 168 } 169 hs.sentDummyCCS = true 170 171 _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) 172 return err 173 } 174 175 // processHelloRetryRequest handles the HRR in hs.serverHello, modifies and 176 // resends hs.hello, and reads the new ServerHello into hs.serverHello. 177 func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error { 178 c := hs.c 179 180 // The first ClientHello gets double-hashed into the transcript upon a 181 // HelloRetryRequest. See RFC 8446, Section 4.4.1. 182 chHash := hs.transcript.Sum(nil) 183 hs.transcript.Reset() 184 hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) 185 hs.transcript.Write(chHash) 186 hs.transcript.Write(hs.serverHello.marshal()) 187 188 if hs.serverHello.serverShare.group != 0 { 189 c.sendAlert(alertDecodeError) 190 return errors.New("tls: received malformed key_share extension") 191 } 192 193 curveID := hs.serverHello.selectedGroup 194 if curveID == 0 { 195 c.sendAlert(alertMissingExtension) 196 return errors.New("tls: received HelloRetryRequest without selected group") 197 } 198 curveOK := false 199 for _, id := range hs.hello.supportedCurves { 200 if id == curveID { 201 curveOK = true 202 break 203 } 204 } 205 if !curveOK { 206 c.sendAlert(alertIllegalParameter) 207 return errors.New("tls: server selected unsupported group") 208 } 209 if hs.ecdheParams.CurveID() == curveID { 210 c.sendAlert(alertIllegalParameter) 211 return errors.New("tls: server sent an unnecessary HelloRetryRequest message") 212 } 213 if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { 214 c.sendAlert(alertInternalError) 215 return errors.New("tls: CurvePreferences includes unsupported curve") 216 } 217 params, err := generateECDHEParameters(c.config.rand(), curveID) 218 if err != nil { 219 c.sendAlert(alertInternalError) 220 return err 221 } 222 hs.ecdheParams = params 223 hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} 224 225 hs.hello.cookie = hs.serverHello.cookie 226 227 hs.hello.raw = nil 228 if len(hs.hello.pskIdentities) > 0 { 229 pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) 230 if pskSuite == nil { 231 return c.sendAlert(alertInternalError) 232 } 233 if pskSuite.hash == hs.suite.hash { 234 // Update binders and obfuscated_ticket_age. 235 ticketAge := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond) 236 hs.hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + hs.session.ageAdd 237 238 transcript := hs.suite.hash.New() 239 transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) 240 transcript.Write(chHash) 241 transcript.Write(hs.serverHello.marshal()) 242 transcript.Write(hs.hello.marshalWithoutBinders()) 243 pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)} 244 hs.hello.updateBinders(pskBinders) 245 } else { 246 // Server selected a cipher suite incompatible with the PSK. 247 hs.hello.pskIdentities = nil 248 hs.hello.pskBinders = nil 249 } 250 } 251 252 hs.transcript.Write(hs.hello.marshal()) 253 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 254 return err 255 } 256 257 msg, err := c.readHandshake() 258 if err != nil { 259 return err 260 } 261 262 serverHello, ok := msg.(*serverHelloMsg) 263 if !ok { 264 c.sendAlert(alertUnexpectedMessage) 265 return unexpectedMessageError(serverHello, msg) 266 } 267 hs.serverHello = serverHello 268 269 if err := hs.checkServerHelloOrHRR(); err != nil { 270 return err 271 } 272 273 return nil 274 } 275 276 func (hs *clientHandshakeStateTLS13) processServerHello() error { 277 c := hs.c 278 279 if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { 280 c.sendAlert(alertUnexpectedMessage) 281 return errors.New("tls: server sent two HelloRetryRequest messages") 282 } 283 284 if len(hs.serverHello.cookie) != 0 { 285 c.sendAlert(alertUnsupportedExtension) 286 return errors.New("tls: server sent a cookie in a normal ServerHello") 287 } 288 289 if hs.serverHello.selectedGroup != 0 { 290 c.sendAlert(alertDecodeError) 291 return errors.New("tls: malformed key_share extension") 292 } 293 294 if hs.serverHello.serverShare.group == 0 { 295 c.sendAlert(alertIllegalParameter) 296 return errors.New("tls: server did not send a key share") 297 } 298 if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() { 299 c.sendAlert(alertIllegalParameter) 300 return errors.New("tls: server selected unsupported group") 301 } 302 303 if !hs.serverHello.selectedIdentityPresent { 304 return nil 305 } 306 307 if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) { 308 c.sendAlert(alertIllegalParameter) 309 return errors.New("tls: server selected an invalid PSK") 310 } 311 312 if len(hs.hello.pskIdentities) != 1 || hs.session == nil { 313 return c.sendAlert(alertInternalError) 314 } 315 pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) 316 if pskSuite == nil { 317 return c.sendAlert(alertInternalError) 318 } 319 if pskSuite.hash != hs.suite.hash { 320 c.sendAlert(alertIllegalParameter) 321 return errors.New("tls: server selected an invalid PSK and cipher suite pair") 322 } 323 324 hs.usingPSK = true 325 c.didResume = true 326 c.peerCertificates = hs.session.serverCertificates 327 c.verifiedChains = hs.session.verifiedChains 328 return nil 329 } 330 331 func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error { 332 c := hs.c 333 334 sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data) 335 if sharedKey == nil { 336 c.sendAlert(alertIllegalParameter) 337 return errors.New("tls: invalid server key share") 338 } 339 340 earlySecret := hs.earlySecret 341 if !hs.usingPSK { 342 earlySecret = hs.suite.extract(nil, nil) 343 } 344 handshakeSecret := hs.suite.extract(sharedKey, 345 hs.suite.deriveSecret(earlySecret, "derived", nil)) 346 347 clientSecret := hs.suite.deriveSecret(handshakeSecret, 348 clientHandshakeTrafficLabel, hs.transcript) 349 c.out.setTrafficSecret(hs.suite, clientSecret) 350 serverSecret := hs.suite.deriveSecret(handshakeSecret, 351 serverHandshakeTrafficLabel, hs.transcript) 352 c.in.setTrafficSecret(hs.suite, serverSecret) 353 354 err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret) 355 if err != nil { 356 c.sendAlert(alertInternalError) 357 return err 358 } 359 err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret) 360 if err != nil { 361 c.sendAlert(alertInternalError) 362 return err 363 } 364 365 hs.masterSecret = hs.suite.extract(nil, 366 hs.suite.deriveSecret(handshakeSecret, "derived", nil)) 367 368 return nil 369 } 370 371 func (hs *clientHandshakeStateTLS13) readServerParameters() error { 372 c := hs.c 373 374 msg, err := c.readHandshake() 375 if err != nil { 376 return err 377 } 378 379 encryptedExtensions, ok := msg.(*encryptedExtensionsMsg) 380 if !ok { 381 c.sendAlert(alertUnexpectedMessage) 382 return unexpectedMessageError(encryptedExtensions, msg) 383 } 384 hs.transcript.Write(encryptedExtensions.marshal()) 385 386 if len(encryptedExtensions.alpnProtocol) != 0 && len(hs.hello.alpnProtocols) == 0 { 387 c.sendAlert(alertUnsupportedExtension) 388 return errors.New("tls: server advertised unrequested ALPN extension") 389 } 390 c.clientProtocol = encryptedExtensions.alpnProtocol 391 392 return nil 393 } 394 395 func (hs *clientHandshakeStateTLS13) readServerCertificate() error { 396 c := hs.c 397 398 // Either a PSK or a certificate is always used, but not both. 399 // See RFC 8446, Section 4.1.1. 400 if hs.usingPSK { 401 return nil 402 } 403 404 msg, err := c.readHandshake() 405 if err != nil { 406 return err 407 } 408 409 certReq, ok := msg.(*certificateRequestMsgTLS13) 410 if ok { 411 hs.transcript.Write(certReq.marshal()) 412 413 hs.certReq = certReq 414 415 msg, err = c.readHandshake() 416 if err != nil { 417 return err 418 } 419 } 420 421 certMsg, ok := msg.(*certificateMsgTLS13) 422 if !ok { 423 c.sendAlert(alertUnexpectedMessage) 424 return unexpectedMessageError(certMsg, msg) 425 } 426 if len(certMsg.certificate.Certificate) == 0 { 427 c.sendAlert(alertDecodeError) 428 return errors.New("tls: received empty certificates message") 429 } 430 hs.transcript.Write(certMsg.marshal()) 431 432 c.scts = certMsg.certificate.SignedCertificateTimestamps 433 c.ocspResponse = certMsg.certificate.OCSPStaple 434 435 if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil { 436 return err 437 } 438 439 msg, err = c.readHandshake() 440 if err != nil { 441 return err 442 } 443 444 certVerify, ok := msg.(*certificateVerifyMsg) 445 if !ok { 446 c.sendAlert(alertUnexpectedMessage) 447 return unexpectedMessageError(certVerify, msg) 448 } 449 450 // See RFC 8446, Section 4.4.3. 451 if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { 452 c.sendAlert(alertIllegalParameter) 453 return errors.New("tls: invalid certificate signature algorithm") 454 } 455 sigType := signatureFromSignatureScheme(certVerify.signatureAlgorithm) 456 sigHash, err := hashFromSignatureScheme(certVerify.signatureAlgorithm) 457 if sigType == 0 || err != nil { 458 c.sendAlert(alertInternalError) 459 return err 460 } 461 if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { 462 c.sendAlert(alertIllegalParameter) 463 return errors.New("tls: invalid certificate signature algorithm") 464 } 465 signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) 466 if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, 467 sigHash, signed, certVerify.signature); err != nil { 468 c.sendAlert(alertDecryptError) 469 return errors.New("tls: invalid certificate signature") 470 } 471 472 hs.transcript.Write(certVerify.marshal()) 473 474 return nil 475 } 476 477 func (hs *clientHandshakeStateTLS13) readServerFinished() error { 478 c := hs.c 479 480 msg, err := c.readHandshake() 481 if err != nil { 482 return err 483 } 484 485 finished, ok := msg.(*finishedMsg) 486 if !ok { 487 c.sendAlert(alertUnexpectedMessage) 488 return unexpectedMessageError(finished, msg) 489 } 490 491 expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) 492 if !hmac.Equal(expectedMAC, finished.verifyData) { 493 c.sendAlert(alertDecryptError) 494 return errors.New("tls: invalid server finished hash") 495 } 496 497 hs.transcript.Write(finished.marshal()) 498 499 // Derive secrets that take context through the server Finished. 500 501 hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, 502 clientApplicationTrafficLabel, hs.transcript) 503 serverSecret := hs.suite.deriveSecret(hs.masterSecret, 504 serverApplicationTrafficLabel, hs.transcript) 505 c.in.setTrafficSecret(hs.suite, serverSecret) 506 507 err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret) 508 if err != nil { 509 c.sendAlert(alertInternalError) 510 return err 511 } 512 err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret) 513 if err != nil { 514 c.sendAlert(alertInternalError) 515 return err 516 } 517 518 c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) 519 520 return nil 521 } 522 523 func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { 524 c := hs.c 525 526 if hs.certReq == nil { 527 return nil 528 } 529 530 cert, err := c.getClientCertificate(&CertificateRequestInfo{ 531 AcceptableCAs: hs.certReq.certificateAuthorities, 532 SignatureSchemes: hs.certReq.supportedSignatureAlgorithms, 533 }) 534 if err != nil { 535 return err 536 } 537 538 certMsg := new(certificateMsgTLS13) 539 540 certMsg.certificate = *cert 541 certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0 542 certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0 543 544 hs.transcript.Write(certMsg.marshal()) 545 if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { 546 return err 547 } 548 549 // If we sent an empty certificate message, skip the CertificateVerify. 550 if len(cert.Certificate) == 0 { 551 return nil 552 } 553 554 certVerifyMsg := new(certificateVerifyMsg) 555 certVerifyMsg.hasSignatureAlgorithm = true 556 557 supportedAlgs := signatureSchemesForCertificate(c.vers, cert) 558 if supportedAlgs == nil { 559 c.sendAlert(alertInternalError) 560 return unsupportedCertificateError(cert) 561 } 562 // Pick signature scheme in server preference order, as the client 563 // preference order is not configurable. 564 for _, preferredAlg := range hs.certReq.supportedSignatureAlgorithms { 565 if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { 566 certVerifyMsg.signatureAlgorithm = preferredAlg 567 break 568 } 569 } 570 if certVerifyMsg.signatureAlgorithm == 0 { 571 // getClientCertificate returned a certificate incompatible with the 572 // CertificateRequestInfo supported signature algorithms. 573 c.sendAlert(alertHandshakeFailure) 574 return errors.New("tls: server doesn't support selected certificate") 575 } 576 577 sigType := signatureFromSignatureScheme(certVerifyMsg.signatureAlgorithm) 578 sigHash, err := hashFromSignatureScheme(certVerifyMsg.signatureAlgorithm) 579 if sigType == 0 || err != nil { 580 return c.sendAlert(alertInternalError) 581 } 582 583 signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) 584 signOpts := crypto.SignerOpts(sigHash) 585 if sigType == signatureRSAPSS { 586 signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} 587 } 588 sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts) 589 if err != nil { 590 c.sendAlert(alertInternalError) 591 return errors.New("tls: failed to sign handshake: " + err.Error()) 592 } 593 certVerifyMsg.signature = sig 594 595 hs.transcript.Write(certVerifyMsg.marshal()) 596 if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { 597 return err 598 } 599 600 return nil 601 } 602 603 func (hs *clientHandshakeStateTLS13) sendClientFinished() error { 604 c := hs.c 605 606 finished := &finishedMsg{ 607 verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), 608 } 609 610 hs.transcript.Write(finished.marshal()) 611 if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { 612 return err 613 } 614 615 c.out.setTrafficSecret(hs.suite, hs.trafficSecret) 616 617 if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil { 618 c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret, 619 resumptionLabel, hs.transcript) 620 } 621 622 return nil 623 } 624 625 func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error { 626 if !c.isClient { 627 c.sendAlert(alertUnexpectedMessage) 628 return errors.New("tls: received new session ticket from a client") 629 } 630 631 if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { 632 return nil 633 } 634 635 // See RFC 8446, Section 4.6.1. 636 if msg.lifetime == 0 { 637 return nil 638 } 639 lifetime := time.Duration(msg.lifetime) * time.Second 640 if lifetime > maxSessionTicketLifetime { 641 c.sendAlert(alertIllegalParameter) 642 return errors.New("tls: received a session ticket with invalid lifetime") 643 } 644 645 cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite) 646 if cipherSuite == nil || c.resumptionSecret == nil { 647 return c.sendAlert(alertInternalError) 648 } 649 650 // Save the resumption_master_secret and nonce instead of deriving the PSK 651 // to do the least amount of work on NewSessionTicket messages before we 652 // know if the ticket will be used. Forward secrecy of resumed connections 653 // is guaranteed by the requirement for pskModeDHE. 654 session := &ClientSessionState{ 655 sessionTicket: msg.label, 656 vers: c.vers, 657 cipherSuite: c.cipherSuite, 658 masterSecret: c.resumptionSecret, 659 serverCertificates: c.peerCertificates, 660 verifiedChains: c.verifiedChains, 661 receivedAt: c.config.time(), 662 nonce: msg.nonce, 663 useBy: c.config.time().Add(lifetime), 664 ageAdd: msg.ageAdd, 665 } 666 667 cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config) 668 c.config.ClientSessionCache.Put(cacheKey, session) 669 670 return nil 671 }