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

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: minor cleanup 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
« no previous file with comments | « chrome/browser/ssl/chrome_security_state_model_client.cc ('k') | chrome/browser/ui/browser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
35 #include "net/dns/mock_host_resolver.h" 43 #include "net/dns/mock_host_resolver.h"
44 #include "net/ssl/ssl_cipher_suite_names.h"
45 #include "net/ssl/ssl_connection_status_flags.h"
46 #include "net/test/cert_test_util.h"
36 #include "net/test/embedded_test_server/embedded_test_server.h" 47 #include "net/test/embedded_test_server/embedded_test_server.h"
37 #include "net/test/embedded_test_server/request_handler_util.h" 48 #include "net/test/embedded_test_server/request_handler_util.h"
38 #include "net/test/url_request/url_request_failed_job.h" 49 #include "net/test/url_request/url_request_failed_job.h"
50 #include "net/test/url_request/url_request_mock_http_job.h"
39 #include "net/url_request/url_request_filter.h" 51 #include "net/url_request/url_request_filter.h"
52 #include "net/url_request/url_request_test_util.h"
53 #include "ui/base/l10n/l10n_util.h"
40 54
41 using security_state::SecurityStateModel; 55 using security_state::SecurityStateModel;
42 56
43 namespace { 57 namespace {
44 58
59 enum CertificateStatus { VALID_CERTIFICATE, INVALID_CERTIFICATE };
60
45 const base::FilePath::CharType kDocRoot[] = 61 const base::FilePath::CharType kDocRoot[] =
46 FILE_PATH_LITERAL("chrome/test/data"); 62 FILE_PATH_LITERAL("chrome/test/data");
47 63
64 // A WebContentsObserver useful for testing the SecurityStyleChanged()
65 // method: it keeps track of the latest security style and explanation
66 // that was fired.
67 class SecurityStyleTestObserver : public content::WebContentsObserver {
68 public:
69 explicit SecurityStyleTestObserver(content::WebContents* web_contents)
70 : content::WebContentsObserver(web_contents),
71 latest_security_style_(content::SECURITY_STYLE_UNKNOWN) {}
72 ~SecurityStyleTestObserver() override {}
73
74 void SecurityStyleChanged(content::SecurityStyle security_style,
75 const content::SecurityStyleExplanations&
76 security_style_explanations) override {
77 latest_security_style_ = security_style;
78 latest_explanations_ = security_style_explanations;
79 }
80
81 content::SecurityStyle latest_security_style() const {
82 return latest_security_style_;
83 }
84
85 const content::SecurityStyleExplanations& latest_explanations() const {
86 return latest_explanations_;
87 }
88
89 void ClearLatestSecurityStyleAndExplanations() {
90 latest_security_style_ = content::SECURITY_STYLE_UNKNOWN;
91 latest_explanations_ = content::SecurityStyleExplanations();
92 }
93
94 private:
95 content::SecurityStyle latest_security_style_;
96 content::SecurityStyleExplanations latest_explanations_;
97
98 DISALLOW_COPY_AND_ASSIGN(SecurityStyleTestObserver);
99 };
100
101 // Check that |observer|'s latest event was for an expired certificate
102 // and that it saw the proper SecurityStyle and explanations.
103 void CheckBrokenSecurityStyle(const SecurityStyleTestObserver& observer,
104 int error,
105 Browser* browser) {
106 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
107 observer.latest_security_style());
108
109 const content::SecurityStyleExplanations& expired_explanation =
110 observer.latest_explanations();
111 EXPECT_EQ(0u, expired_explanation.unauthenticated_explanations.size());
112 ASSERT_EQ(1u, expired_explanation.broken_explanations.size());
113
114 // Check that the summary and description are as expected.
115 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_CERTIFICATE_CHAIN_ERROR),
116 expired_explanation.broken_explanations[0].summary);
117
118 base::string16 error_string = base::UTF8ToUTF16(net::ErrorToString(error));
119 EXPECT_EQ(l10n_util::GetStringFUTF8(
120 IDS_CERTIFICATE_CHAIN_ERROR_DESCRIPTION_FORMAT, error_string),
121 expired_explanation.broken_explanations[0].description);
122
123 // Check the associated certificate id.
124 int cert_id = browser->tab_strip_model()
125 ->GetActiveWebContents()
126 ->GetController()
127 .GetActiveEntry()
128 ->GetSSL()
129 .cert_id;
130 EXPECT_EQ(cert_id, expired_explanation.broken_explanations[0].cert_id);
131 }
132
133 // Checks that the given |secure_explanations| contains an appropriate
134 // explanation if the certificate status is valid.
135 void CheckSecureExplanations(
136 const std::vector<content::SecurityStyleExplanation>& secure_explanations,
137 CertificateStatus cert_status,
138 Browser* browser) {
139 ASSERT_EQ(cert_status == VALID_CERTIFICATE ? 2u : 1u,
140 secure_explanations.size());
141 if (cert_status == VALID_CERTIFICATE) {
142 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE),
143 secure_explanations[0].summary);
144 EXPECT_EQ(
145 l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION),
146 secure_explanations[0].description);
147 int cert_id = browser->tab_strip_model()
148 ->GetActiveWebContents()
149 ->GetController()
150 .GetActiveEntry()
151 ->GetSSL()
152 .cert_id;
153 EXPECT_EQ(cert_id, secure_explanations[0].cert_id);
154 }
155
156 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE),
157 secure_explanations.back().summary);
158 EXPECT_EQ(
159 l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE_DESCRIPTION),
160 secure_explanations.back().description);
161 }
162
48 void CheckSecurityInfoForSecure( 163 void CheckSecurityInfoForSecure(
49 content::WebContents* contents, 164 content::WebContents* contents,
50 SecurityStateModel::SecurityLevel expect_security_level, 165 SecurityStateModel::SecurityLevel expect_security_level,
51 SecurityStateModel::SHA1DeprecationStatus expect_sha1_status, 166 SecurityStateModel::SHA1DeprecationStatus expect_sha1_status,
52 SecurityStateModel::MixedContentStatus expect_mixed_content_status, 167 SecurityStateModel::MixedContentStatus expect_mixed_content_status,
53 bool expect_cert_error) { 168 bool expect_cert_error) {
54 ASSERT_TRUE(contents); 169 ASSERT_TRUE(contents);
55 170
56 ChromeSecurityStateModelClient* model_client = 171 ChromeSecurityStateModelClient* model_client =
57 ChromeSecurityStateModelClient::FromWebContents(contents); 172 ChromeSecurityStateModelClient::FromWebContents(contents);
(...skipping 27 matching lines...) Expand all
85 security_info.sha1_deprecation_status); 200 security_info.sha1_deprecation_status);
86 EXPECT_EQ(SecurityStateModel::NO_MIXED_CONTENT, 201 EXPECT_EQ(SecurityStateModel::NO_MIXED_CONTENT,
87 security_info.mixed_content_status); 202 security_info.mixed_content_status);
88 EXPECT_TRUE(security_info.sct_verify_statuses.empty()); 203 EXPECT_TRUE(security_info.sct_verify_statuses.empty());
89 EXPECT_FALSE(security_info.scheme_is_cryptographic); 204 EXPECT_FALSE(security_info.scheme_is_cryptographic);
90 EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); 205 EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status));
91 EXPECT_EQ(-1, security_info.security_bits); 206 EXPECT_EQ(-1, security_info.security_bits);
92 EXPECT_EQ(0, security_info.cert_id); 207 EXPECT_EQ(0, security_info.cert_id);
93 } 208 }
94 209
210 void ProceedThroughInterstitial(content::WebContents* tab) {
211 content::InterstitialPage* interstitial_page = tab->GetInterstitialPage();
212 ASSERT_TRUE(interstitial_page);
213 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
214 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
215 content::WindowedNotificationObserver observer(
216 content::NOTIFICATION_LOAD_STOP,
217 content::Source<content::NavigationController>(&tab->GetController()));
218 interstitial_page->Proceed();
219 observer.Wait();
220 }
221
222 void GetFilePathWithHostAndPortReplacement(
223 const std::string& original_file_path,
224 const net::HostPortPair& host_port_pair,
225 std::string* replacement_path) {
226 base::StringPairs replacement_text;
227 replacement_text.push_back(
228 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
229 net::test_server::GetFilePathWithReplacements(
230 original_file_path, replacement_text, replacement_path);
231 }
232
95 class ChromeSecurityStateModelClientTest : public CertVerifierBrowserTest { 233 class ChromeSecurityStateModelClientTest : public CertVerifierBrowserTest {
96 public: 234 public:
97 ChromeSecurityStateModelClientTest() 235 ChromeSecurityStateModelClientTest()
98 : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { 236 : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
99 https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); 237 https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
100 } 238 }
101 239
102 void SetUpCommandLine(base::CommandLine* command_line) override { 240 void SetUpCommandLine(base::CommandLine* command_line) override {
103 // Browser will both run and display insecure content. 241 // Browser will both run and display insecure content.
104 command_line->AppendSwitch(switches::kAllowRunningInsecureContent); 242 command_line->AppendSwitch(switches::kAllowRunningInsecureContent);
105 } 243 }
106 244
107 void ProceedThroughInterstitial(content::WebContents* tab) {
108 content::InterstitialPage* interstitial_page = tab->GetInterstitialPage();
109 ASSERT_TRUE(interstitial_page);
110 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
111 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
112 content::WindowedNotificationObserver observer(
113 content::NOTIFICATION_LOAD_STOP,
114 content::Source<content::NavigationController>(&tab->GetController()));
115 interstitial_page->Proceed();
116 observer.Wait();
117 }
118
119 static void GetFilePathWithHostAndPortReplacement(
120 const std::string& original_file_path,
121 const net::HostPortPair& host_port_pair,
122 std::string* replacement_path) {
123 base::StringPairs replacement_text;
124 replacement_text.push_back(
125 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
126 net::test_server::GetFilePathWithReplacements(
127 original_file_path, replacement_text, replacement_path);
128 }
129
130 protected: 245 protected:
131 void SetUpMockCertVerifierForHttpsServer(net::CertStatus cert_status, 246 void SetUpMockCertVerifierForHttpsServer(net::CertStatus cert_status,
132 int net_result) { 247 int net_result) {
133 scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate()); 248 scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate());
134 net::CertVerifyResult verify_result; 249 net::CertVerifyResult verify_result;
135 verify_result.is_issued_by_known_root = true; 250 verify_result.is_issued_by_known_root = true;
136 verify_result.verified_cert = cert; 251 verify_result.verified_cert = cert;
137 verify_result.cert_status = cert_status; 252 verify_result.cert_status = cert_status;
138 253
139 mock_cert_verifier()->AddResultForCert(cert.get(), verify_result, 254 mock_cert_verifier()->AddResultForCert(cert.get(), verify_result,
140 net_result); 255 net_result);
141 } 256 }
142 257
143 net::EmbeddedTestServer https_server_; 258 net::EmbeddedTestServer https_server_;
144 259
145 private: 260 private:
146 DISALLOW_COPY_AND_ASSIGN(ChromeSecurityStateModelClientTest); 261 DISALLOW_COPY_AND_ASSIGN(ChromeSecurityStateModelClientTest);
147 }; 262 };
148 263
264 class SecurityStyleChangedTest : public InProcessBrowserTest {
265 public:
266 SecurityStyleChangedTest()
267 : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
268 https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
269 }
270
271 void SetUpCommandLine(base::CommandLine* command_line) override {
272 // Browser will both run and display insecure content.
273 command_line->AppendSwitch(switches::kAllowRunningInsecureContent);
274 }
275
276 protected:
277 net::EmbeddedTestServer https_server_;
278
279 private:
280 DISALLOW_COPY_AND_ASSIGN(SecurityStyleChangedTest);
281 };
282
149 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, HttpPage) { 283 IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, HttpPage) {
150 ASSERT_TRUE(embedded_test_server()->Start()); 284 ASSERT_TRUE(embedded_test_server()->Start());
151 ui_test_utils::NavigateToURL( 285 ui_test_utils::NavigateToURL(
152 browser(), embedded_test_server()->GetURL("/ssl/google.html")); 286 browser(), embedded_test_server()->GetURL("/ssl/google.html"));
153 content::WebContents* contents = 287 content::WebContents* contents =
154 browser()->tab_strip_model()->GetActiveWebContents(); 288 browser()->tab_strip_model()->GetActiveWebContents();
155 ASSERT_TRUE(contents); 289 ASSERT_TRUE(contents);
156 290
157 ChromeSecurityStateModelClient* model_client = 291 ChromeSecurityStateModelClient* model_client =
158 ChromeSecurityStateModelClient::FromWebContents(contents); 292 ChromeSecurityStateModelClient::FromWebContents(contents);
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 false /* expect cert status error */); 662 false /* expect cert status error */);
529 663
530 browser()->tab_strip_model()->InsertWebContentsAt(0, new_contents, 664 browser()->tab_strip_model()->InsertWebContentsAt(0, new_contents,
531 TabStripModel::ADD_NONE); 665 TabStripModel::ADD_NONE);
532 CheckSecurityInfoForSecure(new_contents, SecurityStateModel::SECURE, 666 CheckSecurityInfoForSecure(new_contents, SecurityStateModel::SECURE,
533 SecurityStateModel::NO_DEPRECATED_SHA1, 667 SecurityStateModel::NO_DEPRECATED_SHA1,
534 SecurityStateModel::NO_MIXED_CONTENT, 668 SecurityStateModel::NO_MIXED_CONTENT,
535 false /* expect cert status error */); 669 false /* expect cert status error */);
536 } 670 }
537 671
672 // Tests that the WebContentsObserver::SecurityStyleChanged event fires
673 // with the current style on HTTP, broken HTTPS, and valid HTTPS pages.
674 IN_PROC_BROWSER_TEST_F(SecurityStyleChangedTest, SecurityStyleChangedObserver) {
675 ASSERT_TRUE(https_server_.Start());
676 ASSERT_TRUE(embedded_test_server()->Start());
677
678 net::EmbeddedTestServer https_test_server_expired(
679 net::EmbeddedTestServer::TYPE_HTTPS);
680 https_test_server_expired.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
681 https_test_server_expired.ServeFilesFromSourceDirectory(
682 base::FilePath(kDocRoot));
683 ASSERT_TRUE(https_test_server_expired.Start());
684
685 content::WebContents* web_contents =
686 browser()->tab_strip_model()->GetActiveWebContents();
687 SecurityStyleTestObserver observer(web_contents);
688
689 // Visit an HTTP url.
690 GURL http_url(embedded_test_server()->GetURL("/"));
691 ui_test_utils::NavigateToURL(browser(), http_url);
692 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
693 observer.latest_security_style());
694 EXPECT_EQ(0u,
695 observer.latest_explanations().unauthenticated_explanations.size());
696 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
697 EXPECT_EQ(0u, observer.latest_explanations().secure_explanations.size());
698 EXPECT_FALSE(observer.latest_explanations().scheme_is_cryptographic);
699 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
700 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
701
702 // Visit an (otherwise valid) HTTPS page that displays mixed content.
703 std::string replacement_path;
704 GetFilePathWithHostAndPortReplacement(
705 "/ssl/page_displays_insecure_content.html",
706 embedded_test_server()->host_port_pair(), &replacement_path);
707
708 GURL mixed_content_url(https_server_.GetURL(replacement_path));
709 ui_test_utils::NavigateToURL(browser(), mixed_content_url);
710 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
711 observer.latest_security_style());
712
713 const content::SecurityStyleExplanations& mixed_content_explanation =
714 observer.latest_explanations();
715 ASSERT_EQ(0u, mixed_content_explanation.unauthenticated_explanations.size());
716 ASSERT_EQ(0u, mixed_content_explanation.broken_explanations.size());
717 CheckSecureExplanations(mixed_content_explanation.secure_explanations,
718 VALID_CERTIFICATE, browser());
719 EXPECT_TRUE(mixed_content_explanation.scheme_is_cryptographic);
720 EXPECT_TRUE(mixed_content_explanation.displayed_insecure_content);
721 EXPECT_FALSE(mixed_content_explanation.ran_insecure_content);
722 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
723 mixed_content_explanation.displayed_insecure_content_style);
724 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
725 mixed_content_explanation.ran_insecure_content_style);
726
727 // Visit a broken HTTPS url.
728 GURL expired_url(https_test_server_expired.GetURL(std::string("/")));
729 ui_test_utils::NavigateToURL(browser(), expired_url);
730
731 // An interstitial should show, and an event for the lock icon on the
732 // interstitial should fire.
733 content::WaitForInterstitialAttach(web_contents);
734 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
735 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser());
736 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
737 INVALID_CERTIFICATE, browser());
738 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
739 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
740 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
741
742 // Before clicking through, navigate to a different page, and then go
743 // back to the interstitial.
744 GURL valid_https_url(https_server_.GetURL(std::string("/")));
745 ui_test_utils::NavigateToURL(browser(), valid_https_url);
746 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
747 observer.latest_security_style());
748 EXPECT_EQ(0u,
749 observer.latest_explanations().unauthenticated_explanations.size());
750 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
751 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
752 VALID_CERTIFICATE, browser());
753 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
754 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
755 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
756
757 // After going back to the interstitial, an event for a broken lock
758 // icon should fire again.
759 ui_test_utils::NavigateToURL(browser(), expired_url);
760 content::WaitForInterstitialAttach(web_contents);
761 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
762 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser());
763 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
764 INVALID_CERTIFICATE, browser());
765 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
766 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
767 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
768
769 // Since the next expected style is the same as the previous, clear
770 // the observer (to make sure that the event fires twice and we don't
771 // just see the previous event's style).
772 observer.ClearLatestSecurityStyleAndExplanations();
773
774 // Other conditions cannot be tested on this host after clicking
775 // through because once the interstitial is clicked through, all URLs
776 // for this host will remain in a broken state.
777 ProceedThroughInterstitial(web_contents);
778 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser());
779 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
780 INVALID_CERTIFICATE, browser());
781 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
782 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
783 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
784 }
785
786 // Visit a valid HTTPS page, then a broken HTTPS page, and then go back,
787 // and test that the observed security style matches.
788 IN_PROC_BROWSER_TEST_F(SecurityStyleChangedTest,
789 SecurityStyleChangedObserverGoBack) {
790 ASSERT_TRUE(https_server_.Start());
791
792 net::EmbeddedTestServer https_test_server_expired(
793 net::EmbeddedTestServer::TYPE_HTTPS);
794 https_test_server_expired.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
795 https_test_server_expired.ServeFilesFromSourceDirectory(
796 base::FilePath(kDocRoot));
797 ASSERT_TRUE(https_test_server_expired.Start());
798
799 content::WebContents* web_contents =
800 browser()->tab_strip_model()->GetActiveWebContents();
801 SecurityStyleTestObserver observer(web_contents);
802
803 // Visit a valid HTTPS url.
804 GURL valid_https_url(https_server_.GetURL(std::string("/")));
805 ui_test_utils::NavigateToURL(browser(), valid_https_url);
806 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
807 observer.latest_security_style());
808 EXPECT_EQ(0u,
809 observer.latest_explanations().unauthenticated_explanations.size());
810 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
811 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
812 VALID_CERTIFICATE, browser());
813 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
814 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
815 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
816
817 // Navigate to a bad HTTPS page on a different host, and then click
818 // Back to verify that the previous good security style is seen again.
819 GURL expired_https_url(https_test_server_expired.GetURL(std::string("/")));
820 host_resolver()->AddRule("www.example_broken.test", "127.0.0.1");
821 GURL::Replacements replace_host;
822 replace_host.SetHostStr("www.example_broken.test");
823 GURL https_url_different_host =
824 expired_https_url.ReplaceComponents(replace_host);
825
826 ui_test_utils::NavigateToURL(browser(), https_url_different_host);
827
828 content::WaitForInterstitialAttach(web_contents);
829 EXPECT_TRUE(web_contents->ShowingInterstitialPage());
830 CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID,
831 browser());
832 ProceedThroughInterstitial(web_contents);
833 CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID,
834 browser());
835 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
836 INVALID_CERTIFICATE, browser());
837 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
838 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
839 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
840
841 content::WindowedNotificationObserver back_nav_load_observer(
842 content::NOTIFICATION_LOAD_STOP,
843 content::Source<content::NavigationController>(
844 &web_contents->GetController()));
845 chrome::GoBack(browser(), CURRENT_TAB);
846 back_nav_load_observer.Wait();
847
848 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
849 observer.latest_security_style());
850 EXPECT_EQ(0u,
851 observer.latest_explanations().unauthenticated_explanations.size());
852 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size());
853 CheckSecureExplanations(observer.latest_explanations().secure_explanations,
854 VALID_CERTIFICATE, browser());
855 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
856 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
857 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
858 }
859
860 // After AddNonsecureUrlHandler() is called, requests to this hostname
861 // will use obsolete TLS settings.
862 const char kMockNonsecureHostname[] = "example-nonsecure.test";
863
864 // A URLRequestMockHTTPJob that mocks a TLS connection with an obsolete
865 // protocol version.
866 class URLRequestObsoleteTLSJob : public net::URLRequestMockHTTPJob {
867 public:
868 URLRequestObsoleteTLSJob(net::URLRequest* request,
869 net::NetworkDelegate* network_delegate,
870 const base::FilePath& file_path,
871 scoped_refptr<net::X509Certificate> cert,
872 scoped_refptr<base::TaskRunner> task_runner)
873 : net::URLRequestMockHTTPJob(request,
874 network_delegate,
875 file_path,
876 task_runner),
877 cert_(std::move(cert)) {}
878
879 void GetResponseInfo(net::HttpResponseInfo* info) override {
880 net::URLRequestMockHTTPJob::GetResponseInfo(info);
881 net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_1,
882 &info->ssl_info.connection_status);
883 const uint16_t kTlsEcdheRsaWithAes128CbcSha = 0xc013;
884 net::SSLConnectionStatusSetCipherSuite(kTlsEcdheRsaWithAes128CbcSha,
885 &info->ssl_info.connection_status);
886 info->ssl_info.cert = cert_;
887 }
888
889 protected:
890 ~URLRequestObsoleteTLSJob() override {}
891
892 private:
893 const scoped_refptr<net::X509Certificate> cert_;
894
895 DISALLOW_COPY_AND_ASSIGN(URLRequestObsoleteTLSJob);
896 };
897
898 // A URLRequestInterceptor that handles requests with
899 // URLRequestObsoleteTLSJob jobs.
900 class URLRequestNonsecureInterceptor : public net::URLRequestInterceptor {
901 public:
902 URLRequestNonsecureInterceptor(
903 const base::FilePath& base_path,
904 scoped_refptr<base::SequencedWorkerPool> worker_pool,
905 scoped_refptr<net::X509Certificate> cert)
906 : base_path_(base_path),
907 worker_pool_(std::move(worker_pool)),
908 cert_(std::move(cert)) {}
909
910 ~URLRequestNonsecureInterceptor() override {}
911
912 // net::URLRequestInterceptor:
913 net::URLRequestJob* MaybeInterceptRequest(
914 net::URLRequest* request,
915 net::NetworkDelegate* network_delegate) const override {
916 return new URLRequestObsoleteTLSJob(
917 request, network_delegate, base_path_, cert_,
918 worker_pool_->GetTaskRunnerWithShutdownBehavior(
919 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
920 }
921
922 private:
923 const base::FilePath base_path_;
924 const scoped_refptr<base::SequencedWorkerPool> worker_pool_;
925 const scoped_refptr<net::X509Certificate> cert_;
926
927 DISALLOW_COPY_AND_ASSIGN(URLRequestNonsecureInterceptor);
928 };
929
930 // Installs a handler to serve HTTPS requests to
931 // |kMockNonsecureHostname| with connections that have obsolete TLS
932 // settings.
933 void AddNonsecureUrlHandler(
934 const base::FilePath& base_path,
935 scoped_refptr<net::X509Certificate> cert,
936 scoped_refptr<base::SequencedWorkerPool> worker_pool) {
937 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
938 filter->AddHostnameInterceptor(
939 "https", kMockNonsecureHostname,
940 std::unique_ptr<net::URLRequestInterceptor>(
941 new URLRequestNonsecureInterceptor(base_path, worker_pool, cert)));
942 }
943
944 class BrowserTestNonsecureURLRequest : public InProcessBrowserTest {
945 public:
946 BrowserTestNonsecureURLRequest() : InProcessBrowserTest(), 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
« no previous file with comments | « chrome/browser/ssl/chrome_security_state_model_client.cc ('k') | chrome/browser/ui/browser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698