Index: chrome/browser/ssl/ssl_error_handler.cc |
diff --git a/chrome/browser/ssl/ssl_error_handler.cc b/chrome/browser/ssl/ssl_error_handler.cc |
index b35cf835d7de62fdf1ae8d62be94aa0536accd4b..e9bce7b753272453fea007c4a94f2bc5309037d1 100644 |
--- a/chrome/browser/ssl/ssl_error_handler.cc |
+++ b/chrome/browser/ssl/ssl_error_handler.cc |
@@ -20,6 +20,7 @@ |
#include "chrome/browser/ssl/ssl_blocking_page.h" |
#include "chrome/browser/ssl/ssl_cert_reporter.h" |
#include "chrome/common/features.h" |
+#include "components/network_time/network_time_tracker.h" |
#include "components/ssl_errors/error_classification.h" |
#include "components/ssl_errors/error_info.h" |
#include "content/public/browser/notification_service.h" |
@@ -56,6 +57,8 @@ SSLErrorHandler::TimerStartedCallback* g_timer_started_callback = nullptr; |
// The clock to use when deciding which error type to display. Used for testing. |
base::Clock* g_testing_clock = nullptr; |
+network_time::NetworkTimeTracker* g_network_time_tracker = nullptr; |
+ |
// Events for UMA. |
enum SSLErrorHandlerEvent { |
HANDLE_ALL, |
@@ -183,6 +186,12 @@ void SSLErrorHandler::SetClockForTest(base::Clock* testing_clock) { |
g_testing_clock = testing_clock; |
} |
+// static |
+void SSLErrorHandler::SetNetworkTimeTrackerForTest( |
+ network_time::NetworkTimeTracker* tracker) { |
+ g_network_time_tracker = tracker; |
+} |
+ |
SSLErrorHandler::SSLErrorHandler( |
content::WebContents* web_contents, |
int cert_error, |
@@ -199,7 +208,8 @@ SSLErrorHandler::SSLErrorHandler( |
options_mask_(options_mask), |
callback_(callback), |
profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())), |
- ssl_cert_reporter_(std::move(ssl_cert_reporter)) {} |
+ ssl_cert_reporter_(std::move(ssl_cert_reporter)), |
+ weak_ptr_factory_(this) {} |
SSLErrorHandler::~SSLErrorHandler() { |
} |
@@ -207,18 +217,10 @@ SSLErrorHandler::~SSLErrorHandler() { |
void SSLErrorHandler::StartHandlingError() { |
RecordUMA(HANDLE_ALL); |
- const base::Time now = g_testing_clock == nullptr |
- ? base::Time::NowFromSystemTime() |
- : g_testing_clock->Now(); |
if (ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error_) == |
ssl_errors::ErrorInfo::CERT_DATE_INVALID) { |
- ssl_errors::ClockState clock_state = ssl_errors::GetClockState( |
- now, g_browser_process->network_time_tracker()); |
- if (clock_state == ssl_errors::CLOCK_STATE_FUTURE || |
- clock_state == ssl_errors::CLOCK_STATE_PAST) { |
- ShowBadClockInterstitial(now, clock_state); |
- return; // |this| is deleted after showing the interstitial. |
- } |
+ HandleCertDateInvalidError(); |
+ return; |
} |
std::vector<std::string> dns_names; |
@@ -421,3 +423,46 @@ void SSLErrorHandler::DeleteSSLErrorHandler() { |
// Deletes |this| and also destroys the timer. |
web_contents_->RemoveUserData(UserDataKey()); |
} |
+ |
+void SSLErrorHandler::HandleCertDateInvalidError() { |
+ network_time::NetworkTimeTracker* tracker = |
+ g_network_time_tracker ? g_network_time_tracker |
+ : g_browser_process->network_time_tracker(); |
+ timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( |
+ g_interstitial_delay_in_milliseconds), |
+ base::Bind(&SSLErrorHandler::HandleCertDateInvalidErrorImpl, |
+ base::Unretained(this))); |
+ // Try kicking off a time fetch to get an up-to-date estimate of the |
+ // true time. This will only have an effect if network time is |
+ // unavailable or if there is not already a query in progress. |
+ // |
+ // Pass a weak pointer as the callback; if the timer fires before the |
+ // fetch completes and shows an interstitial, this SSLErrorHandler |
+ // will be deleted. |
+ if (!tracker->StartTimeFetch( |
+ base::Bind(&SSLErrorHandler::HandleCertDateInvalidErrorImpl, |
+ weak_ptr_factory_.GetWeakPtr()))) { |
+ HandleCertDateInvalidErrorImpl(); |
+ return; |
+ } |
+ |
+ if (g_timer_started_callback) |
+ g_timer_started_callback->Run(web_contents_); |
+} |
+ |
+void SSLErrorHandler::HandleCertDateInvalidErrorImpl() { |
+ network_time::NetworkTimeTracker* tracker = |
+ g_network_time_tracker ? g_network_time_tracker |
+ : g_browser_process->network_time_tracker(); |
+ timer_.Stop(); |
+ const base::Time now = g_testing_clock == nullptr |
+ ? base::Time::NowFromSystemTime() |
+ : g_testing_clock->Now(); |
+ ssl_errors::ClockState clock_state = ssl_errors::GetClockState(now, tracker); |
+ if (clock_state == ssl_errors::CLOCK_STATE_FUTURE || |
+ clock_state == ssl_errors::CLOCK_STATE_PAST) { |
+ ShowBadClockInterstitial(now, clock_state); |
+ return; // |this| is deleted after showing the interstitial. |
+ } |
+ ShowSSLInterstitial(); |
+} |