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