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

Side by Side Diff: chrome/browser/ssl/ssl_error_handler.cc

Issue 2581903002: Add SSL error assistant component to dynamically update captive portal list (Closed)
Patch Set: Rebase Created 3 years, 10 months 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/browser/ssl/ssl_error_handler.h" 5 #include "chrome/browser/ssl/ssl_error_handler.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <unordered_set> 8 #include <unordered_set>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 UMA_HISTOGRAM_ENUMERATION(kHistogram, event, 132 UMA_HISTOGRAM_ENUMERATION(kHistogram, event,
133 SSLErrorHandler::SSL_ERROR_HANDLER_EVENT_COUNT); 133 SSLErrorHandler::SSL_ERROR_HANDLER_EVENT_COUNT);
134 } 134 }
135 135
136 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) 136 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
137 bool IsCaptivePortalInterstitialEnabled() { 137 bool IsCaptivePortalInterstitialEnabled() {
138 return base::FeatureList::IsEnabled(kCaptivePortalInterstitial); 138 return base::FeatureList::IsEnabled(kCaptivePortalInterstitial);
139 } 139 }
140 140
141 // Reads the SSL error assistant configuration from the resource bundle. 141 // Reads the SSL error assistant configuration from the resource bundle.
142 bool ReadErrorAssistantProtoFromResourceBundle( 142 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig>
143 chrome_browser_ssl::SSLErrorAssistantConfig* proto) { 143 ReadErrorAssistantProtoFromResourceBundle() {
144 auto proto = base::MakeUnique<chrome_browser_ssl::SSLErrorAssistantConfig>();
144 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 145 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
145 DCHECK(proto); 146 DCHECK(proto);
146 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); 147 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
147 base::StringPiece data = 148 base::StringPiece data =
148 bundle.GetRawDataResource(IDR_SSL_ERROR_ASSISTANT_PB); 149 bundle.GetRawDataResource(IDR_SSL_ERROR_ASSISTANT_PB);
149 google::protobuf::io::ArrayInputStream stream(data.data(), data.size()); 150 google::protobuf::io::ArrayInputStream stream(data.data(), data.size());
150 return proto->ParseFromZeroCopyStream(&stream); 151 return proto->ParseFromZeroCopyStream(&stream) ? std::move(proto) : nullptr;
151 } 152 }
152 153
153 std::unique_ptr<std::unordered_set<std::string>> LoadCaptivePortalCertHashes( 154 std::unique_ptr<std::unordered_set<std::string>> LoadCaptivePortalCertHashes(
154 const chrome_browser_ssl::SSLErrorAssistantConfig& proto) { 155 const chrome_browser_ssl::SSLErrorAssistantConfig& proto) {
155 auto hashes = base::MakeUnique<std::unordered_set<std::string>>(); 156 auto hashes = base::MakeUnique<std::unordered_set<std::string>>();
156 for (const chrome_browser_ssl::CaptivePortalCert& cert : 157 for (const chrome_browser_ssl::CaptivePortalCert& cert :
157 proto.captive_portal_cert()) { 158 proto.captive_portal_cert()) {
158 hashes.get()->insert(cert.sha256_hash()); 159 hashes.get()->insert(cert.sha256_hash());
159 } 160 }
160 return hashes; 161 return hashes;
(...skipping 24 matching lines...) Expand all
185 // Testing methods: 186 // Testing methods:
186 void ResetForTesting(); 187 void ResetForTesting();
187 void SetInterstitialDelayForTesting(const base::TimeDelta& delay); 188 void SetInterstitialDelayForTesting(const base::TimeDelta& delay);
188 void SetTimerStartedCallbackForTesting( 189 void SetTimerStartedCallbackForTesting(
189 SSLErrorHandler::TimerStartedCallback* callback); 190 SSLErrorHandler::TimerStartedCallback* callback);
190 void SetClockForTesting(base::Clock* clock); 191 void SetClockForTesting(base::Clock* clock);
191 void SetNetworkTimeTrackerForTesting( 192 void SetNetworkTimeTrackerForTesting(
192 network_time::NetworkTimeTracker* tracker); 193 network_time::NetworkTimeTracker* tracker);
193 194
194 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) 195 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
195 void SetErrorAssistantProtoForTesting( 196 void SetErrorAssistantProto(
196 const chrome_browser_ssl::SSLErrorAssistantConfig& error_assistant_proto); 197 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig>
198 error_assistant_proto);
197 #endif 199 #endif
198 200
199 private: 201 private:
200 base::TimeDelta interstitial_delay_; 202 base::TimeDelta interstitial_delay_;
201 203
202 // Callback to call when the interstitial timer is started. Used for 204 // Callback to call when the interstitial timer is started. Used for
203 // testing. 205 // testing.
204 SSLErrorHandler::TimerStartedCallback* timer_started_callback_ = nullptr; 206 SSLErrorHandler::TimerStartedCallback* timer_started_callback_ = nullptr;
205 207
206 // The clock to use when deciding which error type to display. Used for 208 // The clock to use when deciding which error type to display. Used for
207 // testing. 209 // testing.
208 base::Clock* testing_clock_ = nullptr; 210 base::Clock* testing_clock_ = nullptr;
209 211
210 network_time::NetworkTimeTracker* network_time_tracker_ = nullptr; 212 network_time::NetworkTimeTracker* network_time_tracker_ = nullptr;
211 213
212 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) 214 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
215 // Error assistant configuration.
216 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig>
217 error_assistant_proto_;
218
213 // SPKI hashes belonging to certs treated as captive portals. Null until the 219 // SPKI hashes belonging to certs treated as captive portals. Null until the
214 // first time IsKnownCaptivePortalCert() or SetErrorAssistantProtoForTesting() 220 // first time IsKnownCaptivePortalCert() or SetErrorAssistantProto()
215 // is called. 221 // is called.
216 std::unique_ptr<std::unordered_set<std::string>> captive_portal_spki_hashes_; 222 std::unique_ptr<std::unordered_set<std::string>> captive_portal_spki_hashes_;
217 #endif 223 #endif
218 }; 224 };
219 225
220 ConfigSingleton::ConfigSingleton() 226 ConfigSingleton::ConfigSingleton()
221 : interstitial_delay_( 227 : interstitial_delay_(
222 base::TimeDelta::FromMilliseconds(kInterstitialDelayInMilliseconds)) { 228 base::TimeDelta::FromMilliseconds(kInterstitialDelayInMilliseconds)) {
223 } 229 }
224 230
(...skipping 16 matching lines...) Expand all
241 return testing_clock_; 247 return testing_clock_;
242 } 248 }
243 249
244 void ConfigSingleton::ResetForTesting() { 250 void ConfigSingleton::ResetForTesting() {
245 interstitial_delay_ = 251 interstitial_delay_ =
246 base::TimeDelta::FromMilliseconds(kInterstitialDelayInMilliseconds); 252 base::TimeDelta::FromMilliseconds(kInterstitialDelayInMilliseconds);
247 timer_started_callback_ = nullptr; 253 timer_started_callback_ = nullptr;
248 network_time_tracker_ = nullptr; 254 network_time_tracker_ = nullptr;
249 testing_clock_ = nullptr; 255 testing_clock_ = nullptr;
250 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) 256 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
257 error_assistant_proto_.reset();
251 captive_portal_spki_hashes_.reset(); 258 captive_portal_spki_hashes_.reset();
252 #endif 259 #endif
253 } 260 }
254 261
255 void ConfigSingleton::SetInterstitialDelayForTesting( 262 void ConfigSingleton::SetInterstitialDelayForTesting(
256 const base::TimeDelta& delay) { 263 const base::TimeDelta& delay) {
257 interstitial_delay_ = delay; 264 interstitial_delay_ = delay;
258 } 265 }
259 266
260 void ConfigSingleton::SetTimerStartedCallbackForTesting( 267 void ConfigSingleton::SetTimerStartedCallbackForTesting(
261 SSLErrorHandler::TimerStartedCallback* callback) { 268 SSLErrorHandler::TimerStartedCallback* callback) {
262 DCHECK(!callback || !callback->is_null()); 269 DCHECK(!callback || !callback->is_null());
263 timer_started_callback_ = callback; 270 timer_started_callback_ = callback;
264 } 271 }
265 272
266 void ConfigSingleton::SetClockForTesting(base::Clock* clock) { 273 void ConfigSingleton::SetClockForTesting(base::Clock* clock) {
267 testing_clock_ = clock; 274 testing_clock_ = clock;
268 } 275 }
269 276
270 void ConfigSingleton::SetNetworkTimeTrackerForTesting( 277 void ConfigSingleton::SetNetworkTimeTrackerForTesting(
271 network_time::NetworkTimeTracker* tracker) { 278 network_time::NetworkTimeTracker* tracker) {
272 network_time_tracker_ = tracker; 279 network_time_tracker_ = tracker;
273 } 280 }
274 281
275 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) 282 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
276 void ConfigSingleton::SetErrorAssistantProtoForTesting( 283 void ConfigSingleton::SetErrorAssistantProto(
277 const chrome_browser_ssl::SSLErrorAssistantConfig& error_assistant_proto) { 284 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> proto) {
278 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 285 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
279 DCHECK(!captive_portal_spki_hashes_); 286 CHECK(proto);
estark 2017/02/08 20:31:17 Why is this a CHECK instead of a DCHECK? (probably
meacer 2017/02/08 22:34:32 If it's null, it's going to crash a couple of line
287 // Ignore versions that are not new.
288 if (error_assistant_proto_ &&
289 proto->version_id() <= error_assistant_proto_->version_id()) {
290 return;
291 }
292 error_assistant_proto_ = std::move(proto);
280 captive_portal_spki_hashes_ = 293 captive_portal_spki_hashes_ =
281 LoadCaptivePortalCertHashes(error_assistant_proto); 294 LoadCaptivePortalCertHashes(*error_assistant_proto_);
282 } 295 }
283 296
284 bool ConfigSingleton::IsKnownCaptivePortalCert(const net::SSLInfo& ssl_info) { 297 bool ConfigSingleton::IsKnownCaptivePortalCert(const net::SSLInfo& ssl_info) {
285 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 298 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
286 if (!captive_portal_spki_hashes_) { 299 if (!captive_portal_spki_hashes_) {
287 chrome_browser_ssl::SSLErrorAssistantConfig proto; 300 error_assistant_proto_ = ReadErrorAssistantProtoFromResourceBundle();
288 CHECK(ReadErrorAssistantProtoFromResourceBundle(&proto)); 301 CHECK(error_assistant_proto_);
289 captive_portal_spki_hashes_ = LoadCaptivePortalCertHashes(proto); 302 captive_portal_spki_hashes_ =
303 LoadCaptivePortalCertHashes(*error_assistant_proto_);
290 } 304 }
291 305
292 for (const net::HashValue& hash_value : ssl_info.public_key_hashes) { 306 for (const net::HashValue& hash_value : ssl_info.public_key_hashes) {
293 if (hash_value.tag != net::HASH_VALUE_SHA256) { 307 if (hash_value.tag != net::HASH_VALUE_SHA256) {
294 continue; 308 continue;
295 } 309 }
296 if (captive_portal_spki_hashes_->find(hash_value.ToString()) != 310 if (captive_portal_spki_hashes_->find(hash_value.ToString()) !=
297 captive_portal_spki_hashes_->end()) { 311 captive_portal_spki_hashes_->end()) {
298 return true; 312 return true;
299 } 313 }
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 503
490 // static 504 // static
491 std::string SSLErrorHandler::GetHistogramNameForTesting() { 505 std::string SSLErrorHandler::GetHistogramNameForTesting() {
492 return kHistogram; 506 return kHistogram;
493 } 507 }
494 508
495 bool SSLErrorHandler::IsTimerRunningForTesting() const { 509 bool SSLErrorHandler::IsTimerRunningForTesting() const {
496 return timer_.IsRunning(); 510 return timer_.IsRunning();
497 } 511 }
498 512
499 void SSLErrorHandler::SetErrorAssistantProtoForTesting( 513 void SSLErrorHandler::SetErrorAssistantProto(
500 const chrome_browser_ssl::SSLErrorAssistantConfig& config_proto) { 514 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig> config_proto) {
501 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) 515 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
502 g_config.Pointer()->SetErrorAssistantProtoForTesting(config_proto); 516 g_config.Pointer()->SetErrorAssistantProto(std::move(config_proto));
503 #endif 517 #endif
504 } 518 }
505 519
506 SSLErrorHandler::SSLErrorHandler( 520 SSLErrorHandler::SSLErrorHandler(
507 std::unique_ptr<Delegate> delegate, 521 std::unique_ptr<Delegate> delegate,
508 content::WebContents* web_contents, 522 content::WebContents* web_contents,
509 Profile* profile, 523 Profile* profile,
510 int cert_error, 524 int cert_error,
511 const net::SSLInfo& ssl_info, 525 const net::SSLInfo& ssl_info,
512 const GURL& request_url, 526 const GURL& request_url,
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 network_time::NetworkTimeTracker* tracker = 760 network_time::NetworkTimeTracker* tracker =
747 g_config.Pointer()->network_time_tracker(); 761 g_config.Pointer()->network_time_tracker();
748 ssl_errors::ClockState clock_state = ssl_errors::GetClockState(now, tracker); 762 ssl_errors::ClockState clock_state = ssl_errors::GetClockState(now, tracker);
749 if (clock_state == ssl_errors::CLOCK_STATE_FUTURE || 763 if (clock_state == ssl_errors::CLOCK_STATE_FUTURE ||
750 clock_state == ssl_errors::CLOCK_STATE_PAST) { 764 clock_state == ssl_errors::CLOCK_STATE_PAST) {
751 ShowBadClockInterstitial(now, clock_state); 765 ShowBadClockInterstitial(now, clock_state);
752 return; // |this| is deleted after showing the interstitial. 766 return; // |this| is deleted after showing the interstitial.
753 } 767 }
754 ShowSSLInterstitial(); 768 ShowSSLInterstitial();
755 } 769 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698