diff options
author | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-22 04:08:12 +0000 |
---|---|---|
committer | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-22 04:08:12 +0000 |
commit | 59c0bbd87fc1b5e71f9bf5762feec9d58ba032b7 (patch) | |
tree | 5e1cd2a8821c46a5945c8887e8fbdaa9f2a35011 | |
parent | c1c5a411a13208daa1cc59a8056cad6242490cde (diff) | |
download | chromium_src-59c0bbd87fc1b5e71f9bf5762feec9d58ba032b7.zip chromium_src-59c0bbd87fc1b5e71f9bf5762feec9d58ba032b7.tar.gz chromium_src-59c0bbd87fc1b5e71f9bf5762feec9d58ba032b7.tar.bz2 |
Remove the QuicStreamFactory's crypto config map, and instead
rely on the QuicCryptoConfig's cached state map.
Move the canonical server behavior from the QuicStreamFactory to
the QuicCryptoConfig.
Review URL: https://codereview.chromium.org/204023004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258771 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/http/http_network_session.cc | 1 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_job.cc | 3 | ||||
-rw-r--r-- | net/quic/crypto/quic_crypto_client_config.cc | 58 | ||||
-rw-r--r-- | net/quic/crypto/quic_crypto_client_config.h | 32 | ||||
-rw-r--r-- | net/quic/crypto/quic_crypto_client_config_test.cc | 3 | ||||
-rw-r--r-- | net/quic/quic_crypto_client_stream.cc | 18 | ||||
-rw-r--r-- | net/quic/quic_crypto_client_stream.h | 4 | ||||
-rw-r--r-- | net/quic/quic_stream_factory.cc | 104 | ||||
-rw-r--r-- | net/quic/quic_stream_factory.h | 38 | ||||
-rw-r--r-- | net/quic/quic_stream_factory_test.cc | 72 | ||||
-rw-r--r-- | net/quic/test_tools/crypto_test_utils.h | 2 | ||||
-rw-r--r-- | net/quic/test_tools/crypto_test_utils_chromium.cc | 10 |
12 files changed, 132 insertions, 213 deletions
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 73d969c..0e07653 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -113,6 +113,7 @@ HttpNetworkSession::HttpNetworkSession(const Params& params) params.client_socket_factory : net::ClientSocketFactory::GetDefaultFactory(), params.http_server_properties, + params.cert_verifier, params.quic_crypto_client_stream_factory, params.quic_random ? params.quic_random : QuicRandom::GetInstance(), diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index 960bc58..a801787 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc @@ -740,8 +740,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { next_state_ = STATE_INIT_CONNECTION_COMPLETE; bool secure_quic = using_ssl_ || proxy_info_.is_quic(); int rv = quic_request_.Request( - destination, secure_quic, request_info_.method, - session_->cert_verifier(), net_log_, io_callback_); + destination, secure_quic, request_info_.method, net_log_, io_callback_); if (rv != OK) { // OK, there's no available QUIC session. Let |waiting_job_| resume // if it's paused. diff --git a/net/quic/crypto/quic_crypto_client_config.cc b/net/quic/crypto/quic_crypto_client_config.cc index 0fa78a4..96369dd 100644 --- a/net/quic/crypto/quic_crypto_client_config.cc +++ b/net/quic/crypto/quic_crypto_client_config.cc @@ -5,6 +5,7 @@ #include "net/quic/crypto/quic_crypto_client_config.h" #include "base/stl_util.h" +#include "base/strings/string_util.h" #include "net/quic/crypto/cert_compressor.h" #include "net/quic/crypto/channel_id.h" #include "net/quic/crypto/common_cert_set.h" @@ -256,19 +257,19 @@ void QuicCryptoClientConfig::SetDefaults() { QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate( const QuicSessionKey& server_key) { - map<QuicSessionKey, CachedState*>::const_iterator it = - cached_states_.find(server_key); + CachedStateMap::const_iterator it = cached_states_.find(server_key); if (it != cached_states_.end()) { return it->second; } CachedState* cached = new CachedState; cached_states_.insert(make_pair(server_key, cached)); + PopulateFromCanonicalConfig(server_key, cached); return cached; } void QuicCryptoClientConfig::FillInchoateClientHello( - const string& server_hostname, + const QuicSessionKey& server_key, const QuicVersion preferred_version, const CachedState* cached, QuicCryptoNegotiatedParameters* out_params, @@ -278,8 +279,8 @@ void QuicCryptoClientConfig::FillInchoateClientHello( // Server name indication. We only send SNI if it's a valid domain name, as // per the spec. - if (CryptoUtils::IsValidSNI(server_hostname)) { - out->SetStringPiece(kSNI, server_hostname); + if (CryptoUtils::IsValidSNI(server_key.host())) { + out->SetStringPiece(kSNI, server_key.host()); } out->SetValue(kVER, QuicVersionToQuicTag(preferred_version)); @@ -287,7 +288,7 @@ void QuicCryptoClientConfig::FillInchoateClientHello( out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token()); } - if (proof_verifier_.get()) { + if (server_key.is_https()) { // Don't request ECDSA proofs on platforms that do not support ECDSA // certificates. bool disableECDSA = false; @@ -324,7 +325,7 @@ void QuicCryptoClientConfig::FillInchoateClientHello( } QuicErrorCode QuicCryptoClientConfig::FillClientHello( - const string& server_hostname, + const QuicSessionKey& server_key, QuicConnectionId connection_id, const QuicVersion preferred_version, const CachedState* cached, @@ -335,7 +336,7 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello( string* error_details) const { DCHECK(error_details != NULL); - FillInchoateClientHello(server_hostname, preferred_version, cached, + FillInchoateClientHello(server_key, preferred_version, cached, out_params, out); const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); @@ -455,7 +456,7 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello( hkdf_input.append(cached->server_config()); string key, signature; - if (!channel_id_signer_->Sign(server_hostname, hkdf_input, + if (!channel_id_signer_->Sign(server_key.host(), hkdf_input, &key, &signature)) { *error_details = "Channel ID signature failed"; return QUIC_INVALID_CHANNEL_ID_SIGNATURE; @@ -680,4 +681,43 @@ void QuicCryptoClientConfig::InitializeFrom( cached->InitializeFrom(*canonical_cached); } +void QuicCryptoClientConfig::AddCanonicalSuffix(const std::string& suffix) { + canoncial_suffixes_.push_back(suffix); +} + +void QuicCryptoClientConfig::PopulateFromCanonicalConfig( + const QuicSessionKey& server_key, + CachedState* server_state) { + DCHECK(server_state->IsEmpty()); + unsigned i = 0; + for (; i < canoncial_suffixes_.size(); ++i) { + if (EndsWith(server_key.host(), canoncial_suffixes_[i], false)) { + break; + } + } + if (i == canoncial_suffixes_.size()) + return; + + QuicSessionKey suffix_server_key( + canoncial_suffixes_[i], server_key.port(), server_key.is_https()); + if (!ContainsKey(canonical_server_map_, suffix_server_key)) { + // This is the first host we've seen which matches the suffix, so make it + // canonical. + canonical_server_map_[suffix_server_key] = server_key; + return; + } + + const QuicSessionKey& canonical_server_key = + canonical_server_map_[suffix_server_key]; + CachedState* canonical_state = cached_states_[canonical_server_key]; + if (!canonical_state->proof_valid()) { + return; + } + + // Update canonical version to point at the "most recent" entry. + canonical_server_map_[suffix_server_key] = server_key; + + server_state->InitializeFrom(*canonical_state); +} + } // namespace net diff --git a/net/quic/crypto/quic_crypto_client_config.h b/net/quic/crypto/quic_crypto_client_config.h index f2e8649..d68f437 100644 --- a/net/quic/crypto/quic_crypto_client_config.h +++ b/net/quic/crypto/quic_crypto_client_config.h @@ -143,7 +143,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // |out_params->cached_certs|. |preferred_version| is the version of the // QUIC protocol that this client chose to use initially. This allows the // server to detect downgrade attacks. - void FillInchoateClientHello(const std::string& server_hostname, + void FillInchoateClientHello(const QuicSessionKey& server_key, const QuicVersion preferred_version, const CachedState* cached, QuicCryptoNegotiatedParameters* out_params, @@ -151,7 +151,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // FillClientHello sets |out| to be a CHLO message based on the configuration // of this object. This object must have cached enough information about - // |server_hostname| in order to perform a handshake. This can be checked + // the server's hostname in order to perform a handshake. This can be checked // with the |IsComplete| member of |CachedState|. // // |clock| and |rand| are used to generate the nonce and |out_params| is @@ -159,7 +159,7 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // accept. |preferred_version| is the version of the QUIC protocol that this // client chose to use initially. This allows the server to detect downgrade // attacks. - QuicErrorCode FillClientHello(const std::string& server_hostname, + QuicErrorCode FillClientHello(const QuicSessionKey& server_key, QuicConnectionId connection_id, const QuicVersion preferred_version, const CachedState* cached, @@ -218,10 +218,34 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { const QuicSessionKey& canonical_server_key, QuicCryptoClientConfig* canonical_crypto_config); + // Adds |suffix| as a domain suffix for which the server's crypto config + // is expected to be shared among servers with the domain suffix. If a server + // matches this suffix, then the server config from another server with the + // suffix will be used to initialize the cached state for this server. + void AddCanonicalSuffix(const std::string& suffix); + private: + typedef std::map<QuicSessionKey, CachedState*> CachedStateMap; + + // If the suffix of the hostname in |server_key| is in |canoncial_suffixes_|, + // then populate |cached| with the canonical cached state from + // |canonical_server_map_| for that suffix. + void PopulateFromCanonicalConfig(const QuicSessionKey& server_key, + CachedState* cached); + // cached_states_ maps from the server_key to the cached information about // that server. - std::map<QuicSessionKey, CachedState*> cached_states_; + CachedStateMap cached_states_; + + // Contains a map of servers which could share the same server config. Map + // from a canonical host suffix/port/scheme to a representative server with + // the canonical suffix, which has a plausible set of initial certificates + // (or at least server public key). + std::map<QuicSessionKey, QuicSessionKey> canonical_server_map_; + + // Contains list of suffixes (for exmaple ".c.youtube.com", + // ".googlevideo.com") of canoncial hostnames. + std::vector<std::string> canoncial_suffixes_; scoped_ptr<ProofVerifier> proof_verifier_; scoped_ptr<ChannelIDSigner> channel_id_signer_; diff --git a/net/quic/crypto/quic_crypto_client_config_test.cc b/net/quic/crypto/quic_crypto_client_config_test.cc index d151e0c..f295ef5 100644 --- a/net/quic/crypto/quic_crypto_client_config_test.cc +++ b/net/quic/crypto/quic_crypto_client_config_test.cc @@ -56,7 +56,8 @@ TEST(QuicCryptoClientConfigTest, InchoateChlo) { QuicCryptoClientConfig config; QuicCryptoNegotiatedParameters params; CryptoHandshakeMessage msg; - config.FillInchoateClientHello("www.google.com", QuicVersionMax(), &state, + QuicSessionKey server_key("www.google.com", 80, false); + config.FillInchoateClientHello(server_key, QuicVersionMax(), &state, ¶ms, &msg); QuicTag cver; diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc index 5de69c2..7c840ba 100644 --- a/net/quic/quic_crypto_client_stream.cc +++ b/net/quic/quic_crypto_client_stream.cc @@ -107,7 +107,8 @@ void QuicCryptoClientStream::DoHandshakeLoop( switch (state) { case STATE_INITIALIZE: { if (!cached->IsEmpty() && !cached->signature().empty() && - crypto_config_->proof_verifier()) { + server_key_.is_https()) { + DCHECK(crypto_config_->proof_verifier()); // If the cached state needs to be verified, do it now. next_state_ = STATE_VERIFY_PROOF; } else { @@ -126,7 +127,7 @@ void QuicCryptoClientStream::DoHandshakeLoop( if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { crypto_config_->FillInchoateClientHello( - server_key_.host(), + server_key_, session()->connection()->supported_versions().front(), cached, &crypto_negotiated_params_, &out); // Pad the inchoate client hello to fill up a packet. @@ -152,7 +153,7 @@ void QuicCryptoClientStream::DoHandshakeLoop( } session()->config()->ToHandshakeMessage(&out); error = crypto_config_->FillClientHello( - server_key_.host(), + server_key_, session()->connection()->connection_id(), session()->connection()->supported_versions().front(), cached, @@ -214,10 +215,9 @@ void QuicCryptoClientStream::DoHandshakeLoop( return; } if (!cached->proof_valid()) { - ProofVerifier* verifier = crypto_config_->proof_verifier(); - if (!verifier) { - // If no verifier is set then we don't check the certificates. - SetProofValid(cached); + if (!server_key_.is_https()) { + // We don't check the certificates for insecure QUIC connections. + SetCachedProofValid(cached); } else if (!cached->signature().empty()) { next_state_ = STATE_VERIFY_PROOF; break; @@ -274,7 +274,7 @@ void QuicCryptoClientStream::DoHandshakeLoop( if (generation_counter_ != cached->generation_counter()) { next_state_ = STATE_VERIFY_PROOF; } else { - SetProofValid(cached); + SetCachedProofValid(cached); cached->SetProofVerifyDetails(verify_details_.release()); next_state_ = STATE_SEND_CHLO; } @@ -352,7 +352,7 @@ void QuicCryptoClientStream::DoHandshakeLoop( } } -void QuicCryptoClientStream::SetProofValid( +void QuicCryptoClientStream::SetCachedProofValid( QuicCryptoClientConfig::CachedState* cached) { cached->SetProofValid(); if (visitor_) { diff --git a/net/quic/quic_crypto_client_stream.h b/net/quic/quic_crypto_client_stream.h index 812cf43..1c8508e 100644 --- a/net/quic/quic_crypto_client_stream.h +++ b/net/quic/quic_crypto_client_stream.h @@ -104,9 +104,9 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream { // |in| may be NULL if the call did not result from a received message. void DoHandshakeLoop(const CryptoHandshakeMessage* in); - // Called to set the proof of |cache| valid. Also invokes the visitor's + // Called to set the proof of |cached| valid. Also invokes the visitor's // OnProofValid() method. - void SetProofValid(QuicCryptoClientConfig::CachedState* cached); + void SetCachedProofValid(QuicCryptoClientConfig::CachedState* cached); Visitor* visitor_; diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index 06b5134..2d94951 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc @@ -77,7 +77,6 @@ class QuicStreamFactory::Job { const HostPortPair& host_port_pair, bool is_https, base::StringPiece method, - CertVerifier* cert_verifier, QuicServerInfo* server_info, const BoundNetLog& net_log); @@ -120,7 +119,6 @@ class QuicStreamFactory::Job { bool is_https_; QuicSessionKey session_key_; bool is_post_; - CertVerifier* cert_verifier_; scoped_ptr<QuicServerInfo> server_info_; const BoundNetLog net_log_; QuicClientSession* session_; @@ -136,7 +134,6 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory, const HostPortPair& host_port_pair, bool is_https, base::StringPiece method, - CertVerifier* cert_verifier, QuicServerInfo* server_info, const BoundNetLog& net_log) : factory_(factory), @@ -144,7 +141,6 @@ QuicStreamFactory::Job::Job(QuicStreamFactory* factory, is_https_(is_https), session_key_(host_port_pair, is_https), is_post_(method == "POST"), - cert_verifier_(cert_verifier), server_info_(server_info), net_log_(net_log), session_(NULL), @@ -266,8 +262,8 @@ int QuicStreamFactory::Job::DoConnect() { io_state_ = STATE_CONNECT_COMPLETE; int rv = factory_->CreateSession(session_key_.host_port_pair(), is_https_, - cert_verifier_, server_info_.Pass(), - address_list_, net_log_, &session_); + server_info_.Pass(), address_list_, + net_log_, &session_); if (rv != OK) { DCHECK(rv != ERR_IO_PENDING); DCHECK(!session_); @@ -315,18 +311,15 @@ QuicStreamRequest::~QuicStreamRequest() { int QuicStreamRequest::Request(const HostPortPair& host_port_pair, bool is_https, base::StringPiece method, - CertVerifier* cert_verifier, const BoundNetLog& net_log, const CompletionCallback& callback) { DCHECK(!stream_); DCHECK(callback_.is_null()); DCHECK(factory_); - int rv = factory_->Create(host_port_pair, is_https, - method, cert_verifier, net_log, this); + int rv = factory_->Create(host_port_pair, is_https, method, net_log, this); if (rv == ERR_IO_PENDING) { host_port_pair_ = host_port_pair; is_https_ = is_https; - cert_verifier_ = cert_verifier; net_log_ = net_log; callback_ = callback; } else { @@ -356,6 +349,7 @@ QuicStreamFactory::QuicStreamFactory( HostResolver* host_resolver, ClientSocketFactory* client_socket_factory, base::WeakPtr<HttpServerProperties> http_server_properties, + CertVerifier* cert_verifier, QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory, QuicRandom* random_generator, QuicClock* clock, @@ -367,6 +361,7 @@ QuicStreamFactory::QuicStreamFactory( host_resolver_(host_resolver), client_socket_factory_(client_socket_factory), http_server_properties_(http_server_properties), + cert_verifier_(cert_verifier), quic_server_info_factory_(NULL), quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), random_generator_(random_generator), @@ -383,21 +378,21 @@ QuicStreamFactory::QuicStreamFactory( QuicTime::Delta::FromSeconds(30), QuicTime::Delta::FromSeconds(30)); - canoncial_suffixes_.push_back(string(".c.youtube.com")); - canoncial_suffixes_.push_back(string(".googlevideo.com")); + crypto_config_.SetDefaults(); + crypto_config_.AddCanonicalSuffix(".c.youtube.com"); + crypto_config_.AddCanonicalSuffix(".googlevideo.com"); + crypto_config_.SetProofVerifier(new ProofVerifierChromium(cert_verifier)); } QuicStreamFactory::~QuicStreamFactory() { CloseAllSessions(ERR_ABORTED); STLDeleteElements(&all_sessions_); STLDeleteValues(&active_jobs_); - STLDeleteValues(&all_crypto_configs_); } int QuicStreamFactory::Create(const HostPortPair& host_port_pair, bool is_https, base::StringPiece method, - CertVerifier* cert_verifier, const BoundNetLog& net_log, QuicStreamRequest* request) { QuicSessionKey session_key(host_port_pair, is_https); @@ -415,18 +410,15 @@ int QuicStreamFactory::Create(const HostPortPair& host_port_pair, QuicServerInfo* quic_server_info = NULL; if (quic_server_info_factory_) { - QuicCryptoClientConfig* crypto_config = - GetOrCreateCryptoConfig(session_key); QuicCryptoClientConfig::CachedState* cached = - crypto_config->LookupOrCreate(session_key); + crypto_config_.LookupOrCreate(session_key); DCHECK(cached); if (cached->IsEmpty()) { quic_server_info = quic_server_info_factory_->GetForServer(session_key); } } scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, - is_https, method, cert_verifier, - quic_server_info, net_log)); + is_https, method, quic_server_info, net_log)); int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, base::Unretained(this), job.get())); @@ -651,7 +643,6 @@ bool QuicStreamFactory::HasActiveSession( int QuicStreamFactory::CreateSession( const HostPortPair& host_port_pair, bool is_https, - CertVerifier* cert_verifier, scoped_ptr<QuicServerInfo> server_info, const AddressList& address_list, const BoundNetLog& net_log, @@ -717,9 +708,7 @@ int QuicStreamFactory::CreateSession( writer->SetConnection(connection); connection->options()->max_packet_length = max_packet_length_; - QuicCryptoClientConfig* crypto_config = GetOrCreateCryptoConfig(session_key); - InitializeCachedState(session_key, crypto_config, server_info); - DCHECK(crypto_config); + InitializeCachedState(session_key, server_info); QuicConfig config = config_; if (http_server_properties_) { @@ -734,11 +723,8 @@ int QuicStreamFactory::CreateSession( *session = new QuicClientSession( connection, socket.Pass(), writer.Pass(), this, quic_crypto_client_stream_factory_, server_info.Pass(), session_key, - config, crypto_config, net_log.net_log()); + config, &crypto_config_, net_log.net_log()); all_sessions_.insert(*session); // owning pointer - if (is_https) { - crypto_config->SetProofVerifier(new ProofVerifierChromium(cert_verifier)); - } return OK; } @@ -758,72 +744,14 @@ void QuicStreamFactory::ActivateSession( ip_aliases_[ip_alias_key].insert(session); } -QuicCryptoClientConfig* QuicStreamFactory::GetOrCreateCryptoConfig( - const QuicSessionKey& session_key) { - QuicCryptoClientConfig* crypto_config; - - if (ContainsKey(all_crypto_configs_, session_key)) { - crypto_config = all_crypto_configs_[session_key]; - DCHECK(crypto_config); - } else { - // TODO(rtenneti): if two quic_sessions for the same host_port_pair - // share the same crypto_config, will it cause issues? - crypto_config = new QuicCryptoClientConfig(); - crypto_config->SetDefaults(); - all_crypto_configs_[session_key] = crypto_config; - PopulateFromCanonicalConfig(session_key, crypto_config); - } - return crypto_config; -} - -void QuicStreamFactory::PopulateFromCanonicalConfig( - const QuicSessionKey& session_key, - QuicCryptoClientConfig* crypto_config) { - const string server_hostname = session_key.host(); - unsigned i = 0; - for (; i < canoncial_suffixes_.size(); ++i) { - if (EndsWith(server_hostname, canoncial_suffixes_[i], false)) { - break; - } - } - if (i == canoncial_suffixes_.size()) - return; - - HostPortPair suffix_host_port_pair(canoncial_suffixes_[i], - session_key.port()); - QuicSessionKey suffix_session_key(suffix_host_port_pair, - session_key.is_https()); - if (!ContainsKey(canonical_hostname_to_origin_map_, suffix_session_key)) { - // This is the first host we've seen which matches the suffix, so make it - // canonical. - canonical_hostname_to_origin_map_[suffix_session_key] = session_key; - return; - } - - const QuicSessionKey& canonical_session_key = - canonical_hostname_to_origin_map_[suffix_session_key]; - QuicCryptoClientConfig* canonical_crypto_config = - all_crypto_configs_[canonical_session_key]; - DCHECK(canonical_crypto_config); - - // Copy the CachedState for the canonical server from canonical_crypto_config - // as the initial CachedState for the server_hostname in crypto_config. - crypto_config->InitializeFrom(session_key, canonical_session_key, - canonical_crypto_config); - // Update canonical version to point at the "most recent" crypto_config. - canonical_hostname_to_origin_map_[suffix_session_key] = - canonical_session_key; -} - void QuicStreamFactory::InitializeCachedState( const QuicSessionKey& session_key, - QuicCryptoClientConfig* crypto_config, const scoped_ptr<QuicServerInfo>& server_info) { if (!server_info) return; QuicCryptoClientConfig::CachedState* cached = - crypto_config->LookupOrCreate(session_key); + crypto_config_.LookupOrCreate(session_key); if (!cached->IsEmpty()) return; @@ -834,8 +762,8 @@ void QuicStreamFactory::InitializeCachedState( clock_->WallNow())) return; - if (!crypto_config->proof_verifier()) { - // If no verifier is set then we don't check the certificates. + if (!session_key.is_https()) { + // Don't check the certificates for insecure QUIC. cached->SetProofValid(); } } diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h index 61806a7..44686c8 100644 --- a/net/quic/quic_stream_factory.h +++ b/net/quic/quic_stream_factory.h @@ -55,7 +55,6 @@ class NET_EXPORT_PRIVATE QuicStreamRequest { int Request(const HostPortPair& host_port_pair, bool is_https, base::StringPiece method, - CertVerifier* cert_verifier, const BoundNetLog& net_log, const CompletionCallback& callback); @@ -73,7 +72,6 @@ class NET_EXPORT_PRIVATE QuicStreamRequest { QuicStreamFactory* factory_; HostPortPair host_port_pair_; bool is_https_; - CertVerifier* cert_verifier_; BoundNetLog net_log_; CompletionCallback callback_; scoped_ptr<QuicHttpStream> stream_; @@ -91,6 +89,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory HostResolver* host_resolver, ClientSocketFactory* client_socket_factory, base::WeakPtr<HttpServerProperties> http_server_properties, + CertVerifier* cert_verifier, QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory, QuicRandom* random_generator, QuicClock* clock, @@ -110,7 +109,6 @@ class NET_EXPORT_PRIVATE QuicStreamFactory int Create(const HostPortPair& host_port_pair, bool is_https, base::StringPiece method, - CertVerifier* cert_verifier, const BoundNetLog& net_log, QuicStreamRequest* request); @@ -187,7 +185,6 @@ class NET_EXPORT_PRIVATE QuicStreamFactory typedef std::set<QuicClientSession*> SessionSet; typedef std::map<IpAliasKey, SessionSet> IPAliasMap; typedef std::map<QuicSessionKey, QuicCryptoClientConfig*> CryptoConfigMap; - typedef std::map<QuicSessionKey, QuicSessionKey> CanonicalHostMap; typedef std::map<QuicSessionKey, Job*> JobMap; typedef std::map<QuicStreamRequest*, Job*> RequestMap; typedef std::set<QuicStreamRequest*> RequestSet; @@ -205,7 +202,6 @@ class NET_EXPORT_PRIVATE QuicStreamFactory bool HasActiveJob(const QuicSessionKey& session_key) const; int CreateSession(const HostPortPair& host_port_pair, bool is_https, - CertVerifier* cert_verifier, scoped_ptr<QuicServerInfo> quic_server_info, const AddressList& address_list, const BoundNetLog& net_log, @@ -213,20 +209,9 @@ class NET_EXPORT_PRIVATE QuicStreamFactory void ActivateSession(const QuicSessionKey& key, QuicClientSession* session); - QuicCryptoClientConfig* GetOrCreateCryptoConfig( - const QuicSessionKey& session_key); - - // If the suffix of the hostname in |session_key| is in |canoncial_suffixes_|, - // then populate |crypto_config| with a canonical server config data from - // |canonical_hostname_to_origin_map_| for that suffix. - void PopulateFromCanonicalConfig( - const QuicSessionKey& session_key, - QuicCryptoClientConfig* crypto_config); - // Initializes the cached state associated with |session_key| in - // |crypto_config| with the information in |server_info|. + // |crypto_config_| with the information in |server_info|. void InitializeCachedState(const QuicSessionKey& session_key, - QuicCryptoClientConfig* crypto_config, const scoped_ptr<QuicServerInfo>& server_info); void ExpireBrokenAlternateProtocolMappings(); @@ -236,6 +221,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory HostResolver* host_resolver_; ClientSocketFactory* client_socket_factory_; base::WeakPtr<HttpServerProperties> http_server_properties_; + CertVerifier* cert_verifier_; QuicServerInfoFactory* quic_server_info_factory_; QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory_; QuicRandom* random_generator_; @@ -258,23 +244,6 @@ class NET_EXPORT_PRIVATE QuicStreamFactory // Origins which have gone away recently. AliasSet gone_away_aliases_; - // Contains owning pointers to QuicCryptoClientConfig. QuicCryptoClientConfig - // contains configuration and cached state about servers. - // TODO(rtenneti): Persist all_crypto_configs_ to disk and decide when to - // clear the data in the map. - CryptoConfigMap all_crypto_configs_; - - // Contains a map of servers which could share the same server config. Map - // from a Canonical host/port/scheme (host is some postfix of host names) to - // an actual origin, which has a plausible set of initial certificates (or at - // least server public key). - CanonicalHostMap canonical_hostname_to_origin_map_; - - // Contains list of suffixes (for exmaple ".c.youtube.com", - // ".googlevideo.com") of canoncial hostnames. - std::vector<std::string> canoncial_suffixes_; - - // List of broken host:ports and the times when they can be expired. struct BrokenAlternateProtocolEntry { HostPortPair origin; @@ -290,6 +259,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory BrokenAlternateProtocolMap broken_alternate_protocol_map_; QuicConfig config_; + QuicCryptoClientConfig crypto_config_; JobMap active_jobs_; JobRequestsMap job_requests_map_; diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index f7e271c..8aed98b 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc @@ -41,12 +41,8 @@ const int kDefaultServerPort = 443; class QuicStreamFactoryPeer { public: - static QuicCryptoClientConfig* GetOrCreateCryptoConfig( - QuicStreamFactory* factory, - const HostPortPair& host_port_pair, - bool is_https) { - QuicSessionKey server_key(host_port_pair, is_https); - return factory->GetOrCreateCryptoConfig(server_key); + static QuicCryptoClientConfig* GetCryptoConfig(QuicStreamFactory* factory) { + return &factory->crypto_config_; } static bool HasActiveSession(QuicStreamFactory* factory, @@ -92,14 +88,15 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<QuicVersion> { : random_generator_(0), maker_(GetParam(), 0), clock_(new MockClock()), + cert_verifier_(CertVerifier::CreateDefault()), factory_(&host_resolver_, &socket_factory_, base::WeakPtr<HttpServerProperties>(), + cert_verifier_.get(), &crypto_client_stream_factory_, &random_generator_, clock_, kDefaultMaxPacketSize, SupportedVersions(GetParam()), true, true), host_port_pair_(kDefaultServerHostName, kDefaultServerPort), - is_https_(false), - cert_verifier_(CertVerifier::CreateDefault()) { + is_https_(false) { factory_.set_require_confirmation(false); } @@ -137,7 +134,6 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<QuicVersion> { request.Request(destination, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -181,10 +177,10 @@ class QuicStreamFactoryTest : public ::testing::TestWithParam<QuicVersion> { MockRandom random_generator_; QuicTestPacketMaker maker_; MockClock* clock_; // Owned by factory_. + scoped_ptr<CertVerifier> cert_verifier_; QuicStreamFactory factory_; HostPortPair host_port_pair_; bool is_https_; - scoped_ptr<CertVerifier> cert_verifier_; BoundNetLog net_log_; TestCompletionCallback callback_; }; @@ -209,7 +205,6 @@ TEST_P(QuicStreamFactoryTest, Create) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -228,7 +223,6 @@ TEST_P(QuicStreamFactoryTest, Create) { request2.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); stream = request2.ReleaseStream(); // Will reset stream 5. @@ -254,7 +248,6 @@ TEST_P(QuicStreamFactoryTest, CreateHttpVsHttps) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -267,7 +260,6 @@ TEST_P(QuicStreamFactoryTest, CreateHttpVsHttps) { request2.Request(host_port_pair_, !is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); EXPECT_EQ(OK, callback_.WaitForResult()); @@ -306,7 +298,6 @@ TEST_P(QuicStreamFactoryTest, Pooling) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); @@ -318,7 +309,6 @@ TEST_P(QuicStreamFactoryTest, Pooling) { request2.Request(server2, is_https_, "GET", - cert_verifier_.get(), net_log_, callback.callback())); scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream(); @@ -356,7 +346,6 @@ TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); @@ -368,7 +357,6 @@ TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) { request2.Request(server2, is_https_, "GET", - cert_verifier_.get(), net_log_, callback.callback())); scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream(); @@ -387,7 +375,6 @@ TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) { request3.Request(server2, is_https_, "GET", - cert_verifier_.get(), net_log_, callback3.callback())); scoped_ptr<QuicHttpStream> stream3 = request3.ReleaseStream(); @@ -435,7 +422,6 @@ TEST_P(QuicStreamFactoryTest, HttpsPooling) { request.Request(server1, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); @@ -447,7 +433,6 @@ TEST_P(QuicStreamFactoryTest, HttpsPooling) { request2.Request(server2, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream(); @@ -500,7 +485,6 @@ TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithCertMismatch) { request.Request(server1, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); @@ -512,7 +496,6 @@ TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithCertMismatch) { request2.Request(server2, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream(); @@ -545,7 +528,6 @@ TEST_P(QuicStreamFactoryTest, Goaway) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -570,7 +552,6 @@ TEST_P(QuicStreamFactoryTest, Goaway) { request2.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); EXPECT_EQ(OK, callback_.WaitForResult()); @@ -618,7 +599,6 @@ TEST_P(QuicStreamFactoryTest, MaxOpenStream) { int rv = request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback()); if (i == 0) { @@ -639,7 +619,6 @@ TEST_P(QuicStreamFactoryTest, MaxOpenStream) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, CompletionCallback())); scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); @@ -670,7 +649,6 @@ TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -692,7 +670,6 @@ TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -714,7 +691,6 @@ TEST_P(QuicStreamFactoryTest, CancelCreate) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); } @@ -782,7 +758,6 @@ TEST_P(QuicStreamFactoryTest, CloseAllSessions) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -806,7 +781,6 @@ TEST_P(QuicStreamFactoryTest, CloseAllSessions) { request2.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -846,7 +820,6 @@ TEST_P(QuicStreamFactoryTest, OnIPAddressChanged) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -871,7 +844,6 @@ TEST_P(QuicStreamFactoryTest, OnIPAddressChanged) { request2.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -911,7 +883,6 @@ TEST_P(QuicStreamFactoryTest, OnCertAdded) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -936,7 +907,6 @@ TEST_P(QuicStreamFactoryTest, OnCertAdded) { request2.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -976,7 +946,6 @@ TEST_P(QuicStreamFactoryTest, OnCACertChanged) { request.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -1001,7 +970,6 @@ TEST_P(QuicStreamFactoryTest, OnCACertChanged) { request2.Request(host_port_pair_, is_https_, "GET", - cert_verifier_.get(), net_log_, callback_.callback())); @@ -1027,13 +995,11 @@ TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) { r2_host_name.append(cannoncial_suffixes[i]); HostPortPair host_port_pair1(r1_host_name, 80); - QuicCryptoClientConfig* crypto_config1 = - QuicStreamFactoryPeer::GetOrCreateCryptoConfig( - &factory_, host_port_pair1, is_https_); - DCHECK(crypto_config1); + QuicCryptoClientConfig* crypto_config = + QuicStreamFactoryPeer::GetCryptoConfig(&factory_); QuicSessionKey server_key1(host_port_pair1, is_https_); QuicCryptoClientConfig::CachedState* cached1 = - crypto_config1->LookupOrCreate(server_key1); + crypto_config->LookupOrCreate(server_key1); EXPECT_FALSE(cached1->proof_valid()); EXPECT_TRUE(cached1->source_address_token().empty()); @@ -1043,13 +1009,9 @@ TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) { cached1->SetProofValid(); HostPortPair host_port_pair2(r2_host_name, 80); - QuicCryptoClientConfig* crypto_config2 = - QuicStreamFactoryPeer::GetOrCreateCryptoConfig( - &factory_, host_port_pair2, is_https_); - DCHECK(crypto_config2); QuicSessionKey server_key2(host_port_pair2, is_https_); QuicCryptoClientConfig::CachedState* cached2 = - crypto_config2->LookupOrCreate(server_key2); + crypto_config->LookupOrCreate(server_key2); EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token()); EXPECT_TRUE(cached2->proof_valid()); } @@ -1067,13 +1029,11 @@ TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) { r4_host_name.append(cannoncial_suffixes[i]); HostPortPair host_port_pair1(r3_host_name, 80); - QuicCryptoClientConfig* crypto_config1 = - QuicStreamFactoryPeer::GetOrCreateCryptoConfig( - &factory_, host_port_pair1, is_https_); - DCHECK(crypto_config1); + QuicCryptoClientConfig* crypto_config = + QuicStreamFactoryPeer::GetCryptoConfig(&factory_); QuicSessionKey server_key1(host_port_pair1, is_https_); QuicCryptoClientConfig::CachedState* cached1 = - crypto_config1->LookupOrCreate(server_key1); + crypto_config->LookupOrCreate(server_key1); EXPECT_FALSE(cached1->proof_valid()); EXPECT_TRUE(cached1->source_address_token().empty()); @@ -1083,13 +1043,9 @@ TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) { cached1->SetProofInvalid(); HostPortPair host_port_pair2(r4_host_name, 80); - QuicCryptoClientConfig* crypto_config2 = - QuicStreamFactoryPeer::GetOrCreateCryptoConfig( - &factory_, host_port_pair2, is_https_); - DCHECK(crypto_config2); QuicSessionKey server_key2(host_port_pair2, is_https_); QuicCryptoClientConfig::CachedState* cached2 = - crypto_config2->LookupOrCreate(server_key2); + crypto_config->LookupOrCreate(server_key2); EXPECT_NE(cached1->source_address_token(), cached2->source_address_token()); EXPECT_TRUE(cached2->source_address_token().empty()); EXPECT_FALSE(cached2->proof_valid()); diff --git a/net/quic/test_tools/crypto_test_utils.h b/net/quic/test_tools/crypto_test_utils.h index 4a38b0e..1d26dc7 100644 --- a/net/quic/test_tools/crypto_test_utils.h +++ b/net/quic/test_tools/crypto_test_utils.h @@ -98,7 +98,7 @@ class CryptoTestUtils { static ProofVerifier* ProofVerifierForTesting(); // Returns a |ProofVerifyContext| that must be used with the verifier - // returned by ||ProofVerifierForTesting. + // returned by |ProofVerifierForTesting|. static ProofVerifyContext* ProofVerifyContextForTesting(); // MockCommonCertSets returns a CommonCertSets that contains a single set with diff --git a/net/quic/test_tools/crypto_test_utils_chromium.cc b/net/quic/test_tools/crypto_test_utils_chromium.cc index 12dadb1..eb4fec0 100644 --- a/net/quic/test_tools/crypto_test_utils_chromium.cc +++ b/net/quic/test_tools/crypto_test_utils_chromium.cc @@ -42,17 +42,17 @@ ProofSource* CryptoTestUtils::ProofSourceForTesting() { } // static -ProofVerifyContext* CryptoTestUtils::ProofVerifyContextForTesting() { - return new ProofVerifyContextChromium(BoundNetLog()); -} - -// static ProofVerifier* CryptoTestUtils::ProofVerifierForTesting() { TestProofVerifierChromium* proof_verifier = new TestProofVerifierChromium( CertVerifier::CreateDefault(), "quic_root.crt"); return proof_verifier; } +// static +ProofVerifyContext* CryptoTestUtils::ProofVerifyContextForTesting() { + return new ProofVerifyContextChromium(BoundNetLog()); +} + } // namespace test } // namespace net |