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

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

Issue 1986953002: Move SecurityStyleChanged logic and tests to chrome/browser/ssl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove unnecessary namespace Created 4 years, 7 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/chrome_security_state_model_client.h" 5 #include "chrome/browser/ssl/chrome_security_state_model_client.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/strings/string_split.h" 10 #include "base/strings/string_split.h"
11 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/ssl/cert_verifier_browser_test.h" 12 #include "chrome/browser/ssl/cert_verifier_browser_test.h"
12 #include "chrome/browser/ssl/chrome_security_state_model_client.h" 13 #include "chrome/browser/ssl/chrome_security_state_model_client.h"
13 #include "chrome/browser/ssl/ssl_blocking_page.h" 14 #include "chrome/browser/ssl/ssl_blocking_page.h"
14 #include "chrome/browser/ui/browser.h" 15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_commands.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h" 17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/common/chrome_paths.h" 18 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/pref_names.h" 20 #include "chrome/common/pref_names.h"
21 #include "chrome/grit/generated_resources.h"
19 #include "chrome/test/base/in_process_browser_test.h" 22 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/ui_test_utils.h" 23 #include "chrome/test/base/ui_test_utils.h"
21 #include "components/prefs/pref_service.h" 24 #include "components/prefs/pref_service.h"
22 #include "content/public/browser/cert_store.h" 25 #include "content/public/browser/cert_store.h"
23 #include "content/public/browser/interstitial_page.h" 26 #include "content/public/browser/interstitial_page.h"
24 #include "content/public/browser/navigation_controller.h" 27 #include "content/public/browser/navigation_controller.h"
28 #include "content/public/browser/navigation_entry.h"
25 #include "content/public/browser/notification_service.h" 29 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/notification_types.h" 30 #include "content/public/browser/notification_types.h"
31 #include "content/public/browser/security_style_explanation.h"
32 #include "content/public/browser/security_style_explanations.h"
27 #include "content/public/browser/web_contents.h" 33 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/referrer.h" 34 #include "content/public/common/referrer.h"
35 #include "content/public/common/ssl_status.h"
29 #include "content/public/test/browser_test_utils.h" 36 #include "content/public/test/browser_test_utils.h"
30 #include "net/base/net_errors.h" 37 #include "net/base/net_errors.h"
38 #include "net/base/test_data_directory.h"
31 #include "net/cert/cert_status_flags.h" 39 #include "net/cert/cert_status_flags.h"
32 #include "net/cert/cert_verify_result.h" 40 #include "net/cert/cert_verify_result.h"
33 #include "net/cert/mock_cert_verifier.h" 41 #include "net/cert/mock_cert_verifier.h"
34 #include "net/cert/x509_certificate.h" 42 #include "net/cert/x509_certificate.h"
43 #include "net/cert/x509_certificate.h"
msw 2016/05/18 17:20:24 nit: remove (duplicate of line above)
estark 2016/05/20 22:12:09 Done.
35 #include "net/dns/mock_host_resolver.h" 44 #include "net/dns/mock_host_resolver.h"
45 #include "net/ssl/ssl_cipher_suite_names.h"
46 #include "net/ssl/ssl_connection_status_flags.h"
47 #include "net/test/cert_test_util.h"
36 #include "net/test/embedded_test_server/embedded_test_server.h" 48 #include "net/test/embedded_test_server/embedded_test_server.h"
37 #include "net/test/embedded_test_server/request_handler_util.h" 49 #include "net/test/embedded_test_server/request_handler_util.h"
38 #include "net/test/url_request/url_request_failed_job.h" 50 #include "net/test/url_request/url_request_failed_job.h"
51 #include "net/test/url_request/url_request_mock_http_job.h"
39 #include "net/url_request/url_request_filter.h" 52 #include "net/url_request/url_request_filter.h"
53 #include "net/url_request/url_request_test_util.h"
54 #include "ui/base/l10n/l10n_util.h"
40 55
41 using security_state::SecurityStateModel; 56 using security_state::SecurityStateModel;
42 57
43 namespace { 58 namespace {
44 59
60 enum CertificateStatus { VALID_CERTIFICATE, INVALID_CERTIFICATE };
61
45 const base::FilePath::CharType kDocRoot[] = 62 const base::FilePath::CharType kDocRoot[] =
46 FILE_PATH_LITERAL("chrome/test/data"); 63 FILE_PATH_LITERAL("chrome/test/data");
47 64
65 // A WebContentsObserver useful for testing the SecurityStyleChanged()
66 // method: it keeps track of the latest security style and explanation
67 // that was fired.
68 class SecurityStyleTestObserver : public content::WebContentsObserver {
69 public:
70 explicit SecurityStyleTestObserver(content::WebContents* web_contents)
71 : content::WebContentsObserver(web_contents),
72 latest_security_style_(content::SECURITY_STYLE_UNKNOWN) {}
73 ~SecurityStyleTestObserver() override {}
74
75 void SecurityStyleChanged(content::SecurityStyle security_style,
76 const content::SecurityStyleExplanations&
77 security_style_explanations) override {
78 latest_security_style_ = security_style;
79 latest_explanations_ = security_style_explanations;
80 }
81
82 content::SecurityStyle latest_security_style() const {
83 return latest_security_style_;
84 }
85
86 const content::SecurityStyleExplanations& latest_explanations() const {
87 return latest_explanations_;
88 }
89
90 void ClearLatestSecurityStyleAndExplanations() {
91 latest_security_style_ = content::SECURITY_STYLE_UNKNOWN;
92 latest_explanations_ = content::SecurityStyleExplanations();
93 }
94
95 private:
96 content::SecurityStyle latest_security_style_;
97 content::SecurityStyleExplanations latest_explanations_;
98
99 DISALLOW_COPY_AND_ASSIGN(SecurityStyleTestObserver);
100 };
101
102 // Check that |observer|'s latest event was for an expired certificate
103 // and that it saw the proper SecurityStyle and explanations.
104 void CheckBrokenSecurityStyle(const SecurityStyleTestObserver& observer,
105 int error,
106 Browser* browser) {
107 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
108 observer.latest_security_style());
109
110 const content::SecurityStyleExplanations& expired_explanation =
111 observer.latest_explanations();
112 EXPECT_EQ(0u, expired_explanation.unauthenticated_explanations.size());
113 ASSERT_EQ(1u, expired_explanation.broken_explanations.size());
114
115 // Check that the summary and description are as expected.
116 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_CERTIFICATE_CHAIN_ERROR),
117 expired_explanation.broken_explanations[0].summary);
118
119 base::string16 error_string = base::UTF8ToUTF16(net::ErrorToString(error));
120 EXPECT_EQ(l10n_util::GetStringFUTF8(
121 IDS_CERTIFICATE_CHAIN_ERROR_DESCRIPTION_FORMAT, error_string),
122 expired_explanation.broken_explanations[0].description);
123
124 // Check the associated certificate id.
125 int cert_id = browser->tab_strip_model()
126 ->GetActiveWebContents()
127 ->GetController()
128 .GetActiveEntry()
129 ->GetSSL()
130 .cert_id;
131 EXPECT_EQ(cert_id, expired_explanation.broken_explanations[0].cert_id);
132 }
133
134 // Checks that the given |secure_explanations| contains appropriate
135 // an appropriate explanation if the certificate status is valid.
136 void CheckSecureExplanations(
137 const std::vector<content::SecurityStyleExplanation>& secure_explanations,
138 CertificateStatus cert_status,
139 Browser* browser) {
140 ASSERT_EQ(cert_status == VALID_CERTIFICATE ? 2u : 1u,
141 secure_explanations.size());
142 if (cert_status == VALID_CERTIFICATE) {
143 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE),
144 secure_explanations[0].summary);
145 EXPECT_EQ(
146 l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION),
147 secure_explanations[0].description);
148 int cert_id = browser->tab_strip_model()
149 ->GetActiveWebContents()
150 ->GetController()
151 .GetActiveEntry()
152 ->GetSSL()
153 .cert_id;
154 EXPECT_EQ(cert_id, secure_explanations[0].cert_id);
155 }
156
157 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE),
158 secure_explanations.back().summary);
159 EXPECT_EQ(
160 l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE_DESCRIPTION),
161 secure_explanations.back().description);
162 }
163
48 void CheckSecurityInfoForSecure( 164 void CheckSecurityInfoForSecure(
49 content::WebContents* contents, 165 content::WebContents* contents,
50 SecurityStateModel::SecurityLevel expect_security_level, 166 SecurityStateModel::SecurityLevel expect_security_level,
51 SecurityStateModel::SHA1DeprecationStatus expect_sha1_status, 167 SecurityStateModel::SHA1DeprecationStatus expect_sha1_status,
52 SecurityStateModel::MixedContentStatus expect_mixed_content_status, 168 SecurityStateModel::MixedContentStatus expect_mixed_content_status,
53 bool expect_cert_error) { 169 bool expect_cert_error) {
54 ASSERT_TRUE(contents); 170 ASSERT_TRUE(contents);
55 171
56 ChromeSecurityStateModelClient* model_client = 172 ChromeSecurityStateModelClient* model_client =
57 ChromeSecurityStateModelClient::FromWebContents(contents); 173 ChromeSecurityStateModelClient::FromWebContents(contents);
(...skipping 27 matching lines...) Expand all
85 security_info.sha1_deprecation_status); 201 security_info.sha1_deprecation_status);
86 EXPECT_EQ(SecurityStateModel::NO_MIXED_CONTENT, 202 EXPECT_EQ(SecurityStateModel::NO_MIXED_CONTENT,
87 security_info.mixed_content_status); 203 security_info.mixed_content_status);
88 EXPECT_TRUE(security_info.sct_verify_statuses.empty()); 204 EXPECT_TRUE(security_info.sct_verify_statuses.empty());
89 EXPECT_FALSE(security_info.scheme_is_cryptographic); 205 EXPECT_FALSE(security_info.scheme_is_cryptographic);
90 EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); 206 EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status));
91 EXPECT_EQ(-1, security_info.security_bits); 207 EXPECT_EQ(-1, security_info.security_bits);
92 EXPECT_EQ(0, security_info.cert_id); 208 EXPECT_EQ(0, security_info.cert_id);
93 } 209 }
94 210
211 void SetUpMockCertVerifierForServer(net::MockCertVerifier* verifier,
212 const net::EmbeddedTestServer& server,
213 net::CertStatus cert_status,
214 int net_result) {
215 scoped_refptr<net::X509Certificate> cert(server.GetCertificate());
216 net::CertVerifyResult verify_result;
217 verify_result.is_issued_by_known_root = true;
218 verify_result.verified_cert = cert;
219 verify_result.cert_status = cert_status;
220
221 verifier->AddResultForCert(cert.get(), verify_result, net_result);
222 }
223
95 class ChromeSecurityStateModelClientTest : public CertVerifierBrowserTest { 224 class ChromeSecurityStateModelClientTest : public CertVerifierBrowserTest {
96 public: 225 public:
97 ChromeSecurityStateModelClientTest() 226 ChromeSecurityStateModelClientTest()
98 : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { 227 : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
99 https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); 228 https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
100 } 229 }
101 230
102 void SetUpCommandLine(base::CommandLine* command_line) override { 231 void SetUpCommandLine(base::CommandLine* command_line) override {
103 // Browser will both run and display insecure content. 232 // Browser will both run and display insecure content.
104 command_line->AppendSwitch(switches::kAllowRunningInsecureContent); 233 command_line->AppendSwitch(switches::kAllowRunningInsecureContent);
(...skipping 18 matching lines...) Expand all
123 base::StringPairs replacement_text; 252 base::StringPairs replacement_text;
124 replacement_text.push_back( 253 replacement_text.push_back(
125 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString())); 254 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
126 net::test_server::GetFilePathWithReplacements( 255 net::test_server::GetFilePathWithReplacements(
127 original_file_path, replacement_text, replacement_path); 256 original_file_path, replacement_text, replacement_path);
128 } 257 }
129 258
130 protected: 259 protected:
131 void SetUpMockCertVerifierForHttpsServer(net::CertStatus cert_status, 260 void SetUpMockCertVerifierForHttpsServer(net::CertStatus cert_status,
132 int net_result) { 261 int net_result) {
133 scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate()); 262 SetUpMockCertVerifierForServer(mock_cert_verifier(), https_server_,
134 net::CertVerifyResult verify_result; 263 cert_status, net_result);
135 verify_result.is_issued_by_known_root = true;
136 verify_result.verified_cert = cert;
137 verify_result.cert_status = cert_status;
138
139 mock_cert_verifier()->AddResultForCert(cert.get(), verify_result,
140 net_result);
141 } 264 }
142 265
143 net::EmbeddedTestServer https_server_; 266 net::EmbeddedTestServer https_server_;
144 267
145 private: 268 private:
146 DISALLOW_COPY_AND_ASSIGN(ChromeSecurityStateModelClientTest); 269 DISALLOW_COPY_AND_ASSIGN(ChromeSecurityStateModelClientTest);
147 }; 270 };
148 271
149 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, HttpPage) { 272 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, HttpPage) {
150 ASSERT_TRUE(embedded_test_server()->Start()); 273 ASSERT_TRUE(embedded_test_server()->Start());
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 false /* expect cert status error */); 651 false /* expect cert status error */);
529 652
530 browser()->tab_strip_model()->InsertWebContentsAt(0, new_contents, 653 browser()->tab_strip_model()->InsertWebContentsAt(0, new_contents,
531 TabStripModel::ADD_NONE); 654 TabStripModel::ADD_NONE);
532 CheckSecurityInfoForSecure(new_contents, SecurityStateModel::SECURE, 655 CheckSecurityInfoForSecure(new_contents, SecurityStateModel::SECURE,
533 SecurityStateModel::NO_DEPRECATED_SHA1, 656 SecurityStateModel::NO_DEPRECATED_SHA1,
534 SecurityStateModel::NO_MIXED_CONTENT, 657 SecurityStateModel::NO_MIXED_CONTENT,
535 false /* expect cert status error */); 658 false /* expect cert status error */);
536 } 659 }
537 660
661 // Tests that the WebContentsObserver::SecurityStyleChanged event fires
662 // with the current style on HTTP, broken HTTPS, and valid HTTPS pages.
663 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest,
664 SecurityStyleChangedObserver) {
665 ASSERT_TRUE(https_server_.Start());
666 SetUpMockCertVerifierForHttpsServer(0, net::OK);
msw 2016/05/18 17:20:24 q: Is this necessary? It wasn't part of the old te
estark 2016/05/20 22:12:09 Ehh, I did it to be consistent with the rest of th
667
668 net::EmbeddedTestServer https_test_server_expired(
669 net::EmbeddedTestServer::TYPE_HTTPS);
670 https_test_server_expired.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
671 https_test_server_expired.ServeFilesFromSourceDirectory(
672 base::FilePath(kDocRoot));
673 ASSERT_TRUE(https_test_server_expired.Start());
674 SetUpMockCertVerifierForServer(
675 mock_cert_verifier(), https_test_server_expired,
676 net::CERT_STATUS_DATE_INVALID, net::ERR_CERT_DATE_INVALID);
677
678 ASSERT_TRUE(embedded_test_server()->Start());
679
680 content::WebContents* web_contents =
681 browser()->tab_strip_model()->GetActiveWebContents();
682 SecurityStyleTestObserver observer(web_contents);
683
684 // Visit an HTTP url.
685 GURL http_url(embedded_test_server()->GetURL("/"));
686 ui_test_utils::NavigateToURL(browser(), http_url);
687 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
688 observer.latest_security_style());
689 EXPECT_EQ(0u,
690 observer.latest_explanations().unauthenticated_explanations.size());
691 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
692 EXPECT_EQ(0u, observer.latest_explanations().secure_explanations.size());
693 EXPECT_FALSE(observer.latest_explanations().scheme_is_cryptographic);
694 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
695 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
696
697 // Visit an (otherwise valid) HTTPS page that displays mixed content.
698 std::string replacement_path;
699 GetFilePathWithHostAndPortReplacement(
700 "/ssl/page_displays_insecure_content.html",
701 embedded_test_server()->host_port_pair(), &replacement_path);
702
703 GURL mixed_content_url(https_server_.GetURL(replacement_path));
704 ui_test_utils::NavigateToURL(browser(), mixed_content_url);
705 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
706 observer.latest_security_style());
707
708 const content::SecurityStyleExplanations& mixed_content_explanation =
709 observer.latest_explanations();
710 ASSERT_EQ(0u, mixed_content_explanation.unauthenticated_explanations.size());
711 ASSERT_EQ(0u, mixed_content_explanation.broken_explanations.size());
712 CheckSecureExplanations(mixed_content_explanation.secure_explanations,
713 VALID_CERTIFICATE, browser());
714 EXPECT_TRUE(mixed_content_explanation.scheme_is_cryptographic);
715 EXPECT_TRUE(mixed_content_explanation.displayed_insecure_content);
716 EXPECT_FALSE(mixed_content_explanation.ran_insecure_content);
717 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
718 mixed_content_explanation.displayed_insecure_content_style);
719 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
720 mixed_content_explanation.ran_insecure_content_style);
721
722 // Visit a broken HTTPS url.
723 GURL expired_url(https_test_server_expired.GetURL(std::string("/")));
724 ui_test_utils::NavigateToURL(browser(), expired_url);
725
726 // An interstitial should show, and an event for the lock icon on the
727 // interstitial should fire.
728 content::WaitForInterstitialAttach(web_contents);
729 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
730 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser());
731 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
732 INVALID_CERTIFICATE, browser());
733 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
734 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
735 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
736
737 // Before clicking through, navigate to a different page, and then go
738 // back to the interstitial.
739 GURL valid_https_url(https_server_.GetURL(std::string("/")));
740 ui_test_utils::NavigateToURL(browser(), valid_https_url);
741 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
742 observer.latest_security_style());
743 EXPECT_EQ(0u,
744 observer.latest_explanations().unauthenticated_explanations.size());
745 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
746 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
747 VALID_CERTIFICATE, browser());
748 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
749 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
750 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
751
752 // After going back to the interstitial, an event for a broken lock
753 // icon should fire again.
754 ui_test_utils::NavigateToURL(browser(), expired_url);
755 content::WaitForInterstitialAttach(web_contents);
756 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
757 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser());
758 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
759 INVALID_CERTIFICATE, browser());
760 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
761 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
762 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
763
764 // Since the next expected style is the same as the previous, clear
765 // the observer (to make sure that the event fires twice and we don't
766 // just see the previous event's style).
767 observer.ClearLatestSecurityStyleAndExplanations();
768
769 // Other conditions cannot be tested on this host after clicking
770 // through because once the interstitial is clicked through, all URLs
771 // for this host will remain in a broken state.
772 ProceedThroughInterstitial(web_contents);
773 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser());
774 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
775 INVALID_CERTIFICATE, browser());
776 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
777 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
778 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
779 }
780
781 // Visit a valid HTTPS page, then a broken HTTPS page, and then go back,
782 // and test that the observed security style matches.
783 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest,
784 SecurityStyleChangedObserverGoBack) {
785 ASSERT_TRUE(https_server_.Start());
786 SetUpMockCertVerifierForHttpsServer(0, net::OK);
787
788 net::EmbeddedTestServer https_test_server_expired(
789 net::EmbeddedTestServer::TYPE_HTTPS);
790 https_test_server_expired.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
791 https_test_server_expired.ServeFilesFromSourceDirectory(
792 base::FilePath(kDocRoot));
793 ASSERT_TRUE(https_test_server_expired.Start());
794 SetUpMockCertVerifierForServer(
795 mock_cert_verifier(), https_test_server_expired,
796 net::CERT_STATUS_COMMON_NAME_INVALID, net::ERR_CERT_COMMON_NAME_INVALID);
797
798 content::WebContents* web_contents =
799 browser()->tab_strip_model()->GetActiveWebContents();
800 SecurityStyleTestObserver observer(web_contents);
801
802 // Visit a valid HTTPS url.
803 GURL valid_https_url(https_server_.GetURL(std::string("/")));
804 ui_test_utils::NavigateToURL(browser(), valid_https_url);
805 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
806 observer.latest_security_style());
807 EXPECT_EQ(0u,
808 observer.latest_explanations().unauthenticated_explanations.size());
809 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
810 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
811 VALID_CERTIFICATE, browser());
812 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
813 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
814 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
815
816 // Navigate to a bad HTTPS page on a different host, and then click
817 // Back to verify that the previous good security style is seen again.
818 GURL expired_https_url(https_test_server_expired.GetURL(std::string("/")));
819 host_resolver()->AddRule("www.example_broken.test", "127.0.0.1");
820 GURL::Replacements replace_host;
821 replace_host.SetHostStr("www.example_broken.test");
822 GURL https_url_different_host =
823 expired_https_url.ReplaceComponents(replace_host);
824
825 ui_test_utils::NavigateToURL(browser(), https_url_different_host);
826
827 content::WaitForInterstitialAttach(web_contents);
828 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
829 CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID,
830 browser());
831 ProceedThroughInterstitial(web_contents);
832 CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID,
833 browser());
834 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
835 INVALID_CERTIFICATE, browser());
836 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
837 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
838 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
839
840 content::WindowedNotificationObserver back_nav_load_observer(
841 content::NOTIFICATION_LOAD_STOP,
842 content::Source<content::NavigationController>(
843 &web_contents->GetController()));
844 chrome::GoBack(browser(), CURRENT_TAB);
845 back_nav_load_observer.Wait();
846
847 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
848 observer.latest_security_style());
849 EXPECT_EQ(0u,
850 observer.latest_explanations().unauthenticated_explanations.size());
851 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
852 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
853 VALID_CERTIFICATE, browser());
854 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
855 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
856 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
857 }
858
859 // After AddNonsecureUrlHandler() is called, requests to this hostname
860 // will use obsolete TLS settings.
861 const char kMockNonsecureHostname[] = "example-nonsecure.test";
862
863 // A URLRequestMockHTTPJob that mocks a TLS connection with an obsolete
864 // protocol version.
865 class URLRequestObsoleteTLSJob : public net::URLRequestMockHTTPJob {
866 public:
867 URLRequestObsoleteTLSJob(net::URLRequest* request,
868 net::NetworkDelegate* network_delegate,
869 const base::FilePath& file_path,
870 scoped_refptr<net::X509Certificate> cert,
871 scoped_refptr<base::TaskRunner> task_runner)
872 : net::URLRequestMockHTTPJob(request,
873 network_delegate,
874 file_path,
875 task_runner),
876 cert_(std::move(cert)) {}
877
878 void GetResponseInfo(net::HttpResponseInfo* info) override {
879 net::URLRequestMockHTTPJob::GetResponseInfo(info);
880 net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_1,
881 &info->ssl_info.connection_status);
882 const uint16_t kTlsEcdheRsaWithAes128CbcSha = 0xc013;
883 net::SSLConnectionStatusSetCipherSuite(kTlsEcdheRsaWithAes128CbcSha,
884 &info->ssl_info.connection_status);
885 info->ssl_info.cert = cert_;
886 }
887
888 protected:
889 ~URLRequestObsoleteTLSJob() override {}
890
891 private:
892 const scoped_refptr<net::X509Certificate> cert_;
893
894 DISALLOW_COPY_AND_ASSIGN(URLRequestObsoleteTLSJob);
895 };
896
897 // A URLRequestInterceptor that handles requests with
898 // URLRequestObsoleteTLSJob jobs.
899 class URLRequestNonsecureInterceptor : public net::URLRequestInterceptor {
900 public:
901 URLRequestNonsecureInterceptor(
902 const base::FilePath& base_path,
903 scoped_refptr<base::SequencedWorkerPool> worker_pool,
904 scoped_refptr<net::X509Certificate> cert)
905 : base_path_(base_path),
906 worker_pool_(std::move(worker_pool)),
907 cert_(std::move(cert)) {}
908
909 ~URLRequestNonsecureInterceptor() override {}
910
911 // net::URLRequestInterceptor:
912 net::URLRequestJob* MaybeInterceptRequest(
913 net::URLRequest* request,
914 net::NetworkDelegate* network_delegate) const override {
915 return new URLRequestObsoleteTLSJob(
916 request, network_delegate, base_path_, cert_,
917 worker_pool_->GetTaskRunnerWithShutdownBehavior(
918 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
919 }
920
921 private:
922 const base::FilePath base_path_;
923 const scoped_refptr<base::SequencedWorkerPool> worker_pool_;
924 const scoped_refptr<net::X509Certificate> cert_;
925
926 DISALLOW_COPY_AND_ASSIGN(URLRequestNonsecureInterceptor);
927 };
928
929 // Installs a handler to serve HTTPS requests to
930 // |kMockNonsecureHostname| with connections that have obsolete TLS
931 // settings.
932 void AddNonsecureUrlHandler(
933 const base::FilePath& base_path,
934 scoped_refptr<net::X509Certificate> cert,
935 scoped_refptr<base::SequencedWorkerPool> worker_pool) {
936 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
937 filter->AddHostnameInterceptor(
938 "https", kMockNonsecureHostname,
939 std::unique_ptr<net::URLRequestInterceptor>(
940 new URLRequestNonsecureInterceptor(base_path, worker_pool, cert)));
941 }
942
943 class BrowserTestNonsecureURLRequest : public CertVerifierBrowserTest {
944 public:
945 BrowserTestNonsecureURLRequest()
946 : CertVerifierBrowserTest(), cert_(nullptr) {}
947
948 void SetUpInProcessBrowserTestFixture() override {
949 cert_ =
950 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
951 ASSERT_TRUE(cert_);
952 }
953
954 void SetUpOnMainThread() override {
955 base::FilePath serve_file;
956 PathService::Get(chrome::DIR_TEST_DATA, &serve_file);
957 serve_file = serve_file.Append(FILE_PATH_LITERAL("title1.html"));
958 content::BrowserThread::PostTask(
959 content::BrowserThread::IO, FROM_HERE,
960 base::Bind(
961 &AddNonsecureUrlHandler, serve_file, cert_,
962 make_scoped_refptr(content::BrowserThread::GetBlockingPool())));
963 }
964
965 private:
966 scoped_refptr<net::X509Certificate> cert_;
967
968 DISALLOW_COPY_AND_ASSIGN(BrowserTestNonsecureURLRequest);
969 };
970
971 // Tests that a connection with obsolete TLS settings does not get a
972 // secure connection explanation.
973 IN_PROC_BROWSER_TEST_F(BrowserTestNonsecureURLRequest,
974 SecurityStyleChangedObserverNonsecureConnection) {
975 content::WebContents* web_contents =
976 browser()->tab_strip_model()->GetActiveWebContents();
977 SecurityStyleTestObserver observer(web_contents);
978
979 ui_test_utils::NavigateToURL(
980 browser(), GURL(std::string("https://") + kMockNonsecureHostname));
981
982 // The security style of the page doesn't get downgraded for obsolete
983 // TLS settings, so it should remain at SECURITY_STYLE_AUTHENTICATED.
984 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
985 observer.latest_security_style());
986
987 // The messages explaining the security style do, however, get
988 // downgraded: SECURE_PROTOCOL_AND_CIPHERSUITE should not show up when
989 // the TLS settings are obsolete.
990 for (const auto& explanation :
991 observer.latest_explanations().secure_explanations) {
992 EXPECT_NE(l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE),
993 explanation.summary);
994 }
995 }
996
538 } // namespace 997 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698