| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_crypto_client_stream.h" | 5 #include "net/quic/quic_crypto_client_stream.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "base/profiler/scoped_tracker.h" | 8 #include "base/profiler/scoped_tracker.h" |
| 9 #include "net/quic/crypto/crypto_protocol.h" | 9 #include "net/quic/crypto/crypto_protocol.h" |
| 10 #include "net/quic/crypto/crypto_utils.h" | 10 #include "net/quic/crypto/crypto_utils.h" |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 break; | 224 break; |
| 225 case STATE_NONE: | 225 case STATE_NONE: |
| 226 NOTREACHED(); | 226 NOTREACHED(); |
| 227 return; // We are done. | 227 return; // We are done. |
| 228 } | 228 } |
| 229 } while (rv != QUIC_PENDING && next_state_ != STATE_NONE); | 229 } while (rv != QUIC_PENDING && next_state_ != STATE_NONE); |
| 230 } | 230 } |
| 231 | 231 |
| 232 void QuicCryptoClientStream::DoInitialize( | 232 void QuicCryptoClientStream::DoInitialize( |
| 233 QuicCryptoClientConfig::CachedState* cached) { | 233 QuicCryptoClientConfig::CachedState* cached) { |
| 234 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 235 tracked_objects::ScopedTracker tracking_profile( |
| 236 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 237 "422516 QuicCryptoClientStream::DoInitialize")); |
| 238 |
| 234 if (!cached->IsEmpty() && !cached->signature().empty() && | 239 if (!cached->IsEmpty() && !cached->signature().empty() && |
| 235 server_id_.is_https()) { | 240 server_id_.is_https()) { |
| 236 // Note that we verify the proof even if the cached proof is valid. | 241 // Note that we verify the proof even if the cached proof is valid. |
| 237 // This allows us to respond to CA trust changes or certificate | 242 // This allows us to respond to CA trust changes or certificate |
| 238 // expiration because it may have been a while since we last verified | 243 // expiration because it may have been a while since we last verified |
| 239 // the proof. | 244 // the proof. |
| 240 DCHECK(crypto_config_->proof_verifier()); | 245 DCHECK(crypto_config_->proof_verifier()); |
| 241 // If the cached state needs to be verified, do it now. | 246 // If the cached state needs to be verified, do it now. |
| 242 next_state_ = STATE_VERIFY_PROOF; | 247 next_state_ = STATE_VERIFY_PROOF; |
| 243 } else { | 248 } else { |
| 244 next_state_ = STATE_GET_CHANNEL_ID; | 249 next_state_ = STATE_GET_CHANNEL_ID; |
| 245 } | 250 } |
| 246 } | 251 } |
| 247 | 252 |
| 248 void QuicCryptoClientStream::DoSendCHLO( | 253 void QuicCryptoClientStream::DoSendCHLO( |
| 249 const CryptoHandshakeMessage* in, | 254 const CryptoHandshakeMessage* in, |
| 250 QuicCryptoClientConfig::CachedState* cached) { | 255 QuicCryptoClientConfig::CachedState* cached) { |
| 256 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 257 tracked_objects::ScopedTracker tracking_profile( |
| 258 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 259 "422516 QuicCryptoClientStream::DoSendCHLO")); |
| 260 |
| 251 // Send the client hello in plaintext. | 261 // Send the client hello in plaintext. |
| 252 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); | 262 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); |
| 253 if (num_client_hellos_ > kMaxClientHellos) { | 263 if (num_client_hellos_ > kMaxClientHellos) { |
| 254 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); | 264 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); |
| 255 return; | 265 return; |
| 256 } | 266 } |
| 257 num_client_hellos_++; | 267 num_client_hellos_++; |
| 258 | 268 |
| 259 CryptoHandshakeMessage out; | 269 CryptoHandshakeMessage out; |
| 260 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { | 270 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 QuicSession::ENCRYPTION_FIRST_ESTABLISHED); | 339 QuicSession::ENCRYPTION_FIRST_ESTABLISHED); |
| 330 } else { | 340 } else { |
| 331 session()->OnCryptoHandshakeEvent( | 341 session()->OnCryptoHandshakeEvent( |
| 332 QuicSession::ENCRYPTION_REESTABLISHED); | 342 QuicSession::ENCRYPTION_REESTABLISHED); |
| 333 } | 343 } |
| 334 } | 344 } |
| 335 | 345 |
| 336 void QuicCryptoClientStream::DoReceiveREJ( | 346 void QuicCryptoClientStream::DoReceiveREJ( |
| 337 const CryptoHandshakeMessage* in, | 347 const CryptoHandshakeMessage* in, |
| 338 QuicCryptoClientConfig::CachedState* cached) { | 348 QuicCryptoClientConfig::CachedState* cached) { |
| 349 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 350 tracked_objects::ScopedTracker tracking_profile( |
| 351 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 352 "422516 QuicCryptoClientStream::DoReceiveREJ")); |
| 353 |
| 339 // We sent a dummy CHLO because we didn't have enough information to | 354 // We sent a dummy CHLO because we didn't have enough information to |
| 340 // perform a handshake, or we sent a full hello that the server | 355 // perform a handshake, or we sent a full hello that the server |
| 341 // rejected. Here we hope to have a REJ that contains the information | 356 // rejected. Here we hope to have a REJ that contains the information |
| 342 // that we need. | 357 // that we need. |
| 343 if (in->tag() != kREJ) { | 358 if (in->tag() != kREJ) { |
| 344 next_state_ = STATE_NONE; | 359 next_state_ = STATE_NONE; |
| 345 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, | 360 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, |
| 346 "Expected REJ"); | 361 "Expected REJ"); |
| 347 return; | 362 return; |
| 348 } | 363 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 367 // has happened since then. | 382 // has happened since then. |
| 368 next_state_ = STATE_VERIFY_PROOF; | 383 next_state_ = STATE_VERIFY_PROOF; |
| 369 return; | 384 return; |
| 370 } | 385 } |
| 371 } | 386 } |
| 372 next_state_ = STATE_GET_CHANNEL_ID; | 387 next_state_ = STATE_GET_CHANNEL_ID; |
| 373 } | 388 } |
| 374 | 389 |
| 375 QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof( | 390 QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof( |
| 376 QuicCryptoClientConfig::CachedState* cached) { | 391 QuicCryptoClientConfig::CachedState* cached) { |
| 392 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 393 tracked_objects::ScopedTracker tracking_profile( |
| 394 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 395 "422516 QuicCryptoClientStream::DoVerifyProof")); |
| 396 |
| 377 ProofVerifier* verifier = crypto_config_->proof_verifier(); | 397 ProofVerifier* verifier = crypto_config_->proof_verifier(); |
| 378 DCHECK(verifier); | 398 DCHECK(verifier); |
| 379 next_state_ = STATE_VERIFY_PROOF_COMPLETE; | 399 next_state_ = STATE_VERIFY_PROOF_COMPLETE; |
| 380 generation_counter_ = cached->generation_counter(); | 400 generation_counter_ = cached->generation_counter(); |
| 381 | 401 |
| 382 ProofVerifierCallbackImpl* proof_verify_callback = | 402 ProofVerifierCallbackImpl* proof_verify_callback = |
| 383 new ProofVerifierCallbackImpl(this); | 403 new ProofVerifierCallbackImpl(this); |
| 384 | 404 |
| 385 verify_ok_ = false; | 405 verify_ok_ = false; |
| 386 | 406 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 405 case QUIC_SUCCESS: | 425 case QUIC_SUCCESS: |
| 406 delete proof_verify_callback; | 426 delete proof_verify_callback; |
| 407 verify_ok_ = true; | 427 verify_ok_ = true; |
| 408 break; | 428 break; |
| 409 } | 429 } |
| 410 return status; | 430 return status; |
| 411 } | 431 } |
| 412 | 432 |
| 413 void QuicCryptoClientStream::DoVerifyProofComplete( | 433 void QuicCryptoClientStream::DoVerifyProofComplete( |
| 414 QuicCryptoClientConfig::CachedState* cached) { | 434 QuicCryptoClientConfig::CachedState* cached) { |
| 435 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 436 tracked_objects::ScopedTracker tracking_profile( |
| 437 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 438 "422516 QuicCryptoClientStream::DoVerifyProofComplete")); |
| 439 |
| 415 if (!verify_ok_) { | 440 if (!verify_ok_) { |
| 416 next_state_ = STATE_NONE; | 441 next_state_ = STATE_NONE; |
| 417 client_session()->OnProofVerifyDetailsAvailable(*verify_details_); | 442 client_session()->OnProofVerifyDetailsAvailable(*verify_details_); |
| 418 UMA_HISTOGRAM_BOOLEAN("Net.QuicVerifyProofFailed.HandshakeConfirmed", | 443 UMA_HISTOGRAM_BOOLEAN("Net.QuicVerifyProofFailed.HandshakeConfirmed", |
| 419 handshake_confirmed()); | 444 handshake_confirmed()); |
| 420 CloseConnectionWithDetails( | 445 CloseConnectionWithDetails( |
| 421 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_); | 446 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_); |
| 422 return; | 447 return; |
| 423 } | 448 } |
| 424 | 449 |
| 425 // Check if generation_counter has changed between STATE_VERIFY_PROOF and | 450 // Check if generation_counter has changed between STATE_VERIFY_PROOF and |
| 426 // STATE_VERIFY_PROOF_COMPLETE state changes. | 451 // STATE_VERIFY_PROOF_COMPLETE state changes. |
| 427 if (generation_counter_ != cached->generation_counter()) { | 452 if (generation_counter_ != cached->generation_counter()) { |
| 428 next_state_ = STATE_VERIFY_PROOF; | 453 next_state_ = STATE_VERIFY_PROOF; |
| 429 } else { | 454 } else { |
| 430 SetCachedProofValid(cached); | 455 SetCachedProofValid(cached); |
| 431 cached->SetProofVerifyDetails(verify_details_.release()); | 456 cached->SetProofVerifyDetails(verify_details_.release()); |
| 432 if (!handshake_confirmed()) { | 457 if (!handshake_confirmed()) { |
| 433 next_state_ = STATE_GET_CHANNEL_ID; | 458 next_state_ = STATE_GET_CHANNEL_ID; |
| 434 } else { | 459 } else { |
| 435 next_state_ = STATE_NONE; | 460 next_state_ = STATE_NONE; |
| 436 } | 461 } |
| 437 } | 462 } |
| 438 } | 463 } |
| 439 | 464 |
| 440 QuicAsyncStatus QuicCryptoClientStream::DoGetChannelID( | 465 QuicAsyncStatus QuicCryptoClientStream::DoGetChannelID( |
| 441 QuicCryptoClientConfig::CachedState* cached) { | 466 QuicCryptoClientConfig::CachedState* cached) { |
| 467 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 468 tracked_objects::ScopedTracker tracking_profile( |
| 469 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 470 "422516 QuicCryptoClientStream::DoGetChannelID")); |
| 471 |
| 442 next_state_ = STATE_GET_CHANNEL_ID_COMPLETE; | 472 next_state_ = STATE_GET_CHANNEL_ID_COMPLETE; |
| 443 channel_id_key_.reset(); | 473 channel_id_key_.reset(); |
| 444 if (!RequiresChannelID(cached)) { | 474 if (!RequiresChannelID(cached)) { |
| 445 next_state_ = STATE_SEND_CHLO; | 475 next_state_ = STATE_SEND_CHLO; |
| 446 return QUIC_SUCCESS; | 476 return QUIC_SUCCESS; |
| 447 } | 477 } |
| 448 | 478 |
| 449 ChannelIDSourceCallbackImpl* channel_id_source_callback = | 479 ChannelIDSourceCallbackImpl* channel_id_source_callback = |
| 450 new ChannelIDSourceCallbackImpl(this); | 480 new ChannelIDSourceCallbackImpl(this); |
| 451 QuicAsyncStatus status = | 481 QuicAsyncStatus status = |
| (...skipping 13 matching lines...) Expand all Loading... |
| 465 "Channel ID lookup failed"); | 495 "Channel ID lookup failed"); |
| 466 break; | 496 break; |
| 467 case QUIC_SUCCESS: | 497 case QUIC_SUCCESS: |
| 468 delete channel_id_source_callback; | 498 delete channel_id_source_callback; |
| 469 break; | 499 break; |
| 470 } | 500 } |
| 471 return status; | 501 return status; |
| 472 } | 502 } |
| 473 | 503 |
| 474 void QuicCryptoClientStream::DoGetChannelIDComplete() { | 504 void QuicCryptoClientStream::DoGetChannelIDComplete() { |
| 505 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 506 tracked_objects::ScopedTracker tracking_profile( |
| 507 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 508 "422516 QuicCryptoClientStream::DoGetChannelIDComplete")); |
| 509 |
| 475 if (!channel_id_key_.get()) { | 510 if (!channel_id_key_.get()) { |
| 476 next_state_ = STATE_NONE; | 511 next_state_ = STATE_NONE; |
| 477 CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE, | 512 CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE, |
| 478 "Channel ID lookup failed"); | 513 "Channel ID lookup failed"); |
| 479 return; | 514 return; |
| 480 } | 515 } |
| 481 next_state_ = STATE_SEND_CHLO; | 516 next_state_ = STATE_SEND_CHLO; |
| 482 } | 517 } |
| 483 | 518 |
| 484 void QuicCryptoClientStream::DoReceiveSHLO( | 519 void QuicCryptoClientStream::DoReceiveSHLO( |
| 485 const CryptoHandshakeMessage* in, | 520 const CryptoHandshakeMessage* in, |
| 486 QuicCryptoClientConfig::CachedState* cached) { | 521 QuicCryptoClientConfig::CachedState* cached) { |
| 522 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 523 tracked_objects::ScopedTracker tracking_profile( |
| 524 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 525 "422516 QuicCryptoClientStream::DoReceiveSHLO")); |
| 526 |
| 487 next_state_ = STATE_NONE; | 527 next_state_ = STATE_NONE; |
| 488 // We sent a CHLO that we expected to be accepted and now we're hoping | 528 // We sent a CHLO that we expected to be accepted and now we're hoping |
| 489 // for a SHLO from the server to confirm that. | 529 // for a SHLO from the server to confirm that. |
| 490 if (in->tag() == kREJ) { | 530 if (in->tag() == kREJ) { |
| 491 // alternative_decrypter will be nullptr if the original alternative | 531 // alternative_decrypter will be nullptr if the original alternative |
| 492 // decrypter latched and became the primary decrypter. That happens | 532 // decrypter latched and became the primary decrypter. That happens |
| 493 // if we received a message encrypted with the INITIAL key. | 533 // if we received a message encrypted with the INITIAL key. |
| 494 if (session()->connection()->alternative_decrypter() == nullptr) { | 534 if (session()->connection()->alternative_decrypter() == nullptr) { |
| 495 // The rejection was sent encrypted! | 535 // The rejection was sent encrypted! |
| 496 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, | 536 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 session()->connection()->SetDefaultEncryptionLevel( | 587 session()->connection()->SetDefaultEncryptionLevel( |
| 548 ENCRYPTION_FORWARD_SECURE); | 588 ENCRYPTION_FORWARD_SECURE); |
| 549 | 589 |
| 550 handshake_confirmed_ = true; | 590 handshake_confirmed_ = true; |
| 551 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); | 591 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); |
| 552 session()->connection()->OnHandshakeComplete(); | 592 session()->connection()->OnHandshakeComplete(); |
| 553 } | 593 } |
| 554 | 594 |
| 555 void QuicCryptoClientStream::DoInitializeServerConfigUpdate( | 595 void QuicCryptoClientStream::DoInitializeServerConfigUpdate( |
| 556 QuicCryptoClientConfig::CachedState* cached) { | 596 QuicCryptoClientConfig::CachedState* cached) { |
| 597 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 598 tracked_objects::ScopedTracker tracking_profile( |
| 599 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 600 "422516 QuicCryptoClientStream::DoInitializeServerConfigUpdate")); |
| 601 |
| 557 bool update_ignored = false; | 602 bool update_ignored = false; |
| 558 if (!server_id_.is_https()) { | 603 if (!server_id_.is_https()) { |
| 559 // We don't check the certificates for insecure QUIC connections. | 604 // We don't check the certificates for insecure QUIC connections. |
| 560 SetCachedProofValid(cached); | 605 SetCachedProofValid(cached); |
| 561 next_state_ = STATE_NONE; | 606 next_state_ = STATE_NONE; |
| 562 } else if (!cached->IsEmpty() && !cached->signature().empty()) { | 607 } else if (!cached->IsEmpty() && !cached->signature().empty()) { |
| 563 // Note that we verify the proof even if the cached proof is valid. | 608 // Note that we verify the proof even if the cached proof is valid. |
| 564 DCHECK(crypto_config_->proof_verifier()); | 609 DCHECK(crypto_config_->proof_verifier()); |
| 565 next_state_ = STATE_VERIFY_PROOF; | 610 next_state_ = STATE_VERIFY_PROOF; |
| 566 } else { | 611 } else { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 } | 645 } |
| 601 } | 646 } |
| 602 return false; | 647 return false; |
| 603 } | 648 } |
| 604 | 649 |
| 605 QuicClientSessionBase* QuicCryptoClientStream::client_session() { | 650 QuicClientSessionBase* QuicCryptoClientStream::client_session() { |
| 606 return reinterpret_cast<QuicClientSessionBase*>(session()); | 651 return reinterpret_cast<QuicClientSessionBase*>(session()); |
| 607 } | 652 } |
| 608 | 653 |
| 609 } // namespace net | 654 } // namespace net |
| OLD | NEW |