Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(513)

Side by Side Diff: net/quic/crypto/quic_crypto_client_config.cc

Issue 723343002: Update from https://crrev.com/304121 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/crypto/quic_crypto_client_config.h ('k') | net/quic/crypto/quic_server_info.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "base/metrics/sparse_histogram.h" 8 #include "base/metrics/sparse_histogram.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
(...skipping 14 matching lines...) Expand all
25 using std::find; 25 using std::find;
26 using std::make_pair; 26 using std::make_pair;
27 using std::map; 27 using std::map;
28 using std::string; 28 using std::string;
29 using std::vector; 29 using std::vector;
30 30
31 namespace net { 31 namespace net {
32 32
33 namespace { 33 namespace {
34 34
35 enum ServerConfigState { 35 // Tracks the reason (the state of the server config) for sending inchoate
36 // WARNING: Do not change the numerical values of any of server config state. 36 // ClientHello to the server.
37 // Do not remove deprecated server config states - just comment them as 37 void RecordInchoateClientHelloReason(
38 // deprecated. 38 QuicCryptoClientConfig::CachedState::ServerConfigState state) {
39 SERVER_CONFIG_EMPTY = 0, 39 UMA_HISTOGRAM_ENUMERATION(
40 SERVER_CONFIG_INVALID = 1, 40 "Net.QuicInchoateClientHelloReason", state,
41 SERVER_CONFIG_CORRUPTED = 2, 41 QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT);
42 SERVER_CONFIG_EXPIRED = 3, 42 }
43 SERVER_CONFIG_INVALID_EXPIRY = 4,
44 43
45 // NOTE: Add new server config states only immediately above this line. Make 44 // Tracks the state of the QUIC server information loaded from the disk cache.
46 // sure to update the QuicServerConfigState enum in 45 void RecordDiskCacheServerConfigState(
47 // tools/metrics/histograms/histograms.xml accordingly. 46 QuicCryptoClientConfig::CachedState::ServerConfigState state) {
48 SERVER_CONFIG_COUNT 47 UMA_HISTOGRAM_ENUMERATION(
49 }; 48 "Net.QuicServerInfo.DiskCacheState", state,
50 49 QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT);
51 void RecordServerConfigState(ServerConfigState server_config_state) {
52 UMA_HISTOGRAM_ENUMERATION("Net.QuicClientHelloServerConfigState",
53 server_config_state, SERVER_CONFIG_COUNT);
54 } 50 }
55 51
56 } // namespace 52 } // namespace
57 53
58 QuicCryptoClientConfig::QuicCryptoClientConfig() 54 QuicCryptoClientConfig::QuicCryptoClientConfig()
59 : disable_ecdsa_(false) { 55 : disable_ecdsa_(false) {
60 SetDefaults(); 56 SetDefaults();
61 } 57 }
62 58
63 QuicCryptoClientConfig::~QuicCryptoClientConfig() { 59 QuicCryptoClientConfig::~QuicCryptoClientConfig() {
64 STLDeleteValues(&cached_states_); 60 STLDeleteValues(&cached_states_);
65 } 61 }
66 62
67 QuicCryptoClientConfig::CachedState::CachedState() 63 QuicCryptoClientConfig::CachedState::CachedState()
68 : server_config_valid_(false), 64 : server_config_valid_(false),
69 generation_counter_(0) {} 65 generation_counter_(0) {}
70 66
71 QuicCryptoClientConfig::CachedState::~CachedState() {} 67 QuicCryptoClientConfig::CachedState::~CachedState() {}
72 68
73 bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const { 69 bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const {
74 if (server_config_.empty()) { 70 if (server_config_.empty()) {
75 RecordServerConfigState(SERVER_CONFIG_EMPTY); 71 RecordInchoateClientHelloReason(SERVER_CONFIG_EMPTY);
76 return false; 72 return false;
77 } 73 }
78 74
79 if (!server_config_valid_) { 75 if (!server_config_valid_) {
80 RecordServerConfigState(SERVER_CONFIG_INVALID); 76 RecordInchoateClientHelloReason(SERVER_CONFIG_INVALID);
81 return false; 77 return false;
82 } 78 }
83 79
84 const CryptoHandshakeMessage* scfg = GetServerConfig(); 80 const CryptoHandshakeMessage* scfg = GetServerConfig();
85 if (!scfg) { 81 if (!scfg) {
86 // Should be impossible short of cache corruption. 82 // Should be impossible short of cache corruption.
87 DCHECK(false); 83 DCHECK(false);
88 RecordServerConfigState(SERVER_CONFIG_CORRUPTED); 84 RecordInchoateClientHelloReason(SERVER_CONFIG_CORRUPTED);
89 return false; 85 return false;
90 } 86 }
91 87
92 uint64 expiry_seconds; 88 uint64 expiry_seconds;
93 if (scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) { 89 if (scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
94 RecordServerConfigState(SERVER_CONFIG_INVALID_EXPIRY); 90 RecordInchoateClientHelloReason(SERVER_CONFIG_INVALID_EXPIRY);
95 return false; 91 return false;
96 } 92 }
97 if (now.ToUNIXSeconds() >= expiry_seconds) { 93 if (now.ToUNIXSeconds() >= expiry_seconds) {
98 UMA_HISTOGRAM_CUSTOM_TIMES( 94 UMA_HISTOGRAM_CUSTOM_TIMES(
99 "Net.QuicClientHelloServerConfig.InvalidDuration", 95 "Net.QuicClientHelloServerConfig.InvalidDuration",
100 base::TimeDelta::FromSeconds(now.ToUNIXSeconds() - expiry_seconds), 96 base::TimeDelta::FromSeconds(now.ToUNIXSeconds() - expiry_seconds),
101 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromDays(20), 50); 97 base::TimeDelta::FromMinutes(1), base::TimeDelta::FromDays(20), 50);
102 RecordServerConfigState(SERVER_CONFIG_EXPIRED); 98 RecordInchoateClientHelloReason(SERVER_CONFIG_EXPIRED);
103 return false; 99 return false;
104 } 100 }
105 101
106 return true; 102 return true;
107 } 103 }
108 104
109 bool QuicCryptoClientConfig::CachedState::IsEmpty() const { 105 bool QuicCryptoClientConfig::CachedState::IsEmpty() const {
110 return server_config_.empty(); 106 return server_config_.empty();
111 } 107 }
112 108
113 const CryptoHandshakeMessage* 109 const CryptoHandshakeMessage*
114 QuicCryptoClientConfig::CachedState::GetServerConfig() const { 110 QuicCryptoClientConfig::CachedState::GetServerConfig() const {
115 if (server_config_.empty()) { 111 if (server_config_.empty()) {
116 return nullptr; 112 return nullptr;
117 } 113 }
118 114
119 if (!scfg_.get()) { 115 if (!scfg_.get()) {
120 scfg_.reset(CryptoFramer::ParseMessage(server_config_)); 116 scfg_.reset(CryptoFramer::ParseMessage(server_config_));
121 DCHECK(scfg_.get()); 117 DCHECK(scfg_.get());
122 } 118 }
123 return scfg_.get(); 119 return scfg_.get();
124 } 120 }
125 121
126 QuicErrorCode QuicCryptoClientConfig::CachedState::SetServerConfig( 122 QuicCryptoClientConfig::CachedState::ServerConfigState
123 QuicCryptoClientConfig::CachedState::SetServerConfig(
127 StringPiece server_config, QuicWallTime now, string* error_details) { 124 StringPiece server_config, QuicWallTime now, string* error_details) {
128 const bool matches_existing = server_config == server_config_; 125 const bool matches_existing = server_config == server_config_;
129 126
130 // Even if the new server config matches the existing one, we still wish to 127 // Even if the new server config matches the existing one, we still wish to
131 // reject it if it has expired. 128 // reject it if it has expired.
132 scoped_ptr<CryptoHandshakeMessage> new_scfg_storage; 129 scoped_ptr<CryptoHandshakeMessage> new_scfg_storage;
133 const CryptoHandshakeMessage* new_scfg; 130 const CryptoHandshakeMessage* new_scfg;
134 131
135 if (!matches_existing) { 132 if (!matches_existing) {
136 new_scfg_storage.reset(CryptoFramer::ParseMessage(server_config)); 133 new_scfg_storage.reset(CryptoFramer::ParseMessage(server_config));
137 new_scfg = new_scfg_storage.get(); 134 new_scfg = new_scfg_storage.get();
138 } else { 135 } else {
139 new_scfg = GetServerConfig(); 136 new_scfg = GetServerConfig();
140 } 137 }
141 138
142 if (!new_scfg) { 139 if (!new_scfg) {
143 *error_details = "SCFG invalid"; 140 *error_details = "SCFG invalid";
144 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 141 return SERVER_CONFIG_INVALID;
145 } 142 }
146 143
147 uint64 expiry_seconds; 144 uint64 expiry_seconds;
148 if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) { 145 if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
149 *error_details = "SCFG missing EXPY"; 146 *error_details = "SCFG missing EXPY";
150 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 147 return SERVER_CONFIG_INVALID_EXPIRY;
151 } 148 }
152 149
153 if (now.ToUNIXSeconds() >= expiry_seconds) { 150 if (now.ToUNIXSeconds() >= expiry_seconds) {
154 *error_details = "SCFG has expired"; 151 *error_details = "SCFG has expired";
155 return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED; 152 return SERVER_CONFIG_EXPIRED;
156 } 153 }
157 154
158 if (!matches_existing) { 155 if (!matches_existing) {
159 server_config_ = server_config.as_string(); 156 server_config_ = server_config.as_string();
160 SetProofInvalid(); 157 SetProofInvalid();
161 scfg_.reset(new_scfg_storage.release()); 158 scfg_.reset(new_scfg_storage.release());
162 } 159 }
163 return QUIC_NO_ERROR; 160 return SERVER_CONFIG_VALID;
164 } 161 }
165 162
166 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { 163 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() {
167 server_config_.clear(); 164 server_config_.clear();
168 scfg_.reset(); 165 scfg_.reset();
169 SetProofInvalid(); 166 SetProofInvalid();
170 } 167 }
171 168
172 void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs, 169 void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs,
173 StringPiece signature) { 170 StringPiece signature) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 218
222 bool QuicCryptoClientConfig::CachedState::Initialize( 219 bool QuicCryptoClientConfig::CachedState::Initialize(
223 StringPiece server_config, 220 StringPiece server_config,
224 StringPiece source_address_token, 221 StringPiece source_address_token,
225 const vector<string>& certs, 222 const vector<string>& certs,
226 StringPiece signature, 223 StringPiece signature,
227 QuicWallTime now) { 224 QuicWallTime now) {
228 DCHECK(server_config_.empty()); 225 DCHECK(server_config_.empty());
229 226
230 if (server_config.empty()) { 227 if (server_config.empty()) {
228 RecordDiskCacheServerConfigState(SERVER_CONFIG_EMPTY);
231 return false; 229 return false;
232 } 230 }
233 231
234 string error_details; 232 string error_details;
235 QuicErrorCode error = SetServerConfig(server_config, now, 233 ServerConfigState state = SetServerConfig(server_config, now,
236 &error_details); 234 &error_details);
237 if (error != QUIC_NO_ERROR) { 235 RecordDiskCacheServerConfigState(state);
236 if (state != SERVER_CONFIG_VALID) {
238 DVLOG(1) << "SetServerConfig failed with " << error_details; 237 DVLOG(1) << "SetServerConfig failed with " << error_details;
239 return false; 238 return false;
240 } 239 }
241 240
242 signature.CopyToString(&server_config_sig_); 241 signature.CopyToString(&server_config_sig_);
243 source_address_token.CopyToString(&source_address_token_); 242 source_address_token.CopyToString(&source_address_token_);
244 certs_ = certs; 243 certs_ = certs;
245 return true; 244 return true;
246 } 245 }
247 246
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 317
319 QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate( 318 QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate(
320 const QuicServerId& server_id) { 319 const QuicServerId& server_id) {
321 CachedStateMap::const_iterator it = cached_states_.find(server_id); 320 CachedStateMap::const_iterator it = cached_states_.find(server_id);
322 if (it != cached_states_.end()) { 321 if (it != cached_states_.end()) {
323 return it->second; 322 return it->second;
324 } 323 }
325 324
326 CachedState* cached = new CachedState; 325 CachedState* cached = new CachedState;
327 cached_states_.insert(make_pair(server_id, cached)); 326 cached_states_.insert(make_pair(server_id, cached));
328 PopulateFromCanonicalConfig(server_id, cached); 327 bool cache_populated = PopulateFromCanonicalConfig(server_id, cached);
328 UMA_HISTOGRAM_BOOLEAN(
329 "Net.QuicCryptoClientConfig.PopulatedFromCanonicalConfig",
330 cache_populated);
329 return cached; 331 return cached;
330 } 332 }
331 333
332 void QuicCryptoClientConfig::ClearCachedStates() { 334 void QuicCryptoClientConfig::ClearCachedStates() {
333 for (CachedStateMap::const_iterator it = cached_states_.begin(); 335 for (CachedStateMap::const_iterator it = cached_states_.begin();
334 it != cached_states_.end(); ++it) { 336 it != cached_states_.end(); ++it) {
335 it->second->Clear(); 337 it->second->Clear();
336 } 338 }
337 } 339 }
338 340
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 CachedState* cached, 586 CachedState* cached,
585 string* error_details) { 587 string* error_details) {
586 DCHECK(error_details != nullptr); 588 DCHECK(error_details != nullptr);
587 589
588 StringPiece scfg; 590 StringPiece scfg;
589 if (!message.GetStringPiece(kSCFG, &scfg)) { 591 if (!message.GetStringPiece(kSCFG, &scfg)) {
590 *error_details = "Missing SCFG"; 592 *error_details = "Missing SCFG";
591 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; 593 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
592 } 594 }
593 595
594 QuicErrorCode error = cached->SetServerConfig(scfg, now, error_details); 596 CachedState::ServerConfigState state = cached->SetServerConfig(
595 if (error != QUIC_NO_ERROR) { 597 scfg, now, error_details);
596 return error; 598 if (state == CachedState::SERVER_CONFIG_EXPIRED) {
599 return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED;
600 }
601 // TODO(rtenneti): Return more specific error code than returning
602 // QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER.
603 if (state != CachedState::SERVER_CONFIG_VALID) {
604 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
597 } 605 }
598 606
599 StringPiece token; 607 StringPiece token;
600 if (message.GetStringPiece(kSourceAddressTokenTag, &token)) { 608 if (message.GetStringPiece(kSourceAddressTokenTag, &token)) {
601 cached->set_source_address_token(token); 609 cached->set_source_address_token(token);
602 } 610 }
603 611
604 StringPiece proof, cert_bytes; 612 StringPiece proof, cert_bytes;
605 bool has_proof = message.GetStringPiece(kPROF, &proof); 613 bool has_proof = message.GetStringPiece(kPROF, &proof);
606 bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes); 614 bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes);
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 if (pos != aead.end()) { 830 if (pos != aead.end()) {
823 aead.erase(pos); 831 aead.erase(pos);
824 aead.insert(aead.begin(), kAESG); 832 aead.insert(aead.begin(), kAESG);
825 } 833 }
826 } 834 }
827 835
828 void QuicCryptoClientConfig::DisableEcdsa() { 836 void QuicCryptoClientConfig::DisableEcdsa() {
829 disable_ecdsa_ = true; 837 disable_ecdsa_ = true;
830 } 838 }
831 839
832 void QuicCryptoClientConfig::PopulateFromCanonicalConfig( 840 bool QuicCryptoClientConfig::PopulateFromCanonicalConfig(
833 const QuicServerId& server_id, 841 const QuicServerId& server_id,
834 CachedState* server_state) { 842 CachedState* server_state) {
835 DCHECK(server_state->IsEmpty()); 843 DCHECK(server_state->IsEmpty());
836 size_t i = 0; 844 size_t i = 0;
837 for (; i < canonical_suffixes_.size(); ++i) { 845 for (; i < canonical_suffixes_.size(); ++i) {
838 if (EndsWith(server_id.host(), canonical_suffixes_[i], false)) { 846 if (EndsWith(server_id.host(), canonical_suffixes_[i], false)) {
839 break; 847 break;
840 } 848 }
841 } 849 }
842 if (i == canonical_suffixes_.size()) 850 if (i == canonical_suffixes_.size())
843 return; 851 return false;
844 852
845 QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(), 853 QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(),
846 server_id.is_https(), 854 server_id.is_https(),
847 server_id.privacy_mode()); 855 server_id.privacy_mode());
848 if (!ContainsKey(canonical_server_map_, suffix_server_id)) { 856 if (!ContainsKey(canonical_server_map_, suffix_server_id)) {
849 // This is the first host we've seen which matches the suffix, so make it 857 // This is the first host we've seen which matches the suffix, so make it
850 // canonical. 858 // canonical.
851 canonical_server_map_[suffix_server_id] = server_id; 859 canonical_server_map_[suffix_server_id] = server_id;
852 return; 860 return false;
853 } 861 }
854 862
855 const QuicServerId& canonical_server_id = 863 const QuicServerId& canonical_server_id =
856 canonical_server_map_[suffix_server_id]; 864 canonical_server_map_[suffix_server_id];
857 CachedState* canonical_state = cached_states_[canonical_server_id]; 865 CachedState* canonical_state = cached_states_[canonical_server_id];
858 if (!canonical_state->proof_valid()) { 866 if (!canonical_state->proof_valid()) {
859 return; 867 return false;
860 } 868 }
861 869
862 // Update canonical version to point at the "most recent" entry. 870 // Update canonical version to point at the "most recent" entry.
863 canonical_server_map_[suffix_server_id] = server_id; 871 canonical_server_map_[suffix_server_id] = server_id;
864 872
865 server_state->InitializeFrom(*canonical_state); 873 server_state->InitializeFrom(*canonical_state);
874 return true;
866 } 875 }
867 876
868 } // namespace net 877 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/quic_crypto_client_config.h ('k') | net/quic/crypto/quic_server_info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698