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

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: remove unnecessary namespace Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..f8a05147236c3b9c1b86d66225a27e52983db3d1 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,159 @@
#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/cert/x509_certificate.h"
msw 2016/05/18 17:20:24 nit: remove (duplicate of line above)
estark 2016/05/20 22:12:09 Done.
#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 appropriate
+// 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 +208,19 @@ void CheckSecurityInfoForNonSecure(content::WebContents* contents) {
EXPECT_EQ(0, security_info.cert_id);
}
+void SetUpMockCertVerifierForServer(net::MockCertVerifier* verifier,
+ const net::EmbeddedTestServer& server,
+ net::CertStatus cert_status,
+ int net_result) {
+ scoped_refptr<net::X509Certificate> cert(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;
+
+ verifier->AddResultForCert(cert.get(), verify_result, net_result);
+}
+
class ChromeSecurityStateModelClientTest : public CertVerifierBrowserTest {
public:
ChromeSecurityStateModelClientTest()
@@ -130,14 +259,8 @@ class ChromeSecurityStateModelClientTest : public CertVerifierBrowserTest {
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.get(), verify_result,
- net_result);
+ SetUpMockCertVerifierForServer(mock_cert_verifier(), https_server_,
+ cert_status, net_result);
}
net::EmbeddedTestServer https_server_;
@@ -535,4 +658,340 @@ 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(ChromeSecurityStateModelClientTest,
+ SecurityStyleChangedObserver) {
+ ASSERT_TRUE(https_server_.Start());
+ SetUpMockCertVerifierForHttpsServer(0, net::OK);
msw 2016/05/18 17:20:24 q: Is this necessary? It wasn't part of the old te
estark 2016/05/20 22:12:09 Ehh, I did it to be consistent with the rest of th
+
+ 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());
+ SetUpMockCertVerifierForServer(
+ mock_cert_verifier(), https_test_server_expired,
+ net::CERT_STATUS_DATE_INVALID, net::ERR_CERT_DATE_INVALID);
+
+ ASSERT_TRUE(embedded_test_server()->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(ChromeSecurityStateModelClientTest,
+ SecurityStyleChangedObserverGoBack) {
+ ASSERT_TRUE(https_server_.Start());
+ SetUpMockCertVerifierForHttpsServer(0, net::OK);
+
+ 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());
+ SetUpMockCertVerifierForServer(
+ mock_cert_verifier(), https_test_server_expired,
+ net::CERT_STATUS_COMMON_NAME_INVALID, net::ERR_CERT_COMMON_NAME_INVALID);
+
+ 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 CertVerifierBrowserTest {
+ public:
+ BrowserTestNonsecureURLRequest()
+ : CertVerifierBrowserTest(), 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

Powered by Google App Engine
This is Rietveld 408576698