Index: chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc |
diff --git a/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc b/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc |
deleted file mode 100644 |
index 25f615ac942edcb308d6e78e7fae1c2173f761b9..0000000000000000000000000000000000000000 |
--- a/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc |
+++ /dev/null |
@@ -1,2093 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/ssl/chrome_security_state_model_client.h" |
- |
-#include "base/command_line.h" |
-#include "base/files/file_path.h" |
-#include "base/macros.h" |
-#include "base/strings/string_split.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "chrome/browser/ssl/cert_verifier_browser_test.h" |
-#include "chrome/browser/ssl/chrome_security_state_model_client.h" |
-#include "chrome/browser/ssl/ssl_blocking_page.h" |
-#include "chrome/browser/ui/browser.h" |
-#include "chrome/browser/ui/browser_commands.h" |
-#include "chrome/browser/ui/tabs/tab_strip_model.h" |
-#include "chrome/common/chrome_paths.h" |
-#include "chrome/common/chrome_switches.h" |
-#include "chrome/common/pref_names.h" |
-#include "chrome/grit/generated_resources.h" |
-#include "chrome/test/base/in_process_browser_test.h" |
-#include "chrome/test/base/ui_test_utils.h" |
-#include "components/prefs/pref_service.h" |
-#include "components/security_state/switches.h" |
-#include "content/public/browser/interstitial_page.h" |
-#include "content/public/browser/navigation_controller.h" |
-#include "content/public/browser/navigation_entry.h" |
-#include "content/public/browser/notification_service.h" |
-#include "content/public/browser/notification_types.h" |
-#include "content/public/browser/security_style_explanation.h" |
-#include "content/public/browser/security_style_explanations.h" |
-#include "content/public/browser/ssl_status.h" |
-#include "content/public/browser/web_contents.h" |
-#include "content/public/common/referrer.h" |
-#include "content/public/test/browser_test_utils.h" |
-#include "net/base/net_errors.h" |
-#include "net/cert/cert_status_flags.h" |
-#include "net/cert/cert_verify_result.h" |
-#include "net/cert/mock_cert_verifier.h" |
-#include "net/cert/sct_status_flags.h" |
-#include "net/cert/signed_certificate_timestamp.h" |
-#include "net/cert/signed_certificate_timestamp_and_status.h" |
-#include "net/cert/x509_certificate.h" |
-#include "net/dns/mock_host_resolver.h" |
-#include "net/ssl/ssl_cipher_suite_names.h" |
-#include "net/ssl/ssl_connection_status_flags.h" |
-#include "net/test/cert_test_util.h" |
-#include "net/test/embedded_test_server/embedded_test_server.h" |
-#include "net/test/embedded_test_server/request_handler_util.h" |
-#include "net/test/test_data_directory.h" |
-#include "net/test/url_request/url_request_failed_job.h" |
-#include "net/test/url_request/url_request_mock_http_job.h" |
-#include "net/url_request/url_request_filter.h" |
-#include "net/url_request/url_request_test_util.h" |
-#include "third_party/boringssl/src/include/openssl/ssl.h" |
-#include "ui/base/l10n/l10n_util.h" |
- |
-using security_state::SecurityStateModel; |
- |
-namespace { |
- |
-enum CertificateStatus { VALID_CERTIFICATE, INVALID_CERTIFICATE }; |
- |
-const base::FilePath::CharType kDocRoot[] = |
- FILE_PATH_LITERAL("chrome/test/data"); |
- |
-// A WebContentsObserver useful for testing the SecurityStyleChanged() |
-// method: it keeps track of the latest security style and explanation |
-// that was fired. |
-class SecurityStyleTestObserver : public content::WebContentsObserver { |
- public: |
- explicit SecurityStyleTestObserver(content::WebContents* web_contents) |
- : content::WebContentsObserver(web_contents), |
- latest_security_style_(blink::WebSecurityStyleUnknown) {} |
- ~SecurityStyleTestObserver() override {} |
- |
- void SecurityStyleChanged(blink::WebSecurityStyle security_style, |
- const content::SecurityStyleExplanations& |
- security_style_explanations) override { |
- latest_security_style_ = security_style; |
- latest_explanations_ = security_style_explanations; |
- } |
- |
- blink::WebSecurityStyle latest_security_style() const { |
- return latest_security_style_; |
- } |
- |
- const content::SecurityStyleExplanations& latest_explanations() const { |
- return latest_explanations_; |
- } |
- |
- void ClearLatestSecurityStyleAndExplanations() { |
- latest_security_style_ = blink::WebSecurityStyleUnknown; |
- latest_explanations_ = content::SecurityStyleExplanations(); |
- } |
- |
- private: |
- blink::WebSecurityStyle latest_security_style_; |
- content::SecurityStyleExplanations latest_explanations_; |
- |
- DISALLOW_COPY_AND_ASSIGN(SecurityStyleTestObserver); |
-}; |
- |
-// Check that |observer|'s latest event was for an expired certificate |
-// and that it saw the proper SecurityStyle and explanations. |
-void CheckBrokenSecurityStyle(const SecurityStyleTestObserver& observer, |
- int error, |
- Browser* browser, |
- net::X509Certificate* expected_cert) { |
- EXPECT_EQ(blink::WebSecurityStyleAuthenticationBroken, |
- observer.latest_security_style()); |
- |
- const content::SecurityStyleExplanations& expired_explanation = |
- observer.latest_explanations(); |
- EXPECT_EQ(0u, expired_explanation.unauthenticated_explanations.size()); |
- ASSERT_EQ(1u, expired_explanation.broken_explanations.size()); |
- EXPECT_FALSE(expired_explanation.pkp_bypassed); |
- EXPECT_TRUE(expired_explanation.info_explanations.empty()); |
- |
- // Check that the summary and description are as expected. |
- EXPECT_EQ(l10n_util::GetStringUTF8(IDS_CERTIFICATE_CHAIN_ERROR), |
- expired_explanation.broken_explanations[0].summary); |
- |
- base::string16 error_string = base::UTF8ToUTF16(net::ErrorToString(error)); |
- EXPECT_EQ(l10n_util::GetStringFUTF8( |
- IDS_CERTIFICATE_CHAIN_ERROR_DESCRIPTION_FORMAT, error_string), |
- expired_explanation.broken_explanations[0].description); |
- |
- // Check the associated certificate. |
- net::X509Certificate* cert = browser->tab_strip_model() |
- ->GetActiveWebContents() |
- ->GetController() |
- .GetActiveEntry() |
- ->GetSSL() |
- .certificate.get(); |
- EXPECT_TRUE(cert->Equals(expected_cert)); |
- EXPECT_TRUE(expired_explanation.broken_explanations[0].has_certificate); |
-} |
- |
-// Checks that the given |secure_explanations| contains an appropriate |
-// explanation if the certificate status is valid. |
-void CheckSecureExplanations( |
- const std::vector<content::SecurityStyleExplanation>& secure_explanations, |
- CertificateStatus cert_status, |
- Browser* browser, |
- net::X509Certificate* expected_cert) { |
- ASSERT_EQ(cert_status == VALID_CERTIFICATE ? 2u : 1u, |
- secure_explanations.size()); |
- if (cert_status == VALID_CERTIFICATE) { |
- EXPECT_EQ(l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE), |
- secure_explanations[0].summary); |
- EXPECT_EQ( |
- l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION), |
- secure_explanations[0].description); |
- net::X509Certificate* cert = browser->tab_strip_model() |
- ->GetActiveWebContents() |
- ->GetController() |
- .GetActiveEntry() |
- ->GetSSL() |
- .certificate.get(); |
- EXPECT_TRUE(cert->Equals(expected_cert)); |
- EXPECT_TRUE(secure_explanations[0].has_certificate); |
- } |
- |
- EXPECT_EQ(l10n_util::GetStringUTF8(IDS_STRONG_SSL_SUMMARY), |
- secure_explanations.back().summary); |
- |
- content::WebContents* web_contents = |
- browser->tab_strip_model()->GetActiveWebContents(); |
- SecurityStateModel::SecurityInfo security_info; |
- ChromeSecurityStateModelClient::FromWebContents(web_contents) |
- ->GetSecurityInfo(&security_info); |
- |
- const char *protocol, *key_exchange, *cipher, *mac; |
- int ssl_version = |
- net::SSLConnectionStatusToVersion(security_info.connection_status); |
- net::SSLVersionToString(&protocol, ssl_version); |
- bool is_aead, is_tls13; |
- uint16_t cipher_suite = |
- net::SSLConnectionStatusToCipherSuite(security_info.connection_status); |
- net::SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, |
- &is_tls13, cipher_suite); |
- EXPECT_TRUE(is_aead); |
- EXPECT_EQ(nullptr, mac); // The default secure cipher does not have a MAC. |
- EXPECT_FALSE(is_tls13); // The default secure cipher is not TLS 1.3. |
- |
- base::string16 key_exchange_name = base::ASCIIToUTF16(key_exchange); |
- if (security_info.key_exchange_group != 0) { |
- key_exchange_name = l10n_util::GetStringFUTF16( |
- IDS_SSL_KEY_EXCHANGE_WITH_GROUP, key_exchange_name, |
- base::ASCIIToUTF16( |
- SSL_get_curve_name(security_info.key_exchange_group))); |
- } |
- |
- std::vector<base::string16> description_replacements; |
- description_replacements.push_back(base::ASCIIToUTF16(protocol)); |
- description_replacements.push_back(key_exchange_name); |
- description_replacements.push_back(base::ASCIIToUTF16(cipher)); |
- base::string16 secure_description = l10n_util::GetStringFUTF16( |
- IDS_STRONG_SSL_DESCRIPTION, description_replacements, nullptr); |
- |
- EXPECT_EQ(secure_description, |
- base::ASCIIToUTF16(secure_explanations.back().description)); |
-} |
- |
-void CheckSecurityInfoForSecure( |
- content::WebContents* contents, |
- SecurityStateModel::SecurityLevel expect_security_level, |
- SecurityStateModel::SHA1DeprecationStatus expect_sha1_status, |
- SecurityStateModel::ContentStatus expect_mixed_content_status, |
- bool pkp_bypassed, |
- bool expect_cert_error) { |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(expect_security_level, security_info.security_level); |
- EXPECT_EQ(expect_sha1_status, security_info.sha1_deprecation_status); |
- EXPECT_EQ(expect_mixed_content_status, security_info.mixed_content_status); |
- EXPECT_TRUE(security_info.sct_verify_statuses.empty()); |
- EXPECT_TRUE(security_info.scheme_is_cryptographic); |
- EXPECT_EQ(pkp_bypassed, security_info.pkp_bypassed); |
- EXPECT_EQ(expect_cert_error, |
- net::IsCertStatusError(security_info.cert_status)); |
- EXPECT_GT(security_info.security_bits, 0); |
- EXPECT_TRUE(!!security_info.certificate); |
-} |
- |
-void CheckSecurityInfoForNonSecure(content::WebContents* contents) { |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(SecurityStateModel::NONE, security_info.security_level); |
- EXPECT_EQ(SecurityStateModel::NO_DEPRECATED_SHA1, |
- security_info.sha1_deprecation_status); |
- EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_NONE, |
- security_info.mixed_content_status); |
- EXPECT_TRUE(security_info.sct_verify_statuses.empty()); |
- EXPECT_FALSE(security_info.scheme_is_cryptographic); |
- EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); |
- EXPECT_EQ(-1, security_info.security_bits); |
- EXPECT_FALSE(!!security_info.certificate); |
-} |
- |
-void ProceedThroughInterstitial(content::WebContents* tab) { |
- content::InterstitialPage* interstitial_page = tab->GetInterstitialPage(); |
- ASSERT_TRUE(interstitial_page); |
- ASSERT_EQ(SSLBlockingPage::kTypeForTesting, |
- interstitial_page->GetDelegateForTesting()->GetTypeForTesting()); |
- content::WindowedNotificationObserver observer( |
- content::NOTIFICATION_LOAD_STOP, |
- content::Source<content::NavigationController>(&tab->GetController())); |
- interstitial_page->Proceed(); |
- observer.Wait(); |
-} |
- |
-void GetFilePathWithHostAndPortReplacement( |
- const std::string& original_file_path, |
- const net::HostPortPair& host_port_pair, |
- std::string* replacement_path) { |
- base::StringPairs replacement_text; |
- replacement_text.push_back( |
- make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString())); |
- net::test_server::GetFilePathWithReplacements( |
- original_file_path, replacement_text, replacement_path); |
-} |
- |
-class ChromeSecurityStateModelClientTest : public CertVerifierBrowserTest { |
- public: |
- ChromeSecurityStateModelClientTest() |
- : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { |
- https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); |
- } |
- |
- void SetUpCommandLine(base::CommandLine* command_line) override { |
- // Browser will both run and display insecure content. |
- command_line->AppendSwitch(switches::kAllowRunningInsecureContent); |
- } |
- |
- protected: |
- void SetUpMockCertVerifierForHttpsServer(net::CertStatus cert_status, |
- int net_result) { |
- scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate()); |
- net::CertVerifyResult verify_result; |
- verify_result.is_issued_by_known_root = true; |
- verify_result.verified_cert = cert; |
- verify_result.cert_status = cert_status; |
- |
- mock_cert_verifier()->AddResultForCert(cert, verify_result, net_result); |
- } |
- |
- net::EmbeddedTestServer https_server_; |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(ChromeSecurityStateModelClientTest); |
-}; |
- |
-GURL GetURLWithNonLocalHostname(net::EmbeddedTestServer* server, |
- const std::string& path) { |
- GURL::Replacements replace_host; |
- replace_host.SetHostStr("example.test"); |
- return server->GetURL(path).ReplaceComponents(replace_host); |
-} |
- |
-class ChromeSecurityStateModelClientTestWithPasswordCcSwitch |
- : public ChromeSecurityStateModelClientTest, |
- public testing::WithParamInterface<bool> { |
- public: |
- ChromeSecurityStateModelClientTestWithPasswordCcSwitch() |
- : ChromeSecurityStateModelClientTest() {} |
- |
- void SetUpOnMainThread() override { |
- ASSERT_TRUE(embedded_test_server()->Start()); |
- ASSERT_TRUE(https_server_.Start()); |
- host_resolver()->AddRule("*", embedded_test_server()->GetURL("/").host()); |
- SetUpMockCertVerifierForHttpsServer(0, net::OK); |
- } |
- |
- void SetUpCommandLine(base::CommandLine* command_line) override { |
- ChromeSecurityStateModelClientTest::SetUpCommandLine(command_line); |
- if (GetParam()) { |
- command_line->AppendSwitchASCII( |
- security_state::switches::kMarkHttpAs, |
- security_state::switches:: |
- kMarkHttpWithPasswordsOrCcWithChipAndFormWarning); |
- } else { |
- command_line->AppendSwitchASCII( |
- security_state::switches::kMarkHttpAs, |
- security_state::switches::kMarkHttpWithPasswordsOrCcWithChip); |
- } |
- } |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN( |
- ChromeSecurityStateModelClientTestWithPasswordCcSwitch); |
-}; |
- |
-class SecurityStyleChangedTest : public InProcessBrowserTest { |
- public: |
- SecurityStyleChangedTest() |
- : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { |
- https_server_.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); |
- } |
- |
- void SetUpCommandLine(base::CommandLine* command_line) override { |
- // Browser will both run and display insecure content. |
- command_line->AppendSwitch(switches::kAllowRunningInsecureContent); |
- } |
- |
- protected: |
- net::EmbeddedTestServer https_server_; |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(SecurityStyleChangedTest); |
-}; |
- |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, HttpPage) { |
- ASSERT_TRUE(embedded_test_server()->Start()); |
- ui_test_utils::NavigateToURL( |
- browser(), embedded_test_server()->GetURL("/ssl/google.html")); |
- content::WebContents* contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(SecurityStateModel::NONE, security_info.security_level); |
- EXPECT_EQ(SecurityStateModel::NO_DEPRECATED_SHA1, |
- security_info.sha1_deprecation_status); |
- EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_NONE, |
- security_info.mixed_content_status); |
- EXPECT_TRUE(security_info.sct_verify_statuses.empty()); |
- EXPECT_FALSE(security_info.scheme_is_cryptographic); |
- EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); |
- EXPECT_FALSE(!!security_info.certificate); |
- EXPECT_EQ(-1, security_info.security_bits); |
- EXPECT_EQ(0, security_info.connection_status); |
-} |
- |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, HttpsPage) { |
- ASSERT_TRUE(https_server_.Start()); |
- SetUpMockCertVerifierForHttpsServer(0, net::OK); |
- |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL("/ssl/google.html")); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- false /* expect cert status error */); |
-} |
- |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, SHA1Broken) { |
- ASSERT_TRUE(https_server_.Start()); |
- // The test server uses a long-lived cert by default, so a SHA1 |
- // signature in it will register as a "broken" condition rather than |
- // "warning". |
- SetUpMockCertVerifierForHttpsServer(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT, |
- net::OK); |
- |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL("/ssl/google.html")); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::DEPRECATED_SHA1_MAJOR, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- false /* expect cert status error */); |
-} |
- |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, MixedContent) { |
- ASSERT_TRUE(embedded_test_server()->Start()); |
- ASSERT_TRUE(https_server_.Start()); |
- SetUpMockCertVerifierForHttpsServer(0, net::OK); |
- host_resolver()->AddRule("example.test", |
- https_server_.GetURL("/title1.html").host()); |
- |
- net::HostPortPair replacement_pair = embedded_test_server()->host_port_pair(); |
- replacement_pair.set_host("example.test"); |
- |
- // Navigate to an HTTPS page that displays mixed content. |
- std::string replacement_path; |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_displays_insecure_content.html", |
- replacement_pair, &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::NONE, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, |
- false /* expect cert status error */); |
- |
- // Navigate to an HTTPS page that displays mixed content dynamically. |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_with_dynamic_insecure_content.html", |
- replacement_pair, &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- false /* expect cert status error */); |
- // Load the insecure image. |
- bool js_result = false; |
- EXPECT_TRUE(content::ExecuteScriptAndExtractBool( |
- browser()->tab_strip_model()->GetActiveWebContents(), "loadBadImage();", |
- &js_result)); |
- EXPECT_TRUE(js_result); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::NONE, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, |
- false /* expect cert status error */); |
- |
- // Navigate to an HTTPS page that runs mixed content. |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_runs_insecure_content.html", |
- replacement_pair, &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_RAN, false, |
- false /* expect cert status error */); |
- |
- // Navigate to an HTTPS page that runs and displays mixed content. |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_runs_and_displays_insecure_content.html", |
- replacement_pair, &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN, false, |
- false /* expect cert status error */); |
- |
- // Navigate to an HTTPS page that runs mixed content in an iframe. |
- net::HostPortPair host_port_pair = |
- net::HostPortPair::FromURL(https_server_.GetURL("/title1.html")); |
- host_port_pair.set_host("different-host.test"); |
- host_resolver()->AddRule("different-host.test", |
- https_server_.GetURL("/title1.html").host()); |
- host_resolver()->AddRule( |
- "different-http-host.test", |
- embedded_test_server()->GetURL("/title1.html").host()); |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_runs_insecure_content_in_iframe.html", host_port_pair, |
- &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_RAN, false, |
- false /* expect cert status error */); |
-} |
- |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, |
- ActiveContentWithCertErrors) { |
- ASSERT_TRUE(https_server_.Start()); |
- SetUpMockCertVerifierForHttpsServer(0, net::OK); |
- |
- // Navigate to an HTTPS page and simulate active content with |
- // certificate errors. |
- ui_test_utils::NavigateToURL(browser(), https_server_.GetURL("/title1.html")); |
- content::WebContents* web_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(web_contents); |
- content::NavigationEntry* entry = |
- web_contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- entry->GetSSL().content_status |= |
- content::SSLStatus::RAN_CONTENT_WITH_CERT_ERRORS; |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(web_contents); |
- ASSERT_TRUE(model_client); |
- SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- |
- EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); |
- EXPECT_EQ(SecurityStateModel::DANGEROUS, security_info.security_level); |
- EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_RAN, |
- security_info.content_with_cert_errors_status); |
-} |
- |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, |
- PassiveContentWithCertErrors) { |
- ASSERT_TRUE(https_server_.Start()); |
- SetUpMockCertVerifierForHttpsServer(0, net::OK); |
- |
- // Navigate to an HTTPS page and simulate passive content with |
- // certificate errors. |
- ui_test_utils::NavigateToURL(browser(), https_server_.GetURL("/title1.html")); |
- content::WebContents* web_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(web_contents); |
- content::NavigationEntry* entry = |
- web_contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- entry->GetSSL().content_status |= |
- content::SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS; |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(web_contents); |
- ASSERT_TRUE(model_client); |
- SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- |
- EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); |
- EXPECT_EQ(SecurityStateModel::NONE, security_info.security_level); |
- EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_DISPLAYED, |
- security_info.content_with_cert_errors_status); |
-} |
- |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, |
- ActiveAndPassiveContentWithCertErrors) { |
- ASSERT_TRUE(https_server_.Start()); |
- SetUpMockCertVerifierForHttpsServer(0, net::OK); |
- |
- // Navigate to an HTTPS page and simulate active and passive content |
- // with certificate errors. |
- ui_test_utils::NavigateToURL(browser(), https_server_.GetURL("/title1.html")); |
- content::WebContents* web_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(web_contents); |
- content::NavigationEntry* entry = |
- web_contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- entry->GetSSL().content_status |= |
- content::SSLStatus::RAN_CONTENT_WITH_CERT_ERRORS; |
- entry->GetSSL().content_status |= |
- content::SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS; |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(web_contents); |
- ASSERT_TRUE(model_client); |
- SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- |
- EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); |
- EXPECT_EQ(SecurityStateModel::DANGEROUS, security_info.security_level); |
- EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN, |
- security_info.content_with_cert_errors_status); |
-} |
- |
-// Same as the test above but with a long-lived SHA1 cert. |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, |
- MixedContentWithBrokenSHA1) { |
- ASSERT_TRUE(embedded_test_server()->Start()); |
- ASSERT_TRUE(https_server_.Start()); |
- // The test server uses a long-lived cert by default, so a SHA1 |
- // signature in it will register as a "broken" condition rather than |
- // "warning". |
- SetUpMockCertVerifierForHttpsServer(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT, |
- net::OK); |
- |
- host_resolver()->AddRule("example.test", |
- https_server_.GetURL("/title1.html").host()); |
- |
- net::HostPortPair replacement_pair = embedded_test_server()->host_port_pair(); |
- replacement_pair.set_host("example.test"); |
- |
- // Navigate to an HTTPS page that displays mixed content. |
- std::string replacement_path; |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_displays_insecure_content.html", |
- replacement_pair, &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::DEPRECATED_SHA1_MAJOR, |
- SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, |
- false /* expect cert status error */); |
- |
- // Navigate to an HTTPS page that displays mixed content dynamically. |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_with_dynamic_insecure_content.html", |
- replacement_pair, &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::DEPRECATED_SHA1_MAJOR, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- false /* expect cert status error */); |
- // Load the insecure image. |
- bool js_result = false; |
- EXPECT_TRUE(content::ExecuteScriptAndExtractBool( |
- browser()->tab_strip_model()->GetActiveWebContents(), "loadBadImage();", |
- &js_result)); |
- EXPECT_TRUE(js_result); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::DEPRECATED_SHA1_MAJOR, |
- SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, |
- false /* expect cert status error */); |
- |
- // Navigate to an HTTPS page that runs mixed content. |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_runs_insecure_content.html", |
- replacement_pair, &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::DEPRECATED_SHA1_MAJOR, |
- SecurityStateModel::CONTENT_STATUS_RAN, false, |
- false /* expect cert status error */); |
- |
- // Navigate to an HTTPS page that runs and displays mixed content. |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_runs_and_displays_insecure_content.html", |
- replacement_pair, &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::DEPRECATED_SHA1_MAJOR, |
- SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN, false, |
- false /* expect cert status error */); |
-} |
- |
-// Tests that the Content Security Policy block-all-mixed-content |
-// directive stops mixed content from running. |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, |
- MixedContentStrictBlocking) { |
- ASSERT_TRUE(https_server_.Start()); |
- SetUpMockCertVerifierForHttpsServer(0, net::OK); |
- |
- // Navigate to an HTTPS page that tries to run mixed content in an |
- // iframe, with strict mixed content blocking. |
- std::string replacement_path; |
- net::HostPortPair host_port_pair = |
- net::HostPortPair::FromURL(https_server_.GetURL("/title1.html")); |
- host_port_pair.set_host("different-host.test"); |
- host_resolver()->AddRule("different-host.test", |
- https_server_.GetURL("/title1.html").host()); |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_runs_insecure_content_in_iframe_with_strict_blocking.html", |
- host_port_pair, &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- false /* expect cert status error */); |
-} |
- |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, BrokenHTTPS) { |
- ASSERT_TRUE(embedded_test_server()->Start()); |
- ASSERT_TRUE(https_server_.Start()); |
- SetUpMockCertVerifierForHttpsServer(net::CERT_STATUS_DATE_INVALID, |
- net::ERR_CERT_DATE_INVALID); |
- |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL("/ssl/google.html")); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- true /* expect cert status error */); |
- |
- ProceedThroughInterstitial( |
- browser()->tab_strip_model()->GetActiveWebContents()); |
- |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- true /* expect cert status error */); |
- |
- // Navigate to a broken HTTPS page that displays mixed content. |
- std::string replacement_path; |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_displays_insecure_content.html", |
- embedded_test_server()->host_port_pair(), &replacement_path); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL(replacement_path)); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::DANGEROUS, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, |
- true /* expect cert status error */); |
-} |
- |
-const char kReportURI[] = "https://report-hpkp.test"; |
- |
-class PKPModelClientTest : public ChromeSecurityStateModelClientTest { |
- public: |
- void SetUpOnMainThread() override { |
- ASSERT_TRUE(https_server_.Start()); |
- url_request_context_getter_ = browser()->profile()->GetRequestContext(); |
- content::BrowserThread::PostTask( |
- content::BrowserThread::IO, FROM_HERE, |
- base::Bind(&PKPModelClientTest::SetUpOnIOThread, |
- base::Unretained(this))); |
- } |
- |
- void SetUpOnIOThread() { |
- net::URLRequestContext* request_context = |
- url_request_context_getter_->GetURLRequestContext(); |
- net::TransportSecurityState* security_state = |
- request_context->transport_security_state(); |
- |
- base::Time expiration = |
- base::Time::Now() + base::TimeDelta::FromSeconds(10000); |
- |
- net::HashValue hash(net::HASH_VALUE_SHA256); |
- memset(hash.data(), 0x99, hash.size()); |
- net::HashValueVector hashes; |
- hashes.push_back(hash); |
- |
- security_state->AddHPKP(https_server_.host_port_pair().host(), expiration, |
- true, hashes, GURL(kReportURI)); |
- } |
- |
- protected: |
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; |
-}; |
- |
-IN_PROC_BROWSER_TEST_F(PKPModelClientTest, PKPBypass) { |
- content::WebContents* web_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- SecurityStyleTestObserver observer(web_contents); |
- |
- scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate()); |
- net::CertVerifyResult verify_result; |
- // PKP is bypassed when |is_issued_by_known_root| is false. |
- verify_result.is_issued_by_known_root = false; |
- verify_result.verified_cert = cert; |
- net::HashValue hash(net::HASH_VALUE_SHA256); |
- memset(hash.data(), 1, hash.size()); |
- verify_result.public_key_hashes.push_back(hash); |
- |
- mock_cert_verifier()->AddResultForCert(cert, verify_result, net::OK); |
- |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL("/ssl/google.html")); |
- |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_NONE, true, false); |
- |
- const content::SecurityStyleExplanations& explanation = |
- observer.latest_explanations(); |
- EXPECT_TRUE(explanation.pkp_bypassed); |
- EXPECT_FALSE(explanation.info_explanations.empty()); |
-} |
- |
-IN_PROC_BROWSER_TEST_F(PKPModelClientTest, PKPEnforced) { |
- content::WebContents* web_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- SecurityStyleTestObserver observer(web_contents); |
- |
- scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate()); |
- net::CertVerifyResult verify_result; |
- // PKP requires |is_issued_by_known_root| to be true. |
- verify_result.is_issued_by_known_root = true; |
- verify_result.verified_cert = cert; |
- net::HashValue hash(net::HASH_VALUE_SHA256); |
- memset(hash.data(), 1, hash.size()); |
- verify_result.public_key_hashes.push_back(hash); |
- |
- mock_cert_verifier()->AddResultForCert(cert, verify_result, net::OK); |
- |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL("/ssl/google.html")); |
- CheckBrokenSecurityStyle(observer, net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, |
- browser(), cert.get()); |
-} |
- |
-// Fails requests with ERR_IO_PENDING. Can be used to simulate a navigation |
-// that never stops loading. |
-class PendingJobInterceptor : public net::URLRequestInterceptor { |
- public: |
- PendingJobInterceptor() {} |
- ~PendingJobInterceptor() override {} |
- |
- // URLRequestInterceptor implementation |
- net::URLRequestJob* MaybeInterceptRequest( |
- net::URLRequest* request, |
- net::NetworkDelegate* network_delegate) const override { |
- return new net::URLRequestFailedJob(request, network_delegate, |
- net::ERR_IO_PENDING); |
- } |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(PendingJobInterceptor); |
-}; |
- |
-void InstallLoadingInterceptor(const std::string& host) { |
- net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); |
- filter->AddHostnameInterceptor( |
- "http", host, |
- std::unique_ptr<net::URLRequestInterceptor>(new PendingJobInterceptor())); |
-} |
- |
-class SecurityStateModelLoadingTest |
- : public ChromeSecurityStateModelClientTest { |
- public: |
- SecurityStateModelLoadingTest() : ChromeSecurityStateModelClientTest() {} |
- ~SecurityStateModelLoadingTest() override{}; |
- |
- protected: |
- void SetUpOnMainThread() override { |
- ASSERT_TRUE(embedded_test_server()->Start()); |
- |
- content::BrowserThread::PostTask( |
- content::BrowserThread::IO, FROM_HERE, |
- base::Bind(&InstallLoadingInterceptor, |
- embedded_test_server()->GetURL("/title1.html").host())); |
- } |
- |
- DISALLOW_COPY_AND_ASSIGN(SecurityStateModelLoadingTest); |
-}; |
- |
-// Tests that navigation state changes cause the security state to be |
-// updated. |
-IN_PROC_BROWSER_TEST_F(SecurityStateModelLoadingTest, NavigationStateChanges) { |
- ASSERT_TRUE(https_server_.Start()); |
- SetUpMockCertVerifierForHttpsServer(0, net::OK); |
- |
- // Navigate to an HTTPS page. |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL("/ssl/google.html")); |
- CheckSecurityInfoForSecure( |
- browser()->tab_strip_model()->GetActiveWebContents(), |
- SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- false /* expect cert status error */); |
- |
- // Navigate to a page that doesn't finish loading. Test that the |
- // security state is neutral while the page is loading. |
- browser()->OpenURL(content::OpenURLParams( |
- embedded_test_server()->GetURL("/title1.html"), content::Referrer(), |
- WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false)); |
- CheckSecurityInfoForNonSecure( |
- browser()->tab_strip_model()->GetActiveWebContents()); |
-} |
- |
-// Tests that the NavigationEntry's flags for nonsecure password/credit |
-// card inputs are reflected in the VisibleSecurityState. |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, |
- VisibleSecurityStateNonsecureFormInputs) { |
- ASSERT_TRUE(https_server_.Start()); |
- ui_test_utils::NavigateToURL(browser(), |
- https_server_.GetURL("/ssl/google.html")); |
- |
- content::WebContents* contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- |
- // First, test that if the flags aren't set on the NavigationEntry, |
- // then they also aren't set on the VisibleSecurityState. |
- content::SSLStatus& ssl_status = |
- contents->GetController().GetVisibleEntry()->GetSSL(); |
- ASSERT_FALSE(ssl_status.content_status & |
- content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
- ASSERT_FALSE(ssl_status.content_status & |
- content::SSLStatus::DISPLAYED_CREDIT_CARD_FIELD_ON_HTTP); |
- SecurityStateModel::VisibleSecurityState |
- visible_security_state_no_sensitive_inputs; |
- model_client->GetVisibleSecurityState( |
- &visible_security_state_no_sensitive_inputs); |
- EXPECT_FALSE(visible_security_state_no_sensitive_inputs |
- .displayed_password_field_on_http); |
- EXPECT_FALSE(visible_security_state_no_sensitive_inputs |
- .displayed_credit_card_field_on_http); |
- |
- // Now, set the flags on the NavigationEntry and test that they are |
- // reflected in the VisibleSecurityState. |
- ssl_status.content_status |= |
- content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP; |
- ssl_status.content_status |= |
- content::SSLStatus::DISPLAYED_CREDIT_CARD_FIELD_ON_HTTP; |
- SecurityStateModel::VisibleSecurityState |
- visible_security_state_sensitive_inputs; |
- model_client->GetVisibleSecurityState( |
- &visible_security_state_sensitive_inputs); |
- EXPECT_TRUE( |
- visible_security_state_sensitive_inputs.displayed_password_field_on_http); |
- EXPECT_TRUE(visible_security_state_sensitive_inputs |
- .displayed_credit_card_field_on_http); |
-} |
- |
-// Tests that when a visible password field is detected on an HTTP page |
-// load, and when the command-line flag is set, the security level is |
-// downgraded to HTTP_SHOW_WARNING. |
-IN_PROC_BROWSER_TEST_P(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- PasswordSecurityLevelDowngraded) { |
- content::WebContents* contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- |
- ui_test_utils::NavigateToURL( |
- browser(), GetURLWithNonLocalHostname(embedded_test_server(), |
- "/password/simple_password.html")); |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_TRUE(entry->GetSSL().content_status & |
- content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
-} |
- |
-// Tests that when an invisible password field is present on an HTTP page |
-// load, and when the command-line flag is set, the security level is |
-// *not* downgraded to HTTP_SHOW_WARNING. |
-IN_PROC_BROWSER_TEST_P(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- PasswordSecurityLevelNotDowngradedForInvisibleInput) { |
- content::WebContents* contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- |
- ui_test_utils::NavigateToURL( |
- browser(), |
- GetURLWithNonLocalHostname(embedded_test_server(), |
- "/password/invisible_password.html")); |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::NONE, |
- security_info.security_level); |
- |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_FALSE(entry->GetSSL().content_status & |
- content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
-} |
- |
-// Tests that when a visible password field is detected inside an iframe |
-// on an HTTP page load, and when the command-line flag is set, the |
-// security level is downgraded to HTTP_SHOW_WARNING. |
-IN_PROC_BROWSER_TEST_P(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- PasswordSecurityLevelDowngradedFromIframe) { |
- content::WebContents* contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- |
- ui_test_utils::NavigateToURL( |
- browser(), |
- GetURLWithNonLocalHostname(embedded_test_server(), |
- "/password/simple_password_in_iframe.html")); |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_TRUE(entry->GetSSL().content_status & |
- content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
-} |
- |
-// Tests that when a visible password field is detected inside an iframe |
-// on an HTTP page load, and when the command-line flag is set, the |
-// security level is downgraded to HTTP_SHOW_WARNING, even if the iframe |
-// itself was loaded over HTTPS. |
-#if defined(OS_LINUX) |
-// Flaky on Linux. See https://crbug.com/662485. |
-#define MAYBE_PasswordSecurityLevelDowngradedFromHttpsIframe \ |
- DISABLED_PasswordSecurityLevelDowngradedFromHttpsIframe |
-#else |
-#define MAYBE_PasswordSecurityLevelDowngradedFromHttpsIframe \ |
- PasswordSecurityLevelDowngradedFromHttpsIframe |
-#endif |
-IN_PROC_BROWSER_TEST_P(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- MAYBE_PasswordSecurityLevelDowngradedFromHttpsIframe) { |
- content::WebContents* contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- |
- // Navigate to an HTTP URL, which loads an iframe using the host and port of |
- // |https_server_|. |
- std::string replacement_path; |
- GetFilePathWithHostAndPortReplacement( |
- "/password/simple_password_in_https_iframe.html", |
- https_server_.host_port_pair(), &replacement_path); |
- ui_test_utils::NavigateToURL( |
- browser(), |
- GetURLWithNonLocalHostname(embedded_test_server(), replacement_path)); |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_TRUE(entry->GetSSL().content_status & |
- content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
-} |
- |
-// Tests that when a visible password field is detected on an HTTP page |
-// load, and when the command-line flag is *not* set, the security level is |
-// *not* downgraded to HTTP_SHOW_WARNING. |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, |
- PasswordSecurityLevelNotDowngradedWithoutSwitch) { |
- ASSERT_TRUE(embedded_test_server()->Start()); |
- host_resolver()->AddRule("*", embedded_test_server()->GetURL("/").host()); |
- |
- content::WebContents* contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- |
- ui_test_utils::NavigateToURL( |
- browser(), GetURLWithNonLocalHostname(embedded_test_server(), |
- "/password/simple_password.html")); |
- // The security level should not be HTTP_SHOW_WARNING, because the |
- // command-line switch was not set. |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::NONE, |
- security_info.security_level); |
- |
- // The appropriate SSLStatus flags should be set, however. |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_TRUE(entry->GetSSL().content_status & |
- content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
-} |
- |
-// Tests that when a visible password field is detected on an HTTPS page |
-// load, and when the command-line flag is set, the security level is |
-// *not* downgraded to HTTP_SHOW_WARNING. |
-IN_PROC_BROWSER_TEST_P(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- PasswordSecurityLevelNotDowngradedOnHttps) { |
- content::WebContents* contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(contents); |
- |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(model_client); |
- |
- GURL url = GetURLWithNonLocalHostname(&https_server_, |
- "/password/simple_password.html"); |
- ui_test_utils::NavigateToURL(browser(), url); |
- // The security level should not be HTTP_SHOW_WARNING, because the page was |
- // HTTPS instead of HTTP. |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::SECURE, |
- security_info.security_level); |
- |
- // The SSLStatus flags should only be set if the top-level page load was HTTP, |
- // which it was not in this case. |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_FALSE(entry->GetSSL().content_status & |
- content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); |
-} |
- |
-// A Browser subclass that keeps track of messages that have been |
-// added to the console. Messages can be retrieved or cleared with |
-// console_messages() and ClearConsoleMessages(). The user of this class |
-// can set a callback to run when the next console message notification |
-// arrives. |
-class ConsoleWebContentsDelegate : public Browser { |
- public: |
- explicit ConsoleWebContentsDelegate(const Browser::CreateParams& params) |
- : Browser(params) {} |
- ~ConsoleWebContentsDelegate() override {} |
- |
- const std::vector<base::string16>& console_messages() const { |
- return console_messages_; |
- } |
- |
- void set_console_message_callback(const base::Closure& callback) { |
- console_message_callback_ = callback; |
- } |
- |
- void ClearConsoleMessages() { console_messages_.clear(); } |
- |
- // content::WebContentsDelegate |
- bool DidAddMessageToConsole(content::WebContents* source, |
- int32_t level, |
- const base::string16& message, |
- int32_t line_no, |
- const base::string16& source_id) override { |
- console_messages_.push_back(message); |
- if (!console_message_callback_.is_null()) { |
- console_message_callback_.Run(); |
- console_message_callback_.Reset(); |
- } |
- return true; |
- } |
- |
- private: |
- std::vector<base::string16> console_messages_; |
- base::Closure console_message_callback_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ConsoleWebContentsDelegate); |
-}; |
- |
-// Checks that |delegate| has observed exactly one console message for |
-// HTTP_SHOW_WARNING. To avoid brittleness, this just looks for keywords |
-// in the string rather than the exact text. |
-void CheckForOneHttpWarningConsoleMessage( |
- ConsoleWebContentsDelegate* delegate) { |
- const std::vector<base::string16>& messages = delegate->console_messages(); |
- ASSERT_EQ(1u, messages.size()); |
- EXPECT_NE(base::string16::npos, |
- messages[0].find(base::ASCIIToUTF16("warning has been added"))); |
-} |
- |
-// Checks that |delegate| has observed exactly one console message for |
-// NONE that will be HTTP_SHOW_WARNING in future. To avoid brittleness, |
-// this just looks for keywords in the string rather than the exact |
-// text. |
-void CheckForOneFutureHttpWarningConsoleMessage( |
- ConsoleWebContentsDelegate* delegate) { |
- const std::vector<base::string16>& messages = delegate->console_messages(); |
- ASSERT_EQ(1u, messages.size()); |
- EXPECT_NE(base::string16::npos, |
- messages[0].find(base::ASCIIToUTF16("warning will be added"))); |
-} |
- |
-// Tests that console messages are printed upon a call to |
-// GetSecurityInfo() on an HTTP_SHOW_WARNING page, exactly once per |
-// main-frame navigation. |
-IN_PROC_BROWSER_TEST_P(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- ConsoleMessage) { |
- ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( |
- Browser::CreateParams(browser()->profile())); |
- content::WebContents* original_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- content::WebContents* contents = |
- content::WebContents::Create(content::WebContents::CreateParams( |
- original_contents->GetBrowserContext())); |
- ASSERT_TRUE(contents); |
- contents->SetDelegate(delegate); |
- delegate->tab_strip_model()->AppendWebContents(contents, true); |
- int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); |
- delegate->tab_strip_model()->ActivateTabAt(index, true); |
- ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); |
- |
- // Navigate to an HTTP page. Use a non-local hostname so that is it |
- // not considered secure. |
- GURL http_url = |
- GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"); |
- ui_test_utils::NavigateToURL(delegate, http_url); |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_EQ(http_url, entry->GetURL()); |
- EXPECT_TRUE(delegate->console_messages().empty()); |
- |
- // Trigger the HTTP_SHOW_WARNING state. |
- base::RunLoop first_message; |
- delegate->set_console_message_callback(first_message.QuitClosure()); |
- contents->OnPasswordInputShownOnHttp(); |
- first_message.Run(); |
- |
- // Check that the HTTP_SHOW_WARNING state was actually triggered. |
- ChromeSecurityStateModelClient* client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(client); |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- |
- // Check that the expected console message is present. |
- ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
- delegate->ClearConsoleMessages(); |
- |
- // Two subsequent triggers of VisibleSecurityStateChanged -- one on the |
- // same navigation and one on another navigation -- should only result |
- // in one additional console message. |
- contents->OnCreditCardInputShownOnHttp(); |
- GURL second_http_url = |
- GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); |
- ui_test_utils::NavigateToURL(delegate, second_http_url); |
- entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_EQ(second_http_url, entry->GetURL()); |
- |
- base::RunLoop second_message; |
- delegate->set_console_message_callback(second_message.QuitClosure()); |
- contents->OnPasswordInputShownOnHttp(); |
- second_message.Run(); |
- |
- client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- |
- ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
-} |
- |
-// Tests that console messages are printed upon a call to |
-// GetSecurityInfo() on a NONE page that will be marked |
-// HTTP_SHOW_WARNING in future, exactly once per main-frame navigation. |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, ConsoleMessage) { |
- ASSERT_TRUE(embedded_test_server()->Start()); |
- host_resolver()->AddRule("*", embedded_test_server()->GetURL("/").host()); |
- ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( |
- Browser::CreateParams(browser()->profile())); |
- content::WebContents* original_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- content::WebContents* contents = |
- content::WebContents::Create(content::WebContents::CreateParams( |
- original_contents->GetBrowserContext())); |
- ASSERT_TRUE(contents); |
- contents->SetDelegate(delegate); |
- delegate->tab_strip_model()->AppendWebContents(contents, true); |
- int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); |
- delegate->tab_strip_model()->ActivateTabAt(index, true); |
- ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); |
- |
- // Navigate to an HTTP page. Use a non-local hostname so that is it |
- // not considered secure. |
- GURL http_url = |
- GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"); |
- ui_test_utils::NavigateToURL(delegate, http_url); |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_EQ(http_url, entry->GetURL()); |
- EXPECT_TRUE(delegate->console_messages().empty()); |
- |
- // Trigger the a state that will be marked as HTTP_SHOW_WARNING in future. |
- base::RunLoop first_message; |
- delegate->set_console_message_callback(first_message.QuitClosure()); |
- contents->OnPasswordInputShownOnHttp(); |
- first_message.Run(); |
- |
- // Check that the correct state was actually triggered. |
- ChromeSecurityStateModelClient* client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(client); |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::NONE, |
- security_info.security_level); |
- EXPECT_TRUE(security_info.displayed_password_field_on_http); |
- |
- // Check that the expected console message is present. |
- ASSERT_NO_FATAL_FAILURE(CheckForOneFutureHttpWarningConsoleMessage(delegate)); |
- delegate->ClearConsoleMessages(); |
- |
- // Two subsequent triggers of VisibleSecurityStateChanged -- one on the |
- // same navigation and one on another navigation -- should only result |
- // in one additional console message. |
- contents->OnCreditCardInputShownOnHttp(); |
- GURL second_http_url = |
- GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); |
- ui_test_utils::NavigateToURL(delegate, second_http_url); |
- entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_EQ(second_http_url, entry->GetURL()); |
- |
- base::RunLoop second_message; |
- delegate->set_console_message_callback(second_message.QuitClosure()); |
- contents->OnPasswordInputShownOnHttp(); |
- second_message.Run(); |
- |
- client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::NONE, |
- security_info.security_level); |
- EXPECT_TRUE(security_info.displayed_password_field_on_http); |
- EXPECT_FALSE(security_info.displayed_credit_card_field_on_http); |
- |
- ASSERT_NO_FATAL_FAILURE(CheckForOneFutureHttpWarningConsoleMessage(delegate)); |
- delegate->ClearConsoleMessages(); |
- |
- // Check that a console message is printed for credit card field shown. |
- ui_test_utils::NavigateToURL(delegate, http_url); |
- entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_EQ(http_url, entry->GetURL()); |
- |
- base::RunLoop third_message; |
- delegate->set_console_message_callback(third_message.QuitClosure()); |
- contents->OnCreditCardInputShownOnHttp(); |
- third_message.Run(); |
- |
- client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::NONE, |
- security_info.security_level); |
- EXPECT_TRUE(security_info.displayed_credit_card_field_on_http); |
- |
- ASSERT_NO_FATAL_FAILURE(CheckForOneFutureHttpWarningConsoleMessage(delegate)); |
-} |
- |
-// Tests that additional HTTP_SHOW_WARNING console messages are not |
-// printed after subframe navigations. |
-IN_PROC_BROWSER_TEST_P(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- ConsoleMessageNotPrintedForFrameNavigation) { |
- ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( |
- Browser::CreateParams(browser()->profile())); |
- content::WebContents* original_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- content::WebContents* contents = |
- content::WebContents::Create(content::WebContents::CreateParams( |
- original_contents->GetBrowserContext())); |
- ASSERT_TRUE(contents); |
- contents->SetDelegate(delegate); |
- delegate->tab_strip_model()->AppendWebContents(contents, true); |
- int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); |
- delegate->tab_strip_model()->ActivateTabAt(index, true); |
- ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); |
- |
- // Navigate to an HTTP page. Use a non-local hostname so that is it |
- // not considered secure. |
- GURL http_url = GetURLWithNonLocalHostname(embedded_test_server(), |
- "/ssl/page_with_frame.html"); |
- ui_test_utils::NavigateToURL(delegate, http_url); |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_EQ(http_url, entry->GetURL()); |
- EXPECT_TRUE(delegate->console_messages().empty()); |
- |
- // Trigger the HTTP_SHOW_WARNING state. |
- base::RunLoop first_message; |
- delegate->set_console_message_callback(first_message.QuitClosure()); |
- contents->OnPasswordInputShownOnHttp(); |
- first_message.Run(); |
- |
- // Check that the HTTP_SHOW_WARNING state was actually triggered. |
- ChromeSecurityStateModelClient* client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(client); |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- |
- // Check that the expected console message is present. |
- ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
- delegate->ClearConsoleMessages(); |
- |
- // Navigate the subframe and trigger VisibleSecurityStateChanged |
- // again. While the security level is still HTTP_SHOW_WARNING, an |
- // additional console message should not be logged because there was |
- // already a console message logged for the current main-frame |
- // navigation. |
- content::WindowedNotificationObserver subframe_observer( |
- content::NOTIFICATION_LOAD_STOP, |
- content::Source<content::NavigationController>( |
- &contents->GetController())); |
- EXPECT_TRUE(content::ExecuteScript( |
- contents, "document.getElementById('navFrame').src = '/title2.html';")); |
- subframe_observer.Wait(); |
- contents->OnCreditCardInputShownOnHttp(); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- |
- // Do a main frame navigation and then trigger HTTP_SHOW_WARNING |
- // again. From the above subframe navigation and this main-frame |
- // navigation, exactly one console message is expected. |
- GURL second_http_url = |
- GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); |
- ui_test_utils::NavigateToURL(delegate, second_http_url); |
- entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_EQ(second_http_url, entry->GetURL()); |
- |
- base::RunLoop second_message; |
- delegate->set_console_message_callback(second_message.QuitClosure()); |
- contents->OnPasswordInputShownOnHttp(); |
- second_message.Run(); |
- |
- client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
-} |
- |
-// Tests that additional HTTP_SHOW_WARNING console messages are not |
-// printed after pushState navigations. |
-IN_PROC_BROWSER_TEST_P(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- ConsoleMessageNotPrintedForPushStateNavigation) { |
- ConsoleWebContentsDelegate* delegate = new ConsoleWebContentsDelegate( |
- Browser::CreateParams(browser()->profile())); |
- content::WebContents* original_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- content::WebContents* contents = |
- content::WebContents::Create(content::WebContents::CreateParams( |
- original_contents->GetBrowserContext())); |
- ASSERT_TRUE(contents); |
- contents->SetDelegate(delegate); |
- delegate->tab_strip_model()->AppendWebContents(contents, true); |
- int index = delegate->tab_strip_model()->GetIndexOfWebContents(contents); |
- delegate->tab_strip_model()->ActivateTabAt(index, true); |
- ASSERT_EQ(contents, delegate->tab_strip_model()->GetActiveWebContents()); |
- |
- // Navigate to an HTTP page. Use a non-local hostname so that is it |
- // not considered secure. |
- GURL http_url = |
- GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"); |
- ui_test_utils::NavigateToURL(delegate, http_url); |
- content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_EQ(http_url, entry->GetURL()); |
- EXPECT_TRUE(delegate->console_messages().empty()); |
- |
- // Trigger the HTTP_SHOW_WARNING state. |
- base::RunLoop first_message; |
- delegate->set_console_message_callback(first_message.QuitClosure()); |
- contents->OnPasswordInputShownOnHttp(); |
- first_message.Run(); |
- |
- // Check that the HTTP_SHOW_WARNING state was actually triggered. |
- ChromeSecurityStateModelClient* client = |
- ChromeSecurityStateModelClient::FromWebContents(contents); |
- ASSERT_TRUE(client); |
- security_state::SecurityStateModel::SecurityInfo security_info; |
- client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- |
- // Check that the expected console message is present. |
- ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
- delegate->ClearConsoleMessages(); |
- |
- // Navigate with pushState and trigger VisibleSecurityStateChanged |
- // again. While the security level is still HTTP_SHOW_WARNING, an |
- // additional console message should not be logged because there was |
- // already a console message logged for the current main-frame |
- // navigation. |
- EXPECT_TRUE(content::ExecuteScript( |
- contents, "history.pushState({ foo: 'bar' }, 'foo', 'bar');")); |
- contents->OnCreditCardInputShownOnHttp(); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- |
- // Do a main frame navigation and then trigger HTTP_SHOW_WARNING |
- // again. From the above pushState navigation and this main-frame |
- // navigation, exactly one console message is expected. |
- GURL second_http_url = |
- GetURLWithNonLocalHostname(embedded_test_server(), "/title2.html"); |
- ui_test_utils::NavigateToURL(delegate, second_http_url); |
- entry = contents->GetController().GetVisibleEntry(); |
- ASSERT_TRUE(entry); |
- EXPECT_EQ(second_http_url, entry->GetURL()); |
- |
- base::RunLoop second_message; |
- delegate->set_console_message_callback(second_message.QuitClosure()); |
- contents->OnPasswordInputShownOnHttp(); |
- second_message.Run(); |
- |
- client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, |
- security_info.security_level); |
- ASSERT_NO_FATAL_FAILURE(CheckForOneHttpWarningConsoleMessage(delegate)); |
-} |
- |
-INSTANTIATE_TEST_CASE_P(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- ChromeSecurityStateModelClientTestWithPasswordCcSwitch, |
- // Here 'true' means that the omnibox warning + form |
- // warning are enabled, and 'false' means just the |
- // omnibox warning is enabled. |
- testing::Bool()); |
- |
-// Tests that the SecurityStateModel for a WebContents is up to date |
-// when the WebContents is inserted into a Browser's TabStripModel. |
-IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, AddedTab) { |
- ASSERT_TRUE(https_server_.Start()); |
- SetUpMockCertVerifierForHttpsServer(0, net::OK); |
- |
- content::WebContents* tab = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(tab); |
- |
- content::WebContents* new_contents = content::WebContents::Create( |
- content::WebContents::CreateParams(tab->GetBrowserContext())); |
- content::NavigationController& controller = new_contents->GetController(); |
- ChromeSecurityStateModelClient::CreateForWebContents(new_contents); |
- CheckSecurityInfoForNonSecure(new_contents); |
- controller.LoadURL(https_server_.GetURL("/title1.html"), content::Referrer(), |
- ui::PAGE_TRANSITION_TYPED, std::string()); |
- EXPECT_TRUE(content::WaitForLoadStop(new_contents)); |
- CheckSecurityInfoForSecure(new_contents, SecurityStateModel::SECURE, |
- SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- false /* expect cert status error */); |
- |
- browser()->tab_strip_model()->InsertWebContentsAt(0, new_contents, |
- TabStripModel::ADD_NONE); |
- CheckSecurityInfoForSecure(new_contents, SecurityStateModel::SECURE, |
- SecurityStateModel::NO_DEPRECATED_SHA1, |
- SecurityStateModel::CONTENT_STATUS_NONE, false, |
- false /* expect cert status error */); |
-} |
- |
-// Tests that the WebContentsObserver::SecurityStyleChanged event fires |
-// with the current style on HTTP, broken HTTPS, and valid HTTPS pages. |
-IN_PROC_BROWSER_TEST_F(SecurityStyleChangedTest, SecurityStyleChangedObserver) { |
- ASSERT_TRUE(https_server_.Start()); |
- ASSERT_TRUE(embedded_test_server()->Start()); |
- |
- net::EmbeddedTestServer https_test_server_expired( |
- net::EmbeddedTestServer::TYPE_HTTPS); |
- https_test_server_expired.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED); |
- https_test_server_expired.ServeFilesFromSourceDirectory( |
- base::FilePath(kDocRoot)); |
- ASSERT_TRUE(https_test_server_expired.Start()); |
- |
- content::WebContents* web_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- SecurityStyleTestObserver observer(web_contents); |
- |
- // Visit an HTTP url. |
- GURL http_url(embedded_test_server()->GetURL("/title1.html")); |
- ui_test_utils::NavigateToURL(browser(), http_url); |
- EXPECT_EQ(blink::WebSecurityStyleUnauthenticated, |
- observer.latest_security_style()); |
- EXPECT_EQ(0u, |
- observer.latest_explanations().unauthenticated_explanations.size()); |
- EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); |
- EXPECT_EQ(0u, observer.latest_explanations().secure_explanations.size()); |
- EXPECT_FALSE(observer.latest_explanations().scheme_is_cryptographic); |
- EXPECT_FALSE(observer.latest_explanations().pkp_bypassed); |
- EXPECT_TRUE(observer.latest_explanations().info_explanations.empty()); |
- EXPECT_FALSE(observer.latest_explanations().ran_mixed_content); |
- EXPECT_FALSE(observer.latest_explanations().displayed_mixed_content); |
- |
- // Visit an (otherwise valid) HTTPS page that displays mixed content. |
- std::string replacement_path; |
- GetFilePathWithHostAndPortReplacement( |
- "/ssl/page_displays_insecure_content.html", |
- embedded_test_server()->host_port_pair(), &replacement_path); |
- |
- GURL mixed_content_url(https_server_.GetURL(replacement_path)); |
- ui_test_utils::NavigateToURL(browser(), mixed_content_url); |
- EXPECT_EQ(blink::WebSecurityStyleUnauthenticated, |
- observer.latest_security_style()); |
- |
- const content::SecurityStyleExplanations& mixed_content_explanation = |
- observer.latest_explanations(); |
- ASSERT_EQ(0u, mixed_content_explanation.unauthenticated_explanations.size()); |
- ASSERT_EQ(0u, mixed_content_explanation.broken_explanations.size()); |
- CheckSecureExplanations(mixed_content_explanation.secure_explanations, |
- VALID_CERTIFICATE, browser(), |
- https_server_.GetCertificate().get()); |
- EXPECT_TRUE(mixed_content_explanation.scheme_is_cryptographic); |
- EXPECT_FALSE(observer.latest_explanations().pkp_bypassed); |
- EXPECT_TRUE(observer.latest_explanations().info_explanations.empty()); |
- EXPECT_TRUE(mixed_content_explanation.displayed_mixed_content); |
- EXPECT_FALSE(mixed_content_explanation.ran_mixed_content); |
- EXPECT_EQ(blink::WebSecurityStyleUnauthenticated, |
- mixed_content_explanation.displayed_insecure_content_style); |
- EXPECT_EQ(blink::WebSecurityStyleAuthenticationBroken, |
- mixed_content_explanation.ran_insecure_content_style); |
- |
- // Visit a broken HTTPS url. |
- GURL expired_url(https_test_server_expired.GetURL("/title1.html")); |
- ui_test_utils::NavigateToURL(browser(), expired_url); |
- |
- // An interstitial should show, and an event for the lock icon on the |
- // interstitial should fire. |
- content::WaitForInterstitialAttach(web_contents); |
- EXPECT_TRUE(web_contents->ShowingInterstitialPage()); |
- CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser(), |
- https_test_server_expired.GetCertificate().get()); |
- CheckSecureExplanations(observer.latest_explanations().secure_explanations, |
- INVALID_CERTIFICATE, browser(), |
- https_test_server_expired.GetCertificate().get()); |
- EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); |
- EXPECT_FALSE(observer.latest_explanations().pkp_bypassed); |
- EXPECT_TRUE(observer.latest_explanations().info_explanations.empty()); |
- EXPECT_FALSE(observer.latest_explanations().displayed_mixed_content); |
- EXPECT_FALSE(observer.latest_explanations().ran_mixed_content); |
- |
- // Before clicking through, navigate to a different page, and then go |
- // back to the interstitial. |
- GURL valid_https_url(https_server_.GetURL("/title1.html")); |
- ui_test_utils::NavigateToURL(browser(), valid_https_url); |
- EXPECT_EQ(blink::WebSecurityStyleAuthenticated, |
- observer.latest_security_style()); |
- EXPECT_EQ(0u, |
- observer.latest_explanations().unauthenticated_explanations.size()); |
- EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); |
- CheckSecureExplanations(observer.latest_explanations().secure_explanations, |
- VALID_CERTIFICATE, browser(), |
- https_server_.GetCertificate().get()); |
- EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); |
- EXPECT_FALSE(observer.latest_explanations().pkp_bypassed); |
- EXPECT_TRUE(observer.latest_explanations().info_explanations.empty()); |
- EXPECT_FALSE(observer.latest_explanations().displayed_mixed_content); |
- EXPECT_FALSE(observer.latest_explanations().ran_mixed_content); |
- |
- // After going back to the interstitial, an event for a broken lock |
- // icon should fire again. |
- ui_test_utils::NavigateToURL(browser(), expired_url); |
- content::WaitForInterstitialAttach(web_contents); |
- EXPECT_TRUE(web_contents->ShowingInterstitialPage()); |
- CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser(), |
- https_test_server_expired.GetCertificate().get()); |
- CheckSecureExplanations(observer.latest_explanations().secure_explanations, |
- INVALID_CERTIFICATE, browser(), |
- https_test_server_expired.GetCertificate().get()); |
- EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); |
- EXPECT_FALSE(observer.latest_explanations().pkp_bypassed); |
- EXPECT_TRUE(observer.latest_explanations().info_explanations.empty()); |
- EXPECT_FALSE(observer.latest_explanations().displayed_mixed_content); |
- EXPECT_FALSE(observer.latest_explanations().ran_mixed_content); |
- |
- // Since the next expected style is the same as the previous, clear |
- // the observer (to make sure that the event fires twice and we don't |
- // just see the previous event's style). |
- observer.ClearLatestSecurityStyleAndExplanations(); |
- |
- // Other conditions cannot be tested on this host after clicking |
- // through because once the interstitial is clicked through, all URLs |
- // for this host will remain in a broken state. |
- ProceedThroughInterstitial(web_contents); |
- CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser(), |
- https_test_server_expired.GetCertificate().get()); |
- CheckSecureExplanations(observer.latest_explanations().secure_explanations, |
- INVALID_CERTIFICATE, browser(), |
- https_test_server_expired.GetCertificate().get()); |
- EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); |
- EXPECT_FALSE(observer.latest_explanations().pkp_bypassed); |
- EXPECT_TRUE(observer.latest_explanations().info_explanations.empty()); |
- EXPECT_FALSE(observer.latest_explanations().displayed_mixed_content); |
- EXPECT_FALSE(observer.latest_explanations().ran_mixed_content); |
-} |
- |
-// Visit a valid HTTPS page, then a broken HTTPS page, and then go back, |
-// and test that the observed security style matches. |
-#if defined(OS_CHROMEOS) |
-// Flaky on Chrome OS. See https://crbug.com/638576. |
-#define MAYBE_SecurityStyleChangedObserverGoBack \ |
- DISABLED_SecurityStyleChangedObserverGoBack |
-#else |
-#define MAYBE_SecurityStyleChangedObserverGoBack \ |
- SecurityStyleChangedObserverGoBack |
-#endif |
-IN_PROC_BROWSER_TEST_F(SecurityStyleChangedTest, |
- MAYBE_SecurityStyleChangedObserverGoBack) { |
- ASSERT_TRUE(https_server_.Start()); |
- |
- net::EmbeddedTestServer https_test_server_expired( |
- net::EmbeddedTestServer::TYPE_HTTPS); |
- https_test_server_expired.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED); |
- https_test_server_expired.ServeFilesFromSourceDirectory( |
- base::FilePath(kDocRoot)); |
- ASSERT_TRUE(https_test_server_expired.Start()); |
- |
- content::WebContents* web_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- SecurityStyleTestObserver observer(web_contents); |
- |
- // Visit a valid HTTPS url. |
- GURL valid_https_url(https_server_.GetURL("/title1.html")); |
- ui_test_utils::NavigateToURL(browser(), valid_https_url); |
- EXPECT_EQ(blink::WebSecurityStyleAuthenticated, |
- observer.latest_security_style()); |
- EXPECT_EQ(0u, |
- observer.latest_explanations().unauthenticated_explanations.size()); |
- EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); |
- CheckSecureExplanations(observer.latest_explanations().secure_explanations, |
- VALID_CERTIFICATE, browser(), |
- https_server_.GetCertificate().get()); |
- EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); |
- EXPECT_FALSE(observer.latest_explanations().pkp_bypassed); |
- EXPECT_TRUE(observer.latest_explanations().info_explanations.empty()); |
- EXPECT_FALSE(observer.latest_explanations().displayed_mixed_content); |
- EXPECT_FALSE(observer.latest_explanations().ran_mixed_content); |
- |
- // Navigate to a bad HTTPS page on a different host, and then click |
- // Back to verify that the previous good security style is seen again. |
- GURL expired_https_url(https_test_server_expired.GetURL("/title1.html")); |
- host_resolver()->AddRule("www.example_broken.test", "127.0.0.1"); |
- GURL::Replacements replace_host; |
- replace_host.SetHostStr("www.example_broken.test"); |
- GURL https_url_different_host = |
- expired_https_url.ReplaceComponents(replace_host); |
- |
- ui_test_utils::NavigateToURL(browser(), https_url_different_host); |
- |
- content::WaitForInterstitialAttach(web_contents); |
- EXPECT_TRUE(web_contents->ShowingInterstitialPage()); |
- CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID, |
- browser(), |
- https_test_server_expired.GetCertificate().get()); |
- ProceedThroughInterstitial(web_contents); |
- CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID, |
- browser(), |
- https_test_server_expired.GetCertificate().get()); |
- CheckSecureExplanations(observer.latest_explanations().secure_explanations, |
- INVALID_CERTIFICATE, browser(), |
- https_test_server_expired.GetCertificate().get()); |
- EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); |
- EXPECT_FALSE(observer.latest_explanations().pkp_bypassed); |
- EXPECT_TRUE(observer.latest_explanations().info_explanations.empty()); |
- EXPECT_FALSE(observer.latest_explanations().displayed_mixed_content); |
- EXPECT_FALSE(observer.latest_explanations().ran_mixed_content); |
- |
- content::WindowedNotificationObserver back_nav_load_observer( |
- content::NOTIFICATION_LOAD_STOP, |
- content::Source<content::NavigationController>( |
- &web_contents->GetController())); |
- chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB); |
- back_nav_load_observer.Wait(); |
- |
- EXPECT_EQ(blink::WebSecurityStyleAuthenticated, |
- observer.latest_security_style()); |
- EXPECT_EQ(0u, |
- observer.latest_explanations().unauthenticated_explanations.size()); |
- EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); |
- CheckSecureExplanations(observer.latest_explanations().secure_explanations, |
- VALID_CERTIFICATE, browser(), |
- https_server_.GetCertificate().get()); |
- EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); |
- EXPECT_FALSE(observer.latest_explanations().pkp_bypassed); |
- EXPECT_TRUE(observer.latest_explanations().info_explanations.empty()); |
- EXPECT_FALSE(observer.latest_explanations().displayed_mixed_content); |
- EXPECT_FALSE(observer.latest_explanations().ran_mixed_content); |
-} |
- |
-// After AddNonsecureUrlHandler() is called, requests to this hostname |
-// will use obsolete TLS settings. |
-const char kMockNonsecureHostname[] = "example-nonsecure.test"; |
-const int kObsoleteTLSVersion = net::SSL_CONNECTION_VERSION_TLS1_1; |
-// ECDHE_RSA + AES_128_CBC with HMAC-SHA1 |
-const uint16_t kObsoleteCipherSuite = 0xc013; |
- |
-// A URLRequestMockHTTPJob that mocks a TLS connection with the obsolete |
-// TLS settings specified in kObsoleteTLSVersion and |
-// kObsoleteCipherSuite. |
-class URLRequestObsoleteTLSJob : public net::URLRequestMockHTTPJob { |
- public: |
- URLRequestObsoleteTLSJob(net::URLRequest* request, |
- net::NetworkDelegate* network_delegate, |
- const base::FilePath& file_path, |
- scoped_refptr<net::X509Certificate> cert, |
- scoped_refptr<base::TaskRunner> task_runner) |
- : net::URLRequestMockHTTPJob(request, |
- network_delegate, |
- file_path, |
- task_runner), |
- cert_(std::move(cert)) {} |
- |
- void GetResponseInfo(net::HttpResponseInfo* info) override { |
- net::URLRequestMockHTTPJob::GetResponseInfo(info); |
- net::SSLConnectionStatusSetVersion(kObsoleteTLSVersion, |
- &info->ssl_info.connection_status); |
- net::SSLConnectionStatusSetCipherSuite(kObsoleteCipherSuite, |
- &info->ssl_info.connection_status); |
- info->ssl_info.cert = cert_; |
- } |
- |
- protected: |
- ~URLRequestObsoleteTLSJob() override {} |
- |
- private: |
- const scoped_refptr<net::X509Certificate> cert_; |
- |
- DISALLOW_COPY_AND_ASSIGN(URLRequestObsoleteTLSJob); |
-}; |
- |
-// A URLRequestInterceptor that handles requests with |
-// URLRequestObsoleteTLSJob jobs. |
-class URLRequestNonsecureInterceptor : public net::URLRequestInterceptor { |
- public: |
- URLRequestNonsecureInterceptor( |
- const base::FilePath& base_path, |
- scoped_refptr<base::SequencedWorkerPool> worker_pool, |
- scoped_refptr<net::X509Certificate> cert) |
- : base_path_(base_path), |
- worker_pool_(std::move(worker_pool)), |
- cert_(std::move(cert)) {} |
- |
- ~URLRequestNonsecureInterceptor() override {} |
- |
- // net::URLRequestInterceptor: |
- net::URLRequestJob* MaybeInterceptRequest( |
- net::URLRequest* request, |
- net::NetworkDelegate* network_delegate) const override { |
- return new URLRequestObsoleteTLSJob( |
- request, network_delegate, base_path_, cert_, |
- worker_pool_->GetTaskRunnerWithShutdownBehavior( |
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); |
- } |
- |
- private: |
- const base::FilePath base_path_; |
- const scoped_refptr<base::SequencedWorkerPool> worker_pool_; |
- const scoped_refptr<net::X509Certificate> cert_; |
- |
- DISALLOW_COPY_AND_ASSIGN(URLRequestNonsecureInterceptor); |
-}; |
- |
-// Installs a handler to serve HTTPS requests to |
-// |kMockNonsecureHostname| with connections that have obsolete TLS |
-// settings. |
-void AddNonsecureUrlHandler( |
- const base::FilePath& base_path, |
- scoped_refptr<net::X509Certificate> cert, |
- scoped_refptr<base::SequencedWorkerPool> worker_pool) { |
- net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); |
- filter->AddHostnameInterceptor( |
- "https", kMockNonsecureHostname, |
- std::unique_ptr<net::URLRequestInterceptor>( |
- new URLRequestNonsecureInterceptor(base_path, worker_pool, cert))); |
-} |
- |
-class BrowserTestNonsecureURLRequest : public InProcessBrowserTest { |
- public: |
- BrowserTestNonsecureURLRequest() : InProcessBrowserTest(), cert_(nullptr) {} |
- |
- void SetUpInProcessBrowserTestFixture() override { |
- cert_ = |
- net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); |
- ASSERT_TRUE(cert_); |
- } |
- |
- void SetUpOnMainThread() override { |
- base::FilePath serve_file; |
- PathService::Get(chrome::DIR_TEST_DATA, &serve_file); |
- serve_file = serve_file.Append(FILE_PATH_LITERAL("title1.html")); |
- content::BrowserThread::PostTask( |
- content::BrowserThread::IO, FROM_HERE, |
- base::Bind( |
- &AddNonsecureUrlHandler, serve_file, cert_, |
- make_scoped_refptr(content::BrowserThread::GetBlockingPool()))); |
- } |
- |
- private: |
- scoped_refptr<net::X509Certificate> cert_; |
- |
- DISALLOW_COPY_AND_ASSIGN(BrowserTestNonsecureURLRequest); |
-}; |
- |
-// Tests that a connection with obsolete TLS settings does not get a |
-// secure connection explanation. |
-IN_PROC_BROWSER_TEST_F(BrowserTestNonsecureURLRequest, |
- SecurityStyleChangedObserverNonsecureConnection) { |
- content::WebContents* web_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- SecurityStyleTestObserver observer(web_contents); |
- |
- ui_test_utils::NavigateToURL( |
- browser(), GURL(std::string("https://") + kMockNonsecureHostname)); |
- |
- // The security style of the page doesn't get downgraded for obsolete |
- // TLS settings, so it should remain at WebSecurityStyleAuthenticated. |
- EXPECT_EQ(blink::WebSecurityStyleAuthenticated, |
- observer.latest_security_style()); |
- |
- // The messages explaining the security style do, however, get |
- // downgraded: SECURE_PROTOCOL_AND_CIPHERSUITE should not show up when |
- // the TLS settings are obsolete. |
- for (const auto& explanation : |
- observer.latest_explanations().secure_explanations) { |
- EXPECT_NE(l10n_util::GetStringUTF8(IDS_STRONG_SSL_SUMMARY), |
- explanation.summary); |
- } |
- |
- // Populate description string replacement with values corresponding |
- // to test constants. |
- std::vector<base::string16> description_replacements; |
- description_replacements.push_back( |
- l10n_util::GetStringUTF16(IDS_SSL_AN_OBSOLETE_PROTOCOL)); |
- description_replacements.push_back(base::ASCIIToUTF16("TLS 1.1")); |
- description_replacements.push_back( |
- l10n_util::GetStringUTF16(IDS_SSL_A_STRONG_KEY_EXCHANGE)); |
- description_replacements.push_back(base::ASCIIToUTF16("ECDHE_RSA")); |
- description_replacements.push_back( |
- l10n_util::GetStringUTF16(IDS_SSL_AN_OBSOLETE_CIPHER)); |
- description_replacements.push_back( |
- base::ASCIIToUTF16("AES_128_CBC with HMAC-SHA1")); |
- base::string16 obsolete_description = l10n_util::GetStringFUTF16( |
- IDS_OBSOLETE_SSL_DESCRIPTION, description_replacements, nullptr); |
- |
- EXPECT_EQ( |
- obsolete_description, |
- base::ASCIIToUTF16( |
- observer.latest_explanations().info_explanations[0].description)); |
-} |
- |
-// After AddSCTUrlHandler() is called, requests to this hostname |
-// will be served with Signed Certificate Timestamps. |
-const char kMockHostnameWithSCTs[] = "example-scts.test"; |
- |
-// URLRequestJobWithSCTs mocks a connection that includes a set of dummy |
-// SCTs with these statuses. |
-const std::vector<net::ct::SCTVerifyStatus> kTestSCTStatuses{ |
- net::ct::SCT_STATUS_OK, net::ct::SCT_STATUS_LOG_UNKNOWN, |
- net::ct::SCT_STATUS_OK}; |
- |
-// A URLRequestMockHTTPJob that mocks a TLS connection with SCTs |
-// attached to it. The SCTs will have verification statuses |
-// |kTestSCTStatuses|. |
-class URLRequestJobWithSCTs : public net::URLRequestMockHTTPJob { |
- public: |
- URLRequestJobWithSCTs(net::URLRequest* request, |
- net::NetworkDelegate* network_delegate, |
- const base::FilePath& file_path, |
- scoped_refptr<net::X509Certificate> cert, |
- scoped_refptr<base::TaskRunner> task_runner) |
- : net::URLRequestMockHTTPJob(request, |
- network_delegate, |
- file_path, |
- task_runner), |
- cert_(std::move(cert)) {} |
- |
- void GetResponseInfo(net::HttpResponseInfo* info) override { |
- net::URLRequestMockHTTPJob::GetResponseInfo(info); |
- for (const auto& status : kTestSCTStatuses) { |
- scoped_refptr<net::ct::SignedCertificateTimestamp> dummy_sct = |
- new net::ct::SignedCertificateTimestamp(); |
- info->ssl_info.signed_certificate_timestamps.push_back( |
- net::SignedCertificateTimestampAndStatus(dummy_sct, status)); |
- } |
- info->ssl_info.cert = cert_; |
- } |
- |
- protected: |
- ~URLRequestJobWithSCTs() override {} |
- |
- private: |
- const scoped_refptr<net::X509Certificate> cert_; |
- |
- DISALLOW_COPY_AND_ASSIGN(URLRequestJobWithSCTs); |
-}; |
- |
-// A URLRequestInterceptor that handles requests with |
-// URLRequestJobWithSCTs jobs. |
-class URLRequestWithSCTsInterceptor : public net::URLRequestInterceptor { |
- public: |
- URLRequestWithSCTsInterceptor( |
- const base::FilePath& base_path, |
- scoped_refptr<base::SequencedWorkerPool> worker_pool, |
- scoped_refptr<net::X509Certificate> cert) |
- : base_path_(base_path), |
- worker_pool_(std::move(worker_pool)), |
- cert_(std::move(cert)) {} |
- |
- ~URLRequestWithSCTsInterceptor() override {} |
- |
- // net::URLRequestInterceptor: |
- net::URLRequestJob* MaybeInterceptRequest( |
- net::URLRequest* request, |
- net::NetworkDelegate* network_delegate) const override { |
- return new URLRequestJobWithSCTs( |
- request, network_delegate, base_path_, cert_, |
- worker_pool_->GetTaskRunnerWithShutdownBehavior( |
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); |
- } |
- |
- private: |
- const base::FilePath base_path_; |
- const scoped_refptr<base::SequencedWorkerPool> worker_pool_; |
- const scoped_refptr<net::X509Certificate> cert_; |
- |
- DISALLOW_COPY_AND_ASSIGN(URLRequestWithSCTsInterceptor); |
-}; |
- |
-// Installs a handler to serve HTTPS requests to |kMockHostnameWithSCTs| |
-// with connections that have SCTs. |
-void AddSCTUrlHandler(const base::FilePath& base_path, |
- scoped_refptr<net::X509Certificate> cert, |
- scoped_refptr<base::SequencedWorkerPool> worker_pool) { |
- net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); |
- filter->AddHostnameInterceptor( |
- "https", kMockHostnameWithSCTs, |
- std::unique_ptr<net::URLRequestInterceptor>( |
- new URLRequestWithSCTsInterceptor(base_path, worker_pool, cert))); |
-} |
- |
-class BrowserTestURLRequestWithSCTs : public InProcessBrowserTest { |
- public: |
- BrowserTestURLRequestWithSCTs() : InProcessBrowserTest(), cert_(nullptr) {} |
- |
- void SetUpInProcessBrowserTestFixture() override { |
- cert_ = |
- net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); |
- ASSERT_TRUE(cert_); |
- } |
- |
- void SetUpOnMainThread() override { |
- base::FilePath serve_file; |
- PathService::Get(chrome::DIR_TEST_DATA, &serve_file); |
- serve_file = serve_file.Append(FILE_PATH_LITERAL("title1.html")); |
- content::BrowserThread::PostTask( |
- content::BrowserThread::IO, FROM_HERE, |
- base::Bind( |
- &AddSCTUrlHandler, serve_file, cert_, |
- make_scoped_refptr(content::BrowserThread::GetBlockingPool()))); |
- } |
- |
- private: |
- scoped_refptr<net::X509Certificate> cert_; |
- |
- DISALLOW_COPY_AND_ASSIGN(BrowserTestURLRequestWithSCTs); |
-}; |
- |
-// Tests that, when Signed Certificate Timestamps (SCTs) are served on a |
-// connection, the SCTs verification statuses are exposed on the |
-// SecurityInfo. |
-IN_PROC_BROWSER_TEST_F(BrowserTestURLRequestWithSCTs, |
- SecurityInfoWithSCTsAttached) { |
- ui_test_utils::NavigateToURL( |
- browser(), GURL(std::string("https://") + kMockHostnameWithSCTs)); |
- |
- content::WebContents* web_contents = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- ASSERT_TRUE(web_contents); |
- ChromeSecurityStateModelClient* model_client = |
- ChromeSecurityStateModelClient::FromWebContents(web_contents); |
- ASSERT_TRUE(model_client); |
- SecurityStateModel::SecurityInfo security_info; |
- model_client->GetSecurityInfo(&security_info); |
- EXPECT_EQ(SecurityStateModel::SECURE, security_info.security_level); |
- EXPECT_EQ(kTestSCTStatuses, security_info.sct_verify_statuses); |
-} |
- |
-} // namespace |