github.com/hellobchain/newcryptosm@v0.0.0-20221019060107-edb949a317e9/tls/handshake_client.go (about) 1 /* 2 Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 package tls 17 18 import ( 19 "bytes" 20 "crypto" 21 "crypto/rsa" 22 "crypto/subtle" 23 "errors" 24 "fmt" 25 "github.com/hellobchain/newcryptosm/ecdsa" 26 x5092 "github.com/hellobchain/newcryptosm/x509" 27 "io" 28 "net" 29 "strconv" 30 "strings" 31 ) 32 33 type clientHandshakeState struct { 34 c *Conn 35 serverHello *serverHelloMsg 36 hello *clientHelloMsg 37 suite *cipherSuite 38 finishedHash finishedHash 39 masterSecret []byte 40 session *ClientSessionState 41 } 42 43 // c.out.Mutex <= L; c.handshakeMutex <= L. 44 func (c *Conn) clientHandshake() error { 45 if c.config == nil { 46 c.config = defaultConfig() 47 } 48 49 // This may be a renegotiation handshake, in which case some fields 50 // need to be reset. 51 c.didResume = false 52 53 if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify { 54 return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config") 55 } 56 57 nextProtosLength := 0 58 for _, proto := range c.config.NextProtos { 59 if l := len(proto); l == 0 || l > 255 { 60 return errors.New("tls: invalid NextProtos value") 61 } else { 62 nextProtosLength += 1 + l 63 } 64 } 65 if nextProtosLength > 0xffff { 66 return errors.New("tls: NextProtos values too large") 67 } 68 // client hello (random cipher suites supported proto version) 69 hello := &clientHelloMsg{ 70 vers: c.config.maxVersion(), 71 compressionMethods: []uint8{compressionNone}, 72 random: make([]byte, 32), 73 ocspStapling: true, 74 scts: true, 75 serverName: hostnameInSNI(c.config.ServerName), 76 supportedCurves: c.config.curvePreferences(), 77 supportedPoints: []uint8{pointFormatUncompressed}, 78 nextProtoNeg: len(c.config.NextProtos) > 0, 79 secureRenegotiationSupported: true, 80 alpnProtocols: c.config.NextProtos, 81 } 82 83 if c.handshakes > 0 { 84 hello.secureRenegotiation = c.clientFinished[:] 85 } 86 87 possibleCipherSuites := c.config.cipherSuites() 88 hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites)) 89 // generate cipher suites 90 NextCipherSuite: 91 for _, suiteId := range possibleCipherSuites { 92 for _, suite := range cipherSuites { 93 if suite.id != suiteId { 94 continue 95 } 96 // Don't advertise TLS 1.2-only cipher suites unless 97 // we're attempting TLS 1.2. 98 if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 { 99 continue 100 } 101 hello.cipherSuites = append(hello.cipherSuites, suiteId) 102 continue NextCipherSuite 103 } 104 } 105 // generate hello random 106 _, err := io.ReadFull(c.config.rand(), hello.random) 107 if err != nil { 108 c.sendAlert(alertInternalError) 109 return errors.New("tls: short read from Rand: " + err.Error()) 110 } 111 // signature alg 112 if hello.vers >= VersionTLS12 { 113 hello.signatureAndHashes = supportedSignatureAlgorithms // sm3 114 } 115 116 var session *ClientSessionState 117 var cacheKey string 118 sessionCache := c.config.ClientSessionCache 119 if c.config.SessionTicketsDisabled { 120 sessionCache = nil 121 } 122 123 if sessionCache != nil { 124 hello.ticketSupported = true 125 } 126 127 // Session resumption is not allowed if renegotiating because 128 // renegotiation is primarily used to allow a client to send a client 129 // certificate, which would be skipped if session resumption occurred. 130 if sessionCache != nil && c.handshakes == 0 { 131 // Try to resume a previously negotiated TLS session, if 132 // available. 133 cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config) 134 candidateSession, ok := sessionCache.Get(cacheKey) 135 if ok { 136 // Check that the ciphersuite/version used for the 137 // previous session are still valid. 138 cipherSuiteOk := false 139 for _, id := range hello.cipherSuites { 140 if id == candidateSession.cipherSuite { 141 cipherSuiteOk = true 142 break 143 } 144 } 145 146 versOk := candidateSession.vers >= c.config.minVersion() && 147 candidateSession.vers <= c.config.maxVersion() 148 if versOk && cipherSuiteOk { 149 session = candidateSession 150 } 151 } 152 } 153 154 if session != nil { 155 hello.sessionTicket = session.sessionTicket 156 // A random session ID is used to detect when the 157 // server accepted the ticket and is resuming a session 158 // (see RFC 5077). 159 hello.sessionId = make([]byte, 16) 160 if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil { 161 c.sendAlert(alertInternalError) 162 return errors.New("tls: short read from Rand: " + err.Error()) 163 } 164 } 165 // send server client hello 166 if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil { 167 return err 168 } 169 170 // read server hello 171 msg, err := c.readHandshake() // serverHello 172 if err != nil { 173 return err 174 } 175 serverHello, ok := msg.(*serverHelloMsg) 176 if !ok { 177 c.sendAlert(alertUnexpectedMessage) 178 return unexpectedMessageError(serverHello, msg) 179 } 180 181 vers, ok := c.config.mutualVersion(serverHello.vers) 182 if !ok || vers < VersionTLS10 { 183 // TLS 1.0 is the minimum version supported as a client. 184 c.sendAlert(alertProtocolVersion) 185 return fmt.Errorf("tls: server selected unsupported protocol version %x", serverHello.vers) 186 } 187 c.vers = vers 188 c.haveVers = true 189 190 suite := mutualCipherSuite(hello.cipherSuites, serverHello.cipherSuite) 191 if suite == nil { 192 c.sendAlert(alertHandshakeFailure) 193 return errors.New("tls: server chose an unconfigured cipher suite") 194 } 195 196 hs := &clientHandshakeState{ 197 c: c, 198 serverHello: serverHello, 199 hello: hello, 200 suite: suite, 201 finishedHash: newFinishedHash(c.vers, suite), 202 session: session, 203 } 204 isResume, err := hs.processServerHello() 205 if err != nil { 206 return err 207 } 208 209 // No signatures of the handshake are needed in a resumption. 210 // Otherwise, in a full handshake, if we don't have any certificates 211 // configured then we will never send a CertificateVerify message and 212 // thus no signatures are needed in that case either. 213 if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) { 214 hs.finishedHash.discardHandshakeBuffer() 215 } 216 hs.finishedHash.Write(hs.hello.marshal()) 217 hs.finishedHash.Write(hs.serverHello.marshal()) 218 219 c.buffering = true 220 if isResume { 221 if err := hs.establishKeys(); err != nil { 222 return err 223 } 224 if err := hs.readSessionTicket(); err != nil { 225 return err 226 } 227 if err := hs.readFinished(c.serverFinished[:]); err != nil { 228 return err 229 } 230 c.clientFinishedIsFirst = false 231 if err := hs.sendFinished(c.clientFinished[:]); err != nil { 232 return err 233 } 234 if _, err := c.flush(); err != nil { 235 return err 236 } 237 } else { 238 if err := hs.doFullHandshake(); err != nil { 239 return err 240 } 241 if err := hs.establishKeys(); err != nil { 242 return err 243 } 244 if err := hs.sendFinished(c.clientFinished[:]); err != nil { 245 return err 246 } 247 if _, err := c.flush(); err != nil { 248 return err 249 } 250 c.clientFinishedIsFirst = true 251 if err := hs.readSessionTicket(); err != nil { 252 return err 253 } 254 if err := hs.readFinished(c.serverFinished[:]); err != nil { 255 return err 256 } 257 } 258 259 if sessionCache != nil && hs.session != nil && session != hs.session { 260 sessionCache.Put(cacheKey, hs.session) 261 } 262 263 c.didResume = isResume 264 c.handshakeComplete = true 265 c.cipherSuite = suite.id 266 return nil 267 } 268 269 func (hs *clientHandshakeState) doFullHandshake() error { 270 c := hs.c 271 msg, err := c.readHandshake() 272 if err != nil { 273 return err 274 } 275 certMsg, ok := msg.(*certificateMsg) 276 if !ok || len(certMsg.certificates) == 0 { 277 c.sendAlert(alertUnexpectedMessage) 278 return unexpectedMessageError(certMsg, msg) 279 } 280 hs.finishedHash.Write(certMsg.marshal()) 281 282 if c.handshakes == 0 { 283 // If this is the first handshake on a connection, process and 284 // (optionally) verify the server's certificates. 285 certs := make([]*x5092.Certificate, len(certMsg.certificates)) 286 for i, asn1Data := range certMsg.certificates { 287 cert, err := x5092.ParseCertificate(asn1Data) 288 if err != nil { 289 c.sendAlert(alertBadCertificate) 290 return errors.New("tls: failed to parse certificate from server: " + err.Error()) 291 } 292 certs[i] = cert 293 } 294 295 if !c.config.InsecureSkipVerify { 296 opts := x5092.VerifyOptions{ 297 Roots: c.config.RootCAs, 298 CurrentTime: c.config.time(), 299 DNSName: c.config.ServerName, 300 Intermediates: x5092.NewCertPool(), 301 } 302 303 for i, cert := range certs { 304 if i == 0 { 305 continue 306 } 307 opts.Intermediates.AddCert(cert) 308 } 309 c.verifiedChains, err = certs[0].Verify(opts) 310 if err != nil { 311 c.sendAlert(alertBadCertificate) 312 return err 313 } 314 } 315 316 if c.config.VerifyPeerCertificate != nil { 317 if err := c.config.VerifyPeerCertificate(certMsg.certificates, c.verifiedChains); err != nil { 318 c.sendAlert(alertBadCertificate) 319 return err 320 } 321 } 322 323 switch certs[0].PublicKey.(type) { 324 case *rsa.PublicKey, *ecdsa.PublicKey: 325 break 326 default: 327 c.sendAlert(alertUnsupportedCertificate) 328 return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey) 329 } 330 331 c.peerCertificates = certs 332 } else { 333 // This is a renegotiation handshake. We require that the 334 // server's identity (i.e. leaf certificate) is unchanged and 335 // thus any previous trust decision is still valid. 336 // 337 // See https://mitls.org/pages/attacks/3SHAKE for the 338 // motivation behind this requirement. 339 if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) { 340 c.sendAlert(alertBadCertificate) 341 return errors.New("tls: server's identity changed during renegotiation") 342 } 343 } 344 345 if hs.serverHello.ocspStapling { 346 msg, err = c.readHandshake() 347 if err != nil { 348 return err 349 } 350 cs, ok := msg.(*certificateStatusMsg) 351 if !ok { 352 c.sendAlert(alertUnexpectedMessage) 353 return unexpectedMessageError(cs, msg) 354 } 355 hs.finishedHash.Write(cs.marshal()) 356 357 if cs.statusType == statusTypeOCSP { 358 c.ocspResponse = cs.response 359 } 360 } 361 msg, err = c.readHandshake() 362 if err != nil { 363 return err 364 } 365 keyAgreement := hs.suite.ka(c.vers) 366 367 skx, ok := msg.(*serverKeyExchangeMsg) 368 if ok { 369 hs.finishedHash.Write(skx.marshal()) 370 err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx) 371 if err != nil { 372 c.sendAlert(alertUnexpectedMessage) 373 return err 374 } 375 msg, err = c.readHandshake() 376 if err != nil { 377 return err 378 } 379 } 380 381 var chainToSend *Certificate 382 var certRequested bool 383 certReq, ok := msg.(*certificateRequestMsg) 384 if ok { 385 certRequested = true 386 hs.finishedHash.Write(certReq.marshal()) 387 388 if chainToSend, err = hs.getCertificate(certReq); err != nil { 389 c.sendAlert(alertInternalError) 390 return err 391 } 392 msg, err = c.readHandshake() 393 if err != nil { 394 return err 395 } 396 } 397 398 shd, ok := msg.(*serverHelloDoneMsg) 399 if !ok { 400 c.sendAlert(alertUnexpectedMessage) 401 return unexpectedMessageError(shd, msg) 402 } 403 hs.finishedHash.Write(shd.marshal()) 404 405 // If the server requested a certificate then we have to send a 406 // Certificate message, even if it's empty because we don't have a 407 // certificate to send. 408 if certRequested { 409 certMsg = new(certificateMsg) 410 certMsg.certificates = chainToSend.Certificate 411 hs.finishedHash.Write(certMsg.marshal()) 412 if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { 413 return err 414 } 415 } 416 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0]) 417 if err != nil { 418 c.sendAlert(alertInternalError) 419 return err 420 } 421 if ckx != nil { 422 hs.finishedHash.Write(ckx.marshal()) 423 if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil { 424 return err 425 } 426 } 427 428 if chainToSend != nil && len(chainToSend.Certificate) > 0 { 429 certVerify := &certificateVerifyMsg{ 430 hasSignatureAndHash: c.vers >= VersionTLS12, 431 } 432 433 key, ok := chainToSend.PrivateKey.(crypto.Signer) 434 if !ok { 435 c.sendAlert(alertInternalError) 436 return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey) 437 } 438 439 var signatureType uint8 440 switch key.Public().(type) { 441 case *ecdsa.PublicKey: 442 pub := key.Public().(*ecdsa.PublicKey) 443 if ecdsa.IsSM2(pub.Curve.Params()) { 444 signatureType = signatureSM2 445 } else { 446 signatureType = signatureECDSA 447 } 448 case *rsa.PublicKey: 449 signatureType = signatureRSA 450 default: 451 c.sendAlert(alertInternalError) 452 return fmt.Errorf("tls: failed to sign handshake with client certificate: unknown client certificate key type: %T", key) 453 } 454 455 certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureType) 456 if err != nil { 457 c.sendAlert(alertInternalError) 458 return err 459 } 460 digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret) 461 if err != nil { 462 c.sendAlert(alertInternalError) 463 return err 464 } 465 certVerify.signature, err = key.Sign(c.config.rand(), digest, hashFunc) 466 if err != nil { 467 c.sendAlert(alertInternalError) 468 return err 469 } 470 471 hs.finishedHash.Write(certVerify.marshal()) 472 if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil { 473 return err 474 } 475 } 476 477 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random) 478 if err := c.config.writeKeyLog(hs.hello.random, hs.masterSecret); err != nil { 479 c.sendAlert(alertInternalError) 480 return errors.New("tls: failed to write to key log: " + err.Error()) 481 } 482 483 hs.finishedHash.discardHandshakeBuffer() 484 485 return nil 486 } 487 488 func (hs *clientHandshakeState) establishKeys() error { 489 c := hs.c 490 491 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := 492 keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) 493 var clientCipher, serverCipher interface{} 494 var clientHash, serverHash macFunction 495 if hs.suite.cipher != nil { 496 clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */) 497 clientHash = hs.suite.mac(c.vers, clientMAC) 498 serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */) 499 serverHash = hs.suite.mac(c.vers, serverMAC) 500 } else { 501 clientCipher = hs.suite.aead(clientKey, clientIV) 502 serverCipher = hs.suite.aead(serverKey, serverIV) 503 } 504 505 c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) 506 c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) 507 return nil 508 } 509 510 func (hs *clientHandshakeState) serverResumedSession() bool { 511 // If the server responded with the same sessionId then it means the 512 // sessionTicket is being used to resume a TLS session. 513 return hs.session != nil && hs.hello.sessionId != nil && 514 bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId) 515 } 516 517 func (hs *clientHandshakeState) processServerHello() (bool, error) { 518 c := hs.c 519 520 if hs.serverHello.compressionMethod != compressionNone { 521 c.sendAlert(alertUnexpectedMessage) 522 return false, errors.New("tls: server selected unsupported compression format") 523 } 524 525 if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported { 526 c.secureRenegotiation = true 527 if len(hs.serverHello.secureRenegotiation) != 0 { 528 c.sendAlert(alertHandshakeFailure) 529 return false, errors.New("tls: initial handshake had non-empty renegotiation extension") 530 } 531 } 532 533 if c.handshakes > 0 && c.secureRenegotiation { 534 var expectedSecureRenegotiation [24]byte 535 copy(expectedSecureRenegotiation[:], c.clientFinished[:]) 536 copy(expectedSecureRenegotiation[12:], c.serverFinished[:]) 537 if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) { 538 c.sendAlert(alertHandshakeFailure) 539 return false, errors.New("tls: incorrect renegotiation extension contents") 540 } 541 } 542 543 clientDidNPN := hs.hello.nextProtoNeg 544 clientDidALPN := len(hs.hello.alpnProtocols) > 0 545 serverHasNPN := hs.serverHello.nextProtoNeg 546 serverHasALPN := len(hs.serverHello.alpnProtocol) > 0 547 548 if !clientDidNPN && serverHasNPN { 549 c.sendAlert(alertHandshakeFailure) 550 return false, errors.New("tls: server advertised unrequested NPN extension") 551 } 552 553 if !clientDidALPN && serverHasALPN { 554 c.sendAlert(alertHandshakeFailure) 555 return false, errors.New("tls: server advertised unrequested ALPN extension") 556 } 557 558 if serverHasNPN && serverHasALPN { 559 c.sendAlert(alertHandshakeFailure) 560 return false, errors.New("tls: server advertised both NPN and ALPN extensions") 561 } 562 563 if serverHasALPN { 564 c.clientProtocol = hs.serverHello.alpnProtocol 565 c.clientProtocolFallback = false 566 } 567 c.scts = hs.serverHello.scts 568 569 if !hs.serverResumedSession() { 570 return false, nil 571 } 572 573 if hs.session.vers != c.vers { 574 c.sendAlert(alertHandshakeFailure) 575 return false, errors.New("tls: server resumed a session with a different version") 576 } 577 578 if hs.session.cipherSuite != hs.suite.id { 579 c.sendAlert(alertHandshakeFailure) 580 return false, errors.New("tls: server resumed a session with a different cipher suite") 581 } 582 583 // Restore masterSecret and peerCerts from previous state 584 hs.masterSecret = hs.session.masterSecret 585 c.peerCertificates = hs.session.serverCertificates 586 c.verifiedChains = hs.session.verifiedChains 587 return true, nil 588 } 589 590 func (hs *clientHandshakeState) readFinished(out []byte) error { 591 c := hs.c 592 593 c.readRecord(recordTypeChangeCipherSpec) 594 if c.in.err != nil { 595 return c.in.err 596 } 597 598 msg, err := c.readHandshake() 599 if err != nil { 600 return err 601 } 602 serverFinished, ok := msg.(*finishedMsg) 603 if !ok { 604 c.sendAlert(alertUnexpectedMessage) 605 return unexpectedMessageError(serverFinished, msg) 606 } 607 608 verify := hs.finishedHash.serverSum(hs.masterSecret) 609 if len(verify) != len(serverFinished.verifyData) || 610 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { 611 c.sendAlert(alertHandshakeFailure) 612 return errors.New("tls: server's Finished message was incorrect") 613 } 614 hs.finishedHash.Write(serverFinished.marshal()) 615 copy(out, verify) 616 return nil 617 } 618 619 func (hs *clientHandshakeState) readSessionTicket() error { 620 if !hs.serverHello.ticketSupported { 621 return nil 622 } 623 624 c := hs.c 625 msg, err := c.readHandshake() 626 if err != nil { 627 return err 628 } 629 sessionTicketMsg, ok := msg.(*newSessionTicketMsg) 630 if !ok { 631 c.sendAlert(alertUnexpectedMessage) 632 return unexpectedMessageError(sessionTicketMsg, msg) 633 } 634 hs.finishedHash.Write(sessionTicketMsg.marshal()) 635 636 hs.session = &ClientSessionState{ 637 sessionTicket: sessionTicketMsg.ticket, 638 vers: c.vers, 639 cipherSuite: hs.suite.id, 640 masterSecret: hs.masterSecret, 641 serverCertificates: c.peerCertificates, 642 verifiedChains: c.verifiedChains, 643 } 644 645 return nil 646 } 647 648 func (hs *clientHandshakeState) sendFinished(out []byte) error { 649 c := hs.c 650 651 if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { 652 return err 653 } 654 if hs.serverHello.nextProtoNeg { 655 nextProto := new(nextProtoMsg) 656 proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos) 657 nextProto.proto = proto 658 c.clientProtocol = proto 659 c.clientProtocolFallback = fallback 660 661 hs.finishedHash.Write(nextProto.marshal()) 662 if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil { 663 return err 664 } 665 } 666 667 finished := new(finishedMsg) 668 finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) 669 hs.finishedHash.Write(finished.marshal()) 670 if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { 671 return err 672 } 673 copy(out, finished.verifyData) 674 return nil 675 } 676 677 // tls11SignatureSchemes contains the signature schemes that we synthesise for 678 // a TLS <= 1.1 connection, based on the supported certificate types. 679 var tls11SignatureSchemes = []SignatureScheme{SM2WithP256AndSM3} 680 681 const ( 682 // tls11SignatureSchemesNumECDSA is the number of initial elements of 683 // tls11SignatureSchemes that use ECDSA. 684 tls11SignatureSchemesNumECDSA = 3 685 // tls11SignatureSchemesNumRSA is the number of trailing elements of 686 // tls11SignatureSchemes that use RSA. 687 tls11SignatureSchemesNumRSA = 4 688 // tls11SignatureSchemesNumRSA is the number of trailing elements of 689 // tls11SignatureSchemes that use SM2. 690 tls11SignatureSchemesNumSM2 = 5 691 ) 692 693 func (hs *clientHandshakeState) getCertificate(certReq *certificateRequestMsg) (*Certificate, error) { 694 c := hs.c 695 696 var rsaAvail, ecdsaAvail, sm2Avail bool 697 for _, certType := range certReq.certificateTypes { 698 switch certType { 699 case certTypeRSASign: 700 rsaAvail = true 701 case certTypeECDSASign: 702 ecdsaAvail = true 703 case certTypeSM2Sign: 704 sm2Avail = true 705 } 706 } 707 708 if c.config.GetClientCertificate != nil { 709 var signatureSchemes []SignatureScheme 710 711 if !certReq.hasSignatureAndHash { 712 // Prior to TLS 1.2, the signature schemes were not 713 // included in the certificate request message. In this 714 // case we use a plausible list based on the acceptable 715 // certificate types. 716 signatureSchemes = tls11SignatureSchemes 717 if !ecdsaAvail { 718 signatureSchemes = signatureSchemes[tls11SignatureSchemesNumECDSA:] 719 } 720 if !rsaAvail { 721 signatureSchemes = signatureSchemes[:len(signatureSchemes)-tls11SignatureSchemesNumRSA] 722 } 723 if !sm2Avail { // wsw add 724 signatureSchemes = signatureSchemes[:len(signatureSchemes)-tls11SignatureSchemesNumSM2] 725 } 726 } else { 727 signatureSchemes = make([]SignatureScheme, 0, len(certReq.signatureAndHashes)) 728 for _, sah := range certReq.signatureAndHashes { 729 signatureSchemes = append(signatureSchemes, SignatureScheme(sah.hash)<<8+SignatureScheme(sah.signature)) 730 } 731 } 732 733 return c.config.GetClientCertificate(&CertificateRequestInfo{ 734 AcceptableCAs: certReq.certificateAuthorities, 735 SignatureSchemes: signatureSchemes, 736 }) 737 } 738 739 // RFC 4346 on the certificateAuthorities field: A list of the 740 // distinguished names of acceptable certificate authorities. 741 // These distinguished names may specify a desired 742 // distinguished name for a root CA or for a subordinate CA; 743 // thus, this message can be used to describe both known roots 744 // and a desired authorization space. If the 745 // certificate_authorities list is empty then the client MAY 746 // send any certificate of the appropriate 747 // ClientCertificateType, unless there is some external 748 // arrangement to the contrary. 749 750 // We need to search our list of client certs for one 751 // where SignatureAlgorithm is acceptable to the server and the 752 // Issuer is in certReq.certificateAuthorities 753 findCert: 754 for i, chain := range c.config.Certificates { 755 if !rsaAvail && !ecdsaAvail && !sm2Avail { // wsw add 756 continue 757 } 758 759 for j, cert := range chain.Certificate { 760 x509Cert := chain.Leaf 761 // parse the certificate if this isn't the leaf 762 // node, or if chain.Leaf was nil 763 if j != 0 || x509Cert == nil { 764 var err error 765 if x509Cert, err = x5092.ParseCertificate(cert); err != nil { 766 c.sendAlert(alertInternalError) 767 return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) 768 } 769 } 770 771 switch { 772 case rsaAvail && x509Cert.PublicKeyAlgorithm == x5092.RSA: 773 case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x5092.ECDSA: 774 case sm2Avail && x509Cert.PublicKeyAlgorithm == x5092.SM2: 775 default: 776 continue findCert 777 } 778 779 if len(certReq.certificateAuthorities) == 0 { 780 // they gave us an empty list, so just take the 781 // first cert from c.config.Certificates 782 return &chain, nil 783 } 784 785 for _, ca := range certReq.certificateAuthorities { 786 if bytes.Equal(x509Cert.RawIssuer, ca) { 787 return &chain, nil 788 } 789 } 790 } 791 } 792 793 // No acceptable certificate found. Don't send a certificate. 794 return new(Certificate), nil 795 } 796 797 // clientSessionCacheKey returns a key used to cache sessionTickets that could 798 // be used to resume previously negotiated TLS sessions with a server. 799 func clientSessionCacheKey(serverAddr net.Addr, config *Config) string { 800 if len(config.ServerName) > 0 { 801 return config.ServerName 802 } 803 return serverAddr.String() 804 } 805 806 // mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol 807 // given list of possible protocols and a list of the preference order. The 808 // first list must not be empty. It returns the resulting protocol and flag 809 // indicating if the fallback case was reached. 810 func mutualProtocol(protos, preferenceProtos []string) (string, bool) { 811 for _, s := range preferenceProtos { 812 for _, c := range protos { 813 if s == c { 814 return s, false 815 } 816 } 817 } 818 819 return protos[0], true 820 } 821 822 // hostnameInSNI converts name into an approriate hostname for SNI. 823 // Literal IP addresses and absolute FQDNs are not permitted as SNI values. 824 // See https://tools.ietf.org/html/rfc6066#section-3. 825 func hostnameInSNI(name string) string { 826 host := name 827 if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' { 828 host = host[1 : len(host)-1] 829 } 830 if i := strings.LastIndex(host, "%"); i > 0 { 831 host = host[:i] 832 } 833 if net.ParseIP(host) != nil { 834 return "" 835 } 836 if len(name) > 0 && name[len(name)-1] == '.' { 837 name = name[:len(name)-1] 838 } 839 return name 840 }