github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/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/rsa" 10 "crypto/subtle" 11 "crypto/x509" 12 "errors" 13 "io" 14 ) 15 16 // serverHandshakeState contains details of a server handshake in progress. 17 // It's discarded once the handshake has completed. 18 type serverHandshakeState struct { 19 c *Conn 20 clientHello *clientHelloMsg 21 hello *serverHelloMsg 22 suite *cipherSuite 23 ellipticOk bool 24 sessionState *sessionState 25 finishedHash finishedHash 26 masterSecret []byte 27 certsFromClient [][]byte 28 } 29 30 // serverHandshake performs a TLS handshake as a server. 31 func (c *Conn) serverHandshake() error { 32 config := c.config 33 34 // If this is the first server handshake, we generate a random key to 35 // encrypt the tickets with. 36 config.serverInitOnce.Do(config.serverInit) 37 38 hs := serverHandshakeState{ 39 c: c, 40 } 41 isResume, err := hs.readClientHello() 42 if err != nil { 43 return err 44 } 45 46 // For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3 47 if isResume { 48 // The client has included a session ticket and so we do an abbreviated handshake. 49 if err := hs.doResumeHandshake(); err != nil { 50 return err 51 } 52 if err := hs.establishKeys(); err != nil { 53 return err 54 } 55 if err := hs.sendFinished(); err != nil { 56 return err 57 } 58 if err := hs.readFinished(); err != nil { 59 return err 60 } 61 c.didResume = true 62 } else { 63 // The client didn't include a session ticket, or it wasn't 64 // valid so we do a full handshake. 65 if err := hs.doFullHandshake(); err != nil { 66 return err 67 } 68 if err := hs.establishKeys(); err != nil { 69 return err 70 } 71 if err := hs.readFinished(); err != nil { 72 return err 73 } 74 if err := hs.sendSessionTicket(); err != nil { 75 return err 76 } 77 if err := hs.sendFinished(); err != nil { 78 return err 79 } 80 } 81 c.handshakeComplete = true 82 83 return nil 84 } 85 86 // readClientHello reads a ClientHello message from the client and decides 87 // whether we will perform session resumption. 88 func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) { 89 config := hs.c.config 90 c := hs.c 91 92 msg, err := c.readHandshake() 93 if err != nil { 94 return false, err 95 } 96 var ok bool 97 hs.clientHello, ok = msg.(*clientHelloMsg) 98 if !ok { 99 return false, c.sendAlert(alertUnexpectedMessage) 100 } 101 c.vers, ok = mutualVersion(hs.clientHello.vers) 102 if !ok { 103 return false, c.sendAlert(alertProtocolVersion) 104 } 105 c.haveVers = true 106 107 hs.finishedHash = newFinishedHash(c.vers) 108 hs.finishedHash.Write(hs.clientHello.marshal()) 109 110 hs.hello = new(serverHelloMsg) 111 112 supportedCurve := false 113 Curves: 114 for _, curve := range hs.clientHello.supportedCurves { 115 switch curve { 116 case curveP256, curveP384, curveP521: 117 supportedCurve = true 118 break Curves 119 } 120 } 121 122 supportedPointFormat := false 123 for _, pointFormat := range hs.clientHello.supportedPoints { 124 if pointFormat == pointFormatUncompressed { 125 supportedPointFormat = true 126 break 127 } 128 } 129 hs.ellipticOk = supportedCurve && supportedPointFormat 130 131 foundCompression := false 132 // We only support null compression, so check that the client offered it. 133 for _, compression := range hs.clientHello.compressionMethods { 134 if compression == compressionNone { 135 foundCompression = true 136 break 137 } 138 } 139 140 if !foundCompression { 141 return false, c.sendAlert(alertHandshakeFailure) 142 } 143 144 hs.hello.vers = c.vers 145 t := uint32(config.time().Unix()) 146 hs.hello.random = make([]byte, 32) 147 hs.hello.random[0] = byte(t >> 24) 148 hs.hello.random[1] = byte(t >> 16) 149 hs.hello.random[2] = byte(t >> 8) 150 hs.hello.random[3] = byte(t) 151 _, err = io.ReadFull(config.rand(), hs.hello.random[4:]) 152 if err != nil { 153 return false, c.sendAlert(alertInternalError) 154 } 155 hs.hello.compressionMethod = compressionNone 156 if len(hs.clientHello.serverName) > 0 { 157 c.serverName = hs.clientHello.serverName 158 } 159 if hs.clientHello.nextProtoNeg { 160 hs.hello.nextProtoNeg = true 161 hs.hello.nextProtos = config.NextProtos 162 } 163 164 if hs.checkForResumption() { 165 return true, nil 166 } 167 168 var preferenceList, supportedList []uint16 169 if c.config.PreferServerCipherSuites { 170 preferenceList = c.config.cipherSuites() 171 supportedList = hs.clientHello.cipherSuites 172 } else { 173 preferenceList = hs.clientHello.cipherSuites 174 supportedList = c.config.cipherSuites() 175 } 176 177 for _, id := range preferenceList { 178 if hs.suite = c.tryCipherSuite(id, supportedList, hs.ellipticOk); hs.suite != nil { 179 break 180 } 181 } 182 183 if hs.suite == nil { 184 return false, c.sendAlert(alertHandshakeFailure) 185 } 186 187 return false, nil 188 } 189 190 // checkForResumption returns true if we should perform resumption on this connection. 191 func (hs *serverHandshakeState) checkForResumption() bool { 192 c := hs.c 193 194 var ok bool 195 if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); !ok { 196 return false 197 } 198 199 if hs.sessionState.vers > hs.clientHello.vers { 200 return false 201 } 202 if vers, ok := mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers { 203 return false 204 } 205 206 cipherSuiteOk := false 207 // Check that the client is still offering the ciphersuite in the session. 208 for _, id := range hs.clientHello.cipherSuites { 209 if id == hs.sessionState.cipherSuite { 210 cipherSuiteOk = true 211 break 212 } 213 } 214 if !cipherSuiteOk { 215 return false 216 } 217 218 // Check that we also support the ciphersuite from the session. 219 hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.ellipticOk) 220 if hs.suite == nil { 221 return false 222 } 223 224 sessionHasClientCerts := len(hs.sessionState.certificates) != 0 225 needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert 226 if needClientCerts && !sessionHasClientCerts { 227 return false 228 } 229 if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { 230 return false 231 } 232 233 return true 234 } 235 236 func (hs *serverHandshakeState) doResumeHandshake() error { 237 c := hs.c 238 239 hs.hello.cipherSuite = hs.suite.id 240 // We echo the client's session ID in the ServerHello to let it know 241 // that we're doing a resumption. 242 hs.hello.sessionId = hs.clientHello.sessionId 243 hs.finishedHash.Write(hs.hello.marshal()) 244 c.writeRecord(recordTypeHandshake, hs.hello.marshal()) 245 246 if len(hs.sessionState.certificates) > 0 { 247 if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil { 248 return err 249 } 250 } 251 252 hs.masterSecret = hs.sessionState.masterSecret 253 254 return nil 255 } 256 257 func (hs *serverHandshakeState) doFullHandshake() error { 258 config := hs.c.config 259 c := hs.c 260 261 if len(config.Certificates) == 0 { 262 return c.sendAlert(alertInternalError) 263 } 264 cert := &config.Certificates[0] 265 if len(hs.clientHello.serverName) > 0 { 266 cert = config.getCertificateForName(hs.clientHello.serverName) 267 } 268 269 if hs.clientHello.ocspStapling && len(cert.OCSPStaple) > 0 { 270 hs.hello.ocspStapling = true 271 } 272 273 hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled 274 hs.hello.cipherSuite = hs.suite.id 275 hs.finishedHash.Write(hs.hello.marshal()) 276 c.writeRecord(recordTypeHandshake, hs.hello.marshal()) 277 278 certMsg := new(certificateMsg) 279 certMsg.certificates = cert.Certificate 280 hs.finishedHash.Write(certMsg.marshal()) 281 c.writeRecord(recordTypeHandshake, certMsg.marshal()) 282 283 if hs.hello.ocspStapling { 284 certStatus := new(certificateStatusMsg) 285 certStatus.statusType = statusTypeOCSP 286 certStatus.response = cert.OCSPStaple 287 hs.finishedHash.Write(certStatus.marshal()) 288 c.writeRecord(recordTypeHandshake, certStatus.marshal()) 289 } 290 291 keyAgreement := hs.suite.ka() 292 skx, err := keyAgreement.generateServerKeyExchange(config, cert, hs.clientHello, hs.hello) 293 if err != nil { 294 c.sendAlert(alertHandshakeFailure) 295 return err 296 } 297 if skx != nil { 298 hs.finishedHash.Write(skx.marshal()) 299 c.writeRecord(recordTypeHandshake, skx.marshal()) 300 } 301 302 if config.ClientAuth >= RequestClientCert { 303 // Request a client certificate 304 certReq := new(certificateRequestMsg) 305 certReq.certificateTypes = []byte{certTypeRSASign} 306 307 // An empty list of certificateAuthorities signals to 308 // the client that it may send any certificate in response 309 // to our request. When we know the CAs we trust, then 310 // we can send them down, so that the client can choose 311 // an appropriate certificate to give to us. 312 if config.ClientCAs != nil { 313 certReq.certificateAuthorities = config.ClientCAs.Subjects() 314 } 315 hs.finishedHash.Write(certReq.marshal()) 316 c.writeRecord(recordTypeHandshake, certReq.marshal()) 317 } 318 319 helloDone := new(serverHelloDoneMsg) 320 hs.finishedHash.Write(helloDone.marshal()) 321 c.writeRecord(recordTypeHandshake, helloDone.marshal()) 322 323 var pub *rsa.PublicKey // public key for client auth, if any 324 325 msg, err := c.readHandshake() 326 if err != nil { 327 return err 328 } 329 330 var ok bool 331 // If we requested a client certificate, then the client must send a 332 // certificate message, even if it's empty. 333 if config.ClientAuth >= RequestClientCert { 334 if certMsg, ok = msg.(*certificateMsg); !ok { 335 return c.sendAlert(alertHandshakeFailure) 336 } 337 hs.finishedHash.Write(certMsg.marshal()) 338 339 if len(certMsg.certificates) == 0 { 340 // The client didn't actually send a certificate 341 switch config.ClientAuth { 342 case RequireAnyClientCert, RequireAndVerifyClientCert: 343 c.sendAlert(alertBadCertificate) 344 return errors.New("tls: client didn't provide a certificate") 345 } 346 } 347 348 pub, err = hs.processCertsFromClient(certMsg.certificates) 349 if err != nil { 350 return err 351 } 352 353 msg, err = c.readHandshake() 354 if err != nil { 355 return err 356 } 357 } 358 359 // Get client key exchange 360 ckx, ok := msg.(*clientKeyExchangeMsg) 361 if !ok { 362 return c.sendAlert(alertUnexpectedMessage) 363 } 364 hs.finishedHash.Write(ckx.marshal()) 365 366 // If we received a client cert in response to our certificate request message, 367 // the client will send us a certificateVerifyMsg immediately after the 368 // clientKeyExchangeMsg. This message is a MD5SHA1 digest of all preceding 369 // handshake-layer messages that is signed using the private key corresponding 370 // to the client's certificate. This allows us to verify that the client is in 371 // possession of the private key of the certificate. 372 if len(c.peerCertificates) > 0 { 373 msg, err = c.readHandshake() 374 if err != nil { 375 return err 376 } 377 certVerify, ok := msg.(*certificateVerifyMsg) 378 if !ok { 379 return c.sendAlert(alertUnexpectedMessage) 380 } 381 382 digest := make([]byte, 0, 36) 383 digest = hs.finishedHash.serverMD5.Sum(digest) 384 digest = hs.finishedHash.serverSHA1.Sum(digest) 385 err = rsa.VerifyPKCS1v15(pub, crypto.MD5SHA1, digest, certVerify.signature) 386 if err != nil { 387 c.sendAlert(alertBadCertificate) 388 return errors.New("could not validate signature of connection nonces: " + err.Error()) 389 } 390 391 hs.finishedHash.Write(certVerify.marshal()) 392 } 393 394 preMasterSecret, err := keyAgreement.processClientKeyExchange(config, cert, ckx, c.vers) 395 if err != nil { 396 c.sendAlert(alertHandshakeFailure) 397 return err 398 } 399 hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.clientHello.random, hs.hello.random) 400 401 return nil 402 } 403 404 func (hs *serverHandshakeState) establishKeys() error { 405 c := hs.c 406 407 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := 408 keysFromMasterSecret(c.vers, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) 409 410 clientCipher := hs.suite.cipher(clientKey, clientIV, true /* for reading */) 411 clientHash := hs.suite.mac(c.vers, clientMAC) 412 c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) 413 414 serverCipher := hs.suite.cipher(serverKey, serverIV, false /* not for reading */) 415 serverHash := hs.suite.mac(c.vers, serverMAC) 416 c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) 417 418 return nil 419 } 420 421 func (hs *serverHandshakeState) readFinished() error { 422 c := hs.c 423 424 c.readRecord(recordTypeChangeCipherSpec) 425 if err := c.error(); err != nil { 426 return err 427 } 428 429 if hs.hello.nextProtoNeg { 430 msg, err := c.readHandshake() 431 if err != nil { 432 return err 433 } 434 nextProto, ok := msg.(*nextProtoMsg) 435 if !ok { 436 return c.sendAlert(alertUnexpectedMessage) 437 } 438 hs.finishedHash.Write(nextProto.marshal()) 439 c.clientProtocol = nextProto.proto 440 } 441 442 msg, err := c.readHandshake() 443 if err != nil { 444 return err 445 } 446 clientFinished, ok := msg.(*finishedMsg) 447 if !ok { 448 return c.sendAlert(alertUnexpectedMessage) 449 } 450 451 verify := hs.finishedHash.clientSum(hs.masterSecret) 452 if len(verify) != len(clientFinished.verifyData) || 453 subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { 454 return c.sendAlert(alertHandshakeFailure) 455 } 456 457 hs.finishedHash.Write(clientFinished.marshal()) 458 return nil 459 } 460 461 func (hs *serverHandshakeState) sendSessionTicket() error { 462 if !hs.hello.ticketSupported { 463 return nil 464 } 465 466 c := hs.c 467 m := new(newSessionTicketMsg) 468 469 var err error 470 state := sessionState{ 471 vers: c.vers, 472 cipherSuite: hs.suite.id, 473 masterSecret: hs.masterSecret, 474 certificates: hs.certsFromClient, 475 } 476 m.ticket, err = c.encryptTicket(&state) 477 if err != nil { 478 return err 479 } 480 481 hs.finishedHash.Write(m.marshal()) 482 c.writeRecord(recordTypeHandshake, m.marshal()) 483 484 return nil 485 } 486 487 func (hs *serverHandshakeState) sendFinished() error { 488 c := hs.c 489 490 c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) 491 492 finished := new(finishedMsg) 493 finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) 494 hs.finishedHash.Write(finished.marshal()) 495 c.writeRecord(recordTypeHandshake, finished.marshal()) 496 497 c.cipherSuite = hs.suite.id 498 499 return nil 500 } 501 502 // processCertsFromClient takes a chain of client certificates either from a 503 // Certificates message or from a sessionState and verifies them. It returns 504 // the public key of the leaf certificate. 505 func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (*rsa.PublicKey, error) { 506 c := hs.c 507 508 hs.certsFromClient = certificates 509 certs := make([]*x509.Certificate, len(certificates)) 510 var err error 511 for i, asn1Data := range certificates { 512 if certs[i], err = x509.ParseCertificate(asn1Data); err != nil { 513 c.sendAlert(alertBadCertificate) 514 return nil, errors.New("tls: failed to parse client certificate: " + err.Error()) 515 } 516 } 517 518 if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 { 519 opts := x509.VerifyOptions{ 520 Roots: c.config.ClientCAs, 521 CurrentTime: c.config.time(), 522 Intermediates: x509.NewCertPool(), 523 KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, 524 } 525 526 for _, cert := range certs[1:] { 527 opts.Intermediates.AddCert(cert) 528 } 529 530 chains, err := certs[0].Verify(opts) 531 if err != nil { 532 c.sendAlert(alertBadCertificate) 533 return nil, errors.New("tls: failed to verify client's certificate: " + err.Error()) 534 } 535 536 ok := false 537 for _, ku := range certs[0].ExtKeyUsage { 538 if ku == x509.ExtKeyUsageClientAuth { 539 ok = true 540 break 541 } 542 } 543 if !ok { 544 c.sendAlert(alertHandshakeFailure) 545 return nil, errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication") 546 } 547 548 c.verifiedChains = chains 549 } 550 551 if len(certs) > 0 { 552 pub, ok := certs[0].PublicKey.(*rsa.PublicKey) 553 if !ok { 554 return nil, c.sendAlert(alertUnsupportedCertificate) 555 } 556 c.peerCertificates = certs 557 return pub, nil 558 } 559 560 return nil, nil 561 } 562 563 // tryCipherSuite returns a cipherSuite with the given id if that cipher suite 564 // is acceptable to use. 565 func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, ellipticOk bool) *cipherSuite { 566 for _, supported := range supportedCipherSuites { 567 if id == supported { 568 var candidate *cipherSuite 569 570 for _, s := range cipherSuites { 571 if s.id == id { 572 candidate = s 573 break 574 } 575 } 576 if candidate == nil { 577 continue 578 } 579 // Don't select a ciphersuite which we can't 580 // support for this client. 581 if candidate.elliptic && !ellipticOk { 582 continue 583 } 584 return candidate 585 } 586 } 587 588 return nil 589 }