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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
index d2c41d7c1bcc7e29bcbc91f3c32600f58cfbdc2b..c32738337731383b6506a0c5cbd0bfaf945c8ffc 100644
--- a/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc
+++ b/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc
@@ -8,43 +8,158 @@
#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 "content/public/browser/cert_store.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/web_contents.h"
#include "content/public/common/referrer.h"
+#include "content/public/common/ssl_status.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/net_errors.h"
+#include "net/base/test_data_directory.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/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/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 "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_(content::SECURITY_STYLE_UNKNOWN) {}
+ ~SecurityStyleTestObserver() override {}
+
+ void SecurityStyleChanged(content::SecurityStyle security_style,
+ const content::SecurityStyleExplanations&
+ security_style_explanations) override {
+ latest_security_style_ = security_style;
+ latest_explanations_ = security_style_explanations;
+ }
+
+ content::SecurityStyle latest_security_style() const {
+ return latest_security_style_;
+ }
+
+ const content::SecurityStyleExplanations& latest_explanations() const {
+ return latest_explanations_;
+ }
+
+ void ClearLatestSecurityStyleAndExplanations() {
+ latest_security_style_ = content::SECURITY_STYLE_UNKNOWN;
+ latest_explanations_ = content::SecurityStyleExplanations();
+ }
+
+ private:
+ content::SecurityStyle 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) {
+ EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
+ 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());
+
+ // 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 id.
+ int cert_id = browser->tab_strip_model()
+ ->GetActiveWebContents()
+ ->GetController()
+ .GetActiveEntry()
+ ->GetSSL()
+ .cert_id;
+ EXPECT_EQ(cert_id, expired_explanation.broken_explanations[0].cert_id);
+}
+
+// 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) {
+ 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);
+ int cert_id = browser->tab_strip_model()
+ ->GetActiveWebContents()
+ ->GetController()
+ .GetActiveEntry()
+ ->GetSSL()
+ .cert_id;
+ EXPECT_EQ(cert_id, secure_explanations[0].cert_id);
+ }
+
+ EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE),
+ secure_explanations.back().summary);
+ EXPECT_EQ(
+ l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE_DESCRIPTION),
+ secure_explanations.back().description);
+}
+
void CheckSecurityInfoForSecure(
content::WebContents* contents,
SecurityStateModel::SecurityLevel expect_security_level,
@@ -92,6 +207,29 @@ void CheckSecurityInfoForNonSecure(content::WebContents* contents) {
EXPECT_EQ(0, security_info.cert_id);
}
+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()
@@ -104,29 +242,6 @@ class ChromeSecurityStateModelClientTest : public CertVerifierBrowserTest {
command_line->AppendSwitch(switches::kAllowRunningInsecureContent);
}
- 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();
- }
-
- static 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);
- }
-
protected:
void SetUpMockCertVerifierForHttpsServer(net::CertStatus cert_status,
int net_result) {
@@ -146,6 +261,25 @@ class ChromeSecurityStateModelClientTest : public CertVerifierBrowserTest {
DISALLOW_COPY_AND_ASSIGN(ChromeSecurityStateModelClientTest);
};
+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(
@@ -535,4 +669,329 @@ IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, AddedTab) {
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("/"));
+ ui_test_utils::NavigateToURL(browser(), http_url);
+ EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
+ 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().ran_insecure_content);
+ EXPECT_FALSE(observer.latest_explanations().displayed_insecure_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(content::SECURITY_STYLE_UNAUTHENTICATED,
+ 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());
+ EXPECT_TRUE(mixed_content_explanation.scheme_is_cryptographic);
+ EXPECT_TRUE(mixed_content_explanation.displayed_insecure_content);
+ EXPECT_FALSE(mixed_content_explanation.ran_insecure_content);
+ EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED,
+ mixed_content_explanation.displayed_insecure_content_style);
+ EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
+ mixed_content_explanation.ran_insecure_content_style);
+
+ // Visit a broken HTTPS url.
+ GURL expired_url(https_test_server_expired.GetURL(std::string("/")));
+ 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());
+ CheckSecureExplanations(observer.latest_explanations().secure_explanations,
+ INVALID_CERTIFICATE, browser());
+ EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
+ EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
+ EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
+
+ // Before clicking through, navigate to a different page, and then go
+ // back to the interstitial.
+ GURL valid_https_url(https_server_.GetURL(std::string("/")));
+ ui_test_utils::NavigateToURL(browser(), valid_https_url);
+ EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
+ 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());
+ EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
+ EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
+ EXPECT_FALSE(observer.latest_explanations().ran_insecure_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());
+ CheckSecureExplanations(observer.latest_explanations().secure_explanations,
+ INVALID_CERTIFICATE, browser());
+ EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
+ EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
+ EXPECT_FALSE(observer.latest_explanations().ran_insecure_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());
+ CheckSecureExplanations(observer.latest_explanations().secure_explanations,
+ INVALID_CERTIFICATE, browser());
+ EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
+ EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
+ EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
+}
+
+// Visit a valid HTTPS page, then a broken HTTPS page, and then go back,
+// and test that the observed security style matches.
+IN_PROC_BROWSER_TEST_F(SecurityStyleChangedTest,
+ 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(std::string("/")));
+ ui_test_utils::NavigateToURL(browser(), valid_https_url);
+ EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
+ 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());
+ EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
+ EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
+ EXPECT_FALSE(observer.latest_explanations().ran_insecure_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(std::string("/")));
+ 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());
+ ProceedThroughInterstitial(web_contents);
+ CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID,
+ browser());
+ CheckSecureExplanations(observer.latest_explanations().secure_explanations,
+ INVALID_CERTIFICATE, browser());
+ EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
+ EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
+ EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
+
+ content::WindowedNotificationObserver back_nav_load_observer(
+ content::NOTIFICATION_LOAD_STOP,
+ content::Source<content::NavigationController>(
+ &web_contents->GetController()));
+ chrome::GoBack(browser(), CURRENT_TAB);
+ back_nav_load_observer.Wait();
+
+ EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
+ 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());
+ EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic);
+ EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content);
+ EXPECT_FALSE(observer.latest_explanations().ran_insecure_content);
+}
+
+// After AddNonsecureUrlHandler() is called, requests to this hostname
+// will use obsolete TLS settings.
+const char kMockNonsecureHostname[] = "example-nonsecure.test";
+
+// A URLRequestMockHTTPJob that mocks a TLS connection with an obsolete
+// protocol version.
+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(net::SSL_CONNECTION_VERSION_TLS1_1,
+ &info->ssl_info.connection_status);
+ const uint16_t kTlsEcdheRsaWithAes128CbcSha = 0xc013;
+ net::SSLConnectionStatusSetCipherSuite(kTlsEcdheRsaWithAes128CbcSha,
+ &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 SECURITY_STYLE_AUTHENTICATED.
+ EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
+ 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_SECURE_PROTOCOL_AND_CIPHERSUITE),
+ explanation.summary);
+ }
+}
+
} // namespace
« 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