github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/src/crypto/tls/handshake_client.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 "bytes" 9 "crypto" 10 "crypto/ecdsa" 11 "crypto/rsa" 12 "crypto/subtle" 13 "crypto/x509" 14 "errors" 15 "fmt" 16 "io" 17 "net" 18 "strconv" 19 ) 20 21 type clientHandshakeState struct { 22 c *Conn 23 serverHello *serverHelloMsg 24 hello *clientHelloMsg 25 suite *cipherSuite 26 finishedHash finishedHash 27 masterSecret []byte 28 session *ClientSessionState 29 } 30 31 func (c *Conn) clientHandshake() error { 32 if c.config == nil { 33 c.config = defaultConfig() 34 } 35 36 if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify { 37 return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config") 38 } 39 40 nextProtosLength := 0 41 for _, proto := range c.config.NextProtos { 42 if l := len(proto); l == 0 || l > 255 { 43 return errors.New("tls: invalid NextProtos value") 44 } else { 45 nextProtosLength += 1 + l 46 } 47 } 48 if nextProtosLength > 0xffff { 49 return errors.New("tls: NextProtos values too large") 50 } 51 52 sni := c.config.ServerName 53 // IP address literals are not permitted as SNI values. See 54 // https://tools.ietf.org/html/rfc6066#section-3. 55 if net.ParseIP(sni) != nil { 56 sni = "" 57 } 58 59 hello := &clientHelloMsg{ 60 vers: c.config.maxVersion(), 61 compressionMethods: []uint8{compressionNone}, 62 random: make([]byte, 32), 63 ocspStapling: true, 64 scts: true, 65 serverName: sni, 66 supportedCurves: c.config.curvePreferences(), 67 supportedPoints: []uint8{pointFormatUncompressed}, 68 nextProtoNeg: len(c.config.NextProtos) > 0, 69 secureRenegotiation: true, 70 alpnProtocols: c.config.NextProtos, 71 } 72 73 possibleCipherSuites := c.config.cipherSuites() 74 hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites)) 75 76 NextCipherSuite: 77 for _, suiteId := range possibleCipherSuites { 78 for _, suite := range cipherSuites { 79 if suite.id != suiteId { 80 continue 81 } 82 // Don't advertise TLS 1.2-only cipher suites unless 83 // we're attempting TLS 1.2. 84 if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 { 85 continue 86 } 87 hello.cipherSuites = append(hello.cipherSuites, suiteId) 88 continue NextCipherSuite 89 } 90 } 91 92 _, err := io.ReadFull(c.config.rand(), hello.random) 93 if err != nil { 94 c.sendAlert(alertInternalError) 95 return errors.New("tls: short read from Rand: " + err.Error()) 96 } 97 98 if hello.vers >= VersionTLS12 { 99 hello.signatureAndHashes = supportedSignatureAlgorithms 100 } 101 102 var session *ClientSessionState 103 var cacheKey string 104 sessionCache := c.config.ClientSessionCache 105 if c.config.SessionTicketsDisabled { 106 sessionCache = nil 107 } 108 109 if sessionCache != nil { 110 hello.ticketSupported = true 111 112 // Try to resume a previously negotiated TLS session, if 113 // available. 114 cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config) 115 candidateSession, ok := sessionCache.Get(cacheKey) 116 if ok { 117 // Check that the ciphersuite/version used for the 118 // previous session are still valid. 119 cipherSuiteOk := false 120 for _, id := range hello.cipherSuites { 121 if id == candidateSession.cipherSuite { 122 cipherSuiteOk = true 123 break 124 } 125 } 126 127 versOk := candidateSession.vers >= c.config.minVersion() && 128 candidateSession.vers <= c.config.maxVersion() 129 if versOk && cipherSuiteOk { 130 session = candidateSession 131 } 132 } 133 } 134 135 if session != nil { 136 hello.sessionTicket = session.sessionTicket 137 // A random session ID is used to detect when the 138 // server accepted the ticket and is resuming a session 139 // (see RFC 5077). 140 hello.sessionId = make([]byte, 16) 141 if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil { 142 c.sendAlert(alertInternalError) 143 return errors.New("tls: short read from Rand: " + err.Error()) 144 } 145 } 146 147 c.writeRecord(recordTypeHandshake, hello.marshal()) 148 149 msg, err := c.readHandshake() 150 if err != nil { 151 return err 152 } 153 serverHello, ok := msg.(*serverHelloMsg) 154 if !ok { 155 c.sendAlert(alertUnexpectedMessage) 156 return unexpectedMessageError(serverHello, msg) 157 } 158 159 vers, ok := c.config.mutualVersion(serverHello.vers) 160 if !ok || vers < VersionTLS10 { 161 // TLS 1.0 is the minimum version supported as a client. 162 c.sendAlert(alertProtocolVersion) 163 return fmt.Errorf("tls: server selected unsupported protocol version %x", serverHello.vers) 164 } 165 c.vers = vers 166 c.haveVers = true 167 168 suite := mutualCipherSuite(hello.cipherSuites, serverHello.cipherSuite) 169 if suite == nil { 170 c.sendAlert(alertHandshakeFailure) 171 return errors.New("tls: server chose an unconfigured cipher suite") 172 } 173 174 hs := &clientHandshakeState{ 175 c: c, 176 serverHello: serverHello, 177 hello: hello, 178 suite: suite, 179 finishedHash: newFinishedHash(c.vers, suite), 180 session: session, 181 } 182 183 isResume, err := hs.processServerHello() 184 if err != nil { 185 return err 186 } 187 188 // No signatures of the handshake are needed in a resumption. 189 // Otherwise, in a full handshake, if we don't have any certificates 190 // configured then we will never send a CertificateVerify message and 191 // thus no signatures are needed in that case either. 192 if isResume || len(c.config.Certificates) == 0 { 193 hs.finishedHash.discardHandshakeBuffer() 194 } 195 196 hs.finishedHash.Write(hs.hello.marshal()) 197 hs.finishedHash.Write(hs.serverHello.marshal()) 198 199 if isResume { 200 if err := hs.establishKeys(); err != nil { 201 return err 202 } 203 if err := hs.readSessionTicket(); err != nil { 204 return err 205 } 206 if err := hs.readFinished(c.firstFinished[:]); err != nil { 207 return err 208 } 209 if err := hs.sendFinished(nil); err != nil { 210 return err 211 } 212 } else { 213 if err := hs.doFullHandshake(); err != nil { 214 return err 215 } 216 if err := hs.establishKeys(); err != nil { 217 return err 218 } 219 if err := hs.sendFinished(c.firstFinished[:]); err != nil { 220 return err 221 } 222 if err := hs.readSessionTicket(); err != nil { 223 return err 224 } 225 if err := hs.readFinished(nil); err != nil { 226 return err 227 } 228 } 229 230 if sessionCache != nil && hs.session != nil && session != hs.session { 231 sessionCache.Put(cacheKey, hs.session) 232 } 233 234 c.didResume = isResume 235 c.handshakeComplete = true 236 c.cipherSuite = suite.id 237 return nil 238 } 239 240 func (hs *clientHandshakeState) doFullHandshake() error { 241 c := hs.c 242 243 msg, err := c.readHandshake() 244 if err != nil { 245 return err 246 } 247 certMsg, ok := msg.(*certificateMsg) 248 if !ok || len(certMsg.certificates) == 0 { 249 c.sendAlert(alertUnexpectedMessage) 250 return unexpectedMessageError(certMsg, msg) 251 } 252 hs.finishedHash.Write(certMsg.marshal()) 253 254 certs := make([]*x509.Certificate, len(certMsg.certificates)) 255 for i, asn1Data := range certMsg.certificates { 256 cert, err := x509.ParseCertificate(asn1Data) 257 if err != nil { 258 c.sendAlert(alertBadCertificate) 259 return errors.New("tls: failed to parse certificate from server: " + err.Error()) 260 } 261 certs[i] = cert 262 } 263 264 if !c.config.InsecureSkipVerify { 265 opts := x509.VerifyOptions{ 266 Roots: c.config.RootCAs, 267 CurrentTime: c.config.time(), 268 DNSName: c.config.ServerName, 269 Intermediates: x509.NewCertPool(), 270 } 271 272 for i, cert := range certs { 273 if i == 0 { 274 continue 275 } 276 opts.Intermediates.AddCert(cert) 277 } 278 c.verifiedChains, err = certs[0].Verify(opts) 279 if err != nil { 280 c.sendAlert(alertBadCertificate) 281 return err 282 } 283 } 284 285 switch certs[0].PublicKey.(type) { 286 case *rsa.PublicKey, *ecdsa.PublicKey: 287 break 288 default: 289 c.sendAlert(alertUnsupportedCertificate) 290 return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey) 291 } 292 293 c.peerCertificates = certs 294 295 if hs.serverHello.ocspStapling { 296 msg, err = c.readHandshake() 297 if err != nil { 298 return err 299 } 300 cs, ok := msg.(*certificateStatusMsg) 301 if !ok { 302 c.sendAlert(alertUnexpectedMessage) 303 return unexpectedMessageError(cs, msg) 304 } 305 hs.finishedHash.Write(cs.marshal()) 306 307 if cs.statusType == statusTypeOCSP { 308 c.ocspResponse = cs.response 309 } 310 } 311 312 msg, err = c.readHandshake() 313 if err != nil { 314 return err 315 } 316 317 keyAgreement := hs.suite.ka(c.vers) 318 319 skx, ok := msg.(*serverKeyExchangeMsg) 320 if ok { 321 hs.finishedHash.Write(skx.marshal()) 322 err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, certs[0], skx) 323 if err != nil { 324 c.sendAlert(alertUnexpectedMessage) 325 return err 326 } 327 328 msg, err = c.readHandshake() 329 if err != nil { 330 return err 331 } 332 } 333 334 var chainToSend *Certificate 335 var certRequested bool 336 certReq, ok := msg.(*certificateRequestMsg) 337 if ok { 338 certRequested = true 339 340 // RFC 4346 on the certificateAuthorities field: 341 // A list of the distinguished names of acceptable certificate 342 // authorities. These distinguished names may specify a desired 343 // distinguished name for a root CA or for a subordinate CA; 344 // thus, this message can be used to describe both known roots 345 // and a desired authorization space. If the 346 // certificate_authorities list is empty then the client MAY 347 // send any certificate of the appropriate 348 // ClientCertificateType, unless there is some external 349 // arrangement to the contrary. 350 351 hs.finishedHash.Write(certReq.marshal()) 352 353 var rsaAvail, ecdsaAvail bool 354 for _, certType := range certReq.certificateTypes { 355 switch certType { 356 case certTypeRSASign: 357 rsaAvail = true 358 case certTypeECDSASign: 359 ecdsaAvail = true 360 } 361 } 362 363 // We need to search our list of client certs for one 364 // where SignatureAlgorithm is acceptable to the server and the 365 // Issuer is in certReq.certificateAuthorities 366 findCert: 367 for i, chain := range c.config.Certificates { 368 if !rsaAvail && !ecdsaAvail { 369 continue 370 } 371 372 for j, cert := range chain.Certificate { 373 x509Cert := chain.Leaf 374 // parse the certificate if this isn't the leaf 375 // node, or if chain.Leaf was nil 376 if j != 0 || x509Cert == nil { 377 if x509Cert, err = x509.ParseCertificate(cert); err != nil { 378 c.sendAlert(alertInternalError) 379 return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) 380 } 381 } 382 383 switch { 384 case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA: 385 case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA: 386 default: 387 continue findCert 388 } 389 390 if len(certReq.certificateAuthorities) == 0 { 391 // they gave us an empty list, so just take the 392 // first cert from c.config.Certificates 393 chainToSend = &chain 394 break findCert 395 } 396 397 for _, ca := range certReq.certificateAuthorities { 398 if bytes.Equal(x509Cert.RawIssuer, ca) { 399 chainToSend = &chain 400 break findCert 401 } 402 } 403 } 404 } 405 406 msg, err = c.readHandshake() 407 if err != nil { 408 return err 409 } 410 } 411 412 shd, ok := msg.(*serverHelloDoneMsg) 413 if !ok { 414 c.sendAlert(alertUnexpectedMessage) 415 return unexpectedMessageError(shd, msg) 416 } 417 hs.finishedHash.Write(shd.marshal()) 418 419 // If the server requested a certificate then we have to send a 420 // Certificate message, even if it's empty because we don't have a 421 // certificate to send. 422 if certRequested { 423 certMsg = new(certificateMsg) 424 if chainToSend != nil { 425 certMsg.certificates = chainToSend.Certificate 426 } 427 hs.finishedHash.Write(certMsg.marshal()) 428 c.writeRecord(recordTypeHandshake, certMsg.marshal()) 429 } 430 431 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, certs[0]) 432 if err != nil { 433 c.sendAlert(alertInternalError) 434 return err 435 } 436 if ckx != nil { 437 hs.finishedHash.Write(ckx.marshal()) 438 c.writeRecord(recordTypeHandshake, ckx.marshal()) 439 } 440 441 if chainToSend != nil { 442 certVerify := &certificateVerifyMsg{ 443 hasSignatureAndHash: c.vers >= VersionTLS12, 444 } 445 446 key, ok := chainToSend.PrivateKey.(crypto.Signer) 447 if !ok { 448 c.sendAlert(alertInternalError) 449 return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey) 450 } 451 452 var signatureType uint8 453 switch key.Public().(type) { 454 case *ecdsa.PublicKey: 455 signatureType = signatureECDSA 456 case *rsa.PublicKey: 457 signatureType = signatureRSA 458 default: 459 c.sendAlert(alertInternalError) 460 return fmt.Errorf("tls: failed to sign handshake with client certificate: unknown client certificate key type: %T", key) 461 } 462 463 certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureType) 464 if err != nil { 465 c.sendAlert(alertInternalError) 466 return err 467 } 468 digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret) 469 if err != nil { 470 c.sendAlert(alertInternalError) 471 return err 472 } 473 certVerify.signature, err = key.Sign(c.config.rand(), digest, hashFunc) 474 if err != nil { 475 c.sendAlert(alertInternalError) 476 return err 477 } 478 479 hs.finishedHash.Write(certVerify.marshal()) 480 c.writeRecord(recordTypeHandshake, certVerify.marshal()) 481 } 482 483 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random) 484 485 hs.finishedHash.discardHandshakeBuffer() 486 487 return nil 488 } 489 490 func (hs *clientHandshakeState) establishKeys() error { 491 c := hs.c 492 493 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := 494 keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) 495 var clientCipher, serverCipher interface{} 496 var clientHash, serverHash macFunction 497 if hs.suite.cipher != nil { 498 clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */) 499 clientHash = hs.suite.mac(c.vers, clientMAC) 500 serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */) 501 serverHash = hs.suite.mac(c.vers, serverMAC) 502 } else { 503 clientCipher = hs.suite.aead(clientKey, clientIV) 504 serverCipher = hs.suite.aead(serverKey, serverIV) 505 } 506 507 c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) 508 c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) 509 return nil 510 } 511 512 func (hs *clientHandshakeState) serverResumedSession() bool { 513 // If the server responded with the same sessionId then it means the 514 // sessionTicket is being used to resume a TLS session. 515 return hs.session != nil && hs.hello.sessionId != nil && 516 bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId) 517 } 518 519 func (hs *clientHandshakeState) processServerHello() (bool, error) { 520 c := hs.c 521 522 if hs.serverHello.compressionMethod != compressionNone { 523 c.sendAlert(alertUnexpectedMessage) 524 return false, errors.New("tls: server selected unsupported compression format") 525 } 526 527 clientDidNPN := hs.hello.nextProtoNeg 528 clientDidALPN := len(hs.hello.alpnProtocols) > 0 529 serverHasNPN := hs.serverHello.nextProtoNeg 530 serverHasALPN := len(hs.serverHello.alpnProtocol) > 0 531 532 if !clientDidNPN && serverHasNPN { 533 c.sendAlert(alertHandshakeFailure) 534 return false, errors.New("server advertised unrequested NPN extension") 535 } 536 537 if !clientDidALPN && serverHasALPN { 538 c.sendAlert(alertHandshakeFailure) 539 return false, errors.New("server advertised unrequested ALPN extension") 540 } 541 542 if serverHasNPN && serverHasALPN { 543 c.sendAlert(alertHandshakeFailure) 544 return false, errors.New("server advertised both NPN and ALPN extensions") 545 } 546 547 if serverHasALPN { 548 c.clientProtocol = hs.serverHello.alpnProtocol 549 c.clientProtocolFallback = false 550 } 551 c.scts = hs.serverHello.scts 552 553 if hs.serverResumedSession() { 554 // Restore masterSecret and peerCerts from previous state 555 hs.masterSecret = hs.session.masterSecret 556 c.peerCertificates = hs.session.serverCertificates 557 c.verifiedChains = hs.session.verifiedChains 558 return true, nil 559 } 560 return false, nil 561 } 562 563 func (hs *clientHandshakeState) readFinished(out []byte) error { 564 c := hs.c 565 566 c.readRecord(recordTypeChangeCipherSpec) 567 if err := c.in.error(); err != nil { 568 return err 569 } 570 571 msg, err := c.readHandshake() 572 if err != nil { 573 return err 574 } 575 serverFinished, ok := msg.(*finishedMsg) 576 if !ok { 577 c.sendAlert(alertUnexpectedMessage) 578 return unexpectedMessageError(serverFinished, msg) 579 } 580 581 verify := hs.finishedHash.serverSum(hs.masterSecret) 582 if len(verify) != len(serverFinished.verifyData) || 583 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { 584 c.sendAlert(alertHandshakeFailure) 585 return errors.New("tls: server's Finished message was incorrect") 586 } 587 hs.finishedHash.Write(serverFinished.marshal()) 588 copy(out, verify) 589 return nil 590 } 591 592 func (hs *clientHandshakeState) readSessionTicket() error { 593 if !hs.serverHello.ticketSupported { 594 return nil 595 } 596 597 c := hs.c 598 msg, err := c.readHandshake() 599 if err != nil { 600 return err 601 } 602 sessionTicketMsg, ok := msg.(*newSessionTicketMsg) 603 if !ok { 604 c.sendAlert(alertUnexpectedMessage) 605 return unexpectedMessageError(sessionTicketMsg, msg) 606 } 607 hs.finishedHash.Write(sessionTicketMsg.marshal()) 608 609 hs.session = &ClientSessionState{ 610 sessionTicket: sessionTicketMsg.ticket, 611 vers: c.vers, 612 cipherSuite: hs.suite.id, 613 masterSecret: hs.masterSecret, 614 serverCertificates: c.peerCertificates, 615 verifiedChains: c.verifiedChains, 616 } 617 618 return nil 619 } 620 621 func (hs *clientHandshakeState) sendFinished(out []byte) error { 622 c := hs.c 623 624 c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) 625 if hs.serverHello.nextProtoNeg { 626 nextProto := new(nextProtoMsg) 627 proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos) 628 nextProto.proto = proto 629 c.clientProtocol = proto 630 c.clientProtocolFallback = fallback 631 632 hs.finishedHash.Write(nextProto.marshal()) 633 c.writeRecord(recordTypeHandshake, nextProto.marshal()) 634 } 635 636 finished := new(finishedMsg) 637 finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) 638 hs.finishedHash.Write(finished.marshal()) 639 c.writeRecord(recordTypeHandshake, finished.marshal()) 640 copy(out, finished.verifyData) 641 return nil 642 } 643 644 // clientSessionCacheKey returns a key used to cache sessionTickets that could 645 // be used to resume previously negotiated TLS sessions with a server. 646 func clientSessionCacheKey(serverAddr net.Addr, config *Config) string { 647 if len(config.ServerName) > 0 { 648 return config.ServerName 649 } 650 return serverAddr.String() 651 } 652 653 // mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol 654 // given list of possible protocols and a list of the preference order. The 655 // first list must not be empty. It returns the resulting protocol and flag 656 // indicating if the fallback case was reached. 657 func mutualProtocol(protos, preferenceProtos []string) (string, bool) { 658 for _, s := range preferenceProtos { 659 for _, c := range protos { 660 if s == c { 661 return s, false 662 } 663 } 664 } 665 666 return protos[0], true 667 }