Chromium Code Reviews| 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" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 | 31 |
| 32 QuicCryptoClientConfig::QuicCryptoClientConfig() { | 32 QuicCryptoClientConfig::QuicCryptoClientConfig() { |
| 33 } | 33 } |
| 34 | 34 |
| 35 QuicCryptoClientConfig::~QuicCryptoClientConfig() { | 35 QuicCryptoClientConfig::~QuicCryptoClientConfig() { |
| 36 STLDeleteValues(&cached_states_); | 36 STLDeleteValues(&cached_states_); |
| 37 } | 37 } |
| 38 | 38 |
| 39 QuicCryptoClientConfig::CachedState::CachedState() | 39 QuicCryptoClientConfig::CachedState::CachedState() |
| 40 : server_config_valid_(false), | 40 : server_config_valid_(false), |
| 41 need_to_persist_(false), | |
| 41 generation_counter_(0) {} | 42 generation_counter_(0) {} |
| 42 | 43 |
| 43 QuicCryptoClientConfig::CachedState::CachedState( | 44 QuicCryptoClientConfig::CachedState::CachedState( |
| 44 scoped_ptr<QuicServerInfo> quic_server_info) | 45 scoped_ptr<QuicServerInfo> quic_server_info) |
| 45 : server_config_valid_(false), | 46 : server_config_valid_(false), |
| 47 need_to_persist_(false), | |
| 46 generation_counter_(0), | 48 generation_counter_(0), |
| 47 quic_server_info_(quic_server_info.Pass()) {} | 49 quic_server_info_(quic_server_info.Pass()) {} |
| 48 | 50 |
| 49 QuicCryptoClientConfig::CachedState::~CachedState() {} | 51 QuicCryptoClientConfig::CachedState::~CachedState() {} |
| 50 | 52 |
| 51 bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const { | 53 bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const { |
| 52 if (server_config_.empty() || !server_config_valid_) { | 54 if (server_config_.empty() || !server_config_valid_) { |
| 53 return false; | 55 return false; |
| 54 } | 56 } |
| 55 | 57 |
| 56 const CryptoHandshakeMessage* scfg = GetServerConfig(); | 58 const CryptoHandshakeMessage* scfg = GetServerConfig(); |
| 57 if (!scfg) { | 59 if (!scfg) { |
| 58 // Should be impossible short of cache corruption. | 60 // Should be impossible short of cache corruption. |
| 59 DCHECK(false); | 61 DCHECK(false); |
| 60 return false; | 62 return false; |
| 61 } | 63 } |
| 62 | 64 |
| 63 uint64 expiry_seconds; | 65 uint64 expiry_seconds; |
| 64 if (scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR || | 66 if (scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR || |
| 65 now.ToUNIXSeconds() >= expiry_seconds) { | 67 now.ToUNIXSeconds() >= expiry_seconds) { |
| 66 return false; | 68 return false; |
| 67 } | 69 } |
| 68 | 70 |
| 69 return true; | 71 return true; |
| 70 } | 72 } |
| 71 | 73 |
| 74 bool QuicCryptoClientConfig::CachedState::IsEmpty() const { | |
| 75 return server_config_.empty(); | |
| 76 } | |
| 77 | |
| 72 const CryptoHandshakeMessage* | 78 const CryptoHandshakeMessage* |
| 73 QuicCryptoClientConfig::CachedState::GetServerConfig() const { | 79 QuicCryptoClientConfig::CachedState::GetServerConfig() const { |
| 74 if (server_config_.empty()) { | 80 if (server_config_.empty()) { |
| 75 return NULL; | 81 return NULL; |
| 76 } | 82 } |
| 77 | 83 |
| 78 if (!scfg_.get()) { | 84 if (!scfg_.get()) { |
| 79 scfg_.reset(CryptoFramer::ParseMessage(server_config_)); | 85 scfg_.reset(CryptoFramer::ParseMessage(server_config_)); |
| 80 DCHECK(scfg_.get()); | 86 DCHECK(scfg_.get()); |
| 81 } | 87 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 111 | 117 |
| 112 if (now.ToUNIXSeconds() >= expiry_seconds) { | 118 if (now.ToUNIXSeconds() >= expiry_seconds) { |
| 113 *error_details = "SCFG has expired"; | 119 *error_details = "SCFG has expired"; |
| 114 return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED; | 120 return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED; |
| 115 } | 121 } |
| 116 | 122 |
| 117 if (!matches_existing) { | 123 if (!matches_existing) { |
| 118 server_config_ = server_config.as_string(); | 124 server_config_ = server_config.as_string(); |
| 119 SetProofInvalid(); | 125 SetProofInvalid(); |
| 120 scfg_.reset(new_scfg_storage.release()); | 126 scfg_.reset(new_scfg_storage.release()); |
| 127 need_to_persist_ = true; | |
| 121 } | 128 } |
| 122 return QUIC_NO_ERROR; | 129 return QUIC_NO_ERROR; |
| 123 } | 130 } |
| 124 | 131 |
| 125 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { | 132 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { |
| 126 server_config_.clear(); | 133 server_config_.clear(); |
| 127 scfg_.reset(); | 134 scfg_.reset(); |
| 128 SetProofInvalid(); | 135 SetProofInvalid(); |
| 129 } | 136 } |
| 130 | 137 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 153 } | 160 } |
| 154 | 161 |
| 155 void QuicCryptoClientConfig::CachedState::ClearProof() { | 162 void QuicCryptoClientConfig::CachedState::ClearProof() { |
| 156 SetProofInvalid(); | 163 SetProofInvalid(); |
| 157 certs_.clear(); | 164 certs_.clear(); |
| 158 server_config_sig_.clear(); | 165 server_config_sig_.clear(); |
| 159 } | 166 } |
| 160 | 167 |
| 161 void QuicCryptoClientConfig::CachedState::SetProofValid() { | 168 void QuicCryptoClientConfig::CachedState::SetProofValid() { |
| 162 server_config_valid_ = true; | 169 server_config_valid_ = true; |
| 170 SaveQuicServerInfo(); | |
| 163 } | 171 } |
| 164 | 172 |
| 165 void QuicCryptoClientConfig::CachedState::SetProofInvalid() { | 173 void QuicCryptoClientConfig::CachedState::SetProofInvalid() { |
| 166 server_config_valid_ = false; | 174 server_config_valid_ = false; |
| 167 ++generation_counter_; | 175 ++generation_counter_; |
| 168 } | 176 } |
| 169 | 177 |
| 170 const string& QuicCryptoClientConfig::CachedState::server_config() const { | 178 const string& QuicCryptoClientConfig::CachedState::server_config() const { |
| 171 return server_config_; | 179 return server_config_; |
| 172 } | 180 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 190 | 198 |
| 191 uint64 QuicCryptoClientConfig::CachedState::generation_counter() const { | 199 uint64 QuicCryptoClientConfig::CachedState::generation_counter() const { |
| 192 return generation_counter_; | 200 return generation_counter_; |
| 193 } | 201 } |
| 194 | 202 |
| 195 const ProofVerifyDetails* | 203 const ProofVerifyDetails* |
| 196 QuicCryptoClientConfig::CachedState::proof_verify_details() const { | 204 QuicCryptoClientConfig::CachedState::proof_verify_details() const { |
| 197 return proof_verify_details_.get(); | 205 return proof_verify_details_.get(); |
| 198 } | 206 } |
| 199 | 207 |
| 208 QuicServerInfo* QuicCryptoClientConfig::CachedState::quic_server_info() const { | |
| 209 return quic_server_info_.get(); | |
| 210 } | |
| 211 | |
| 200 void QuicCryptoClientConfig::CachedState::set_source_address_token( | 212 void QuicCryptoClientConfig::CachedState::set_source_address_token( |
| 201 StringPiece token) { | 213 StringPiece token) { |
| 202 source_address_token_ = token.as_string(); | 214 source_address_token_ = token.as_string(); |
| 203 } | 215 } |
| 204 | 216 |
| 205 void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails( | 217 void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails( |
| 206 ProofVerifyDetails* details) { | 218 ProofVerifyDetails* details) { |
| 207 proof_verify_details_.reset(details); | 219 proof_verify_details_.reset(details); |
| 208 } | 220 } |
| 209 | 221 |
| 210 void QuicCryptoClientConfig::CachedState::InitializeFrom( | 222 void QuicCryptoClientConfig::CachedState::InitializeFrom( |
| 211 const QuicCryptoClientConfig::CachedState& other) { | 223 const QuicCryptoClientConfig::CachedState& other) { |
| 212 DCHECK(server_config_.empty()); | 224 DCHECK(server_config_.empty()); |
| 213 DCHECK(!server_config_valid_); | 225 DCHECK(!server_config_valid_); |
| 214 server_config_ = other.server_config_; | 226 server_config_ = other.server_config_; |
| 215 source_address_token_ = other.source_address_token_; | 227 source_address_token_ = other.source_address_token_; |
| 216 certs_ = other.certs_; | 228 certs_ = other.certs_; |
| 217 server_config_sig_ = other.server_config_sig_; | 229 server_config_sig_ = other.server_config_sig_; |
| 218 server_config_valid_ = other.server_config_valid_; | 230 server_config_valid_ = other.server_config_valid_; |
| 231 ++generation_counter_; | |
|
wtc
2014/02/20 20:06:16
I verified that whenever we change (set, modify, o
ramant (doing other things)
2014/02/20 23:44:08
We lazily initialize it in GetServerConfig (which
| |
| 232 } | |
| 233 | |
| 234 // TODO(rtenneti): LoadQuicServerInfo and SaveQuicServerInfo have duplication of | |
| 235 // data in CachedState and QuicServerInfo. We should eliminate the duplication | |
| 236 // of data. | |
| 237 // An issue to be solved: while we are loading the data from disk cache, it is | |
| 238 // possible for another request for the same hostname update the CachedState | |
| 239 // because that request has sent FillInchoateClientHello and got REJ message. | |
| 240 // Loading of data from disk cache shouldn't blindly overwrite what is in | |
| 241 // CachedState. | |
| 242 bool QuicCryptoClientConfig::CachedState::LoadQuicServerInfo(QuicWallTime now) { | |
| 243 DCHECK(server_config_.empty()); | |
| 244 DCHECK(quic_server_info_.get()); | |
| 245 DCHECK(quic_server_info_->IsDataReady()); | |
| 246 | |
| 247 const QuicServerInfo::State& state(quic_server_info_->state()); | |
| 248 if (state.server_config.empty()) { | |
| 249 return false; | |
| 250 } | |
| 251 | |
| 252 string error_details; | |
| 253 QuicErrorCode error = SetServerConfig(state.server_config, now, | |
| 254 &error_details); | |
| 255 if (error != QUIC_NO_ERROR) { | |
| 256 DVLOG(1) << "SetServerConfig failed with " << error_details; | |
| 257 return false; | |
| 258 } | |
| 259 | |
| 260 source_address_token_ = state.source_address_token; | |
| 261 server_config_sig_ = state.server_config_sig; | |
| 262 certs_ = state.certs; | |
| 263 need_to_persist_ = false; | |
| 264 return true; | |
| 265 } | |
| 266 | |
| 267 void QuicCryptoClientConfig::CachedState::SaveQuicServerInfo() { | |
| 268 if (!quic_server_info_.get() || !need_to_persist_) { | |
| 269 return; | |
| 270 } | |
| 271 DCHECK(server_config_valid_); | |
| 272 | |
| 273 // If the QuicServerInfo hasn't managed to load from disk yet then we can't | |
| 274 // save anything. TODO(rtenneti): we should fix this. | |
| 275 if (!quic_server_info_->IsDataReady()) { | |
| 276 return; | |
| 277 } | |
| 278 | |
| 279 QuicServerInfo::State* state = quic_server_info_->mutable_state(); | |
| 280 | |
| 281 state->server_config = server_config_; | |
| 282 state->source_address_token = source_address_token_; | |
| 283 state->server_config_sig = server_config_sig_; | |
| 284 state->certs = certs_; | |
| 285 | |
| 286 quic_server_info_->Persist(); | |
| 287 need_to_persist_ = false; | |
| 219 } | 288 } |
| 220 | 289 |
| 221 void QuicCryptoClientConfig::SetDefaults() { | 290 void QuicCryptoClientConfig::SetDefaults() { |
| 222 // Key exchange methods. | 291 // Key exchange methods. |
| 223 kexs.resize(2); | 292 kexs.resize(2); |
| 224 kexs[0] = kC255; | 293 kexs[0] = kC255; |
| 225 kexs[1] = kP256; | 294 kexs[1] = kP256; |
| 226 | 295 |
| 227 // Authenticated encryption algorithms. | 296 // Authenticated encryption algorithms. |
| 228 aead.resize(1); | 297 aead.resize(1); |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 662 CachedState* canonical_cached = | 731 CachedState* canonical_cached = |
| 663 canonical_crypto_config->LookupOrCreate(canonical_server_hostname); | 732 canonical_crypto_config->LookupOrCreate(canonical_server_hostname); |
| 664 if (!canonical_cached->proof_valid()) { | 733 if (!canonical_cached->proof_valid()) { |
| 665 return; | 734 return; |
| 666 } | 735 } |
| 667 CachedState* cached = LookupOrCreate(server_hostname); | 736 CachedState* cached = LookupOrCreate(server_hostname); |
| 668 cached->InitializeFrom(*canonical_cached); | 737 cached->InitializeFrom(*canonical_cached); |
| 669 } | 738 } |
| 670 | 739 |
| 671 } // namespace net | 740 } // namespace net |
| OLD | NEW |