github.com/Hyperledger-TWGC/tjfoc-gm@v1.4.0/gmtls/handshake_server.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 gmtls 17 18 import ( 19 "crypto" 20 "crypto/ecdsa" 21 "crypto/rsa" 22 "crypto/subtle" 23 "errors" 24 "fmt" 25 "io" 26 27 "github.com/Hyperledger-TWGC/tjfoc-gm/x509" 28 ) 29 30 // serverHandshakeState contains details of a server handshake in progress. 31 // It's discarded once the handshake has completed. 32 type serverHandshakeState struct { 33 c *Conn 34 clientHello *clientHelloMsg 35 hello *serverHelloMsg 36 suite *cipherSuite 37 ellipticOk bool 38 ecdsaOk bool 39 rsaDecryptOk bool 40 rsaSignOk bool 41 sessionState *sessionState 42 finishedHash finishedHash 43 masterSecret []byte 44 certsFromClient [][]byte 45 cert *Certificate 46 cachedClientHelloInfo *ClientHelloInfo 47 } 48 49 // serverHandshake performs a TLS handshake as a server. 50 // c.out.Mutex <= L; c.handshakeMutex <= L. 51 func (c *Conn) serverHandshake() error { 52 // If this is the first server handshake, we generate a random key to 53 // encrypt the tickets with. 54 c.config.serverInitOnce.Do(func() { c.config.serverInit(nil) }) 55 56 hs := serverHandshakeState{ 57 c: c, 58 } 59 isResume, err := hs.readClientHello() 60 if err != nil { 61 return err 62 } 63 64 // For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3 65 c.buffering = true 66 if isResume { 67 // The client has included a session ticket and so we do an abbreviated handshake. 68 if err := hs.doResumeHandshake(); err != nil { 69 return err 70 } 71 if err := hs.establishKeys(); err != nil { 72 return err 73 } 74 // ticketSupported is set in a resumption handshake if the 75 // ticket from the client was encrypted with an old session 76 // ticket key and thus a refreshed ticket should be sent. 77 if hs.hello.ticketSupported { 78 if err := hs.sendSessionTicket(); err != nil { 79 return err 80 } 81 } 82 if err := hs.sendFinished(c.serverFinished[:]); err != nil { 83 return err 84 } 85 if _, err := c.flush(); err != nil { 86 return err 87 } 88 c.clientFinishedIsFirst = false 89 if err := hs.readFinished(nil); err != nil { 90 return err 91 } 92 c.didResume = true 93 } else { 94 // The client didn't include a session ticket, or it wasn't 95 // valid so we do a full handshake. 96 if err := hs.doFullHandshake(); err != nil { 97 return err 98 } 99 if err := hs.establishKeys(); err != nil { 100 return err 101 } 102 if err := hs.readFinished(c.clientFinished[:]); err != nil { 103 return err 104 } 105 c.clientFinishedIsFirst = true 106 c.buffering = true 107 if err := hs.sendSessionTicket(); err != nil { 108 return err 109 } 110 if err := hs.sendFinished(nil); err != nil { 111 return err 112 } 113 if _, err := c.flush(); err != nil { 114 return err 115 } 116 } 117 return nil 118 } 119 120 // readClientHello reads a ClientHello message from the client and decides 121 // whether we will perform session resumption. 122 func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) { 123 c := hs.c 124 125 msg, err := c.readHandshake() 126 if err != nil { 127 return false, err 128 } 129 var ok bool 130 hs.clientHello, ok = msg.(*clientHelloMsg) 131 if !ok { 132 c.sendAlert(alertUnexpectedMessage) 133 return false, unexpectedMessageError(hs.clientHello, msg) 134 } 135 136 if c.config.GetConfigForClient != nil { 137 if newConfig, err := c.config.GetConfigForClient(hs.clientHelloInfo()); err != nil { 138 c.sendAlert(alertInternalError) 139 return false, err 140 } else if newConfig != nil { 141 newConfig.serverInitOnce.Do(func() { newConfig.serverInit(c.config) }) 142 c.config = newConfig 143 } 144 } 145 146 c.vers, ok = c.config.mutualVersion(hs.clientHello.vers) 147 if !ok { 148 c.sendAlert(alertProtocolVersion) 149 return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers) 150 } 151 c.haveVers = true 152 153 hs.hello = new(serverHelloMsg) 154 155 supportedCurve := false 156 preferredCurves := c.config.curvePreferences() 157 Curves: 158 for _, curve := range hs.clientHello.supportedCurves { 159 for _, supported := range preferredCurves { 160 if supported == curve { 161 supportedCurve = true 162 break Curves 163 } 164 } 165 } 166 167 supportedPointFormat := false 168 for _, pointFormat := range hs.clientHello.supportedPoints { 169 if pointFormat == pointFormatUncompressed { 170 supportedPointFormat = true 171 break 172 } 173 } 174 hs.ellipticOk = supportedCurve && supportedPointFormat 175 176 foundCompression := false 177 // We only support null compression, so check that the client offered it. 178 for _, compression := range hs.clientHello.compressionMethods { 179 if compression == compressionNone { 180 foundCompression = true 181 break 182 } 183 } 184 185 if !foundCompression { 186 c.sendAlert(alertHandshakeFailure) 187 return false, errors.New("tls: client does not support uncompressed connections") 188 } 189 190 hs.hello.vers = c.vers 191 hs.hello.random = make([]byte, 32) 192 _, err = io.ReadFull(c.config.rand(), hs.hello.random) 193 if err != nil { 194 c.sendAlert(alertInternalError) 195 return false, err 196 } 197 198 if len(hs.clientHello.secureRenegotiation) != 0 { 199 c.sendAlert(alertHandshakeFailure) 200 return false, errors.New("tls: initial handshake had non-empty renegotiation extension") 201 } 202 203 hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported 204 hs.hello.compressionMethod = compressionNone 205 if len(hs.clientHello.serverName) > 0 { 206 c.serverName = hs.clientHello.serverName 207 } 208 209 if len(hs.clientHello.alpnProtocols) > 0 { 210 if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback { 211 hs.hello.alpnProtocol = selectedProto 212 c.clientProtocol = selectedProto 213 } 214 } else { 215 // Although sending an empty NPN extension is reasonable, Firefox has 216 // had a bug around this. Best to send nothing at all if 217 // c.config.NextProtos is empty. See 218 // https://golang.org/issue/5445. 219 if hs.clientHello.nextProtoNeg && len(c.config.NextProtos) > 0 { 220 hs.hello.nextProtoNeg = true 221 hs.hello.nextProtos = c.config.NextProtos 222 } 223 } 224 225 hs.cert, err = c.config.getCertificate(hs.clientHelloInfo()) 226 if err != nil { 227 c.sendAlert(alertInternalError) 228 return false, err 229 } 230 if hs.clientHello.scts { 231 hs.hello.scts = hs.cert.SignedCertificateTimestamps 232 } 233 234 if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok { 235 switch priv.Public().(type) { 236 case *ecdsa.PublicKey: 237 hs.ecdsaOk = true 238 case *rsa.PublicKey: 239 hs.rsaSignOk = true 240 default: 241 c.sendAlert(alertInternalError) 242 return false, fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public()) 243 } 244 } 245 if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok { 246 switch priv.Public().(type) { 247 case *rsa.PublicKey: 248 hs.rsaDecryptOk = true 249 default: 250 c.sendAlert(alertInternalError) 251 return false, fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public()) 252 } 253 } 254 255 if hs.checkForResumption() { 256 return true, nil 257 } 258 259 var preferenceList, supportedList []uint16 260 if c.config.PreferServerCipherSuites { 261 preferenceList = c.config.cipherSuites() 262 supportedList = hs.clientHello.cipherSuites 263 } else { 264 preferenceList = hs.clientHello.cipherSuites 265 supportedList = c.config.cipherSuites() 266 } 267 268 for _, id := range preferenceList { 269 if hs.setCipherSuite(id, supportedList, c.vers) { 270 break 271 } 272 } 273 274 if hs.suite == nil { 275 c.sendAlert(alertHandshakeFailure) 276 return false, errors.New("tls: no cipher suite supported by both client and server") 277 } 278 279 // See https://tools.ietf.org/html/rfc7507. 280 for _, id := range hs.clientHello.cipherSuites { 281 if id == TLS_FALLBACK_SCSV { 282 // The client is doing a fallback connection. 283 if hs.clientHello.vers < c.config.maxVersion() { 284 c.sendAlert(alertInappropriateFallback) 285 return false, errors.New("tls: client using inappropriate protocol fallback") 286 } 287 break 288 } 289 } 290 291 return false, nil 292 } 293 294 // checkForResumption reports whether we should perform resumption on this connection. 295 func (hs *serverHandshakeState) checkForResumption() bool { 296 c := hs.c 297 298 if c.config.SessionTicketsDisabled { 299 return false 300 } 301 302 var ok bool 303 var sessionTicket = append([]uint8{}, hs.clientHello.sessionTicket...) 304 if hs.sessionState, ok = c.decryptTicket(sessionTicket); !ok { 305 return false 306 } 307 308 // Never resume a session for a different TLS version. 309 if c.vers != hs.sessionState.vers { 310 return false 311 } 312 313 cipherSuiteOk := false 314 // Check that the client is still offering the ciphersuite in the session. 315 for _, id := range hs.clientHello.cipherSuites { 316 if id == hs.sessionState.cipherSuite { 317 cipherSuiteOk = true 318 break 319 } 320 } 321 if !cipherSuiteOk { 322 return false 323 } 324 325 // Check that we also support the ciphersuite from the session. 326 if !hs.setCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers) { 327 return false 328 } 329 330 sessionHasClientCerts := len(hs.sessionState.certificates) != 0 331 needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert 332 if needClientCerts && !sessionHasClientCerts { 333 return false 334 } 335 if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { 336 return false 337 } 338 339 return true 340 } 341 342 func (hs *serverHandshakeState) doResumeHandshake() error { 343 c := hs.c 344 345 hs.hello.cipherSuite = hs.suite.id 346 // We echo the client's session ID in the ServerHello to let it know 347 // that we're doing a resumption. 348 hs.hello.sessionId = hs.clientHello.sessionId 349 hs.hello.ticketSupported = hs.sessionState.usedOldKey 350 hs.finishedHash = newFinishedHash(c.vers, hs.suite) 351 hs.finishedHash.discardHandshakeBuffer() 352 hs.finishedHash.Write(hs.clientHello.marshal()) 353 hs.finishedHash.Write(hs.hello.marshal()) 354 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 355 return err 356 } 357 358 if len(hs.sessionState.certificates) > 0 { 359 if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil { 360 return err 361 } 362 } 363 364 hs.masterSecret = hs.sessionState.masterSecret 365 366 return nil 367 } 368 369 func (hs *serverHandshakeState) doFullHandshake() error { 370 c := hs.c 371 372 if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 { 373 hs.hello.ocspStapling = true 374 } 375 376 hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled 377 hs.hello.cipherSuite = hs.suite.id 378 379 hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite) 380 if c.config.ClientAuth == NoClientCert { 381 // No need to keep a full record of the handshake if client 382 // certificates won't be used. 383 hs.finishedHash.discardHandshakeBuffer() 384 } 385 hs.finishedHash.Write(hs.clientHello.marshal()) 386 hs.finishedHash.Write(hs.hello.marshal()) 387 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 388 return err 389 } 390 391 certMsg := new(certificateMsg) 392 certMsg.certificates = hs.cert.Certificate 393 hs.finishedHash.Write(certMsg.marshal()) 394 if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { 395 return err 396 } 397 398 if hs.hello.ocspStapling { 399 certStatus := new(certificateStatusMsg) 400 certStatus.statusType = statusTypeOCSP 401 certStatus.response = hs.cert.OCSPStaple 402 hs.finishedHash.Write(certStatus.marshal()) 403 if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil { 404 return err 405 } 406 } 407 408 keyAgreement := hs.suite.ka(c.vers) 409 skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert,hs.cert, hs.clientHello, hs.hello) 410 if err != nil { 411 c.sendAlert(alertHandshakeFailure) 412 return err 413 } 414 if skx != nil { 415 hs.finishedHash.Write(skx.marshal()) 416 if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil { 417 return err 418 } 419 } 420 421 if c.config.ClientAuth >= RequestClientCert { 422 // Request a client certificate 423 certReq := new(certificateRequestMsg) 424 certReq.certificateTypes = []byte{ 425 byte(certTypeRSASign), 426 byte(certTypeECDSASign), 427 } 428 if c.vers >= VersionTLS12 { 429 certReq.hasSignatureAndHash = true 430 certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms 431 } 432 433 // An empty list of certificateAuthorities signals to 434 // the client that it may send any certificate in response 435 // to our request. When we know the CAs we trust, then 436 // we can send them down, so that the client can choose 437 // an appropriate certificate to give to us. 438 if c.config.ClientCAs != nil { 439 certReq.certificateAuthorities = c.config.ClientCAs.Subjects() 440 } 441 hs.finishedHash.Write(certReq.marshal()) 442 if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { 443 return err 444 } 445 } 446 447 helloDone := new(serverHelloDoneMsg) 448 hs.finishedHash.Write(helloDone.marshal()) 449 if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil { 450 return err 451 } 452 453 if _, err := c.flush(); err != nil { 454 return err 455 } 456 457 var pub crypto.PublicKey // public key for client auth, if any 458 459 msg, err := c.readHandshake() 460 if err != nil { 461 return err 462 } 463 464 var ok bool 465 // If we requested a client certificate, then the client must send a 466 // certificate message, even if it's empty. 467 if c.config.ClientAuth >= RequestClientCert { 468 if certMsg, ok = msg.(*certificateMsg); !ok { 469 c.sendAlert(alertUnexpectedMessage) 470 return unexpectedMessageError(certMsg, msg) 471 } 472 hs.finishedHash.Write(certMsg.marshal()) 473 474 if len(certMsg.certificates) == 0 { 475 // The client didn't actually send a certificate 476 switch c.config.ClientAuth { 477 case RequireAnyClientCert, RequireAndVerifyClientCert: 478 c.sendAlert(alertBadCertificate) 479 return errors.New("tls: client didn't provide a certificate") 480 } 481 } 482 483 pub, err = hs.processCertsFromClient(certMsg.certificates) 484 if err != nil { 485 return err 486 } 487 488 msg, err = c.readHandshake() 489 if err != nil { 490 return err 491 } 492 } 493 494 // Get client key exchange 495 ckx, ok := msg.(*clientKeyExchangeMsg) 496 if !ok { 497 c.sendAlert(alertUnexpectedMessage) 498 return unexpectedMessageError(ckx, msg) 499 } 500 hs.finishedHash.Write(ckx.marshal()) 501 502 preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers) 503 if err != nil { 504 c.sendAlert(alertHandshakeFailure) 505 return err 506 } 507 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random) 508 if err := c.config.writeKeyLog(hs.clientHello.random, hs.masterSecret); err != nil { 509 c.sendAlert(alertInternalError) 510 return err 511 } 512 513 // If we received a client cert in response to our certificate request message, 514 // the client will send us a certificateVerifyMsg immediately after the 515 // clientKeyExchangeMsg. This message is a digest of all preceding 516 // handshake-layer messages that is signed using the private key corresponding 517 // to the client's certificate. This allows us to verify that the client is in 518 // possession of the private key of the certificate. 519 if len(c.peerCertificates) > 0 { 520 msg, err = c.readHandshake() 521 if err != nil { 522 return err 523 } 524 certVerify, ok := msg.(*certificateVerifyMsg) 525 if !ok { 526 c.sendAlert(alertUnexpectedMessage) 527 return unexpectedMessageError(certVerify, msg) 528 } 529 530 // Determine the signature type. 531 _, sigType, hashFunc, err := pickSignatureAlgorithm(pub, []SignatureScheme{certVerify.signatureAlgorithm}, supportedSignatureAlgorithms, c.vers) 532 if err != nil { 533 c.sendAlert(alertIllegalParameter) 534 return err 535 } 536 537 var digest []byte 538 if digest, err = hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret); err == nil { 539 err = verifyHandshakeSignature(sigType, pub, hashFunc, digest, certVerify.signature) 540 } 541 if err != nil { 542 c.sendAlert(alertBadCertificate) 543 return errors.New("tls: could not validate signature of connection nonces: " + err.Error()) 544 } 545 546 hs.finishedHash.Write(certVerify.marshal()) 547 } 548 549 hs.finishedHash.discardHandshakeBuffer() 550 551 return nil 552 } 553 554 func (hs *serverHandshakeState) establishKeys() error { 555 c := hs.c 556 557 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := 558 keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) 559 560 var clientCipher, serverCipher interface{} 561 var clientHash, serverHash macFunction 562 563 if hs.suite.aead == nil { 564 clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) 565 clientHash = hs.suite.mac(c.vers, clientMAC) 566 serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) 567 serverHash = hs.suite.mac(c.vers, serverMAC) 568 } else { 569 clientCipher = hs.suite.aead(clientKey, clientIV) 570 serverCipher = hs.suite.aead(serverKey, serverIV) 571 } 572 573 c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) 574 c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) 575 576 return nil 577 } 578 579 func (hs *serverHandshakeState) readFinished(out []byte) error { 580 c := hs.c 581 582 c.readRecord(recordTypeChangeCipherSpec) 583 if c.in.err != nil { 584 return c.in.err 585 } 586 587 if hs.hello.nextProtoNeg { 588 msg, err := c.readHandshake() 589 if err != nil { 590 return err 591 } 592 nextProto, ok := msg.(*nextProtoMsg) 593 if !ok { 594 c.sendAlert(alertUnexpectedMessage) 595 return unexpectedMessageError(nextProto, msg) 596 } 597 hs.finishedHash.Write(nextProto.marshal()) 598 c.clientProtocol = nextProto.proto 599 } 600 601 msg, err := c.readHandshake() 602 if err != nil { 603 return err 604 } 605 clientFinished, ok := msg.(*finishedMsg) 606 if !ok { 607 c.sendAlert(alertUnexpectedMessage) 608 return unexpectedMessageError(clientFinished, msg) 609 } 610 611 verify := hs.finishedHash.clientSum(hs.masterSecret) 612 if len(verify) != len(clientFinished.verifyData) || 613 subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { 614 c.sendAlert(alertHandshakeFailure) 615 return errors.New("tls: client's Finished message is incorrect") 616 } 617 618 hs.finishedHash.Write(clientFinished.marshal()) 619 copy(out, verify) 620 return nil 621 } 622 623 func (hs *serverHandshakeState) sendSessionTicket() error { 624 if !hs.hello.ticketSupported { 625 return nil 626 } 627 628 c := hs.c 629 m := new(newSessionTicketMsg) 630 631 var err error 632 state := sessionState{ 633 vers: c.vers, 634 cipherSuite: hs.suite.id, 635 masterSecret: hs.masterSecret, 636 certificates: hs.certsFromClient, 637 } 638 m.ticket, err = c.encryptTicket(&state) 639 if err != nil { 640 return err 641 } 642 643 hs.finishedHash.Write(m.marshal()) 644 if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { 645 return err 646 } 647 648 return nil 649 } 650 651 func (hs *serverHandshakeState) sendFinished(out []byte) error { 652 c := hs.c 653 654 if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { 655 return err 656 } 657 658 finished := new(finishedMsg) 659 finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) 660 hs.finishedHash.Write(finished.marshal()) 661 if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { 662 return err 663 } 664 665 c.cipherSuite = hs.suite.id 666 copy(out, finished.verifyData) 667 668 return nil 669 } 670 671 // processCertsFromClient takes a chain of client certificates either from a 672 // Certificates message or from a sessionState and verifies them. It returns 673 // the public key of the leaf certificate. 674 func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) { 675 c := hs.c 676 677 hs.certsFromClient = certificates 678 certs := make([]*x509.Certificate, len(certificates)) 679 var err error 680 for i, asn1Data := range certificates { 681 if certs[i], err = x509.ParseCertificate(asn1Data); err != nil { 682 c.sendAlert(alertBadCertificate) 683 return nil, errors.New("tls: failed to parse client certificate: " + err.Error()) 684 } 685 } 686 687 if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 { 688 opts := x509.VerifyOptions{ 689 Roots: c.config.ClientCAs, 690 CurrentTime: c.config.time(), 691 Intermediates: x509.NewCertPool(), 692 KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, 693 } 694 695 for _, cert := range certs[1:] { 696 opts.Intermediates.AddCert(cert) 697 } 698 699 chains, err := certs[0].Verify(opts) 700 if err != nil { 701 c.sendAlert(alertBadCertificate) 702 return nil, errors.New("tls: failed to verify client's certificate: " + err.Error()) 703 } 704 705 c.verifiedChains = chains 706 } 707 708 if c.config.VerifyPeerCertificate != nil { 709 if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { 710 c.sendAlert(alertBadCertificate) 711 return nil, err 712 } 713 } 714 715 if len(certs) == 0 { 716 return nil, nil 717 } 718 719 var pub crypto.PublicKey 720 switch key := certs[0].PublicKey.(type) { 721 case *ecdsa.PublicKey, *rsa.PublicKey: 722 pub = key 723 default: 724 c.sendAlert(alertUnsupportedCertificate) 725 return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey) 726 } 727 c.peerCertificates = certs 728 return pub, nil 729 } 730 731 // setCipherSuite sets a cipherSuite with the given id as the serverHandshakeState 732 // suite if that cipher suite is acceptable to use. 733 // It returns a bool indicating if the suite was set. 734 func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16) bool { 735 for _, supported := range supportedCipherSuites { 736 if id == supported { 737 var candidate *cipherSuite 738 739 for _, s := range cipherSuites { 740 if s.id == id { 741 candidate = s 742 break 743 } 744 } 745 if candidate == nil { 746 continue 747 } 748 // Don't select a ciphersuite which we can't 749 // support for this client. 750 if candidate.flags&suiteECDHE != 0 { 751 if !hs.ellipticOk { 752 continue 753 } 754 if candidate.flags&suiteECDSA != 0 { 755 if !hs.ecdsaOk { 756 continue 757 } 758 } else if !hs.rsaSignOk { 759 continue 760 } 761 } else if !hs.rsaDecryptOk { 762 continue 763 } 764 if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { 765 continue 766 } 767 hs.suite = candidate 768 return true 769 } 770 } 771 return false 772 } 773 774 // suppVersArray is the backing array of ClientHelloInfo.SupportedVersions 775 var suppVersArray = [...]uint16{VersionTLS12, VersionTLS11, VersionTLS10, VersionSSL30} 776 777 func (hs *serverHandshakeState) clientHelloInfo() *ClientHelloInfo { 778 if hs.cachedClientHelloInfo != nil { 779 return hs.cachedClientHelloInfo 780 } 781 782 var supportedVersions []uint16 783 if hs.clientHello.vers > VersionTLS12 { 784 supportedVersions = suppVersArray[:] 785 } else if hs.clientHello.vers >= VersionSSL30 { 786 supportedVersions = suppVersArray[VersionTLS12-hs.clientHello.vers:] 787 } 788 789 hs.cachedClientHelloInfo = &ClientHelloInfo{ 790 CipherSuites: hs.clientHello.cipherSuites, 791 ServerName: hs.clientHello.serverName, 792 SupportedCurves: hs.clientHello.supportedCurves, 793 SupportedPoints: hs.clientHello.supportedPoints, 794 SignatureSchemes: hs.clientHello.supportedSignatureAlgorithms, 795 SupportedProtos: hs.clientHello.alpnProtocols, 796 SupportedVersions: supportedVersions, 797 Conn: hs.c.conn, 798 } 799 800 return hs.cachedClientHelloInfo 801 }