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