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

Unified Diff: chrome/browser/ssl/ssl_error_handler_unittest.cc

Issue 2449193002: Attempt an on-demand time fetch when encountering a date invalid error (Closed)
Patch Set: Use WeakPtr so that SSLErrorHandler can be destroyed Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ssl/ssl_error_handler.cc ('k') | chrome/test/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ssl/ssl_error_handler_unittest.cc
diff --git a/chrome/browser/ssl/ssl_error_handler_unittest.cc b/chrome/browser/ssl/ssl_error_handler_unittest.cc
index 0dfb7d1b918dbc6922cb0ac2d9528825ccbaf2df..34310ee6e4fa1bbcf4341b5af4708537a04d44f7 100644
--- a/chrome/browser/ssl/ssl_error_handler_unittest.cc
+++ b/chrome/browser/ssl/ssl_error_handler_unittest.cc
@@ -8,6 +8,8 @@
#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
+#include "base/test/simple_test_clock.h"
+#include "base/test/simple_test_tick_clock.h"
#include "base/time/time.h"
#include "chrome/browser/captive_portal/captive_portal_service.h"
#include "chrome/browser/profiles/profile.h"
@@ -16,13 +18,22 @@
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/captive_portal/captive_portal_testing_utils.h"
+#include "components/network_time/network_time_test_utils.h"
+#include "components/network_time/network_time_tracker.h"
+#include "components/prefs/testing_pref_service.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "net/base/net_errors.h"
+#include "net/cert/cert_status_flags.h"
#include "net/cert/x509_certificate.h"
+#include "net/http/http_response_headers.h"
#include "net/ssl/ssl_info.h"
#include "net/test/cert_test_util.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_response.h"
#include "net/test/test_certificate_data.h"
#include "net/test/test_data_directory.h"
+#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
class SSLErrorHandlerForTest : public SSLErrorHandler {
@@ -32,7 +43,7 @@ class SSLErrorHandlerForTest : public SSLErrorHandler {
const net::SSLInfo& ssl_info)
: SSLErrorHandler(
web_contents,
- net::ERR_CERT_COMMON_NAME_INVALID,
+ net::MapCertStatusToNetError(ssl_info.cert_status),
ssl_info,
GURL(),
0,
@@ -43,6 +54,7 @@ class SSLErrorHandlerForTest : public SSLErrorHandler {
suggested_url_exists_(false),
suggested_url_checked_(false),
ssl_interstitial_shown_(false),
+ bad_clock_interstitial_shown_(false),
captive_portal_interstitial_shown_(false),
redirected_to_suggested_url_(false),
is_overridable_error_(true) {}
@@ -72,6 +84,9 @@ class SSLErrorHandlerForTest : public SSLErrorHandler {
int captive_portal_interstitial_shown() const {
return captive_portal_interstitial_shown_;
}
+ bool bad_clock_interstitial_shown() const {
+ return bad_clock_interstitial_shown_;
+ }
bool suggested_url_checked() const { return suggested_url_checked_; }
bool redirected_to_suggested_url() const {
return redirected_to_suggested_url_;
@@ -85,6 +100,7 @@ class SSLErrorHandlerForTest : public SSLErrorHandler {
suggested_url_exists_ = false;
suggested_url_checked_ = false;
ssl_interstitial_shown_ = false;
+ bad_clock_interstitial_shown_ = false;
captive_portal_interstitial_shown_ = false;
redirected_to_suggested_url_ = false;
}
@@ -104,6 +120,11 @@ class SSLErrorHandlerForTest : public SSLErrorHandler {
void ShowSSLInterstitial() override { ssl_interstitial_shown_ = true; }
+ void ShowBadClockInterstitial(const base::Time& now,
+ ssl_errors::ClockState clock_state) override {
+ bad_clock_interstitial_shown_ = true;
+ }
+
void ShowCaptivePortalInterstitial(const GURL& landing_url) override {
captive_portal_interstitial_shown_ = true;
}
@@ -123,6 +144,7 @@ class SSLErrorHandlerForTest : public SSLErrorHandler {
bool suggested_url_exists_;
bool suggested_url_checked_;
bool ssl_interstitial_shown_;
+ bool bad_clock_interstitial_shown_;
bool captive_portal_interstitial_shown_;
bool redirected_to_suggested_url_;
bool is_overridable_error_;
@@ -130,9 +152,9 @@ class SSLErrorHandlerForTest : public SSLErrorHandler {
DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerForTest);
};
-class SSLErrorHandlerTest : public ChromeRenderViewHostTestHarness {
+class CommonNameSSLErrorHandlerTest : public ChromeRenderViewHostTestHarness {
meacer 2016/10/26 20:03:02 nit: maybe rename to SSLErrorHandlerNameMismatchTe
estark 2016/10/31 16:03:25 Done.
public:
- SSLErrorHandlerTest() : field_trial_list_(nullptr) {}
+ CommonNameSSLErrorHandlerTest() : field_trial_list_(nullptr) {}
void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp();
@@ -162,12 +184,82 @@ class SSLErrorHandlerTest : public ChromeRenderViewHostTestHarness {
net::SSLInfo ssl_info_;
std::unique_ptr<SSLErrorHandlerForTest> error_handler_;
base::FieldTrialList field_trial_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(CommonNameSSLErrorHandlerTest);
+};
+
+class DateInvalidSSLErrorHandlerTest : public ChromeRenderViewHostTestHarness {
meacer 2016/10/26 20:03:03 And this one to SSLErrorHandlerDateInvalidTest?
estark 2016/10/31 16:03:25 Done.
+ public:
+ DateInvalidSSLErrorHandlerTest()
+ : field_trial_test_(new network_time::FieldTrialTest()),
+ clock_(new base::SimpleTestClock),
+ tick_clock_(new base::SimpleTestTickClock),
+ test_server_(new net::EmbeddedTestServer) {
+ SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD);
+ network_time::NetworkTimeTracker::RegisterPrefs(pref_service_.registry());
+ }
+
+ void SetUp() override {
+ ChromeRenderViewHostTestHarness::SetUp();
+
+ field_trial_test()->SetNetworkQueriesWithVariationsService(
+ false, 0.0, network_time::FieldTrialTest::DISABLE_FETCHES_ON_DEMAND);
+ tracker_.reset(new network_time::NetworkTimeTracker(
+ std::unique_ptr<base::Clock>(clock_),
+ std::unique_ptr<base::TickClock>(tick_clock_), &pref_service_,
+ new net::TestURLRequestContextGetter(
+ content::BrowserThread::GetTaskRunnerForThread(
+ content::BrowserThread::IO))));
+
+ // Do this to be sure that |is_null| returns false.
+ clock_->Advance(base::TimeDelta::FromDays(111));
+ tick_clock_->Advance(base::TimeDelta::FromDays(222));
+
+ SSLErrorHandler::SetInterstitialDelayForTest(base::TimeDelta());
+ ssl_info_.cert =
+ net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
+ ssl_info_.cert_status = net::CERT_STATUS_DATE_INVALID;
+ error_handler_.reset(
+ new SSLErrorHandlerForTest(profile(), web_contents(), ssl_info_));
+ error_handler_->SetNetworkTimeTrackerForTest(tracker_.get());
+ }
+
+ void TearDown() override {
+ if (error_handler()) {
+ EXPECT_FALSE(error_handler()->IsTimerRunning());
+ error_handler_.reset(nullptr);
+ }
+ ChromeRenderViewHostTestHarness::TearDown();
+ }
+
+ SSLErrorHandlerForTest* error_handler() { return error_handler_.get(); }
+
+ network_time::FieldTrialTest* field_trial_test() {
+ return field_trial_test_.get();
+ }
+
+ network_time::NetworkTimeTracker* tracker() { return tracker_.get(); }
+
+ net::EmbeddedTestServer* test_server() { return test_server_.get(); }
+
+ void ClearErrorHandler() { error_handler_.reset(nullptr); }
+
+ private:
+ net::SSLInfo ssl_info_;
+ std::unique_ptr<SSLErrorHandlerForTest> error_handler_;
+ std::unique_ptr<network_time::FieldTrialTest> field_trial_test_;
+ base::SimpleTestClock* clock_;
+ base::SimpleTestTickClock* tick_clock_;
+ TestingPrefServiceSimple pref_service_;
+ std::unique_ptr<network_time::NetworkTimeTracker> tracker_;
+ std::unique_ptr<net::EmbeddedTestServer> test_server_;
+
+ DISALLOW_COPY_AND_ASSIGN(DateInvalidSSLErrorHandlerTest);
};
#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
-TEST_F(SSLErrorHandlerTest,
- ShouldShowSSLInterstitialOnTimerExpired) {
+TEST_F(CommonNameSSLErrorHandlerTest, ShouldShowSSLInterstitialOnTimerExpired) {
EXPECT_FALSE(error_handler()->IsTimerRunning());
error_handler()->StartHandlingError();
@@ -185,7 +277,7 @@ TEST_F(SSLErrorHandlerTest,
EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown());
}
-TEST_F(SSLErrorHandlerTest,
+TEST_F(CommonNameSSLErrorHandlerTest,
ShouldShowCustomInterstitialOnCaptivePortalResult) {
EXPECT_FALSE(error_handler()->IsTimerRunning());
error_handler()->StartHandlingError();
@@ -206,7 +298,7 @@ TEST_F(SSLErrorHandlerTest,
EXPECT_TRUE(error_handler()->captive_portal_interstitial_shown());
}
-TEST_F(SSLErrorHandlerTest,
+TEST_F(CommonNameSSLErrorHandlerTest,
ShouldShowSSLInterstitialOnNoCaptivePortalResult) {
EXPECT_FALSE(error_handler()->IsTimerRunning());
error_handler()->StartHandlingError();
@@ -229,7 +321,8 @@ TEST_F(SSLErrorHandlerTest,
EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown());
}
-TEST_F(SSLErrorHandlerTest, ShouldNotCheckSuggestedUrlIfNoSuggestedUrl) {
+TEST_F(CommonNameSSLErrorHandlerTest,
+ ShouldNotCheckSuggestedUrlIfNoSuggestedUrl) {
error_handler()->StartHandlingError();
EXPECT_TRUE(error_handler()->captive_portal_checked());
@@ -241,7 +334,8 @@ TEST_F(SSLErrorHandlerTest, ShouldNotCheckSuggestedUrlIfNoSuggestedUrl) {
EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
}
-TEST_F(SSLErrorHandlerTest, ShouldNotCheckCaptivePortalIfSuggestedUrlExists) {
+TEST_F(CommonNameSSLErrorHandlerTest,
+ ShouldNotCheckCaptivePortalIfSuggestedUrlExists) {
EXPECT_FALSE(error_handler()->IsTimerRunning());
error_handler()->set_suggested_url_exists();
error_handler()->StartHandlingError();
@@ -255,7 +349,8 @@ TEST_F(SSLErrorHandlerTest, ShouldNotCheckCaptivePortalIfSuggestedUrlExists) {
EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
}
-TEST_F(SSLErrorHandlerTest, ShouldNotHandleNameMismatchOnNonOverridableError) {
+TEST_F(CommonNameSSLErrorHandlerTest,
+ ShouldNotHandleNameMismatchOnNonOverridableError) {
error_handler()->set_non_overridable_error();
error_handler()->set_suggested_url_exists();
error_handler()->StartHandlingError();
@@ -271,7 +366,7 @@ TEST_F(SSLErrorHandlerTest, ShouldNotHandleNameMismatchOnNonOverridableError) {
#else // #if !BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
-TEST_F(SSLErrorHandlerTest,
+TEST_F(CommonNameSSLErrorHandlerTest,
ShouldShowSSLInterstitialOnCaptivePortalDetectionDisabled) {
EXPECT_FALSE(error_handler()->IsTimerRunning());
error_handler()->StartHandlingError();
@@ -283,7 +378,7 @@ TEST_F(SSLErrorHandlerTest,
#endif // BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
-TEST_F(SSLErrorHandlerTest,
+TEST_F(CommonNameSSLErrorHandlerTest,
ShouldShowSSLInterstitialOnTimerExpiredWhenSuggestedUrlExists) {
error_handler()->set_suggested_url_exists();
error_handler()->StartHandlingError();
@@ -300,7 +395,7 @@ TEST_F(SSLErrorHandlerTest,
EXPECT_FALSE(error_handler()->redirected_to_suggested_url());
}
-TEST_F(SSLErrorHandlerTest, ShouldRedirectOnSuggestedUrlCheckResult) {
+TEST_F(CommonNameSSLErrorHandlerTest, ShouldRedirectOnSuggestedUrlCheckResult) {
error_handler()->set_suggested_url_exists();
error_handler()->StartHandlingError();
@@ -321,7 +416,8 @@ TEST_F(SSLErrorHandlerTest, ShouldRedirectOnSuggestedUrlCheckResult) {
EXPECT_TRUE(error_handler()->redirected_to_suggested_url());
}
-TEST_F(SSLErrorHandlerTest, ShouldShowSSLInterstitialOnInvalidUrlCheckResult) {
+TEST_F(CommonNameSSLErrorHandlerTest,
+ ShouldShowSSLInterstitialOnInvalidUrlCheckResult) {
error_handler()->set_suggested_url_exists();
error_handler()->StartHandlingError();
@@ -339,3 +435,90 @@ TEST_F(SSLErrorHandlerTest, ShouldShowSSLInterstitialOnInvalidUrlCheckResult) {
EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
EXPECT_FALSE(error_handler()->redirected_to_suggested_url());
}
+
+TEST_F(DateInvalidSSLErrorHandlerTest, TimeQueryStarted) {
+ base::Time network_time;
+ base::TimeDelta uncertainty;
+ EXPECT_EQ(network_time::NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
+ tracker()->GetNetworkTime(&network_time, &uncertainty));
+
+ // Enable network time queries and handle the error. A bad clock interstitial
+ // should be shown.
+ EXPECT_TRUE(test_server()->Start());
+ test_server()->RegisterRequestHandler(
+ base::Bind(&network_time::GoodTimeResponseHandler));
+ tracker()->SetTimeServerURLForTesting(test_server()->GetURL("/"));
+ field_trial_test()->SetNetworkQueriesWithVariationsService(
+ true, 0.0, network_time::FieldTrialTest::ENABLE_FETCHES_ON_DEMAND);
+ error_handler()->StartHandlingError();
+
+ EXPECT_TRUE(error_handler()->IsTimerRunning());
+ tracker()->WaitForFetchForTesting(123123123);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(error_handler()->bad_clock_interstitial_shown());
+ EXPECT_FALSE(error_handler()->IsTimerRunning());
+}
+
+// Tests that an SSL interstitial is shown if the accuracy of the system
+// clock can't be determined because network time is unavailable.
+TEST_F(DateInvalidSSLErrorHandlerTest, NoTimeQueries) {
+ base::Time network_time;
+ base::TimeDelta uncertainty;
+ EXPECT_EQ(network_time::NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
+ tracker()->GetNetworkTime(&network_time, &uncertainty));
+
+ // Handle the error without enabling time queries. A bad clock interstitial
+ // should not be shown.
meacer 2016/10/26 20:03:03 Just to confirm: This is assuming we don't have th
estark 2016/10/31 16:03:25 Sorta. It's assuming that the build time heuristic
+ error_handler()->StartHandlingError();
+
+ EXPECT_FALSE(error_handler()->IsTimerRunning());
+ EXPECT_FALSE(error_handler()->bad_clock_interstitial_shown());
+ EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
+}
+
+// Runs |quit_closure| on the UI thread once a URL request has been
+// seen. Returns a request that hangs.
+std::unique_ptr<net::test_server::HttpResponse> WaitForRequest(
+ const base::Closure& quit_closure,
+ const net::test_server::HttpRequest& request) {
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ quit_closure);
+ return base::MakeUnique<net::test_server::HungResponse>();
+}
+
+// Tests that an SSL interstitial is shown if determing the accuracy of
+// the system clock times out (e.g. because a network time query hangs).
+TEST_F(DateInvalidSSLErrorHandlerTest, TimeQueryHangs) {
+ base::Time network_time;
+ base::TimeDelta uncertainty;
+ EXPECT_EQ(network_time::NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
+ tracker()->GetNetworkTime(&network_time, &uncertainty));
+
+ // Enable network time queries and handle the error. Because the
+ // network time cannot be determined before the timer elapses, an SSL
+ // interstitial should be shown.
+ EXPECT_TRUE(test_server()->Start());
+ base::RunLoop wait_for_time_query_loop;
+ test_server()->RegisterRequestHandler(
+ base::Bind(&WaitForRequest, wait_for_time_query_loop.QuitClosure()));
+ tracker()->SetTimeServerURLForTesting(test_server()->GetURL("/"));
+ field_trial_test()->SetNetworkQueriesWithVariationsService(
+ true, 0.0, network_time::FieldTrialTest::ENABLE_FETCHES_ON_DEMAND);
+ error_handler()->StartHandlingError();
+ EXPECT_TRUE(error_handler()->IsTimerRunning());
+ wait_for_time_query_loop.Run();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(error_handler()->bad_clock_interstitial_shown());
+ EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
+ EXPECT_FALSE(error_handler()->IsTimerRunning());
+
+ // Clear the error handler to test that, when the request completes,
+ // it doesn't try to call a callback on a deleted SSLErrorHandler.
+ ClearErrorHandler();
meacer 2016/10/26 20:03:02 Is the idea here that the test would crash with a
estark 2016/10/31 16:03:25 Yep
+
+ // Shut down the server to cancel the pending request.
+ ASSERT_TRUE(test_server()->ShutdownAndWaitUntilComplete());
+ tracker()->WaitForFetchForTesting(123123123);
+}
« no previous file with comments | « chrome/browser/ssl/ssl_error_handler.cc ('k') | chrome/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698