gitee.com/lh-her-team/common@v1.5.1/crypto/tls/gm_handshake_server.go (about) 1 // Copyright 2009 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 "crypto" 9 "crypto/ecdsa" 10 "crypto/ed25519" 11 "crypto/rsa" 12 "crypto/subtle" 13 gox509 "crypto/x509" 14 "errors" 15 "fmt" 16 "io" 17 "sync/atomic" 18 19 cmx509 "gitee.com/lh-her-team/common/crypto/x509" 20 "github.com/tjfoc/gmsm/sm2" 21 ) 22 23 // serverHandshakeStateGM contains details of a server handshake in progress. 24 // It's discarded once the handshake has completed. 25 type serverHandshakeStateGM struct { 26 c *Conn 27 clientHello *clientHelloMsg 28 hello *serverHelloMsg 29 suite *cipherSuite 30 sessionState *sessionState 31 finishedHash finishedHash 32 masterSecret []byte 33 certsFromClient [][]byte 34 cert []Certificate 35 cachedClientHelloInfo *ClientHelloInfo 36 } 37 38 // serverHandshake performs a TLS handshake as a server. 39 func (c *Conn) serverHandshakeGM() error { 40 // If this is the first server handshake, we generate a random key to 41 // encrypt the tickets with. 42 c.config.serverInitOnce.Do(func() { c.config.serverInit(nil) }) 43 hs := serverHandshakeStateGM{ 44 c: c, 45 } 46 isResume, err := hs.readClientHello() 47 if err != nil { 48 return err 49 } 50 // For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3 51 c.buffering = true 52 if isResume { 53 // The client has included a session ticket and so we do an abbreviated handshake. 54 if err := hs.doResumeHandshake(); err != nil { 55 return err 56 } 57 if err := hs.establishKeys(); err != nil { 58 return err 59 } 60 // ticketSupported is set in a resumption handshake if the 61 // ticket from the client was encrypted with an old session 62 // ticket key and thus a refreshed ticket should be sent. 63 if hs.hello.ticketSupported { 64 if err := hs.sendSessionTicket(); err != nil { 65 return err 66 } 67 } 68 if err := hs.sendFinished(c.serverFinished[:]); err != nil { 69 return err 70 } 71 if _, err := c.flush(); err != nil { 72 return err 73 } 74 c.clientFinishedIsFirst = false 75 if err := hs.readFinished(nil); err != nil { 76 return err 77 } 78 c.didResume = true 79 } else { 80 // The client didn't include a session ticket, or it wasn't 81 // valid so we do a full handshake. 82 if err := hs.doFullHandshake(); err != nil { 83 return err 84 } 85 if err := hs.establishKeys(); err != nil { 86 return err 87 } 88 if err := hs.readFinished(c.clientFinished[:]); err != nil { 89 return err 90 } 91 c.clientFinishedIsFirst = true 92 c.buffering = true 93 if err := hs.sendSessionTicket(); err != nil { 94 return err 95 } 96 if err := hs.sendFinished(nil); err != nil { 97 return err 98 } 99 if _, err := c.flush(); err != nil { 100 return err 101 } 102 } 103 c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random) 104 atomic.StoreUint32(&c.handshakeStatus, 1) 105 return nil 106 } 107 108 // readClientHello reads a ClientHello message from the client and decides 109 // whether we will perform session resumption. 110 func (hs *serverHandshakeStateGM) readClientHello() (isResume bool, err error) { 111 c := hs.c 112 msg, err := c.readHandshake() 113 if err != nil { 114 return false, err 115 } 116 var ok bool 117 hs.clientHello, ok = msg.(*clientHelloMsg) 118 if !ok { 119 c.sendAlert(alertUnexpectedMessage) 120 return false, unexpectedMessageError(hs.clientHello, msg) 121 } 122 if c.config.GetConfigForClient != nil { 123 if newConfig, err := c.config.GetConfigForClient(hs.clientHelloInfo()); err != nil { 124 c.sendAlert(alertInternalError) 125 return false, err 126 } else if newConfig != nil { 127 newConfig.serverInitOnce.Do(func() { newConfig.serverInit(c.config) }) 128 c.config = newConfig 129 } 130 } 131 c.vers, ok = c.config.mutualVersion([]uint16{hs.clientHello.vers}) 132 if !ok { 133 c.sendAlert(alertProtocolVersion) 134 return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers) 135 } 136 c.haveVers = true 137 hs.hello = new(serverHelloMsg) 138 foundCompression := false 139 // We only support null compression, so check that the client offered it. 140 for _, compression := range hs.clientHello.compressionMethods { 141 if compression == compressionNone { 142 foundCompression = true 143 break 144 } 145 } 146 if !foundCompression { 147 c.sendAlert(alertHandshakeFailure) 148 return false, errors.New("tls: client does not support uncompressed connections") 149 } 150 hs.hello.vers = c.vers 151 hs.hello.random = make([]byte, 32) 152 _, err = io.ReadFull(c.config.rand(), hs.hello.random) 153 if err != nil { 154 c.sendAlert(alertInternalError) 155 return false, err 156 } 157 if len(hs.clientHello.secureRenegotiation) != 0 { 158 c.sendAlert(alertHandshakeFailure) 159 return false, errors.New("tls: initial handshake had non-empty renegotiation extension") 160 } 161 hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported 162 hs.hello.compressionMethod = compressionNone 163 if len(hs.clientHello.serverName) > 0 { 164 c.serverName = hs.clientHello.serverName 165 } 166 if len(hs.clientHello.alpnProtocols) > 0 { 167 if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback { 168 hs.hello.alpnProtocol = selectedProto 169 c.clientProtocol = selectedProto 170 } 171 } 172 c.config.getCertificate(hs.clientHelloInfo()) 173 hs.cert = c.config.Certificates 174 // GMT0024 175 if c.config.GMSupport.EncCertEnable && len(hs.cert) < 2 { 176 c.sendAlert(alertInternalError) 177 return false, fmt.Errorf("tls: amount of server certificates must be greater than 2, which will sign and encipher respectively") 178 } else if len(hs.cert) < 1 { 179 c.sendAlert(alertInternalError) 180 return false, fmt.Errorf("tls: amount of server certificates must be greater than 0") 181 } 182 if hs.clientHello.scts { 183 hs.hello.scts = hs.cert[0].SignedCertificateTimestamps 184 } 185 if hs.checkForResumption() { 186 return true, nil 187 } 188 var preferenceList, supportedList []uint16 189 if c.config.PreferServerCipherSuites { 190 preferenceList = getCipherSuites(c.config) 191 supportedList = hs.clientHello.cipherSuites 192 } else { 193 preferenceList = hs.clientHello.cipherSuites 194 supportedList = getCipherSuites(c.config) 195 } 196 for _, id := range preferenceList { 197 if hs.setCipherSuite(id, supportedList, c.vers) { 198 break 199 } 200 } 201 if hs.suite == nil { 202 c.sendAlert(alertHandshakeFailure) 203 return false, errors.New("tls: no cipher suite supported by both client and server") 204 } 205 // See https://tools.ietf.org/html/rfc7507. 206 for _, id := range hs.clientHello.cipherSuites { 207 if id == TLS_FALLBACK_SCSV { 208 // The client is doing a fallback connection. 209 if hs.clientHello.vers < c.config.maxVersion() { 210 c.sendAlert(alertInappropriateFallback) 211 return false, errors.New("tls: client using inappropriate protocol fallback") 212 } 213 break 214 } 215 } 216 return false, nil 217 } 218 219 // checkForResumption reports whether we should perform resumption on this connection. 220 func (hs *serverHandshakeStateGM) checkForResumption() bool { 221 c := hs.c 222 if c.config.SessionTicketsDisabled { 223 return false 224 } 225 plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket) 226 if plaintext == nil { 227 return false 228 } 229 hs.sessionState = &sessionState{usedOldKey: usedOldKey} 230 ok := hs.sessionState.unmarshal(plaintext) 231 if !ok { 232 return false 233 } 234 // Never resume a session for a different TLS version. 235 if c.vers != hs.sessionState.vers { 236 return false 237 } 238 cipherSuiteOk := false 239 // Check that the client is still offering the ciphersuite in the session. 240 for _, id := range hs.clientHello.cipherSuites { 241 if id == hs.sessionState.cipherSuite { 242 cipherSuiteOk = true 243 break 244 } 245 } 246 if !cipherSuiteOk { 247 return false 248 } 249 // Check that we also support the ciphersuite from the session. 250 if !hs.setCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers) { 251 return false 252 } 253 sessionHasClientCerts := len(hs.sessionState.certificates) != 0 254 needClientCerts := requiresClientCert(c.config.ClientAuth) 255 if needClientCerts && !sessionHasClientCerts { 256 return false 257 } 258 if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { 259 return false 260 } 261 return true 262 } 263 264 func (hs *serverHandshakeStateGM) doResumeHandshake() error { 265 c := hs.c 266 hs.hello.cipherSuite = hs.suite.id 267 // We echo the client's session ID in the ServerHello to let it know 268 // that we're doing a resumption. 269 hs.hello.sessionId = hs.clientHello.sessionId 270 hs.hello.ticketSupported = hs.sessionState.usedOldKey 271 hs.finishedHash = newFinishedHash(c.vers, hs.suite) 272 hs.finishedHash.discardHandshakeBuffer() 273 hs.finishedHash.Write(hs.clientHello.marshal()) 274 hs.finishedHash.Write(hs.hello.marshal()) 275 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 276 return err 277 } 278 if len(hs.sessionState.certificates) > 0 { 279 if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil { 280 return err 281 } 282 } 283 hs.masterSecret = hs.sessionState.masterSecret 284 return nil 285 } 286 287 func (hs *serverHandshakeStateGM) doFullHandshake() error { 288 c := hs.c 289 if hs.clientHello.ocspStapling && len(hs.cert[0].OCSPStaple) > 0 { 290 hs.hello.ocspStapling = true 291 } 292 hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled 293 hs.hello.cipherSuite = hs.suite.id 294 hs.finishedHash = newFinishedHashGM(hs.suite) 295 if c.config.ClientAuth == NoClientCert { 296 // No need to keep a full record of the handshake if client 297 // certificates won't be used. 298 hs.finishedHash.discardHandshakeBuffer() 299 } 300 hs.finishedHash.Write(hs.clientHello.marshal()) 301 hs.finishedHash.Write(hs.hello.marshal()) 302 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 303 return err 304 } 305 certMsg := new(certificateMsg) 306 //certMsg.certificates = hs.cert.Certificate 307 for i := 0; i < len(hs.cert); i++ { 308 certMsg.certificates = append(certMsg.certificates, hs.cert[i].Certificate...) 309 } 310 hs.finishedHash.Write(certMsg.marshal()) 311 if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { 312 return err 313 } 314 if hs.hello.ocspStapling { 315 certStatus := new(certificateStatusMsg) 316 certStatus.response = hs.cert[0].OCSPStaple 317 hs.finishedHash.Write(certStatus.marshal()) 318 if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil { 319 return err 320 } 321 } 322 keyAgreement := hs.suite.ka(c.vers) 323 var ( 324 skx *serverKeyExchangeMsg 325 err error 326 ) 327 if c.config.GMSupport.EncCertEnable { 328 skx, err = keyAgreement.generateServerKeyExchange(c.config, &hs.cert[0], &hs.cert[1], hs.clientHello, hs.hello) 329 } else { 330 skx, err = keyAgreement.generateServerKeyExchange(c.config, &hs.cert[0], &hs.cert[0], hs.clientHello, hs.hello) 331 } 332 if err != nil { 333 c.sendAlert(alertHandshakeFailure) 334 return err 335 } 336 if skx != nil { 337 hs.finishedHash.Write(skx.marshal()) 338 if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil { 339 return err 340 } 341 } 342 if c.config.ClientAuth >= RequestClientCert { 343 // Request a client certificate 344 certReq := new(certificateRequestMsgGM) 345 certReq.certificateTypes = []byte{ 346 byte(certTypeRSASign), 347 byte(certTypeECDSASign), 348 } 349 //if c.vers >= VersionTLS12 { 350 // certReq.hasSignatureAndHash = true 351 // certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms 352 //} 353 354 // An empty list of certificateAuthorities signals to 355 // the client that it may send any certificate in response 356 // to our request. When we know the CAs we trust, then 357 // we can send them down, so that the client can choose 358 // an appropriate certificate to give to us. 359 if c.config.ClientCAs != nil { 360 certReq.certificateAuthorities = c.config.ClientCAs.Subjects() 361 } 362 hs.finishedHash.Write(certReq.marshal()) 363 if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { 364 return err 365 } 366 } 367 helloDone := new(serverHelloDoneMsg) 368 hs.finishedHash.Write(helloDone.marshal()) 369 if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil { 370 return err 371 } 372 if _, err := c.flush(); err != nil { 373 return err 374 } 375 var pub crypto.PublicKey // public key for client auth, if any 376 msg, err := c.readHandshake() 377 if err != nil { 378 fmt.Println("readHandshake error:", err) 379 return err 380 } 381 var ok bool 382 // If we requested a client certificate, then the client must send a 383 // certificate message, even if it's empty. 384 if c.config.ClientAuth >= RequestClientCert { 385 if certMsg, ok = msg.(*certificateMsg); !ok { 386 c.sendAlert(alertUnexpectedMessage) 387 return unexpectedMessageError(certMsg, msg) 388 } 389 hs.finishedHash.Write(certMsg.marshal()) 390 if len(certMsg.certificates) == 0 { 391 // The client didn't actually send a certificate 392 switch c.config.ClientAuth { 393 case RequireAnyClientCert, RequireAndVerifyClientCert: 394 c.sendAlert(alertBadCertificate) 395 return errors.New("tls: client didn't provide a certificate") 396 } 397 } 398 pub, err = hs.processCertsFromClient(certMsg.certificates) 399 if err != nil { 400 return err 401 } 402 msg, err = c.readHandshake() 403 if err != nil { 404 return err 405 } 406 } 407 // Get client key exchange 408 ckx, ok := msg.(*clientKeyExchangeMsg) 409 if !ok { 410 c.sendAlert(alertUnexpectedMessage) 411 return unexpectedMessageError(ckx, msg) 412 } 413 hs.finishedHash.Write(ckx.marshal()) 414 var ( 415 preMasterSecret []byte 416 ) 417 if c.config.GMSupport.EncCertEnable { 418 preMasterSecret, err = keyAgreement.processClientKeyExchange(c.config, &hs.cert[1], ckx, c.vers) 419 } else { 420 preMasterSecret, err = keyAgreement.processClientKeyExchange(c.config, &hs.cert[0], ckx, c.vers) 421 } 422 if err != nil { 423 c.sendAlert(alertHandshakeFailure) 424 return err 425 } 426 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random) 427 if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil { 428 c.sendAlert(alertInternalError) 429 return err 430 } 431 // If we received a client cert in response to our certificate request message, 432 // the client will send us a certificateVerifyMsg immediately after the 433 // clientKeyExchangeMsg. This message is a digest of all preceding 434 // handshake-layer messages that is signed using the private key corresponding 435 // to the client's certificate. This allows us to verify that the client is in 436 // possession of the private key of the certificate. 437 if len(c.peerCertificates) > 0 { 438 msg, err = c.readHandshake() 439 if err != nil { 440 return err 441 } 442 certVerify, ok := msg.(*certificateVerifyMsg) 443 if !ok { 444 c.sendAlert(alertUnexpectedMessage) 445 return unexpectedMessageError(certVerify, msg) 446 } 447 // Determine the signature type. 448 sigType, hashFunc, err := typeAndHashFromSignatureScheme(SM2WithSM3) 449 if err != nil { 450 return c.sendAlert(alertInternalError) 451 } 452 var digest = hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret) 453 if err = verifyHandshakeSignature(sigType, pub, hashFunc, digest, certVerify.signature); err != nil { 454 c.sendAlert(alertBadCertificate) 455 return errors.New("tls: could not validate signature of connection nonces: " + err.Error()) 456 } 457 hs.finishedHash.Write(certVerify.marshal()) 458 } 459 hs.finishedHash.discardHandshakeBuffer() 460 return nil 461 } 462 463 func (hs *serverHandshakeStateGM) establishKeys() error { 464 c := hs.c 465 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := 466 keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) 467 var clientCipher, serverCipher interface{} 468 var clientHash, serverHash macFunction 469 if hs.suite.aead == nil { 470 clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) 471 clientHash = hs.suite.mac(c.vers, clientMAC) 472 serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) 473 serverHash = hs.suite.mac(c.vers, serverMAC) 474 } else { 475 clientCipher = hs.suite.aead(clientKey, clientIV) 476 serverCipher = hs.suite.aead(serverKey, serverIV) 477 } 478 c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) 479 c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) 480 return nil 481 } 482 483 func (hs *serverHandshakeStateGM) readFinished(out []byte) error { 484 c := hs.c 485 if err := c.readChangeCipherSpec(); err != nil { 486 return err 487 } 488 msg, err := c.readHandshake() 489 if err != nil { 490 return err 491 } 492 clientFinished, ok := msg.(*finishedMsg) 493 if !ok { 494 c.sendAlert(alertUnexpectedMessage) 495 return unexpectedMessageError(clientFinished, msg) 496 } 497 verify := hs.finishedHash.clientSum(hs.masterSecret) 498 if len(verify) != len(clientFinished.verifyData) || 499 subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { 500 c.sendAlert(alertHandshakeFailure) 501 return errors.New("tls: client's Finished message is incorrect") 502 } 503 hs.finishedHash.Write(clientFinished.marshal()) 504 copy(out, verify) 505 return nil 506 } 507 508 func (hs *serverHandshakeStateGM) sendSessionTicket() error { 509 if !hs.hello.ticketSupported { 510 return nil 511 } 512 c := hs.c 513 m := new(newSessionTicketMsg) 514 state := sessionState{ 515 vers: c.vers, 516 cipherSuite: hs.suite.id, 517 masterSecret: hs.masterSecret, 518 certificates: hs.certsFromClient, 519 } 520 var err error 521 m.ticket, err = c.encryptTicket(state.marshal()) 522 if err != nil { 523 return err 524 } 525 hs.finishedHash.Write(m.marshal()) 526 if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { 527 return err 528 } 529 return nil 530 } 531 532 func (hs *serverHandshakeStateGM) sendFinished(out []byte) error { 533 c := hs.c 534 if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { 535 return err 536 } 537 finished := new(finishedMsg) 538 finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) 539 hs.finishedHash.Write(finished.marshal()) 540 if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { 541 return err 542 } 543 c.cipherSuite = hs.suite.id 544 copy(out, finished.verifyData) 545 return nil 546 } 547 548 // processCertsFromClient takes a chain of client certificates either from a 549 // Certificates message or from a sessionState and verifies them. It returns 550 // the public key of the leaf certificate. 551 func (hs *serverHandshakeStateGM) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) { 552 c := hs.c 553 hs.certsFromClient = certificates 554 certs := make([]*cmx509.Certificate, len(certificates)) 555 var err error 556 for i, asn1Data := range certificates { 557 if certs[i], err = cmx509.ParseCertificate(asn1Data); err != nil { 558 c.sendAlert(alertBadCertificate) 559 return nil, errors.New("tls: failed to parse client certificate: " + err.Error()) 560 } 561 } 562 if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 { 563 opts := cmx509.VerifyOptions{ 564 Roots: c.config.ClientCAs, 565 CurrentTime: c.config.time(), 566 Intermediates: cmx509.NewCertPool(), 567 KeyUsages: []gox509.ExtKeyUsage{gox509.ExtKeyUsageClientAuth}, 568 } 569 for _, cert := range certs[1:] { 570 opts.Intermediates.AddCert(cert) 571 } 572 chains, err := certs[0].Verify(opts) 573 if err != nil { 574 c.sendAlert(alertBadCertificate) 575 return nil, errors.New("tls: failed to verify client certificate: " + err.Error()) 576 } 577 c.verifiedChains = chains 578 } 579 if c.config.VerifyPeerCertificate != nil { 580 if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { 581 c.sendAlert(alertBadCertificate) 582 return nil, err 583 } 584 } 585 if len(certs) == 0 { 586 return nil, nil 587 } 588 x509Cert0, _ := cmx509.HerbtCertToX509Cert(certs[0]) 589 var pub crypto.PublicKey 590 switch key := x509Cert0.PublicKey.(type) { 591 case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey, *sm2.PublicKey: 592 pub = key 593 default: 594 c.sendAlert(alertUnsupportedCertificate) 595 return nil, fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey) 596 } 597 c.peerCertificates = certs 598 return pub, nil 599 } 600 601 // setCipherSuite sets a cipherSuite with the given id as the serverHandshakeStateGM 602 // suite if that cipher suite is acceptable to use. 603 // It returns a bool indicating if the suite was set. 604 func (hs *serverHandshakeStateGM) setCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16) bool { 605 for _, supported := range supportedCipherSuites { 606 if id == supported { 607 var candidate *cipherSuite 608 for _, s := range gmCipherSuites { 609 if s.id == id { 610 candidate = s 611 break 612 } 613 } 614 if candidate == nil { 615 continue 616 } 617 if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { 618 continue 619 } 620 hs.suite = candidate 621 return true 622 } 623 } 624 return false 625 } 626 627 func (hs *serverHandshakeStateGM) clientHelloInfo() *ClientHelloInfo { 628 if hs.cachedClientHelloInfo != nil { 629 return hs.cachedClientHelloInfo 630 } 631 // supportedVersions only include VersionGMSSL 632 supportedVersions := []uint16{VersionGMSSL} 633 hs.cachedClientHelloInfo = &ClientHelloInfo{ 634 CipherSuites: hs.clientHello.cipherSuites, 635 ServerName: hs.clientHello.serverName, 636 SupportedCurves: hs.clientHello.supportedCurves, 637 SupportedPoints: hs.clientHello.supportedPoints, 638 SignatureSchemes: hs.clientHello.supportedSignatureAlgorithms, 639 SupportedProtos: hs.clientHello.alpnProtocols, 640 SupportedVersions: supportedVersions, 641 Conn: hs.c.conn, 642 } 643 return hs.cachedClientHelloInfo 644 }