| 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_macros.h" | 7 #include "base/metrics/histogram_macros.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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 break; | 217 break; |
| 218 case STATE_NONE: | 218 case STATE_NONE: |
| 219 NOTREACHED(); | 219 NOTREACHED(); |
| 220 return; // We are done. | 220 return; // We are done. |
| 221 } | 221 } |
| 222 } while (rv != QUIC_PENDING && next_state_ != STATE_NONE); | 222 } while (rv != QUIC_PENDING && next_state_ != STATE_NONE); |
| 223 } | 223 } |
| 224 | 224 |
| 225 void QuicCryptoClientStream::DoInitialize( | 225 void QuicCryptoClientStream::DoInitialize( |
| 226 QuicCryptoClientConfig::CachedState* cached) { | 226 QuicCryptoClientConfig::CachedState* cached) { |
| 227 if (!cached->IsEmpty() && !cached->signature().empty() && | 227 if (!cached->IsEmpty() && !cached->signature().empty()) { |
| 228 server_id_.is_https()) { | |
| 229 // Note that we verify the proof even if the cached proof is valid. | 228 // Note that we verify the proof even if the cached proof is valid. |
| 230 // This allows us to respond to CA trust changes or certificate | 229 // This allows us to respond to CA trust changes or certificate |
| 231 // expiration because it may have been a while since we last verified | 230 // expiration because it may have been a while since we last verified |
| 232 // the proof. | 231 // the proof. |
| 233 DCHECK(crypto_config_->proof_verifier()); | 232 DCHECK(crypto_config_->proof_verifier()); |
| 234 // If the cached state needs to be verified, do it now. | 233 // If the cached state needs to be verified, do it now. |
| 235 next_state_ = STATE_VERIFY_PROOF; | 234 next_state_ = STATE_VERIFY_PROOF; |
| 236 } else { | 235 } else { |
| 237 next_state_ = STATE_GET_CHANNEL_ID; | 236 next_state_ = STATE_GET_CHANNEL_ID; |
| 238 } | 237 } |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 if ((in->tag() != kREJ) && (in->tag() != kSREJ)) { | 367 if ((in->tag() != kREJ) && (in->tag() != kSREJ)) { |
| 369 next_state_ = STATE_NONE; | 368 next_state_ = STATE_NONE; |
| 370 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, | 369 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, |
| 371 "Expected REJ"); | 370 "Expected REJ"); |
| 372 return; | 371 return; |
| 373 } | 372 } |
| 374 stateless_reject_received_ = in->tag() == kSREJ; | 373 stateless_reject_received_ = in->tag() == kSREJ; |
| 375 string error_details; | 374 string error_details; |
| 376 QuicErrorCode error = crypto_config_->ProcessRejection( | 375 QuicErrorCode error = crypto_config_->ProcessRejection( |
| 377 *in, session()->connection()->clock()->WallNow(), cached, | 376 *in, session()->connection()->clock()->WallNow(), cached, |
| 378 server_id_.is_https(), &crypto_negotiated_params_, &error_details); | 377 &crypto_negotiated_params_, &error_details); |
| 379 | 378 |
| 380 if (error != QUIC_NO_ERROR) { | 379 if (error != QUIC_NO_ERROR) { |
| 381 next_state_ = STATE_NONE; | 380 next_state_ = STATE_NONE; |
| 382 CloseConnectionWithDetails(error, error_details); | 381 CloseConnectionWithDetails(error, error_details); |
| 383 return; | 382 return; |
| 384 } | 383 } |
| 385 if (!cached->proof_valid()) { | 384 if (!cached->proof_valid()) { |
| 386 if (!server_id_.is_https()) { | 385 if (!cached->signature().empty()) { |
| 387 // We don't check the certificates for insecure QUIC connections. | |
| 388 SetCachedProofValid(cached); | |
| 389 } else if (!cached->signature().empty()) { | |
| 390 // Note that we only verify the proof if the cached proof is not | 386 // Note that we only verify the proof if the cached proof is not |
| 391 // valid. If the cached proof is valid here, someone else must have | 387 // valid. If the cached proof is valid here, someone else must have |
| 392 // just added the server config to the cache and verified the proof, | 388 // just added the server config to the cache and verified the proof, |
| 393 // so we can assume no CA trust changes or certificate expiration | 389 // so we can assume no CA trust changes or certificate expiration |
| 394 // has happened since then. | 390 // has happened since then. |
| 395 next_state_ = STATE_VERIFY_PROOF; | 391 next_state_ = STATE_VERIFY_PROOF; |
| 396 return; | 392 return; |
| 397 } | 393 } |
| 398 } | 394 } |
| 399 next_state_ = STATE_GET_CHANNEL_ID; | 395 next_state_ = STATE_GET_CHANNEL_ID; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 ENCRYPTION_FORWARD_SECURE); | 571 ENCRYPTION_FORWARD_SECURE); |
| 576 | 572 |
| 577 handshake_confirmed_ = true; | 573 handshake_confirmed_ = true; |
| 578 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); | 574 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); |
| 579 session()->connection()->OnHandshakeComplete(); | 575 session()->connection()->OnHandshakeComplete(); |
| 580 } | 576 } |
| 581 | 577 |
| 582 void QuicCryptoClientStream::DoInitializeServerConfigUpdate( | 578 void QuicCryptoClientStream::DoInitializeServerConfigUpdate( |
| 583 QuicCryptoClientConfig::CachedState* cached) { | 579 QuicCryptoClientConfig::CachedState* cached) { |
| 584 bool update_ignored = false; | 580 bool update_ignored = false; |
| 585 if (!server_id_.is_https()) { | 581 if (!cached->IsEmpty() && !cached->signature().empty()) { |
| 586 // We don't check the certificates for insecure QUIC connections. | |
| 587 SetCachedProofValid(cached); | |
| 588 next_state_ = STATE_NONE; | |
| 589 } else if (!cached->IsEmpty() && !cached->signature().empty()) { | |
| 590 // Note that we verify the proof even if the cached proof is valid. | 582 // Note that we verify the proof even if the cached proof is valid. |
| 591 DCHECK(crypto_config_->proof_verifier()); | 583 DCHECK(crypto_config_->proof_verifier()); |
| 592 next_state_ = STATE_VERIFY_PROOF; | 584 next_state_ = STATE_VERIFY_PROOF; |
| 593 } else { | 585 } else { |
| 594 update_ignored = true; | 586 update_ignored = true; |
| 595 next_state_ = STATE_NONE; | 587 next_state_ = STATE_NONE; |
| 596 } | 588 } |
| 597 UMA_HISTOGRAM_COUNTS("Net.QuicNumServerConfig.UpdateMessagesIgnored", | 589 UMA_HISTOGRAM_COUNTS("Net.QuicNumServerConfig.UpdateMessagesIgnored", |
| 598 update_ignored); | 590 update_ignored); |
| 599 } | 591 } |
| 600 | 592 |
| 601 void QuicCryptoClientStream::SetCachedProofValid( | 593 void QuicCryptoClientStream::SetCachedProofValid( |
| 602 QuicCryptoClientConfig::CachedState* cached) { | 594 QuicCryptoClientConfig::CachedState* cached) { |
| 603 cached->SetProofValid(); | 595 cached->SetProofValid(); |
| 604 client_session()->OnProofValid(*cached); | 596 client_session()->OnProofValid(*cached); |
| 605 } | 597 } |
| 606 | 598 |
| 607 bool QuicCryptoClientStream::RequiresChannelID( | 599 bool QuicCryptoClientStream::RequiresChannelID( |
| 608 QuicCryptoClientConfig::CachedState* cached) { | 600 QuicCryptoClientConfig::CachedState* cached) { |
| 609 if (!server_id_.is_https() || | 601 if (server_id_.privacy_mode() == PRIVACY_MODE_ENABLED || |
| 610 server_id_.privacy_mode() == PRIVACY_MODE_ENABLED || | |
| 611 !crypto_config_->channel_id_source()) { | 602 !crypto_config_->channel_id_source()) { |
| 612 return false; | 603 return false; |
| 613 } | 604 } |
| 614 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); | 605 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); |
| 615 if (!scfg) { // scfg may be null then we send an inchoate CHLO. | 606 if (!scfg) { // scfg may be null then we send an inchoate CHLO. |
| 616 return false; | 607 return false; |
| 617 } | 608 } |
| 618 const QuicTag* their_proof_demands; | 609 const QuicTag* their_proof_demands; |
| 619 size_t num_their_proof_demands; | 610 size_t num_their_proof_demands; |
| 620 if (scfg->GetTaglist(kPDMD, &their_proof_demands, | 611 if (scfg->GetTaglist(kPDMD, &their_proof_demands, |
| 621 &num_their_proof_demands) != QUIC_NO_ERROR) { | 612 &num_their_proof_demands) != QUIC_NO_ERROR) { |
| 622 return false; | 613 return false; |
| 623 } | 614 } |
| 624 for (size_t i = 0; i < num_their_proof_demands; i++) { | 615 for (size_t i = 0; i < num_their_proof_demands; i++) { |
| 625 if (their_proof_demands[i] == kCHID) { | 616 if (their_proof_demands[i] == kCHID) { |
| 626 return true; | 617 return true; |
| 627 } | 618 } |
| 628 } | 619 } |
| 629 return false; | 620 return false; |
| 630 } | 621 } |
| 631 | 622 |
| 632 QuicClientSessionBase* QuicCryptoClientStream::client_session() { | 623 QuicClientSessionBase* QuicCryptoClientStream::client_session() { |
| 633 return reinterpret_cast<QuicClientSessionBase*>(session()); | 624 return reinterpret_cast<QuicClientSessionBase*>(session()); |
| 634 } | 625 } |
| 635 | 626 |
| 636 } // namespace net | 627 } // namespace net |
| OLD | NEW |