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

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

Issue 2690333006: Captive portal certificate list should be checked when name mismatch is the only error (Closed)
Patch Set: 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 "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"
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 bool captive_portal_interstitial_shown_; 184 bool captive_portal_interstitial_shown_;
185 bool redirected_to_suggested_url_; 185 bool redirected_to_suggested_url_;
186 bool is_overridable_error_; 186 bool is_overridable_error_;
187 CommonNameMismatchHandler::CheckUrlCallback suggested_url_callback_; 187 CommonNameMismatchHandler::CheckUrlCallback suggested_url_callback_;
188 188
189 DISALLOW_COPY_AND_ASSIGN(TestSSLErrorHandlerDelegate); 189 DISALLOW_COPY_AND_ASSIGN(TestSSLErrorHandlerDelegate);
190 }; 190 };
191 191
192 } // namespace 192 } // namespace
193 193
194 template <net::CertStatus cert_status> 194 // A class to test name mismatch errors. Creates an error handler with a name
195 class SSLErrorHandlerCertStatusTestBase 195 // mismatch error by default. The error handler can be recreated by calling
196 : public ChromeRenderViewHostTestHarness { 196 // ResetErrorHandler() with an appropriate cert status.
197 class SSLErrorHandlerNameMismatchTest : public ChromeRenderViewHostTestHarness {
197 public: 198 public:
198 SSLErrorHandlerCertStatusTestBase() : field_trial_list_(nullptr) {} 199 SSLErrorHandlerNameMismatchTest() : field_trial_list_(nullptr) {}
199 200
200 void SetUp() override { 201 void SetUp() override {
201 ChromeRenderViewHostTestHarness::SetUp(); 202 ChromeRenderViewHostTestHarness::SetUp();
202 SSLErrorHandler::ResetConfigForTesting(); 203 SSLErrorHandler::ResetConfigForTesting();
203 SSLErrorHandler::SetInterstitialDelayForTesting(base::TimeDelta()); 204 SSLErrorHandler::SetInterstitialDelayForTesting(base::TimeDelta());
205 ResetErrorHandler(net::CERT_STATUS_COMMON_NAME_INVALID);
206 }
207
208 void TearDown() override {
209 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
210 error_handler_.reset(nullptr);
211 SSLErrorHandler::ResetConfigForTesting();
212 ChromeRenderViewHostTestHarness::TearDown();
213 }
214
215 TestSSLErrorHandler* error_handler() { return error_handler_.get(); }
216 TestSSLErrorHandlerDelegate* delegate() { return delegate_; }
217
218 const net::SSLInfo& ssl_info() { return ssl_info_; }
219
220 protected:
221 // Deletes the current error handler and creates a new one with the given
222 // |cert_status|.
223 void ResetErrorHandler(net::CertStatus cert_status) {
224 ssl_info_.Reset();
204 ssl_info_.cert = 225 ssl_info_.cert =
205 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); 226 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
206 ssl_info_.cert_status = cert_status; 227 ssl_info_.cert_status = cert_status;
207 ssl_info_.public_key_hashes.push_back( 228 ssl_info_.public_key_hashes.push_back(
208 net::HashValue(kCertPublicKeyHashValue)); 229 net::HashValue(kCertPublicKeyHashValue));
209 230
210 delegate_ = 231 delegate_ =
211 new TestSSLErrorHandlerDelegate(profile(), web_contents(), ssl_info_); 232 new TestSSLErrorHandlerDelegate(profile(), web_contents(), ssl_info_);
212 error_handler_.reset(new TestSSLErrorHandler( 233 error_handler_.reset(new TestSSLErrorHandler(
213 std::unique_ptr<SSLErrorHandler::Delegate>(delegate_), web_contents(), 234 std::unique_ptr<SSLErrorHandler::Delegate>(delegate_), web_contents(),
214 profile(), net::MapCertStatusToNetError(ssl_info_.cert_status), 235 profile(), net::MapCertStatusToNetError(ssl_info_.cert_status),
215 ssl_info_, 236 ssl_info_,
216 GURL(), // request_url 237 GURL(), // request_url
217 base::Callback<void(content::CertificateRequestResultType)>())); 238 base::Callback<void(content::CertificateRequestResultType)>()));
218 239
219 // Enable finch experiment for captive portal interstitials. 240 // Enable finch experiment for captive portal interstitials.
220 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 241 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
221 "CaptivePortalInterstitial", "Enabled")); 242 "CaptivePortalInterstitial", "Enabled"));
222 // Enable finch experiment for SSL common name mismatch handling. 243 // Enable finch experiment for SSL common name mismatch handling.
223 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 244 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
224 "SSLCommonNameMismatchHandling", "Enabled")); 245 "SSLCommonNameMismatchHandling", "Enabled"));
225 } 246 }
226 247
227 void TearDown() override { 248 void TestNoCaptivePortalInterstitial(int expected_cert_error) {
249 base::HistogramTester histograms;
250
251 EXPECT_EQ(expected_cert_error, error_handler()->cert_error_for_testing());
estark 2017/02/15 00:31:41 I feel meh about having this cert_error_for_testin
meacer 2017/02/23 23:28:19 Correct.
228 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); 252 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
229 error_handler_.reset(nullptr); 253 EXPECT_EQ(1u, ssl_info().public_key_hashes.size());
230 SSLErrorHandler::ResetConfigForTesting(); 254
231 ChromeRenderViewHostTestHarness::TearDown(); 255 auto config_proto =
256 base::MakeUnique<chrome_browser_ssl::SSLErrorAssistantConfig>();
257 config_proto->add_captive_portal_cert()->set_sha256_hash(
258 "sha256/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
259 config_proto->add_captive_portal_cert()->set_sha256_hash(
260 ssl_info().public_key_hashes[0].ToString());
261 config_proto->add_captive_portal_cert()->set_sha256_hash(
262 "sha256/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
263 SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
264
265 error_handler()->StartHandlingError();
266
267 // Timer should start for captive portal detection.
268 EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
269 EXPECT_TRUE(delegate()->captive_portal_checked());
270 EXPECT_FALSE(delegate()->ssl_interstitial_shown());
271 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
272 EXPECT_FALSE(delegate()->suggested_url_checked());
273
274 base::RunLoop().RunUntilIdle();
275
276 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
277 EXPECT_TRUE(delegate()->captive_portal_checked());
278 EXPECT_TRUE(delegate()->ssl_interstitial_shown());
279 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
280 EXPECT_FALSE(delegate()->suggested_url_checked());
281
282 // Check that the histogram for the captive portal cert was recorded.
283 histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(),
284 2);
285 histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
286 SSLErrorHandler::HANDLE_ALL, 1);
287 histograms.ExpectBucketCount(
288 SSLErrorHandler::GetHistogramNameForTesting(),
289 SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
232 } 290 }
233 291
234 TestSSLErrorHandler* error_handler() { return error_handler_.get(); }
235 TestSSLErrorHandlerDelegate* delegate() { return delegate_; }
236
237 const net::SSLInfo& ssl_info() { return ssl_info_; }
238
239 private: 292 private:
240 net::SSLInfo ssl_info_; 293 net::SSLInfo ssl_info_;
241 std::unique_ptr<TestSSLErrorHandler> error_handler_; 294 std::unique_ptr<TestSSLErrorHandler> error_handler_;
242 TestSSLErrorHandlerDelegate* delegate_; 295 TestSSLErrorHandlerDelegate* delegate_;
243 base::FieldTrialList field_trial_list_; 296 base::FieldTrialList field_trial_list_;
244 297
245 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerCertStatusTestBase); 298 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerNameMismatchTest);
246 }; 299 };
247 300
248 using SSLErrorHandlerNameMismatchTest =
249 SSLErrorHandlerCertStatusTestBase<net::CERT_STATUS_COMMON_NAME_INVALID>;
250 using SSLErrorHandlerAuthorityInvalidTest =
251 SSLErrorHandlerCertStatusTestBase<net::CERT_STATUS_AUTHORITY_INVALID>;
252
253 class SSLErrorHandlerDateInvalidTest : public ChromeRenderViewHostTestHarness { 301 class SSLErrorHandlerDateInvalidTest : public ChromeRenderViewHostTestHarness {
254 public: 302 public:
255 SSLErrorHandlerDateInvalidTest() 303 SSLErrorHandlerDateInvalidTest()
256 : field_trial_test_(new network_time::FieldTrialTest()), 304 : field_trial_test_(new network_time::FieldTrialTest()),
257 clock_(new base::SimpleTestClock), 305 clock_(new base::SimpleTestClock),
258 tick_clock_(new base::SimpleTestTickClock), 306 tick_clock_(new base::SimpleTestTickClock),
259 test_server_(new net::EmbeddedTestServer) { 307 test_server_(new net::EmbeddedTestServer) {
260 SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD); 308 SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD);
261 network_time::NetworkTimeTracker::RegisterPrefs(pref_service_.registry()); 309 network_time::NetworkTimeTracker::RegisterPrefs(pref_service_.registry());
262 } 310 }
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 803
756 // Tests that a certificate marked as a known captive portal certificate does 804 // Tests that a certificate marked as a known captive portal certificate does
757 // not cause the captive portal interstitial to be shown, if the feature is 805 // not cause the captive portal interstitial to be shown, if the feature is
758 // disabled. 806 // disabled.
759 TEST_F(SSLErrorHandlerNameMismatchTest, CaptivePortalCertificateList_Disabled) { 807 TEST_F(SSLErrorHandlerNameMismatchTest, CaptivePortalCertificateList_Disabled) {
760 base::test::ScopedFeatureList scoped_feature_list; 808 base::test::ScopedFeatureList scoped_feature_list;
761 scoped_feature_list.InitFromCommandLine( 809 scoped_feature_list.InitFromCommandLine(
762 std::string() /* enabled */, 810 std::string() /* enabled */,
763 "CaptivePortalCertificateList" /* disabled */); 811 "CaptivePortalCertificateList" /* disabled */);
764 812
765 base::HistogramTester histograms; 813 TestNoCaptivePortalInterstitial(net::ERR_CERT_COMMON_NAME_INVALID);
766
767 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
768 EXPECT_EQ(1u, ssl_info().public_key_hashes.size());
769
770 auto config_proto =
771 base::MakeUnique<chrome_browser_ssl::SSLErrorAssistantConfig>();
772 config_proto->add_captive_portal_cert()->set_sha256_hash(
773 "sha256/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
774 config_proto->add_captive_portal_cert()->set_sha256_hash(
775 ssl_info().public_key_hashes[0].ToString());
776 config_proto->add_captive_portal_cert()->set_sha256_hash(
777 "sha256/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
778 SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
779
780 error_handler()->StartHandlingError();
781
782 // Timer should start since captive portal certificate list feature is
783 // disabled.
784 EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
785 EXPECT_TRUE(delegate()->captive_portal_checked());
786 EXPECT_FALSE(delegate()->ssl_interstitial_shown());
787 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
788 EXPECT_FALSE(delegate()->suggested_url_checked());
789
790 // A buggy SSL error handler might have incorrectly started the timer. Run to
791 // completion to ensure the timer is expired.
792 base::RunLoop().RunUntilIdle();
793
794 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
795 EXPECT_TRUE(delegate()->captive_portal_checked());
796 EXPECT_TRUE(delegate()->ssl_interstitial_shown());
797 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
798 EXPECT_FALSE(delegate()->suggested_url_checked());
799
800 // Check that the histogram for the captive portal cert was recorded.
801 histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
802 histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
803 SSLErrorHandler::HANDLE_ALL, 1);
804 histograms.ExpectBucketCount(
805 SSLErrorHandler::GetHistogramNameForTesting(),
806 SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
807 } 814 }
808 815
809 // Tests that an error other than name mismatch does not cause a captive portal 816 // Tests that an error other than name mismatch does not cause a captive portal
810 // interstitial to be shown, even if the certificate is marked as a known 817 // interstitial to be shown, even if the certificate is marked as a known
811 // captive portal certificate. 818 // captive portal certificate.
812 TEST_F(SSLErrorHandlerAuthorityInvalidTest, 819 TEST_F(SSLErrorHandlerNameMismatchTest,
813 CaptivePortalCertificateList_ShouldShowGenericInterstitial) { 820 CaptivePortalCertificateList_AuthorityInvalid) {
814 base::test::ScopedFeatureList scoped_feature_list; 821 base::test::ScopedFeatureList scoped_feature_list;
815 scoped_feature_list.InitFromCommandLine( 822 scoped_feature_list.InitFromCommandLine(
816 "CaptivePortalCertificateList" /* enabled */, 823 "CaptivePortalCertificateList" /* enabled */,
817 std::string() /* disabled */); 824 std::string() /* disabled */);
818 825
819 base::HistogramTester histograms; 826 ResetErrorHandler(net::CERT_STATUS_AUTHORITY_INVALID);
827 TestNoCaptivePortalInterstitial(net::ERR_CERT_AUTHORITY_INVALID);
828 }
820 829
821 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting()); 830 // Tests that another error in addition to name mismatch error does not cause a
822 EXPECT_EQ(1u, ssl_info().public_key_hashes.size()); 831 // captive portal interstitial to be shown, even if the certificate is marked as
832 // a known captive portal certificate. This is similar to
833 // SSLErrorHandlerNameMismatchTest.CaptivePortalCertificateList_AuthorityInvalid
834 // except there are two errors here (name mismatch + weak key).
835 TEST_F(SSLErrorHandlerNameMismatchTest,
836 CaptivePortalCertificateList_NameMismatchAndWeakKey) {
837 base::test::ScopedFeatureList scoped_feature_list;
838 scoped_feature_list.InitFromCommandLine(
839 "CaptivePortalCertificateList" /* enabled */,
840 std::string() /* disabled */);
823 841
824 auto config_proto = 842 ResetErrorHandler(net::CERT_STATUS_COMMON_NAME_INVALID |
estark 2017/02/15 00:31:41 same nit about sanity-checking to make sure the co
meacer 2017/02/23 23:28:20 Done.
825 base::MakeUnique<chrome_browser_ssl::SSLErrorAssistantConfig>(); 843 net::CERT_STATUS_WEAK_KEY);
826 config_proto->add_captive_portal_cert()->set_sha256_hash( 844 TestNoCaptivePortalInterstitial(net::ERR_CERT_COMMON_NAME_INVALID);
827 "sha256/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
828 config_proto->add_captive_portal_cert()->set_sha256_hash(
829 ssl_info().public_key_hashes[0].ToString());
830 config_proto->add_captive_portal_cert()->set_sha256_hash(
831 "sha256/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
832 SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
833
834 error_handler()->StartHandlingError();
835
836 // Timer should start for captive portal detection.
837 EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
838 EXPECT_TRUE(delegate()->captive_portal_checked());
839 EXPECT_FALSE(delegate()->ssl_interstitial_shown());
840 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
841 EXPECT_FALSE(delegate()->suggested_url_checked());
842
843 base::RunLoop().RunUntilIdle();
844
845 EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
846 EXPECT_TRUE(delegate()->captive_portal_checked());
847 EXPECT_TRUE(delegate()->ssl_interstitial_shown());
848 EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
849 EXPECT_FALSE(delegate()->suggested_url_checked());
850
851 // Check that the histogram for the captive portal cert was recorded.
852 histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
853 histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
854 SSLErrorHandler::HANDLE_ALL, 1);
855 histograms.ExpectBucketCount(
856 SSLErrorHandler::GetHistogramNameForTesting(),
857 SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
858 } 845 }
859 846
860 #endif // BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) 847 #endif // BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
OLDNEW
« chrome/browser/ssl/ssl_browser_tests.cc ('K') | « chrome/browser/ssl/ssl_error_handler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698