| OLD | NEW |
| 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 <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
| 13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "base/time/clock.h" | 15 #include "base/time/clock.h" |
| 16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 17 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/ssl/bad_clock_blocking_page.h" | 19 #include "chrome/browser/ssl/bad_clock_blocking_page.h" |
| 20 #include "chrome/browser/ssl/ssl_blocking_page.h" | 20 #include "chrome/browser/ssl/ssl_blocking_page.h" |
| 21 #include "chrome/browser/ssl/ssl_cert_reporter.h" | 21 #include "chrome/browser/ssl/ssl_cert_reporter.h" |
| 22 #include "chrome/common/features.h" | 22 #include "chrome/common/features.h" |
| 23 #include "components/network_time/network_time_tracker.h" |
| 23 #include "components/ssl_errors/error_classification.h" | 24 #include "components/ssl_errors/error_classification.h" |
| 24 #include "components/ssl_errors/error_info.h" | 25 #include "components/ssl_errors/error_info.h" |
| 25 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
| 26 #include "content/public/browser/notification_source.h" | 27 #include "content/public/browser/notification_source.h" |
| 27 #include "content/public/browser/render_frame_host.h" | 28 #include "content/public/browser/render_frame_host.h" |
| 28 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
| 29 #include "net/base/net_errors.h" | 30 #include "net/base/net_errors.h" |
| 30 | 31 |
| 31 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) | 32 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 32 #include "chrome/browser/captive_portal/captive_portal_service.h" | 33 #include "chrome/browser/captive_portal/captive_portal_service.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 49 // a captive portal interstitial is displayed. | 50 // a captive portal interstitial is displayed. |
| 50 // - Otherwise, an SSL interstitial is displayed. | 51 // - Otherwise, an SSL interstitial is displayed. |
| 51 int64_t g_interstitial_delay_in_milliseconds = 3000; | 52 int64_t g_interstitial_delay_in_milliseconds = 3000; |
| 52 | 53 |
| 53 // Callback to call when the interstitial timer is started. Used for testing. | 54 // Callback to call when the interstitial timer is started. Used for testing. |
| 54 SSLErrorHandler::TimerStartedCallback* g_timer_started_callback = nullptr; | 55 SSLErrorHandler::TimerStartedCallback* g_timer_started_callback = nullptr; |
| 55 | 56 |
| 56 // The clock to use when deciding which error type to display. Used for testing. | 57 // The clock to use when deciding which error type to display. Used for testing. |
| 57 base::Clock* g_testing_clock = nullptr; | 58 base::Clock* g_testing_clock = nullptr; |
| 58 | 59 |
| 60 network_time::NetworkTimeTracker* g_network_time_tracker = nullptr; |
| 61 |
| 59 // Events for UMA. | 62 // Events for UMA. |
| 60 enum SSLErrorHandlerEvent { | 63 enum SSLErrorHandlerEvent { |
| 61 HANDLE_ALL, | 64 HANDLE_ALL, |
| 62 SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE, | 65 SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE, |
| 63 SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE, | 66 SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE, |
| 64 SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE, | 67 SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE, |
| 65 SHOW_SSL_INTERSTITIAL_OVERRIDABLE, | 68 SHOW_SSL_INTERSTITIAL_OVERRIDABLE, |
| 66 WWW_MISMATCH_FOUND, | 69 WWW_MISMATCH_FOUND, |
| 67 WWW_MISMATCH_URL_AVAILABLE, | 70 WWW_MISMATCH_URL_AVAILABLE, |
| 68 WWW_MISMATCH_URL_NOT_AVAILABLE, | 71 WWW_MISMATCH_URL_NOT_AVAILABLE, |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 TimerStartedCallback* callback) { | 179 TimerStartedCallback* callback) { |
| 177 DCHECK(!callback || !callback->is_null()); | 180 DCHECK(!callback || !callback->is_null()); |
| 178 g_timer_started_callback = callback; | 181 g_timer_started_callback = callback; |
| 179 } | 182 } |
| 180 | 183 |
| 181 // static | 184 // static |
| 182 void SSLErrorHandler::SetClockForTest(base::Clock* testing_clock) { | 185 void SSLErrorHandler::SetClockForTest(base::Clock* testing_clock) { |
| 183 g_testing_clock = testing_clock; | 186 g_testing_clock = testing_clock; |
| 184 } | 187 } |
| 185 | 188 |
| 189 // static |
| 190 void SSLErrorHandler::SetNetworkTimeTrackerForTest( |
| 191 network_time::NetworkTimeTracker* tracker) { |
| 192 g_network_time_tracker = tracker; |
| 193 } |
| 194 |
| 186 SSLErrorHandler::SSLErrorHandler( | 195 SSLErrorHandler::SSLErrorHandler( |
| 187 content::WebContents* web_contents, | 196 content::WebContents* web_contents, |
| 188 int cert_error, | 197 int cert_error, |
| 189 const net::SSLInfo& ssl_info, | 198 const net::SSLInfo& ssl_info, |
| 190 const GURL& request_url, | 199 const GURL& request_url, |
| 191 int options_mask, | 200 int options_mask, |
| 192 std::unique_ptr<SSLCertReporter> ssl_cert_reporter, | 201 std::unique_ptr<SSLCertReporter> ssl_cert_reporter, |
| 193 const base::Callback<void(content::CertificateRequestResultType)>& callback) | 202 const base::Callback<void(content::CertificateRequestResultType)>& callback) |
| 194 : content::WebContentsObserver(web_contents), | 203 : content::WebContentsObserver(web_contents), |
| 195 web_contents_(web_contents), | 204 web_contents_(web_contents), |
| 196 cert_error_(cert_error), | 205 cert_error_(cert_error), |
| 197 ssl_info_(ssl_info), | 206 ssl_info_(ssl_info), |
| 198 request_url_(request_url), | 207 request_url_(request_url), |
| 199 options_mask_(options_mask), | 208 options_mask_(options_mask), |
| 200 callback_(callback), | 209 callback_(callback), |
| 201 profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())), | 210 profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())), |
| 202 ssl_cert_reporter_(std::move(ssl_cert_reporter)) {} | 211 ssl_cert_reporter_(std::move(ssl_cert_reporter)), |
| 212 weak_ptr_factory_(this) {} |
| 203 | 213 |
| 204 SSLErrorHandler::~SSLErrorHandler() { | 214 SSLErrorHandler::~SSLErrorHandler() { |
| 205 } | 215 } |
| 206 | 216 |
| 207 void SSLErrorHandler::StartHandlingError() { | 217 void SSLErrorHandler::StartHandlingError() { |
| 208 RecordUMA(HANDLE_ALL); | 218 RecordUMA(HANDLE_ALL); |
| 209 | 219 |
| 210 const base::Time now = g_testing_clock == nullptr | |
| 211 ? base::Time::NowFromSystemTime() | |
| 212 : g_testing_clock->Now(); | |
| 213 if (ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error_) == | 220 if (ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error_) == |
| 214 ssl_errors::ErrorInfo::CERT_DATE_INVALID) { | 221 ssl_errors::ErrorInfo::CERT_DATE_INVALID) { |
| 215 ssl_errors::ClockState clock_state = ssl_errors::GetClockState( | 222 HandleCertDateInvalidError(); |
| 216 now, g_browser_process->network_time_tracker()); | 223 return; |
| 217 if (clock_state == ssl_errors::CLOCK_STATE_FUTURE || | |
| 218 clock_state == ssl_errors::CLOCK_STATE_PAST) { | |
| 219 ShowBadClockInterstitial(now, clock_state); | |
| 220 return; // |this| is deleted after showing the interstitial. | |
| 221 } | |
| 222 } | 224 } |
| 223 | 225 |
| 224 std::vector<std::string> dns_names; | 226 std::vector<std::string> dns_names; |
| 225 ssl_info_.cert->GetDNSNames(&dns_names); | 227 ssl_info_.cert->GetDNSNames(&dns_names); |
| 226 DCHECK(!dns_names.empty()); | 228 DCHECK(!dns_names.empty()); |
| 227 GURL suggested_url; | 229 GURL suggested_url; |
| 228 if (IsSSLCommonNameMismatchHandlingEnabled() && | 230 if (IsSSLCommonNameMismatchHandlingEnabled() && |
| 229 cert_error_ == net::ERR_CERT_COMMON_NAME_INVALID && | 231 cert_error_ == net::ERR_CERT_COMMON_NAME_INVALID && |
| 230 IsErrorOverridable() && GetSuggestedUrl(dns_names, &suggested_url)) { | 232 IsErrorOverridable() && GetSuggestedUrl(dns_names, &suggested_url)) { |
| 231 RecordUMA(WWW_MISMATCH_FOUND); | 233 RecordUMA(WWW_MISMATCH_FOUND); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 base::ResetAndReturn(&callback_) | 416 base::ResetAndReturn(&callback_) |
| 415 .Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY); | 417 .Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY); |
| 416 } | 418 } |
| 417 if (common_name_mismatch_handler_) { | 419 if (common_name_mismatch_handler_) { |
| 418 common_name_mismatch_handler_->Cancel(); | 420 common_name_mismatch_handler_->Cancel(); |
| 419 common_name_mismatch_handler_.reset(); | 421 common_name_mismatch_handler_.reset(); |
| 420 } | 422 } |
| 421 // Deletes |this| and also destroys the timer. | 423 // Deletes |this| and also destroys the timer. |
| 422 web_contents_->RemoveUserData(UserDataKey()); | 424 web_contents_->RemoveUserData(UserDataKey()); |
| 423 } | 425 } |
| 426 |
| 427 void SSLErrorHandler::HandleCertDateInvalidError() { |
| 428 network_time::NetworkTimeTracker* tracker = |
| 429 g_network_time_tracker ? g_network_time_tracker |
| 430 : g_browser_process->network_time_tracker(); |
| 431 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( |
| 432 g_interstitial_delay_in_milliseconds), |
| 433 base::Bind(&SSLErrorHandler::HandleCertDateInvalidErrorImpl, |
| 434 base::Unretained(this))); |
| 435 // Try kicking off a time fetch to get an up-to-date estimate of the |
| 436 // true time. This will only have an effect if network time is |
| 437 // unavailable or if there is not already a query in progress. |
| 438 // |
| 439 // Pass a weak pointer as the callback; if the timer fires before the |
| 440 // fetch completes and shows an interstitial, this SSLErrorHandler |
| 441 // will be deleted. |
| 442 if (!tracker->StartTimeFetch( |
| 443 base::Bind(&SSLErrorHandler::HandleCertDateInvalidErrorImpl, |
| 444 weak_ptr_factory_.GetWeakPtr()))) { |
| 445 HandleCertDateInvalidErrorImpl(); |
| 446 return; |
| 447 } |
| 448 |
| 449 if (g_timer_started_callback) |
| 450 g_timer_started_callback->Run(web_contents_); |
| 451 } |
| 452 |
| 453 void SSLErrorHandler::HandleCertDateInvalidErrorImpl() { |
| 454 network_time::NetworkTimeTracker* tracker = |
| 455 g_network_time_tracker ? g_network_time_tracker |
| 456 : g_browser_process->network_time_tracker(); |
| 457 timer_.Stop(); |
| 458 const base::Time now = g_testing_clock == nullptr |
| 459 ? base::Time::NowFromSystemTime() |
| 460 : g_testing_clock->Now(); |
| 461 ssl_errors::ClockState clock_state = ssl_errors::GetClockState(now, tracker); |
| 462 if (clock_state == ssl_errors::CLOCK_STATE_FUTURE || |
| 463 clock_state == ssl_errors::CLOCK_STATE_PAST) { |
| 464 ShowBadClockInterstitial(now, clock_state); |
| 465 return; // |this| is deleted after showing the interstitial. |
| 466 } |
| 467 ShowSSLInterstitial(); |
| 468 } |
| OLD | NEW |