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