| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/crypto/quic_crypto_client_config.h" | 5 #include "net/quic/crypto/quic_crypto_client_config.h" |
| 6 | 6 |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "net/quic/crypto/cert_compressor.h" | 8 #include "net/quic/crypto/cert_compressor.h" |
| 9 #include "net/quic/crypto/channel_id.h" | 9 #include "net/quic/crypto/channel_id.h" |
| 10 #include "net/quic/crypto/common_cert_set.h" | 10 #include "net/quic/crypto/common_cert_set.h" |
| 11 #include "net/quic/crypto/crypto_framer.h" | 11 #include "net/quic/crypto/crypto_framer.h" |
| 12 #include "net/quic/crypto/crypto_utils.h" | 12 #include "net/quic/crypto/crypto_utils.h" |
| 13 #include "net/quic/crypto/curve25519_key_exchange.h" | 13 #include "net/quic/crypto/curve25519_key_exchange.h" |
| 14 #include "net/quic/crypto/key_exchange.h" | 14 #include "net/quic/crypto/key_exchange.h" |
| 15 #include "net/quic/crypto/p256_key_exchange.h" | 15 #include "net/quic/crypto/p256_key_exchange.h" |
| 16 #include "net/quic/crypto/proof_verifier.h" | 16 #include "net/quic/crypto/proof_verifier.h" |
| 17 #include "net/quic/crypto/quic_encrypter.h" | 17 #include "net/quic/crypto/quic_encrypter.h" |
| 18 #include "net/quic/crypto/quic_server_info.h" | |
| 19 #include "net/quic/quic_utils.h" | 18 #include "net/quic/quic_utils.h" |
| 20 | 19 |
| 21 #if defined(OS_WIN) | 20 #if defined(OS_WIN) |
| 22 #include "base/win/windows_version.h" | 21 #include "base/win/windows_version.h" |
| 23 #endif | 22 #endif |
| 24 | 23 |
| 25 using base::StringPiece; | 24 using base::StringPiece; |
| 26 using std::map; | 25 using std::map; |
| 27 using std::string; | 26 using std::string; |
| 28 using std::vector; | 27 using std::vector; |
| 29 | 28 |
| 30 namespace net { | 29 namespace net { |
| 31 | 30 |
| 32 QuicCryptoClientConfig::QuicCryptoClientConfig() {} | 31 QuicCryptoClientConfig::QuicCryptoClientConfig() {} |
| 33 | 32 |
| 34 QuicCryptoClientConfig::~QuicCryptoClientConfig() { | 33 QuicCryptoClientConfig::~QuicCryptoClientConfig() { |
| 35 STLDeleteValues(&cached_states_); | 34 STLDeleteValues(&cached_states_); |
| 36 } | 35 } |
| 37 | 36 |
| 38 QuicCryptoClientConfig::CachedState::CachedState() | 37 QuicCryptoClientConfig::CachedState::CachedState() |
| 39 : server_config_valid_(false), | 38 : server_config_valid_(false), |
| 40 need_to_persist_(false), | |
| 41 generation_counter_(0) {} | 39 generation_counter_(0) {} |
| 42 | 40 |
| 43 QuicCryptoClientConfig::CachedState::CachedState( | |
| 44 scoped_ptr<QuicServerInfo> quic_server_info) | |
| 45 : server_config_valid_(false), | |
| 46 need_to_persist_(false), | |
| 47 generation_counter_(0), | |
| 48 quic_server_info_(quic_server_info.Pass()) {} | |
| 49 | |
| 50 QuicCryptoClientConfig::CachedState::~CachedState() {} | 41 QuicCryptoClientConfig::CachedState::~CachedState() {} |
| 51 | 42 |
| 52 bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const { | 43 bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const { |
| 53 if (server_config_.empty() || !server_config_valid_) { | 44 if (server_config_.empty() || !server_config_valid_) { |
| 54 return false; | 45 return false; |
| 55 } | 46 } |
| 56 | 47 |
| 57 const CryptoHandshakeMessage* scfg = GetServerConfig(); | 48 const CryptoHandshakeMessage* scfg = GetServerConfig(); |
| 58 if (!scfg) { | 49 if (!scfg) { |
| 59 // Should be impossible short of cache corruption. | 50 // Should be impossible short of cache corruption. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 | 107 |
| 117 if (now.ToUNIXSeconds() >= expiry_seconds) { | 108 if (now.ToUNIXSeconds() >= expiry_seconds) { |
| 118 *error_details = "SCFG has expired"; | 109 *error_details = "SCFG has expired"; |
| 119 return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED; | 110 return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED; |
| 120 } | 111 } |
| 121 | 112 |
| 122 if (!matches_existing) { | 113 if (!matches_existing) { |
| 123 server_config_ = server_config.as_string(); | 114 server_config_ = server_config.as_string(); |
| 124 SetProofInvalid(); | 115 SetProofInvalid(); |
| 125 scfg_.reset(new_scfg_storage.release()); | 116 scfg_.reset(new_scfg_storage.release()); |
| 126 need_to_persist_ = true; | |
| 127 } | 117 } |
| 128 return QUIC_NO_ERROR; | 118 return QUIC_NO_ERROR; |
| 129 } | 119 } |
| 130 | 120 |
| 131 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { | 121 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { |
| 132 server_config_.clear(); | 122 server_config_.clear(); |
| 133 scfg_.reset(); | 123 scfg_.reset(); |
| 134 SetProofInvalid(); | 124 SetProofInvalid(); |
| 135 } | 125 } |
| 136 | 126 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 159 } | 149 } |
| 160 | 150 |
| 161 void QuicCryptoClientConfig::CachedState::ClearProof() { | 151 void QuicCryptoClientConfig::CachedState::ClearProof() { |
| 162 SetProofInvalid(); | 152 SetProofInvalid(); |
| 163 certs_.clear(); | 153 certs_.clear(); |
| 164 server_config_sig_.clear(); | 154 server_config_sig_.clear(); |
| 165 } | 155 } |
| 166 | 156 |
| 167 void QuicCryptoClientConfig::CachedState::SetProofValid() { | 157 void QuicCryptoClientConfig::CachedState::SetProofValid() { |
| 168 server_config_valid_ = true; | 158 server_config_valid_ = true; |
| 169 SaveQuicServerInfo(); | |
| 170 } | 159 } |
| 171 | 160 |
| 172 void QuicCryptoClientConfig::CachedState::SetProofInvalid() { | 161 void QuicCryptoClientConfig::CachedState::SetProofInvalid() { |
| 173 server_config_valid_ = false; | 162 server_config_valid_ = false; |
| 174 ++generation_counter_; | 163 ++generation_counter_; |
| 175 } | 164 } |
| 176 | 165 |
| 166 bool QuicCryptoClientConfig::CachedState::Initialize( |
| 167 StringPiece server_config, |
| 168 StringPiece signature, |
| 169 StringPiece source_address_token, |
| 170 const vector<string>& certs, |
| 171 QuicWallTime now) { |
| 172 DCHECK(server_config_.empty()); |
| 173 |
| 174 if (server_config.empty()) { |
| 175 return false; |
| 176 } |
| 177 |
| 178 string error_details; |
| 179 QuicErrorCode error = SetServerConfig(server_config, now, |
| 180 &error_details); |
| 181 if (error != QUIC_NO_ERROR) { |
| 182 DVLOG(1) << "SetServerConfig failed with " << error_details; |
| 183 return false; |
| 184 } |
| 185 |
| 186 signature.CopyToString(&server_config_sig_); |
| 187 source_address_token.CopyToString(&source_address_token_); |
| 188 certs_ = certs; |
| 189 return true; |
| 190 } |
| 191 |
| 177 const string& QuicCryptoClientConfig::CachedState::server_config() const { | 192 const string& QuicCryptoClientConfig::CachedState::server_config() const { |
| 178 return server_config_; | 193 return server_config_; |
| 179 } | 194 } |
| 180 | 195 |
| 181 const string& | 196 const string& |
| 182 QuicCryptoClientConfig::CachedState::source_address_token() const { | 197 QuicCryptoClientConfig::CachedState::source_address_token() const { |
| 183 return source_address_token_; | 198 return source_address_token_; |
| 184 } | 199 } |
| 185 | 200 |
| 186 const vector<string>& QuicCryptoClientConfig::CachedState::certs() const { | 201 const vector<string>& QuicCryptoClientConfig::CachedState::certs() const { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 197 | 212 |
| 198 uint64 QuicCryptoClientConfig::CachedState::generation_counter() const { | 213 uint64 QuicCryptoClientConfig::CachedState::generation_counter() const { |
| 199 return generation_counter_; | 214 return generation_counter_; |
| 200 } | 215 } |
| 201 | 216 |
| 202 const ProofVerifyDetails* | 217 const ProofVerifyDetails* |
| 203 QuicCryptoClientConfig::CachedState::proof_verify_details() const { | 218 QuicCryptoClientConfig::CachedState::proof_verify_details() const { |
| 204 return proof_verify_details_.get(); | 219 return proof_verify_details_.get(); |
| 205 } | 220 } |
| 206 | 221 |
| 207 QuicServerInfo* QuicCryptoClientConfig::CachedState::quic_server_info() const { | |
| 208 return quic_server_info_.get(); | |
| 209 } | |
| 210 | |
| 211 void QuicCryptoClientConfig::CachedState::set_source_address_token( | 222 void QuicCryptoClientConfig::CachedState::set_source_address_token( |
| 212 StringPiece token) { | 223 StringPiece token) { |
| 213 source_address_token_ = token.as_string(); | 224 source_address_token_ = token.as_string(); |
| 214 } | 225 } |
| 215 | 226 |
| 216 void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails( | 227 void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails( |
| 217 ProofVerifyDetails* details) { | 228 ProofVerifyDetails* details) { |
| 218 proof_verify_details_.reset(details); | 229 proof_verify_details_.reset(details); |
| 219 } | 230 } |
| 220 | 231 |
| 221 void QuicCryptoClientConfig::CachedState::InitializeFrom( | 232 void QuicCryptoClientConfig::CachedState::InitializeFrom( |
| 222 const QuicCryptoClientConfig::CachedState& other) { | 233 const QuicCryptoClientConfig::CachedState& other) { |
| 223 DCHECK(server_config_.empty()); | 234 DCHECK(server_config_.empty()); |
| 224 DCHECK(!server_config_valid_); | 235 DCHECK(!server_config_valid_); |
| 225 server_config_ = other.server_config_; | 236 server_config_ = other.server_config_; |
| 226 source_address_token_ = other.source_address_token_; | 237 source_address_token_ = other.source_address_token_; |
| 227 certs_ = other.certs_; | 238 certs_ = other.certs_; |
| 228 server_config_sig_ = other.server_config_sig_; | 239 server_config_sig_ = other.server_config_sig_; |
| 229 server_config_valid_ = other.server_config_valid_; | 240 server_config_valid_ = other.server_config_valid_; |
| 230 ++generation_counter_; | 241 ++generation_counter_; |
| 231 } | 242 } |
| 232 | 243 |
| 233 // An issue to be solved: while we are loading the data from disk cache, it is | |
| 234 // possible for another request for the same hostname update the CachedState | |
| 235 // because that request has sent FillInchoateClientHello and got REJ message. | |
| 236 // Loading of data from disk cache shouldn't blindly overwrite what is in | |
| 237 // CachedState. | |
| 238 bool QuicCryptoClientConfig::CachedState::LoadQuicServerInfo(QuicWallTime now) { | |
| 239 DCHECK(server_config_.empty()); | |
| 240 DCHECK(quic_server_info_.get()); | |
| 241 DCHECK(quic_server_info_->IsDataReady()); | |
| 242 | |
| 243 const QuicServerInfo::State& state(quic_server_info_->state()); | |
| 244 if (state.server_config.empty()) { | |
| 245 return false; | |
| 246 } | |
| 247 | |
| 248 string error_details; | |
| 249 QuicErrorCode error = SetServerConfig(state.server_config, now, | |
| 250 &error_details); | |
| 251 if (error != QUIC_NO_ERROR) { | |
| 252 DVLOG(1) << "SetServerConfig failed with " << error_details; | |
| 253 return false; | |
| 254 } | |
| 255 | |
| 256 source_address_token_ = state.source_address_token; | |
| 257 server_config_sig_ = state.server_config_sig; | |
| 258 certs_ = state.certs; | |
| 259 need_to_persist_ = false; | |
| 260 return true; | |
| 261 } | |
| 262 | |
| 263 void QuicCryptoClientConfig::CachedState::SaveQuicServerInfo() { | |
| 264 if (!quic_server_info_.get() || !need_to_persist_) { | |
| 265 return; | |
| 266 } | |
| 267 DCHECK(server_config_valid_); | |
| 268 | |
| 269 // If the QuicServerInfo hasn't managed to load from disk yet then we can't | |
| 270 // save anything. TODO(rtenneti): we should fix this. | |
| 271 if (!quic_server_info_->IsDataReady()) { | |
| 272 return; | |
| 273 } | |
| 274 | |
| 275 QuicServerInfo::State* state = quic_server_info_->mutable_state(); | |
| 276 | |
| 277 state->server_config = server_config_; | |
| 278 state->source_address_token = source_address_token_; | |
| 279 state->server_config_sig = server_config_sig_; | |
| 280 state->certs = certs_; | |
| 281 | |
| 282 quic_server_info_->Persist(); | |
| 283 need_to_persist_ = false; | |
| 284 } | |
| 285 | |
| 286 void QuicCryptoClientConfig::SetDefaults() { | 244 void QuicCryptoClientConfig::SetDefaults() { |
| 287 // Key exchange methods. | 245 // Key exchange methods. |
| 288 kexs.resize(2); | 246 kexs.resize(2); |
| 289 kexs[0] = kC255; | 247 kexs[0] = kC255; |
| 290 kexs[1] = kP256; | 248 kexs[1] = kP256; |
| 291 | 249 |
| 292 // Authenticated encryption algorithms. | 250 // Authenticated encryption algorithms. |
| 293 aead.resize(1); | 251 aead.resize(1); |
| 294 aead[0] = kAESG; | 252 aead[0] = kAESG; |
| 295 } | 253 } |
| 296 | 254 |
| 297 QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::Create( | |
| 298 const string& server_hostname, | |
| 299 QuicServerInfoFactory* quic_server_info_factory) { | |
| 300 DCHECK(cached_states_.find(server_hostname) == cached_states_.end()); | |
| 301 scoped_ptr<QuicServerInfo> quic_server_info; | |
| 302 if (quic_server_info_factory) { | |
| 303 quic_server_info.reset( | |
| 304 quic_server_info_factory->GetForHost(server_hostname)); | |
| 305 quic_server_info->Start(); | |
| 306 } | |
| 307 | |
| 308 CachedState* cached = new CachedState(quic_server_info.Pass()); | |
| 309 cached_states_.insert(make_pair(server_hostname, cached)); | |
| 310 return cached; | |
| 311 } | |
| 312 | |
| 313 QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate( | 255 QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate( |
| 314 const string& server_hostname) { | 256 const string& server_hostname) { |
| 315 map<string, CachedState*>::const_iterator it = | 257 map<string, CachedState*>::const_iterator it = |
| 316 cached_states_.find(server_hostname); | 258 cached_states_.find(server_hostname); |
| 317 if (it != cached_states_.end()) { | 259 if (it != cached_states_.end()) { |
| 318 return it->second; | 260 return it->second; |
| 319 } | 261 } |
| 320 return Create(server_hostname, NULL); | 262 |
| 263 CachedState* cached = new CachedState; |
| 264 cached_states_.insert(make_pair(server_hostname, cached)); |
| 265 return cached; |
| 321 } | 266 } |
| 322 | 267 |
| 323 void QuicCryptoClientConfig::FillInchoateClientHello( | 268 void QuicCryptoClientConfig::FillInchoateClientHello( |
| 324 const string& server_hostname, | 269 const string& server_hostname, |
| 325 const QuicVersion preferred_version, | 270 const QuicVersion preferred_version, |
| 326 const CachedState* cached, | 271 const CachedState* cached, |
| 327 QuicCryptoNegotiatedParameters* out_params, | 272 QuicCryptoNegotiatedParameters* out_params, |
| 328 CryptoHandshakeMessage* out) const { | 273 CryptoHandshakeMessage* out) const { |
| 329 out->set_tag(kCHLO); | 274 out->set_tag(kCHLO); |
| 330 out->set_minimum_size(kClientHelloMinimumSize); | 275 out->set_minimum_size(kClientHelloMinimumSize); |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 CachedState* canonical_cached = | 672 CachedState* canonical_cached = |
| 728 canonical_crypto_config->LookupOrCreate(canonical_server_hostname); | 673 canonical_crypto_config->LookupOrCreate(canonical_server_hostname); |
| 729 if (!canonical_cached->proof_valid()) { | 674 if (!canonical_cached->proof_valid()) { |
| 730 return; | 675 return; |
| 731 } | 676 } |
| 732 CachedState* cached = LookupOrCreate(server_hostname); | 677 CachedState* cached = LookupOrCreate(server_hostname); |
| 733 cached->InitializeFrom(*canonical_cached); | 678 cached->InitializeFrom(*canonical_cached); |
| 734 } | 679 } |
| 735 | 680 |
| 736 } // namespace net | 681 } // namespace net |
| OLD | NEW |