Chromium Code Reviews| 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 "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/metrics/field_trial.h" | 10 #include "base/metrics/field_trial.h" |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/test/histogram_tester.h" | 12 #include "base/test/histogram_tester.h" |
| 13 #include "base/test/scoped_feature_list.h" | |
| 13 #include "base/test/simple_test_clock.h" | 14 #include "base/test/simple_test_clock.h" |
| 14 #include "base/test/simple_test_tick_clock.h" | 15 #include "base/test/simple_test_tick_clock.h" |
| 15 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 16 #include "chrome/browser/captive_portal/captive_portal_service.h" | 17 #include "chrome/browser/captive_portal/captive_portal_service.h" |
| 17 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 18 #include "chrome/browser/ssl/common_name_mismatch_handler.h" | 19 #include "chrome/browser/ssl/common_name_mismatch_handler.h" |
| 20 #include "chrome/browser/ssl/ssl_error_assistant.pb.h" | |
| 19 #include "chrome/common/features.h" | 21 #include "chrome/common/features.h" |
| 20 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 22 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| 21 #include "chrome/test/base/testing_profile.h" | 23 #include "chrome/test/base/testing_profile.h" |
| 22 #include "components/captive_portal/captive_portal_testing_utils.h" | 24 #include "components/captive_portal/captive_portal_testing_utils.h" |
| 23 #include "components/network_time/network_time_test_utils.h" | 25 #include "components/network_time/network_time_test_utils.h" |
| 24 #include "components/network_time/network_time_tracker.h" | 26 #include "components/network_time/network_time_tracker.h" |
| 25 #include "components/prefs/testing_pref_service.h" | 27 #include "components/prefs/testing_pref_service.h" |
| 26 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
| 27 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
| 28 #include "net/base/net_errors.h" | 30 #include "net/base/net_errors.h" |
| 29 #include "net/cert/cert_status_flags.h" | 31 #include "net/cert/cert_status_flags.h" |
| 30 #include "net/cert/x509_certificate.h" | 32 #include "net/cert/x509_certificate.h" |
| 31 #include "net/http/http_response_headers.h" | 33 #include "net/http/http_response_headers.h" |
| 32 #include "net/ssl/ssl_info.h" | 34 #include "net/ssl/ssl_info.h" |
| 33 #include "net/test/cert_test_util.h" | 35 #include "net/test/cert_test_util.h" |
| 34 #include "net/test/embedded_test_server/embedded_test_server.h" | 36 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 35 #include "net/test/embedded_test_server/http_response.h" | 37 #include "net/test/embedded_test_server/http_response.h" |
| 36 #include "net/test/test_certificate_data.h" | 38 #include "net/test/test_certificate_data.h" |
| 37 #include "net/test/test_data_directory.h" | 39 #include "net/test/test_data_directory.h" |
| 38 #include "net/url_request/url_request_test_util.h" | 40 #include "net/url_request/url_request_test_util.h" |
| 39 #include "testing/gtest/include/gtest/gtest.h" | 41 #include "testing/gtest/include/gtest/gtest.h" |
| 40 | 42 |
| 41 namespace { | 43 namespace { |
| 42 | 44 |
| 43 const char kCertDateErrorHistogram[] = | 45 const char kCertDateErrorHistogram[] = |
| 44 "interstitial.ssl_error_handler.cert_date_error_delay"; | 46 "interstitial.ssl_error_handler.cert_date_error_delay"; |
| 45 | 47 |
| 48 const net::SHA256HashValue kCertPublicKeyHashValue = {{0x01, 0x02}}; | |
| 49 | |
| 46 // Runs |quit_closure| on the UI thread once a URL request has been | 50 // Runs |quit_closure| on the UI thread once a URL request has been |
| 47 // seen. Returns a request that hangs. | 51 // seen. Returns a request that hangs. |
| 48 std::unique_ptr<net::test_server::HttpResponse> WaitForRequest( | 52 std::unique_ptr<net::test_server::HttpResponse> WaitForRequest( |
| 49 const base::Closure& quit_closure, | 53 const base::Closure& quit_closure, |
| 50 const net::test_server::HttpRequest& request) { | 54 const net::test_server::HttpRequest& request) { |
| 51 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 55 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
| 52 quit_closure); | 56 quit_closure); |
| 53 return base::MakeUnique<net::test_server::HungResponse>(); | 57 return base::MakeUnique<net::test_server::HungResponse>(); |
| 54 } | 58 } |
| 55 | 59 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 bool captive_portal_interstitial_shown_; | 184 bool captive_portal_interstitial_shown_; |
| 181 bool redirected_to_suggested_url_; | 185 bool redirected_to_suggested_url_; |
| 182 bool is_overridable_error_; | 186 bool is_overridable_error_; |
| 183 CommonNameMismatchHandler::CheckUrlCallback suggested_url_callback_; | 187 CommonNameMismatchHandler::CheckUrlCallback suggested_url_callback_; |
| 184 | 188 |
| 185 DISALLOW_COPY_AND_ASSIGN(TestSSLErrorHandlerDelegate); | 189 DISALLOW_COPY_AND_ASSIGN(TestSSLErrorHandlerDelegate); |
| 186 }; | 190 }; |
| 187 | 191 |
| 188 } // namespace | 192 } // namespace |
| 189 | 193 |
| 190 class SSLErrorHandlerNameMismatchTest : public ChromeRenderViewHostTestHarness { | 194 template <net::CertStatus kCertStatus> |
|
Ryan Sleevi
2017/02/01 22:06:06
I haven't really seen template parameters follow t
meacer
2017/02/02 01:56:06
Wasn't sure about it either so I did a code search
| |
| 195 class SSLErrorHandlerCertStatusTestBase | |
| 196 : public ChromeRenderViewHostTestHarness { | |
| 191 public: | 197 public: |
| 192 SSLErrorHandlerNameMismatchTest() : field_trial_list_(nullptr) {} | 198 SSLErrorHandlerCertStatusTestBase() : field_trial_list_(nullptr) {} |
| 193 | 199 |
| 194 void SetUp() override { | 200 void SetUp() override { |
| 195 ChromeRenderViewHostTestHarness::SetUp(); | 201 ChromeRenderViewHostTestHarness::SetUp(); |
| 202 SSLErrorHandler::ResetConfigForTesting(); | |
|
Ryan Sleevi
2017/02/01 22:06:06
Shouldn't you also be doing this in TearDown?
meacer
2017/02/02 01:56:06
Done.
| |
| 196 SSLErrorHandler::SetInterstitialDelayForTesting(base::TimeDelta()); | 203 SSLErrorHandler::SetInterstitialDelayForTesting(base::TimeDelta()); |
| 197 ssl_info_.cert = | 204 ssl_info_.cert = |
| 198 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); | 205 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); |
| 199 ssl_info_.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID; | 206 ssl_info_.cert_status = kCertStatus; |
| 207 ssl_info_.public_key_hashes.push_back( | |
| 208 net::HashValue(kCertPublicKeyHashValue)); | |
| 200 | 209 |
| 201 delegate_ = | 210 delegate_ = |
| 202 new TestSSLErrorHandlerDelegate(profile(), web_contents(), ssl_info_); | 211 new TestSSLErrorHandlerDelegate(profile(), web_contents(), ssl_info_); |
| 203 error_handler_.reset(new TestSSLErrorHandler( | 212 error_handler_.reset(new TestSSLErrorHandler( |
| 204 std::unique_ptr<SSLErrorHandler::Delegate>(delegate_), web_contents(), | 213 std::unique_ptr<SSLErrorHandler::Delegate>(delegate_), web_contents(), |
| 205 profile(), net::MapCertStatusToNetError(ssl_info_.cert_status), | 214 profile(), net::MapCertStatusToNetError(ssl_info_.cert_status), |
| 206 ssl_info_, | 215 ssl_info_, |
| 207 GURL(), // request_url | 216 GURL(), // request_url |
| 208 base::Callback<void(content::CertificateRequestResultType)>())); | 217 base::Callback<void(content::CertificateRequestResultType)>())); |
| 209 | 218 |
| 210 // Enable finch experiment for captive portal interstitials. | 219 // Enable finch experiment for captive portal interstitials. |
| 211 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( | 220 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
| 212 "CaptivePortalInterstitial", "Enabled")); | 221 "CaptivePortalInterstitial", "Enabled")); |
| 213 // Enable finch experiment for SSL common name mismatch handling. | 222 // Enable finch experiment for SSL common name mismatch handling. |
| 214 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( | 223 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
| 215 "SSLCommonNameMismatchHandling", "Enabled")); | 224 "SSLCommonNameMismatchHandling", "Enabled")); |
| 216 } | 225 } |
| 217 | 226 |
| 218 void TearDown() override { | 227 void TearDown() override { |
| 219 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); | 228 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); |
| 220 error_handler_.reset(nullptr); | 229 error_handler_.reset(nullptr); |
| 221 ChromeRenderViewHostTestHarness::TearDown(); | 230 ChromeRenderViewHostTestHarness::TearDown(); |
| 222 } | 231 } |
| 223 | 232 |
| 224 TestSSLErrorHandler* error_handler() { return error_handler_.get(); } | 233 TestSSLErrorHandler* error_handler() { return error_handler_.get(); } |
| 225 TestSSLErrorHandlerDelegate* delegate() { return delegate_; } | 234 TestSSLErrorHandlerDelegate* delegate() { return delegate_; } |
| 226 | 235 |
| 236 const net::SSLInfo& ssl_info() { return ssl_info_; } | |
| 237 | |
| 227 private: | 238 private: |
| 228 net::SSLInfo ssl_info_; | 239 net::SSLInfo ssl_info_; |
| 229 std::unique_ptr<TestSSLErrorHandler> error_handler_; | 240 std::unique_ptr<TestSSLErrorHandler> error_handler_; |
| 230 TestSSLErrorHandlerDelegate* delegate_; | 241 TestSSLErrorHandlerDelegate* delegate_; |
| 231 base::FieldTrialList field_trial_list_; | 242 base::FieldTrialList field_trial_list_; |
| 232 | 243 |
| 233 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerNameMismatchTest); | 244 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerCertStatusTestBase); |
| 234 }; | 245 }; |
| 235 | 246 |
| 247 using SSLErrorHandlerNameMismatchTest = | |
| 248 SSLErrorHandlerCertStatusTestBase<net::CERT_STATUS_COMMON_NAME_INVALID>; | |
| 249 using SSLErrorHandlerAuthorityInvalidTest = | |
| 250 SSLErrorHandlerCertStatusTestBase<net::CERT_STATUS_AUTHORITY_INVALID>; | |
| 251 | |
| 236 class SSLErrorHandlerDateInvalidTest : public ChromeRenderViewHostTestHarness { | 252 class SSLErrorHandlerDateInvalidTest : public ChromeRenderViewHostTestHarness { |
| 237 public: | 253 public: |
| 238 SSLErrorHandlerDateInvalidTest() | 254 SSLErrorHandlerDateInvalidTest() |
| 239 : field_trial_test_(new network_time::FieldTrialTest()), | 255 : field_trial_test_(new network_time::FieldTrialTest()), |
| 240 clock_(new base::SimpleTestClock), | 256 clock_(new base::SimpleTestClock), |
| 241 tick_clock_(new base::SimpleTestTickClock), | 257 tick_clock_(new base::SimpleTestTickClock), |
| 242 test_server_(new net::EmbeddedTestServer) { | 258 test_server_(new net::EmbeddedTestServer) { |
| 243 SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD); | 259 SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD); |
| 244 network_time::NetworkTimeTracker::RegisterPrefs(pref_service_.registry()); | 260 network_time::NetworkTimeTracker::RegisterPrefs(pref_service_.registry()); |
| 245 } | 261 } |
| 246 | 262 |
| 247 void SetUp() override { | 263 void SetUp() override { |
| 248 ChromeRenderViewHostTestHarness::SetUp(); | 264 ChromeRenderViewHostTestHarness::SetUp(); |
| 265 SSLErrorHandler::ResetConfigForTesting(); | |
|
Ryan Sleevi
2017/02/01 22:06:06
Shouldn't you also be doing this in TearDown?
meacer
2017/02/02 01:56:06
Done.
| |
| 249 | 266 |
| 250 field_trial_test()->SetNetworkQueriesWithVariationsService( | 267 field_trial_test()->SetNetworkQueriesWithVariationsService( |
| 251 false, 0.0, | 268 false, 0.0, |
| 252 network_time::NetworkTimeTracker::FETCHES_IN_BACKGROUND_ONLY); | 269 network_time::NetworkTimeTracker::FETCHES_IN_BACKGROUND_ONLY); |
| 253 tracker_.reset(new network_time::NetworkTimeTracker( | 270 tracker_.reset(new network_time::NetworkTimeTracker( |
| 254 std::unique_ptr<base::Clock>(clock_), | 271 std::unique_ptr<base::Clock>(clock_), |
| 255 std::unique_ptr<base::TickClock>(tick_clock_), &pref_service_, | 272 std::unique_ptr<base::TickClock>(tick_clock_), &pref_service_, |
| 256 new net::TestURLRequestContextGetter( | 273 new net::TestURLRequestContextGetter( |
| 257 content::BrowserThread::GetTaskRunnerForThread( | 274 content::BrowserThread::GetTaskRunnerForThread( |
| 258 content::BrowserThread::IO)))); | 275 content::BrowserThread::IO)))); |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 672 // Check that the histogram for the delay was recorded. | 689 // Check that the histogram for the delay was recorded. |
| 673 histograms.ExpectTotalCount(kCertDateErrorHistogram, 1); | 690 histograms.ExpectTotalCount(kCertDateErrorHistogram, 1); |
| 674 | 691 |
| 675 // Clear the error handler to test that, when the request completes, | 692 // Clear the error handler to test that, when the request completes, |
| 676 // it doesn't try to call a callback on a deleted SSLErrorHandler. | 693 // it doesn't try to call a callback on a deleted SSLErrorHandler. |
| 677 ClearErrorHandler(); | 694 ClearErrorHandler(); |
| 678 | 695 |
| 679 // Shut down the server to cancel the pending request. | 696 // Shut down the server to cancel the pending request. |
| 680 ASSERT_TRUE(test_server()->ShutdownAndWaitUntilComplete()); | 697 ASSERT_TRUE(test_server()->ShutdownAndWaitUntilComplete()); |
| 681 } | 698 } |
| 699 | |
| 700 // Tests that a certificate marked as a known captive portal certificate causes | |
| 701 // the captive portal interstitial to be shown. | |
| 702 TEST_F(SSLErrorHandlerNameMismatchTest, CaptivePortalCertificateList_Enabled) { | |
| 703 base::test::ScopedFeatureList scoped_feature_list; | |
| 704 scoped_feature_list.InitFromCommandLine( | |
| 705 "CaptivePortalCertificateList" /* enabled */, "" /* disabled */); | |
| 706 | |
| 707 base::HistogramTester histograms; | |
| 708 | |
| 709 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); | |
| 710 EXPECT_EQ(1u, ssl_info().public_key_hashes.size()); | |
| 711 | |
| 712 chrome_browser_ssl::SSLErrorAssistantConfig config_proto; | |
| 713 config_proto.add_captive_portal_cert()->set_sha256_hash( | |
| 714 "sha256/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); | |
| 715 config_proto.add_captive_portal_cert()->set_sha256_hash( | |
| 716 ssl_info().public_key_hashes[0].ToString()); | |
| 717 config_proto.add_captive_portal_cert()->set_sha256_hash( | |
| 718 "sha256/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); | |
| 719 SSLErrorHandler::SetErrorAssistantProtoForTesting(config_proto); | |
| 720 | |
| 721 error_handler()->StartHandlingError(); | |
| 722 | |
| 723 // Timer shouldn't start for a known captive portal certificate. | |
| 724 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); | |
| 725 EXPECT_FALSE(delegate()->captive_portal_checked()); | |
| 726 EXPECT_FALSE(delegate()->ssl_interstitial_shown()); | |
| 727 EXPECT_TRUE(delegate()->captive_portal_interstitial_shown()); | |
| 728 EXPECT_FALSE(delegate()->suggested_url_checked()); | |
| 729 | |
| 730 // A buggy SSL error handler might have incorrectly started the timer. Run to | |
| 731 // completion to ensure the timer is expired. | |
| 732 base::RunLoop().RunUntilIdle(); | |
| 733 | |
| 734 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); | |
| 735 EXPECT_FALSE(delegate()->captive_portal_checked()); | |
| 736 EXPECT_FALSE(delegate()->ssl_interstitial_shown()); | |
| 737 EXPECT_TRUE(delegate()->captive_portal_interstitial_shown()); | |
| 738 EXPECT_FALSE(delegate()->suggested_url_checked()); | |
| 739 | |
| 740 // Check that the histogram for the captive portal cert was recorded. | |
| 741 histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 3); | |
| 742 histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(), | |
| 743 SSLErrorHandler::HANDLE_ALL, 1); | |
| 744 histograms.ExpectBucketCount( | |
| 745 SSLErrorHandler::GetHistogramNameForTesting(), | |
| 746 SSLErrorHandler::SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE, 1); | |
| 747 histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(), | |
| 748 SSLErrorHandler::CAPTIVE_PORTAL_CERT_FOUND, 1); | |
| 749 } | |
| 750 | |
| 751 // Tests that a certificate marked as a known captive portal certificate does | |
| 752 // not cause the captive portal interstitial to be shown, if the feature is | |
| 753 // disabled. | |
| 754 TEST_F(SSLErrorHandlerNameMismatchTest, CaptivePortalCertificateList_Disabled) { | |
| 755 base::test::ScopedFeatureList scoped_feature_list; | |
| 756 scoped_feature_list.InitFromCommandLine( | |
| 757 "" /* enabled */, "CaptivePortalCertificateList" /* disabled */); | |
| 758 | |
| 759 base::HistogramTester histograms; | |
| 760 | |
| 761 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); | |
| 762 EXPECT_EQ(1u, ssl_info().public_key_hashes.size()); | |
| 763 | |
| 764 chrome_browser_ssl::SSLErrorAssistantConfig config_proto; | |
| 765 config_proto.add_captive_portal_cert()->set_sha256_hash( | |
| 766 "sha256/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); | |
| 767 config_proto.add_captive_portal_cert()->set_sha256_hash( | |
| 768 ssl_info().public_key_hashes[0].ToString()); | |
| 769 config_proto.add_captive_portal_cert()->set_sha256_hash( | |
| 770 "sha256/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); | |
| 771 SSLErrorHandler::SetErrorAssistantProtoForTesting(config_proto); | |
| 772 | |
| 773 error_handler()->StartHandlingError(); | |
| 774 | |
| 775 // Timer shouldn't start for a known captive portal certificate. | |
| 776 EXPECT_TRUE(error_handler()->IsTimerRunningForTesting()); | |
| 777 EXPECT_TRUE(delegate()->captive_portal_checked()); | |
| 778 EXPECT_FALSE(delegate()->ssl_interstitial_shown()); | |
| 779 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown()); | |
| 780 EXPECT_FALSE(delegate()->suggested_url_checked()); | |
| 781 | |
| 782 // A buggy SSL error handler might have incorrectly started the timer. Run to | |
| 783 // completion to ensure the timer is expired. | |
| 784 base::RunLoop().RunUntilIdle(); | |
| 785 | |
| 786 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); | |
| 787 EXPECT_TRUE(delegate()->captive_portal_checked()); | |
| 788 EXPECT_TRUE(delegate()->ssl_interstitial_shown()); | |
| 789 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown()); | |
| 790 EXPECT_FALSE(delegate()->suggested_url_checked()); | |
| 791 | |
| 792 // Check that the histogram for the captive portal cert was recorded. | |
| 793 histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2); | |
| 794 histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(), | |
| 795 SSLErrorHandler::HANDLE_ALL, 1); | |
| 796 histograms.ExpectBucketCount( | |
| 797 SSLErrorHandler::GetHistogramNameForTesting(), | |
| 798 SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1); | |
| 799 } | |
| 800 | |
| 801 // Tests that an error other than name mismatch does not cause a captive portal | |
| 802 // interstitial to be shown, even if the certificate is marked as a known | |
| 803 // captive portal certificate. | |
| 804 TEST_F(SSLErrorHandlerAuthorityInvalidTest, | |
| 805 CaptivePortalCertificateList_ShouldShowGenericInterstitial) { | |
| 806 base::test::ScopedFeatureList scoped_feature_list; | |
| 807 scoped_feature_list.InitFromCommandLine( | |
| 808 "CaptivePortalCertificateList" /* enabled */, "" /* disabled */); | |
| 809 | |
| 810 base::HistogramTester histograms; | |
| 811 | |
| 812 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); | |
| 813 EXPECT_EQ(1u, ssl_info().public_key_hashes.size()); | |
| 814 | |
| 815 chrome_browser_ssl::SSLErrorAssistantConfig config_proto; | |
| 816 config_proto.add_captive_portal_cert()->set_sha256_hash( | |
| 817 "sha256/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); | |
| 818 config_proto.add_captive_portal_cert()->set_sha256_hash( | |
| 819 ssl_info().public_key_hashes[0].ToString()); | |
| 820 config_proto.add_captive_portal_cert()->set_sha256_hash( | |
| 821 "sha256/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); | |
| 822 SSLErrorHandler::SetErrorAssistantProtoForTesting(config_proto); | |
| 823 | |
| 824 error_handler()->StartHandlingError(); | |
| 825 | |
| 826 // Timer should start for captive portal detection. | |
| 827 EXPECT_TRUE(error_handler()->IsTimerRunningForTesting()); | |
| 828 EXPECT_TRUE(delegate()->captive_portal_checked()); | |
| 829 EXPECT_FALSE(delegate()->ssl_interstitial_shown()); | |
| 830 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown()); | |
| 831 EXPECT_FALSE(delegate()->suggested_url_checked()); | |
| 832 | |
| 833 base::RunLoop().RunUntilIdle(); | |
| 834 | |
| 835 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); | |
| 836 EXPECT_TRUE(delegate()->captive_portal_checked()); | |
| 837 EXPECT_TRUE(delegate()->ssl_interstitial_shown()); | |
| 838 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown()); | |
| 839 EXPECT_FALSE(delegate()->suggested_url_checked()); | |
| 840 | |
| 841 // Check that the histogram for the captive portal cert was recorded. | |
| 842 histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2); | |
| 843 histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(), | |
| 844 SSLErrorHandler::HANDLE_ALL, 1); | |
| 845 histograms.ExpectBucketCount( | |
| 846 SSLErrorHandler::GetHistogramNameForTesting(), | |
| 847 SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1); | |
| 848 } | |
| OLD | NEW |