[sql] Remove _HAS_EXCEPTIONS=0 from build info.
[chromium-blink-merge.git] / chrome / browser / ssl / ssl_browser_tests.cc
blob7391243732043000382354af3a24bd330a42787e
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/callback.h"
8 #include "base/command_line.h"
9 #include "base/location.h"
10 #include "base/metrics/field_trial.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/test/histogram_tester.h"
17 #include "base/thread_task_runner_handle.h"
18 #include "base/time/time.h"
19 #include "chrome/app/chrome_command_ids.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chrome_notification_types.h"
22 #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
23 #include "chrome/browser/net/certificate_error_reporter.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/ssl/cert_logger.pb.h"
26 #include "chrome/browser/ssl/cert_report_helper.h"
27 #include "chrome/browser/ssl/cert_verifier_browser_test.h"
28 #include "chrome/browser/ssl/certificate_error_report.h"
29 #include "chrome/browser/ssl/certificate_reporting_test_utils.h"
30 #include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h"
31 #include "chrome/browser/ssl/ssl_blocking_page.h"
32 #include "chrome/browser/ui/browser.h"
33 #include "chrome/browser/ui/browser_commands.h"
34 #include "chrome/browser/ui/browser_navigator.h"
35 #include "chrome/browser/ui/browser_tabstrip.h"
36 #include "chrome/browser/ui/tabs/tab_strip_model.h"
37 #include "chrome/common/chrome_paths.h"
38 #include "chrome/common/chrome_switches.h"
39 #include "chrome/common/pref_names.h"
40 #include "chrome/test/base/in_process_browser_test.h"
41 #include "chrome/test/base/ui_test_utils.h"
42 #include "components/content_settings/core/browser/host_content_settings_map.h"
43 #include "components/security_interstitials/core/metrics_helper.h"
44 #include "components/variations/variations_associated_data.h"
45 #include "components/web_modal/web_contents_modal_dialog_manager.h"
46 #include "content/public/browser/browser_context.h"
47 #include "content/public/browser/interstitial_page.h"
48 #include "content/public/browser/navigation_controller.h"
49 #include "content/public/browser/navigation_entry.h"
50 #include "content/public/browser/notification_service.h"
51 #include "content/public/browser/render_frame_host.h"
52 #include "content/public/browser/render_view_host.h"
53 #include "content/public/browser/render_widget_host_view.h"
54 #include "content/public/browser/web_contents.h"
55 #include "content/public/browser/web_contents_observer.h"
56 #include "content/public/common/security_style.h"
57 #include "content/public/common/ssl_status.h"
58 #include "content/public/test/browser_test_utils.h"
59 #include "content/public/test/download_test_observer.h"
60 #include "content/public/test/test_renderer_host.h"
61 #include "net/base/host_port_pair.h"
62 #include "net/base/net_errors.h"
63 #include "net/base/test_data_directory.h"
64 #include "net/cert/cert_status_flags.h"
65 #include "net/cert/mock_cert_verifier.h"
66 #include "net/cert/x509_certificate.h"
67 #include "net/ssl/ssl_info.h"
68 #include "net/test/spawned_test_server/spawned_test_server.h"
69 #include "net/url_request/url_request_context.h"
71 #if defined(USE_NSS_CERTS)
72 #include "chrome/browser/net/nss_context.h"
73 #include "net/base/crypto_module.h"
74 #include "net/cert/nss_cert_database.h"
75 #endif // defined(USE_NSS_CERTS)
77 using base::ASCIIToUTF16;
78 using chrome_browser_interstitials::SecurityInterstitialIDNTest;
79 using chrome_browser_net::CertificateErrorReporter;
80 using content::InterstitialPage;
81 using content::NavigationController;
82 using content::NavigationEntry;
83 using content::SSLStatus;
84 using content::WebContents;
85 using web_modal::WebContentsModalDialogManager;
87 const base::FilePath::CharType kDocRoot[] =
88 FILE_PATH_LITERAL("chrome/test/data");
90 namespace {
92 class ProvisionalLoadWaiter : public content::WebContentsObserver {
93 public:
94 explicit ProvisionalLoadWaiter(WebContents* tab)
95 : WebContentsObserver(tab), waiting_(false), seen_(false) {}
97 void Wait() {
98 if (seen_)
99 return;
101 waiting_ = true;
102 content::RunMessageLoop();
105 void DidFailProvisionalLoad(
106 content::RenderFrameHost* render_frame_host,
107 const GURL& validated_url,
108 int error_code,
109 const base::string16& error_description,
110 bool was_ignored_by_handler) override {
111 seen_ = true;
112 if (waiting_)
113 base::MessageLoopForUI::current()->Quit();
116 private:
117 bool waiting_;
118 bool seen_;
121 namespace AuthState {
123 enum AuthStateFlags {
124 NONE = 0,
125 DISPLAYED_INSECURE_CONTENT = 1 << 0,
126 RAN_INSECURE_CONTENT = 1 << 1,
127 SHOWING_INTERSTITIAL = 1 << 2,
128 SHOWING_ERROR = 1 << 3
131 void Check(const NavigationEntry& entry, int expected_authentication_state) {
132 if (expected_authentication_state == AuthState::SHOWING_ERROR) {
133 EXPECT_EQ(content::PAGE_TYPE_ERROR, entry.GetPageType());
134 } else {
135 EXPECT_EQ(
136 !!(expected_authentication_state & AuthState::SHOWING_INTERSTITIAL)
137 ? content::PAGE_TYPE_INTERSTITIAL
138 : content::PAGE_TYPE_NORMAL,
139 entry.GetPageType());
142 bool displayed_insecure_content =
143 !!(entry.GetSSL().content_status & SSLStatus::DISPLAYED_INSECURE_CONTENT);
144 EXPECT_EQ(
145 !!(expected_authentication_state & AuthState::DISPLAYED_INSECURE_CONTENT),
146 displayed_insecure_content);
148 bool ran_insecure_content =
149 !!(entry.GetSSL().content_status & SSLStatus::RAN_INSECURE_CONTENT);
150 EXPECT_EQ(!!(expected_authentication_state & AuthState::RAN_INSECURE_CONTENT),
151 ran_insecure_content);
154 } // namespace AuthState
156 namespace SecurityStyle {
158 void Check(const NavigationEntry& entry,
159 content::SecurityStyle expected_security_style) {
160 EXPECT_EQ(expected_security_style, entry.GetSSL().security_style);
163 } // namespace SecurityStyle
165 namespace CertError {
167 enum CertErrorFlags {
168 NONE = 0
171 void Check(const NavigationEntry& entry, net::CertStatus error) {
172 if (error) {
173 EXPECT_EQ(error, entry.GetSSL().cert_status & error);
174 net::CertStatus extra_cert_errors =
175 error ^ (entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS);
176 if (extra_cert_errors)
177 LOG(WARNING) << "Got unexpected cert error: " << extra_cert_errors;
178 } else {
179 EXPECT_EQ(0U, entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS);
183 } // namespace CertError
185 void CheckSecurityState(WebContents* tab,
186 net::CertStatus error,
187 content::SecurityStyle expected_security_style,
188 int expected_authentication_state) {
189 ASSERT_FALSE(tab->IsCrashed());
190 NavigationEntry* entry = tab->GetController().GetActiveEntry();
191 ASSERT_TRUE(entry);
192 CertError::Check(*entry, error);
193 SecurityStyle::Check(*entry, expected_security_style);
194 AuthState::Check(*entry, expected_authentication_state);
197 } // namespace
199 class SSLUITest
200 : public CertificateReportingTestUtils::CertificateReportingTest {
201 public:
202 SSLUITest()
203 : https_server_(net::SpawnedTestServer::TYPE_HTTPS,
204 SSLOptions(SSLOptions::CERT_OK),
205 base::FilePath(kDocRoot)),
206 https_server_expired_(net::SpawnedTestServer::TYPE_HTTPS,
207 SSLOptions(SSLOptions::CERT_EXPIRED),
208 base::FilePath(kDocRoot)),
209 https_server_mismatched_(net::SpawnedTestServer::TYPE_HTTPS,
210 SSLOptions(SSLOptions::CERT_MISMATCHED_NAME),
211 base::FilePath(kDocRoot)),
212 wss_server_expired_(net::SpawnedTestServer::TYPE_WSS,
213 SSLOptions(SSLOptions::CERT_EXPIRED),
214 net::GetWebSocketTestDataDirectory()) {}
216 void SetUpCommandLine(base::CommandLine* command_line) override {
217 // Browser will both run and display insecure content.
218 command_line->AppendSwitch(switches::kAllowRunningInsecureContent);
219 // Use process-per-site so that navigating to a same-site page in a
220 // new tab will use the same process.
221 command_line->AppendSwitch(switches::kProcessPerSite);
224 void CheckAuthenticatedState(WebContents* tab,
225 int expected_authentication_state) {
226 CheckSecurityState(tab,
227 CertError::NONE,
228 content::SECURITY_STYLE_AUTHENTICATED,
229 expected_authentication_state);
232 void CheckUnauthenticatedState(WebContents* tab,
233 int expected_authentication_state) {
234 CheckSecurityState(tab,
235 CertError::NONE,
236 content::SECURITY_STYLE_UNAUTHENTICATED,
237 expected_authentication_state);
240 void CheckAuthenticationBrokenState(WebContents* tab,
241 net::CertStatus error,
242 int expected_authentication_state) {
243 CheckSecurityState(tab,
244 error,
245 content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
246 expected_authentication_state);
247 // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION doesn't lower the security style
248 // to SECURITY_STYLE_AUTHENTICATION_BROKEN.
249 ASSERT_NE(net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, error);
252 void CheckWorkerLoadResult(WebContents* tab, bool expected_load) {
253 // Workers are async and we don't have notifications for them passing
254 // messages since they do it between renderer and worker processes.
255 // So have a polling loop, check every 200ms, timeout at 30s.
256 const int kTimeoutMS = 200;
257 base::Time time_to_quit = base::Time::Now() +
258 base::TimeDelta::FromMilliseconds(30000);
260 while (base::Time::Now() < time_to_quit) {
261 bool worker_finished = false;
262 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
263 tab,
264 "window.domAutomationController.send(IsWorkerFinished());",
265 &worker_finished));
267 if (worker_finished)
268 break;
270 // Wait a bit.
271 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
272 FROM_HERE, base::MessageLoop::QuitClosure(),
273 base::TimeDelta::FromMilliseconds(kTimeoutMS));
274 content::RunMessageLoop();
277 bool actually_loaded_content = false;
278 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
279 tab,
280 "window.domAutomationController.send(IsContentLoaded());",
281 &actually_loaded_content));
282 EXPECT_EQ(expected_load, actually_loaded_content);
285 void ProceedThroughInterstitial(WebContents* tab) {
286 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
287 ASSERT_TRUE(interstitial_page);
288 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
289 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
290 content::WindowedNotificationObserver observer(
291 content::NOTIFICATION_LOAD_STOP,
292 content::Source<NavigationController>(&tab->GetController()));
293 interstitial_page->Proceed();
294 observer.Wait();
297 bool IsShowingWebContentsModalDialog() const {
298 return WebContentsModalDialogManager::FromWebContents(
299 browser()->tab_strip_model()->GetActiveWebContents())->
300 IsDialogActive();
303 static bool GetFilePathWithHostAndPortReplacement(
304 const std::string& original_file_path,
305 const net::HostPortPair& host_port_pair,
306 std::string* replacement_path) {
307 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
308 replacement_text.push_back(
309 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
310 return net::SpawnedTestServer::GetFilePathWithReplacements(
311 original_file_path, replacement_text, replacement_path);
314 static bool GetTopFramePath(const net::SpawnedTestServer& http_server,
315 const net::SpawnedTestServer& good_https_server,
316 const net::SpawnedTestServer& bad_https_server,
317 std::string* top_frame_path) {
318 // The "frame_left.html" page contained in the top_frame.html page contains
319 // <a href>'s to three different servers. This sets up all of the
320 // replacement text to work with test servers which listen on ephemeral
321 // ports.
322 GURL http_url = http_server.GetURL("files/ssl/google.html");
323 GURL good_https_url = good_https_server.GetURL("files/ssl/google.html");
324 GURL bad_https_url = bad_https_server.GetURL(
325 "files/ssl/bad_iframe.html");
327 std::vector<net::SpawnedTestServer::StringPair> replacement_text_frame_left;
328 replacement_text_frame_left.push_back(
329 make_pair("REPLACE_WITH_HTTP_PAGE", http_url.spec()));
330 replacement_text_frame_left.push_back(
331 make_pair("REPLACE_WITH_GOOD_HTTPS_PAGE", good_https_url.spec()));
332 replacement_text_frame_left.push_back(
333 make_pair("REPLACE_WITH_BAD_HTTPS_PAGE", bad_https_url.spec()));
334 std::string frame_left_path;
335 if (!net::SpawnedTestServer::GetFilePathWithReplacements(
336 "frame_left.html",
337 replacement_text_frame_left,
338 &frame_left_path))
339 return false;
341 // Substitute the generated frame_left URL into the top_frame page.
342 std::vector<net::SpawnedTestServer::StringPair> replacement_text_top_frame;
343 replacement_text_top_frame.push_back(
344 make_pair("REPLACE_WITH_FRAME_LEFT_PATH", frame_left_path));
345 return net::SpawnedTestServer::GetFilePathWithReplacements(
346 "files/ssl/top_frame.html",
347 replacement_text_top_frame,
348 top_frame_path);
351 static bool GetPageWithUnsafeWorkerPath(
352 const net::SpawnedTestServer& https_server,
353 std::string* page_with_unsafe_worker_path) {
354 // Get the "imported.js" URL from the expired https server and
355 // substitute it into the unsafe_worker.js file.
356 GURL imported_js_url = https_server.GetURL("files/ssl/imported.js");
357 std::vector<net::SpawnedTestServer::StringPair>
358 replacement_text_for_unsafe_worker;
359 replacement_text_for_unsafe_worker.push_back(
360 make_pair("REPLACE_WITH_IMPORTED_JS_URL", imported_js_url.spec()));
361 std::string unsafe_worker_path;
362 if (!net::SpawnedTestServer::GetFilePathWithReplacements(
363 "unsafe_worker.js",
364 replacement_text_for_unsafe_worker,
365 &unsafe_worker_path))
366 return false;
368 // Now, substitute this into the page with unsafe worker.
369 std::vector<net::SpawnedTestServer::StringPair>
370 replacement_text_for_page_with_unsafe_worker;
371 replacement_text_for_page_with_unsafe_worker.push_back(
372 make_pair("REPLACE_WITH_UNSAFE_WORKER_PATH", unsafe_worker_path));
373 return net::SpawnedTestServer::GetFilePathWithReplacements(
374 "files/ssl/page_with_unsafe_worker.html",
375 replacement_text_for_page_with_unsafe_worker,
376 page_with_unsafe_worker_path);
379 // Helper function for testing invalid certificate chain reporting.
380 void TestBrokenHTTPSReporting(
381 CertificateReportingTestUtils::OptIn opt_in,
382 CertificateReportingTestUtils::Proceed proceed,
383 CertificateReportingTestUtils::ExpectReport expect_report,
384 Browser* browser) {
385 base::RunLoop run_loop;
386 ASSERT_TRUE(https_server_expired_.Start());
388 ASSERT_NO_FATAL_FAILURE(SetUpMockReporter());
390 // Opt in to sending reports for invalid certificate chains.
391 CertificateReportingTestUtils::SetCertReportingOptIn(browser, opt_in);
393 ui_test_utils::NavigateToURL(browser, https_server_expired_.GetURL("/"));
395 WebContents* tab = browser->tab_strip_model()->GetActiveWebContents();
396 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
397 AuthState::SHOWING_INTERSTITIAL);
399 scoped_ptr<SSLCertReporter> ssl_cert_reporter =
400 CertificateReportingTestUtils::SetUpMockSSLCertReporter(&run_loop,
401 expect_report);
403 SSLBlockingPage* interstitial_page = static_cast<SSLBlockingPage*>(
404 tab->GetInterstitialPage()->GetDelegateForTesting());
405 interstitial_page->SetSSLCertReporterForTesting(ssl_cert_reporter.Pass());
407 EXPECT_EQ(std::string(), GetLatestHostnameReported());
409 // Leave the interstitial (either by proceeding or going back)
410 if (proceed == CertificateReportingTestUtils::SSL_INTERSTITIAL_PROCEED) {
411 ProceedThroughInterstitial(tab);
412 } else {
413 // Click "Take me back"
414 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
415 ASSERT_TRUE(interstitial_page);
416 interstitial_page->DontProceed();
419 if (expect_report == CertificateReportingTestUtils::CERT_REPORT_EXPECTED) {
420 // Check that the mock reporter received a request to send a report.
421 run_loop.Run();
422 EXPECT_EQ(https_server_expired_.GetURL("/").host(),
423 GetLatestHostnameReported());
424 } else {
425 EXPECT_EQ(std::string(), GetLatestHostnameReported());
429 net::SpawnedTestServer https_server_;
430 net::SpawnedTestServer https_server_expired_;
431 net::SpawnedTestServer https_server_mismatched_;
432 net::SpawnedTestServer wss_server_expired_;
434 private:
435 typedef net::SpawnedTestServer::SSLOptions SSLOptions;
437 DISALLOW_COPY_AND_ASSIGN(SSLUITest);
440 class SSLUITestBlock : public SSLUITest {
441 public:
442 SSLUITestBlock() : SSLUITest() {}
444 // Browser will neither run nor display insecure content.
445 void SetUpCommandLine(base::CommandLine* command_line) override {
446 command_line->AppendSwitch(switches::kNoDisplayingInsecureContent);
450 class SSLUITestIgnoreCertErrors : public SSLUITest {
451 public:
452 SSLUITestIgnoreCertErrors() : SSLUITest() {}
454 void SetUpCommandLine(base::CommandLine* command_line) override {
455 // Browser will ignore certificate errors.
456 command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
460 class SSLUITestIgnoreLocalhostCertErrors : public SSLUITest {
461 public:
462 SSLUITestIgnoreLocalhostCertErrors() : SSLUITest() {}
464 void SetUpCommandLine(base::CommandLine* command_line) override {
465 // Browser will ignore certificate errors on localhost.
466 command_line->AppendSwitch(switches::kAllowInsecureLocalhost);
470 class SSLUITestWithExtendedReporting : public SSLUITest {
471 public:
472 SSLUITestWithExtendedReporting() : SSLUITest() {}
475 // Visits a regular page over http.
476 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTP) {
477 ASSERT_TRUE(test_server()->Start());
479 ui_test_utils::NavigateToURL(browser(),
480 test_server()->GetURL("files/ssl/google.html"));
482 CheckUnauthenticatedState(
483 browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE);
486 // Visits a page over http which includes broken https resources (status should
487 // be OK).
488 // TODO(jcampan): test that bad HTTPS content is blocked (otherwise we'll give
489 // the secure cookies away!).
490 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) {
491 ASSERT_TRUE(test_server()->Start());
492 ASSERT_TRUE(https_server_expired_.Start());
494 std::string replacement_path;
495 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
496 "files/ssl/page_with_unsafe_contents.html",
497 https_server_expired_.host_port_pair(),
498 &replacement_path));
500 ui_test_utils::NavigateToURL(
501 browser(), test_server()->GetURL(replacement_path));
503 CheckUnauthenticatedState(
504 browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE);
507 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSWithInsecureContent) {
508 ASSERT_TRUE(test_server()->Start());
509 ASSERT_TRUE(https_server_expired_.Start());
511 std::string replacement_path;
512 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
513 "files/ssl/page_displays_insecure_content.html",
514 test_server()->host_port_pair(),
515 &replacement_path));
517 ui_test_utils::NavigateToURL(browser(),
518 https_server_expired_.GetURL(replacement_path));
520 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
521 CheckAuthenticationBrokenState(
522 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
524 ProceedThroughInterstitial(tab);
526 CheckAuthenticationBrokenState(tab,
527 net::CERT_STATUS_DATE_INVALID,
528 AuthState::DISPLAYED_INSECURE_CONTENT);
531 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSMetricsReporting_Proceed) {
532 ASSERT_TRUE(https_server_expired_.Start());
533 ASSERT_NO_FATAL_FAILURE(SetUpMockReporter());
534 base::HistogramTester histograms;
535 const std::string decision_histogram =
536 "interstitial.ssl_overridable.decision";
537 const std::string interaction_histogram =
538 "interstitial.ssl_overridable.interaction";
540 // Histograms should start off empty.
541 histograms.ExpectTotalCount(decision_histogram, 0);
542 histograms.ExpectTotalCount(interaction_histogram, 0);
544 // After navigating to the page, the totals should be set.
545 ui_test_utils::NavigateToURL(browser(), https_server_expired_.GetURL("/"));
546 content::WaitForInterstitialAttach(
547 browser()->tab_strip_model()->GetActiveWebContents());
548 histograms.ExpectTotalCount(decision_histogram, 1);
549 histograms.ExpectBucketCount(decision_histogram,
550 security_interstitials::MetricsHelper::SHOW, 1);
551 histograms.ExpectTotalCount(interaction_histogram, 1);
552 histograms.ExpectBucketCount(
553 interaction_histogram,
554 security_interstitials::MetricsHelper::TOTAL_VISITS, 1);
556 // Decision should be recorded.
557 ProceedThroughInterstitial(
558 browser()->tab_strip_model()->GetActiveWebContents());
559 histograms.ExpectTotalCount(decision_histogram, 2);
560 histograms.ExpectBucketCount(
561 decision_histogram, security_interstitials::MetricsHelper::PROCEED, 1);
562 histograms.ExpectTotalCount(interaction_histogram, 1);
563 histograms.ExpectBucketCount(
564 interaction_histogram,
565 security_interstitials::MetricsHelper::TOTAL_VISITS, 1);
568 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSMetricsReporting_DontProceed) {
569 ASSERT_TRUE(https_server_expired_.Start());
570 ASSERT_NO_FATAL_FAILURE(SetUpMockReporter());
571 base::HistogramTester histograms;
572 const std::string decision_histogram =
573 "interstitial.ssl_overridable.decision";
574 const std::string interaction_histogram =
575 "interstitial.ssl_overridable.interaction";
577 // Histograms should start off empty.
578 histograms.ExpectTotalCount(decision_histogram, 0);
579 histograms.ExpectTotalCount(interaction_histogram, 0);
581 // After navigating to the page, the totals should be set.
582 ui_test_utils::NavigateToURL(browser(), https_server_expired_.GetURL("/"));
583 content::WaitForInterstitialAttach(
584 browser()->tab_strip_model()->GetActiveWebContents());
585 histograms.ExpectTotalCount(decision_histogram, 1);
586 histograms.ExpectBucketCount(decision_histogram,
587 security_interstitials::MetricsHelper::SHOW, 1);
588 histograms.ExpectTotalCount(interaction_histogram, 1);
589 histograms.ExpectBucketCount(
590 interaction_histogram,
591 security_interstitials::MetricsHelper::TOTAL_VISITS, 1);
593 // Decision should be recorded.
594 InterstitialPage* interstitial_page = browser()
595 ->tab_strip_model()
596 ->GetActiveWebContents()
597 ->GetInterstitialPage();
598 interstitial_page->DontProceed();
599 histograms.ExpectTotalCount(decision_histogram, 2);
600 histograms.ExpectBucketCount(
601 decision_histogram, security_interstitials::MetricsHelper::DONT_PROCEED,
603 histograms.ExpectTotalCount(interaction_histogram, 1);
604 histograms.ExpectBucketCount(
605 interaction_histogram,
606 security_interstitials::MetricsHelper::TOTAL_VISITS, 1);
609 // http://crbug.com/91745
610 #if defined(OS_CHROMEOS)
611 #define MAYBE_TestOKHTTPS DISABLED_TestOKHTTPS
612 #else
613 #define MAYBE_TestOKHTTPS TestOKHTTPS
614 #endif
616 // Visits a page over OK https:
617 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestOKHTTPS) {
618 ASSERT_TRUE(https_server_.Start());
620 ui_test_utils::NavigateToURL(browser(),
621 https_server_.GetURL("files/ssl/google.html"));
623 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
624 AuthState::NONE);
627 // Visits a page with https error and proceed:
628 #if defined(OS_LINUX)
629 // flaky http://crbug.com/396462
630 #define MAYBE_TestHTTPSExpiredCertAndProceed \
631 DISABLED_TestHTTPSExpiredCertAndProceed
632 #else
633 #define MAYBE_TestHTTPSExpiredCertAndProceed TestHTTPSExpiredCertAndProceed
634 #endif
635 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndProceed) {
636 ASSERT_TRUE(https_server_expired_.Start());
638 ui_test_utils::NavigateToURL(browser(),
639 https_server_expired_.GetURL("files/ssl/google.html"));
641 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
642 CheckAuthenticationBrokenState(
643 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
645 ProceedThroughInterstitial(tab);
647 CheckAuthenticationBrokenState(
648 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
651 #ifndef NEDBUG
652 // Flaky on Windows debug (http://crbug.com/280537).
653 #define MAYBE_TestHTTPSExpiredCertAndDontProceed \
654 DISABLED_TestHTTPSExpiredCertAndDontProceed
655 #else
656 #define MAYBE_TestHTTPSExpiredCertAndDontProceed \
657 TestHTTPSExpiredCertAndDontProceed
658 #endif
660 // Visits a page with https error and don't proceed (and ensure we can still
661 // navigate at that point):
662 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndDontProceed) {
663 ASSERT_TRUE(test_server()->Start());
664 ASSERT_TRUE(https_server_.Start());
665 ASSERT_TRUE(https_server_expired_.Start());
667 // First navigate to an OK page.
668 ui_test_utils::NavigateToURL(browser(),
669 https_server_.GetURL("files/ssl/google.html"));
671 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
672 NavigationEntry* entry = tab->GetController().GetActiveEntry();
673 ASSERT_TRUE(entry);
675 GURL cross_site_url =
676 https_server_expired_.GetURL("files/ssl/google.html");
677 // Change the host name from 127.0.0.1 to localhost so it triggers a
678 // cross-site navigation so we can test http://crbug.com/5800 is gone.
679 ASSERT_EQ("127.0.0.1", cross_site_url.host());
680 GURL::Replacements replacements;
681 replacements.SetHostStr("localhost");
682 cross_site_url = cross_site_url.ReplaceComponents(replacements);
684 // Now go to a bad HTTPS page.
685 ui_test_utils::NavigateToURL(browser(), cross_site_url);
687 // An interstitial should be showing.
688 CheckAuthenticationBrokenState(tab,
689 net::CERT_STATUS_COMMON_NAME_INVALID,
690 AuthState::SHOWING_INTERSTITIAL);
692 // Simulate user clicking "Take me back".
693 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
694 ASSERT_TRUE(interstitial_page);
695 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
696 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
697 interstitial_page->DontProceed();
699 // We should be back to the original good page.
700 CheckAuthenticatedState(tab, AuthState::NONE);
702 // Try to navigate to a new page. (to make sure bug 5800 is fixed).
703 ui_test_utils::NavigateToURL(browser(),
704 test_server()->GetURL("files/ssl/google.html"));
705 CheckUnauthenticatedState(tab, AuthState::NONE);
708 // Test that localhost pages don't show an interstitial.
709 IN_PROC_BROWSER_TEST_F(SSLUITestIgnoreLocalhostCertErrors,
710 TestNoInterstitialOnLocalhost) {
711 ASSERT_TRUE(https_server_.Start());
713 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
715 // Navigate to a localhost page.
716 GURL url = https_server_.GetURL("files/ssl/page_with_subresource.html");
717 GURL::Replacements replacements;
718 std::string new_host("localhost");
719 replacements.SetHostStr(new_host);
720 url = url.ReplaceComponents(replacements);
722 ui_test_utils::NavigateToURL(browser(), url);
724 // We should see no interstitial, but we should have an error
725 // (red-crossed-out-https) in the URL bar.
726 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
727 AuthState::NONE);
729 // We should see that the script tag in the page loaded and ran (and
730 // wasn't blocked by the certificate error).
731 base::string16 title;
732 base::string16 expected_title = base::ASCIIToUTF16("This script has loaded");
733 ui_test_utils::GetCurrentTabTitle(browser(), &title);
734 EXPECT_EQ(title, expected_title);
737 // Visits a page with https error and then goes back using Browser::GoBack.
738 IN_PROC_BROWSER_TEST_F(SSLUITest,
739 TestHTTPSExpiredCertAndGoBackViaButton) {
740 ASSERT_TRUE(test_server()->Start());
741 ASSERT_TRUE(https_server_expired_.Start());
743 // First navigate to an HTTP page.
744 ui_test_utils::NavigateToURL(browser(),
745 test_server()->GetURL("files/ssl/google.html"));
746 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
747 NavigationEntry* entry = tab->GetController().GetActiveEntry();
748 ASSERT_TRUE(entry);
750 // Now go to a bad HTTPS page that shows an interstitial.
751 ui_test_utils::NavigateToURL(browser(),
752 https_server_expired_.GetURL("files/ssl/google.html"));
753 CheckAuthenticationBrokenState(
754 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
756 ProvisionalLoadWaiter load_failed_observer(tab);
758 // Simulate user clicking on back button (crbug.com/39248).
759 chrome::GoBack(browser(), CURRENT_TAB);
761 // Wait until we hear the load failure, and make sure we haven't swapped out
762 // the previous page. Prevents regression of http://crbug.com/82667.
763 // TODO(creis/nick): Move the swapped-out part of this test into content
764 // and remove IsRenderViewHostSwappedOut from the public API.
765 load_failed_observer.Wait();
766 EXPECT_FALSE(content::RenderFrameHostTester::IsRenderFrameHostSwappedOut(
767 tab->GetMainFrame()));
769 // We should be back at the original good page.
770 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()->
771 GetInterstitialPage());
772 CheckUnauthenticatedState(tab, AuthState::NONE);
775 // Visits a page with https error and then goes back using GoToOffset.
776 // Disabled because its flaky: http://crbug.com/40932, http://crbug.com/43575.
777 IN_PROC_BROWSER_TEST_F(SSLUITest,
778 TestHTTPSExpiredCertAndGoBackViaMenu) {
779 ASSERT_TRUE(test_server()->Start());
780 ASSERT_TRUE(https_server_expired_.Start());
782 // First navigate to an HTTP page.
783 ui_test_utils::NavigateToURL(browser(),
784 test_server()->GetURL("files/ssl/google.html"));
785 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
786 NavigationEntry* entry = tab->GetController().GetActiveEntry();
787 ASSERT_TRUE(entry);
789 // Now go to a bad HTTPS page that shows an interstitial.
790 ui_test_utils::NavigateToURL(browser(),
791 https_server_expired_.GetURL("files/ssl/google.html"));
792 CheckAuthenticationBrokenState(
793 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
795 // Simulate user clicking and holding on back button (crbug.com/37215).
796 tab->GetController().GoToOffset(-1);
798 // We should be back at the original good page.
799 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()->
800 GetInterstitialPage());
801 CheckUnauthenticatedState(tab, AuthState::NONE);
804 // Visits a page with https error and then goes forward using GoToOffset.
805 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndGoForward) {
806 ASSERT_TRUE(test_server()->Start());
807 ASSERT_TRUE(https_server_expired_.Start());
809 // First navigate to two HTTP pages.
810 ui_test_utils::NavigateToURL(browser(),
811 test_server()->GetURL("files/ssl/google.html"));
812 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
813 NavigationEntry* entry1 = tab->GetController().GetActiveEntry();
814 ASSERT_TRUE(entry1);
815 ui_test_utils::NavigateToURL(browser(),
816 test_server()->GetURL("files/ssl/blank_page.html"));
817 NavigationEntry* entry2 = tab->GetController().GetActiveEntry();
818 ASSERT_TRUE(entry2);
820 // Now go back so that a page is in the forward history.
822 content::WindowedNotificationObserver observer(
823 content::NOTIFICATION_LOAD_STOP,
824 content::Source<NavigationController>(&tab->GetController()));
825 tab->GetController().GoBack();
826 observer.Wait();
828 ASSERT_TRUE(tab->GetController().CanGoForward());
829 NavigationEntry* entry3 = tab->GetController().GetActiveEntry();
830 ASSERT_TRUE(entry1 == entry3);
832 // Now go to a bad HTTPS page that shows an interstitial.
833 ui_test_utils::NavigateToURL(browser(),
834 https_server_expired_.GetURL("files/ssl/google.html"));
835 CheckAuthenticationBrokenState(
836 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
838 // Simulate user clicking and holding on forward button.
840 content::WindowedNotificationObserver observer(
841 content::NOTIFICATION_LOAD_STOP,
842 content::Source<NavigationController>(&tab->GetController()));
843 tab->GetController().GoToOffset(1);
844 observer.Wait();
847 // We should be showing the second good page.
848 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()->
849 GetInterstitialPage());
850 CheckUnauthenticatedState(tab, AuthState::NONE);
851 EXPECT_FALSE(tab->GetController().CanGoForward());
852 NavigationEntry* entry4 = tab->GetController().GetActiveEntry();
853 EXPECT_TRUE(entry2 == entry4);
856 // Visit a HTTP page which request WSS connection to a server providing invalid
857 // certificate. Close the page while WSS connection waits for SSLManager's
858 // response from UI thread.
859 // Disabled on Windows because it was flaking on XP Tests (1). crbug.com/165258
860 #if defined(OS_WIN)
861 #define MAYBE_TestWSSInvalidCertAndClose DISABLED_TestWSSInvalidCertAndClose
862 #else
863 #define MAYBE_TestWSSInvalidCertAndClose TestWSSInvalidCertAndClose
864 #endif
865 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestWSSInvalidCertAndClose) {
866 ASSERT_TRUE(test_server()->Start());
867 ASSERT_TRUE(wss_server_expired_.Start());
869 // Setup page title observer.
870 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
871 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
872 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
874 // Create GURLs to test pages.
875 std::string master_url_path = base::StringPrintf("%s?%d",
876 test_server()->GetURL("files/ssl/wss_close.html").spec().c_str(),
877 wss_server_expired_.host_port_pair().port());
878 GURL master_url(master_url_path);
879 std::string slave_url_path = base::StringPrintf("%s?%d",
880 test_server()->GetURL("files/ssl/wss_close_slave.html").spec().c_str(),
881 wss_server_expired_.host_port_pair().port());
882 GURL slave_url(slave_url_path);
884 // Create tabs and visit pages which keep on creating wss connections.
885 WebContents* tabs[16];
886 for (int i = 0; i < 16; ++i) {
887 tabs[i] = chrome::AddSelectedTabWithURL(browser(), slave_url,
888 ui::PAGE_TRANSITION_LINK);
890 chrome::SelectNextTab(browser());
892 // Visit a page which waits for one TLS handshake failure.
893 // The title will be changed to 'PASS'.
894 ui_test_utils::NavigateToURL(browser(), master_url);
895 const base::string16 result = watcher.WaitAndGetTitle();
896 EXPECT_TRUE(base::LowerCaseEqualsASCII(result, "pass"));
898 // Close tabs which contains the test page.
899 for (int i = 0; i < 16; ++i)
900 chrome::CloseWebContents(browser(), tabs[i], false);
901 chrome::CloseWebContents(browser(), tab, false);
904 // Visit a HTTPS page and proceeds despite an invalid certificate. The page
905 // requests WSS connection to the same origin host to check if WSS connection
906 // share certificates policy with HTTPS correcly.
907 IN_PROC_BROWSER_TEST_F(SSLUITest, TestWSSInvalidCertAndGoForward) {
908 ASSERT_TRUE(test_server()->Start());
909 ASSERT_TRUE(wss_server_expired_.Start());
911 // Setup page title observer.
912 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
913 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
914 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
916 // Visit bad HTTPS page.
917 GURL::Replacements replacements;
918 replacements.SetSchemeStr("https");
919 ui_test_utils::NavigateToURL(
920 browser(),
921 wss_server_expired_.GetURL(
922 "connect_check.html").ReplaceComponents(replacements));
923 CheckAuthenticationBrokenState(
924 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
926 // Proceed anyway.
927 ProceedThroughInterstitial(tab);
929 // Test page run a WebSocket wss connection test. The result will be shown
930 // as page title.
931 const base::string16 result = watcher.WaitAndGetTitle();
932 EXPECT_TRUE(base::LowerCaseEqualsASCII(result, "pass"));
935 #if defined(USE_NSS_CERTS)
936 class SSLUITestWithClientCert : public SSLUITest {
937 public:
938 SSLUITestWithClientCert() : cert_db_(NULL) {}
940 void SetUpOnMainThread() override {
941 SSLUITest::SetUpOnMainThread();
943 base::RunLoop loop;
944 GetNSSCertDatabaseForProfile(
945 browser()->profile(),
946 base::Bind(&SSLUITestWithClientCert::DidGetCertDatabase,
947 base::Unretained(this),
948 &loop));
949 loop.Run();
952 protected:
953 void DidGetCertDatabase(base::RunLoop* loop, net::NSSCertDatabase* cert_db) {
954 cert_db_ = cert_db;
955 loop->Quit();
958 net::NSSCertDatabase* cert_db_;
961 // SSL client certificate tests are only enabled when using NSS for private key
962 // storage, as only NSS can avoid modifying global machine state when testing.
963 // See http://crbug.com/51132
965 // Visit a HTTPS page which requires client cert authentication. The client
966 // cert will be selected automatically, then a test which uses WebSocket runs.
967 IN_PROC_BROWSER_TEST_F(SSLUITestWithClientCert, TestWSSClientCert) {
968 // Import a client cert for test.
969 scoped_refptr<net::CryptoModule> crypt_module = cert_db_->GetPublicModule();
970 std::string pkcs12_data;
971 base::FilePath cert_path = net::GetTestCertsDirectory().Append(
972 FILE_PATH_LITERAL("websocket_client_cert.p12"));
973 EXPECT_TRUE(base::ReadFileToString(cert_path, &pkcs12_data));
974 EXPECT_EQ(net::OK,
975 cert_db_->ImportFromPKCS12(
976 crypt_module.get(), pkcs12_data, base::string16(), true, NULL));
978 // Start WebSocket test server with TLS and client cert authentication.
979 net::SpawnedTestServer::SSLOptions options(
980 net::SpawnedTestServer::SSLOptions::CERT_OK);
981 options.request_client_certificate = true;
982 base::FilePath ca_path = net::GetTestCertsDirectory().Append(
983 FILE_PATH_LITERAL("websocket_cacert.pem"));
984 options.client_authorities.push_back(ca_path);
985 net::SpawnedTestServer wss_server(net::SpawnedTestServer::TYPE_WSS,
986 options,
987 net::GetWebSocketTestDataDirectory());
988 ASSERT_TRUE(wss_server.Start());
989 GURL::Replacements replacements;
990 replacements.SetSchemeStr("https");
991 GURL url = wss_server.GetURL("connect_check.html").ReplaceComponents(
992 replacements);
994 // Setup page title observer.
995 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
996 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
997 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
999 // Add an entry into AutoSelectCertificateForUrls policy for automatic client
1000 // cert selection.
1001 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
1002 DCHECK(profile);
1003 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
1004 dict->SetString("ISSUER.CN", "pywebsocket");
1005 profile->GetHostContentSettingsMap()->SetWebsiteSetting(
1006 ContentSettingsPattern::FromURL(url),
1007 ContentSettingsPattern::FromURL(url),
1008 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
1009 std::string(),
1010 dict.release());
1012 // Visit a HTTPS page which requires client certs.
1013 ui_test_utils::NavigateToURL(browser(), url);
1014 CheckAuthenticatedState(tab, AuthState::NONE);
1016 // Test page runs a WebSocket wss connection test. The result will be shown
1017 // as page title.
1018 const base::string16 result = watcher.WaitAndGetTitle();
1019 EXPECT_TRUE(base::LowerCaseEqualsASCII(result, "pass"));
1021 #endif // defined(USE_NSS_CERTS)
1023 // Flaky on CrOS http://crbug.com/92292
1024 #if defined(OS_CHROMEOS)
1025 #define MAYBE_TestHTTPSErrorWithNoNavEntry \
1026 DISABLED_TestHTTPSErrorWithNoNavEntry
1027 #else
1028 #define MAYBE_TestHTTPSErrorWithNoNavEntry TestHTTPSErrorWithNoNavEntry
1029 #endif // defined(OS_CHROMEOS)
1031 // Open a page with a HTTPS error in a tab with no prior navigation (through a
1032 // link with a blank target). This is to test that the lack of navigation entry
1033 // does not cause any problems (it was causing a crasher, see
1034 // http://crbug.com/19941).
1035 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSErrorWithNoNavEntry) {
1036 ASSERT_TRUE(https_server_expired_.Start());
1038 GURL url = https_server_expired_.GetURL("files/ssl/google.htm");
1039 WebContents* tab2 = chrome::AddSelectedTabWithURL(
1040 browser(), url, ui::PAGE_TRANSITION_TYPED);
1041 content::WaitForLoadStop(tab2);
1043 // Verify our assumption that there was no prior navigation.
1044 EXPECT_FALSE(chrome::CanGoBack(browser()));
1046 // We should have an interstitial page showing.
1047 ASSERT_TRUE(tab2->GetInterstitialPage());
1048 ASSERT_EQ(SSLBlockingPage::kTypeForTesting, tab2->GetInterstitialPage()
1049 ->GetDelegateForTesting()
1050 ->GetTypeForTesting());
1053 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadHTTPSDownload) {
1054 ASSERT_TRUE(test_server()->Start());
1055 ASSERT_TRUE(https_server_expired_.Start());
1056 GURL url_non_dangerous = test_server()->GetURL(std::string());
1057 GURL url_dangerous =
1058 https_server_expired_.GetURL("files/downloads/dangerous/dangerous.exe");
1059 base::ScopedTempDir downloads_directory_;
1061 // Need empty temp dir to avoid having Chrome ask us for a new filename
1062 // when we've downloaded dangerous.exe one hundred times.
1063 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
1065 browser()->profile()->GetPrefs()->SetFilePath(
1066 prefs::kDownloadDefaultDirectory,
1067 downloads_directory_.path());
1069 // Visit a non-dangerous page.
1070 ui_test_utils::NavigateToURL(browser(), url_non_dangerous);
1072 // Now, start a transition to dangerous download.
1074 content::WindowedNotificationObserver observer(
1075 content::NOTIFICATION_LOAD_STOP,
1076 content::NotificationService::AllSources());
1077 chrome::NavigateParams navigate_params(browser(), url_dangerous,
1078 ui::PAGE_TRANSITION_TYPED);
1079 chrome::Navigate(&navigate_params);
1080 observer.Wait();
1083 // To exit the browser cleanly (and this test) we need to complete the
1084 // download after completing this test.
1085 content::DownloadTestObserverTerminal dangerous_download_observer(
1086 content::BrowserContext::GetDownloadManager(browser()->profile()),
1088 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT);
1090 // Proceed through the SSL interstitial. This doesn't use
1091 // |ProceedThroughInterstitial| since no page load will commit.
1092 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1093 ASSERT_TRUE(tab != NULL);
1094 ASSERT_TRUE(tab->GetInterstitialPage() != NULL);
1095 ASSERT_EQ(
1096 SSLBlockingPage::kTypeForTesting,
1097 tab->GetInterstitialPage()->GetDelegateForTesting()->GetTypeForTesting());
1099 content::WindowedNotificationObserver observer(
1100 chrome::NOTIFICATION_DOWNLOAD_INITIATED,
1101 content::NotificationService::AllSources());
1102 tab->GetInterstitialPage()->Proceed();
1103 observer.Wait();
1106 // There should still be an interstitial at this point. Press the
1107 // back button on the browser. Note that this doesn't wait for a
1108 // NAV_ENTRY_COMMITTED notification because going back with an
1109 // active interstitial simply hides the interstitial.
1110 ASSERT_TRUE(tab->GetInterstitialPage() != NULL);
1111 ASSERT_EQ(
1112 SSLBlockingPage::kTypeForTesting,
1113 tab->GetInterstitialPage()->GetDelegateForTesting()->GetTypeForTesting());
1114 EXPECT_TRUE(chrome::CanGoBack(browser()));
1115 chrome::GoBack(browser(), CURRENT_TAB);
1117 dangerous_download_observer.WaitForFinished();
1121 // Insecure content
1124 #if defined(OS_WIN)
1125 // http://crbug.com/152940 Flaky on win.
1126 #define MAYBE_TestDisplaysInsecureContent DISABLED_TestDisplaysInsecureContent
1127 #else
1128 #define MAYBE_TestDisplaysInsecureContent TestDisplaysInsecureContent
1129 #endif
1131 // Visits a page that displays insecure content.
1132 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestDisplaysInsecureContent) {
1133 ASSERT_TRUE(test_server()->Start());
1134 ASSERT_TRUE(https_server_.Start());
1136 std::string replacement_path;
1137 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1138 "files/ssl/page_displays_insecure_content.html",
1139 test_server()->host_port_pair(),
1140 &replacement_path));
1142 // Load a page that displays insecure content.
1143 ui_test_utils::NavigateToURL(browser(),
1144 https_server_.GetURL(replacement_path));
1146 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
1147 AuthState::DISPLAYED_INSECURE_CONTENT);
1150 // Test that if the user proceeds and the checkbox is checked, a report
1151 // is sent or not sent depending on the Finch config.
1152 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1153 TestBrokenHTTPSProceedReporting) {
1154 CertificateReportingTestUtils::ExpectReport expect_report =
1155 CertificateReportingTestUtils::GetReportExpectedFromFinch();
1156 TestBrokenHTTPSReporting(
1157 CertificateReportingTestUtils::EXTENDED_REPORTING_OPT_IN,
1158 CertificateReportingTestUtils::SSL_INTERSTITIAL_PROCEED, expect_report,
1159 browser());
1162 // Test that if the user goes back and the checkbox is checked, a report
1163 // is sent or not sent depending on the Finch config.
1164 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1165 TestBrokenHTTPSGoBackReporting) {
1166 CertificateReportingTestUtils::ExpectReport expect_report =
1167 CertificateReportingTestUtils::GetReportExpectedFromFinch();
1168 TestBrokenHTTPSReporting(
1169 CertificateReportingTestUtils::EXTENDED_REPORTING_OPT_IN,
1170 CertificateReportingTestUtils::SSL_INTERSTITIAL_DO_NOT_PROCEED,
1171 expect_report, browser());
1174 // User proceeds, checkbox is shown but unchecked. Reports should never
1175 // be sent, regardless of Finch config.
1176 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1177 TestBrokenHTTPSProceedReportingWithNoOptIn) {
1178 TestBrokenHTTPSReporting(
1179 CertificateReportingTestUtils::EXTENDED_REPORTING_DO_NOT_OPT_IN,
1180 CertificateReportingTestUtils::SSL_INTERSTITIAL_PROCEED,
1181 CertificateReportingTestUtils::CERT_REPORT_NOT_EXPECTED, browser());
1184 // User goes back, checkbox is shown but unchecked. Reports should never
1185 // be sent, regardless of Finch config.
1186 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1187 TestBrokenHTTPSGoBackShowYesCheckNoParamYesReportNo) {
1188 TestBrokenHTTPSReporting(
1189 CertificateReportingTestUtils::EXTENDED_REPORTING_DO_NOT_OPT_IN,
1190 CertificateReportingTestUtils::SSL_INTERSTITIAL_DO_NOT_PROCEED,
1191 CertificateReportingTestUtils::CERT_REPORT_NOT_EXPECTED, browser());
1194 // User proceeds, checkbox is not shown but checked -> we expect no
1195 // report.
1196 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1197 TestBrokenHTTPSProceedShowNoCheckYesReportNo) {
1198 if (base::FieldTrialList::FindFullName(
1199 CertReportHelper::kFinchExperimentName) ==
1200 CertReportHelper::kFinchGroupDontShowDontSend) {
1201 TestBrokenHTTPSReporting(
1202 CertificateReportingTestUtils::EXTENDED_REPORTING_OPT_IN,
1203 CertificateReportingTestUtils::SSL_INTERSTITIAL_PROCEED,
1204 CertificateReportingTestUtils::CERT_REPORT_NOT_EXPECTED, browser());
1208 // Browser is incognito, user proceeds, checkbox has previously opted in
1209 // -> no report, regardless of Finch config.
1210 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1211 TestBrokenHTTPSInIncognitoReportNo) {
1212 TestBrokenHTTPSReporting(
1213 CertificateReportingTestUtils::EXTENDED_REPORTING_OPT_IN,
1214 CertificateReportingTestUtils::SSL_INTERSTITIAL_PROCEED,
1215 CertificateReportingTestUtils::CERT_REPORT_NOT_EXPECTED,
1216 CreateIncognitoBrowser());
1219 // Test that reports don't get sent when extended reporting opt-in is
1220 // disabled by policy.
1221 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1222 TestBrokenHTTPSNoReportingWhenDisallowed) {
1223 browser()->profile()->GetPrefs()->SetBoolean(
1224 prefs::kSafeBrowsingExtendedReportingOptInAllowed, false);
1225 TestBrokenHTTPSReporting(
1226 CertificateReportingTestUtils::EXTENDED_REPORTING_OPT_IN,
1227 CertificateReportingTestUtils::SSL_INTERSTITIAL_PROCEED,
1228 CertificateReportingTestUtils::CERT_REPORT_NOT_EXPECTED, browser());
1231 // Visits a page that runs insecure content and tries to suppress the insecure
1232 // content warnings by randomizing location.hash.
1233 // Based on http://crbug.com/8706
1234 IN_PROC_BROWSER_TEST_F(SSLUITest,
1235 TestRunsInsecuredContentRandomizeHash) {
1236 ASSERT_TRUE(test_server()->Start());
1237 ASSERT_TRUE(https_server_.Start());
1239 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
1240 "files/ssl/page_runs_insecure_content.html"));
1242 CheckAuthenticationBrokenState(
1243 browser()->tab_strip_model()->GetActiveWebContents(),
1244 CertError::NONE,
1245 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1248 // Visits a page with unsafe content and make sure that:
1249 // - frames content is replaced with warning
1250 // - images and scripts are filtered out entirely
1251 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContents) {
1252 ASSERT_TRUE(https_server_.Start());
1253 ASSERT_TRUE(https_server_expired_.Start());
1255 std::string replacement_path;
1256 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1257 "files/ssl/page_with_unsafe_contents.html",
1258 https_server_expired_.host_port_pair(),
1259 &replacement_path));
1260 ui_test_utils::NavigateToURL(browser(),
1261 https_server_.GetURL(replacement_path));
1263 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1264 // When the bad content is filtered, the state is expected to be
1265 // authenticated.
1266 CheckAuthenticatedState(tab, AuthState::NONE);
1268 // Because of cross-frame scripting restrictions, we cannot access the iframe
1269 // content. So to know if the frame was loaded, we just check if a popup was
1270 // opened (the iframe content opens one).
1271 // Note: because of bug 1115868, no web contents modal dialog is opened right
1272 // now. Once the bug is fixed, this will do the real check.
1273 EXPECT_FALSE(IsShowingWebContentsModalDialog());
1275 int img_width;
1276 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
1277 tab,
1278 "window.domAutomationController.send(ImageWidth());",
1279 &img_width));
1280 // In order to check that the image was not loaded, we check its width.
1281 // The actual image (Google logo) is 114 pixels wide, we assume the broken
1282 // image is less than 100.
1283 EXPECT_LT(img_width, 100);
1285 bool js_result = false;
1286 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1287 tab,
1288 "window.domAutomationController.send(IsFooSet());",
1289 &js_result));
1290 EXPECT_FALSE(js_result);
1293 // Visits a page with insecure content loaded by JS (after the initial page
1294 // load).
1295 #if defined(OS_LINUX)
1296 // flaky http://crbug.com/396462
1297 #define MAYBE_TestDisplaysInsecureContentLoadedFromJS \
1298 DISABLED_TestDisplaysInsecureContentLoadedFromJS
1299 #else
1300 #define MAYBE_TestDisplaysInsecureContentLoadedFromJS \
1301 TestDisplaysInsecureContentLoadedFromJS
1302 #endif
1303 IN_PROC_BROWSER_TEST_F(SSLUITest,
1304 MAYBE_TestDisplaysInsecureContentLoadedFromJS) {
1305 ASSERT_TRUE(test_server()->Start());
1306 ASSERT_TRUE(https_server_.Start());
1308 std::string replacement_path;
1309 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1310 "files/ssl/page_with_dynamic_insecure_content.html",
1311 test_server()->host_port_pair(),
1312 &replacement_path));
1313 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
1314 replacement_path));
1316 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1317 CheckAuthenticatedState(tab, AuthState::NONE);
1319 // Load the insecure image.
1320 bool js_result = false;
1321 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1322 tab,
1323 "loadBadImage();",
1324 &js_result));
1325 EXPECT_TRUE(js_result);
1327 // We should now have insecure content.
1328 CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT);
1331 // Visits two pages from the same origin: one that displays insecure content and
1332 // one that doesn't. The test checks that we do not propagate the insecure
1333 // content state from one to the other.
1334 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentTwoTabs) {
1335 ASSERT_TRUE(test_server()->Start());
1336 ASSERT_TRUE(https_server_.Start());
1338 ui_test_utils::NavigateToURL(browser(),
1339 https_server_.GetURL("files/ssl/blank_page.html"));
1341 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1343 // This tab should be fine.
1344 CheckAuthenticatedState(tab1, AuthState::NONE);
1346 // Create a new tab.
1347 std::string replacement_path;
1348 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1349 "files/ssl/page_displays_insecure_content.html",
1350 test_server()->host_port_pair(),
1351 &replacement_path));
1353 GURL url = https_server_.GetURL(replacement_path);
1354 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED);
1355 params.disposition = NEW_FOREGROUND_TAB;
1356 params.tabstrip_index = 0;
1357 params.source_contents = tab1;
1358 content::WindowedNotificationObserver observer(
1359 content::NOTIFICATION_LOAD_STOP,
1360 content::NotificationService::AllSources());
1361 chrome::Navigate(&params);
1362 WebContents* tab2 = params.target_contents;
1363 observer.Wait();
1365 // The new tab has insecure content.
1366 CheckAuthenticatedState(tab2, AuthState::DISPLAYED_INSECURE_CONTENT);
1368 // The original tab should not be contaminated.
1369 CheckAuthenticatedState(tab1, AuthState::NONE);
1372 // Visits two pages from the same origin: one that runs insecure content and one
1373 // that doesn't. The test checks that we propagate the insecure content state
1374 // from one to the other.
1375 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsInsecureContentTwoTabs) {
1376 ASSERT_TRUE(test_server()->Start());
1377 ASSERT_TRUE(https_server_.Start());
1379 ui_test_utils::NavigateToURL(browser(),
1380 https_server_.GetURL("files/ssl/blank_page.html"));
1382 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1384 // This tab should be fine.
1385 CheckAuthenticatedState(tab1, AuthState::NONE);
1387 std::string replacement_path;
1388 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1389 "files/ssl/page_runs_insecure_content.html",
1390 test_server()->host_port_pair(),
1391 &replacement_path));
1393 // Create a new tab in the same process. Using a NEW_FOREGROUND_TAB
1394 // disposition won't usually stay in the same process, but this works
1395 // because we are using process-per-site in SetUpCommandLine.
1396 GURL url = https_server_.GetURL(replacement_path);
1397 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED);
1398 params.disposition = NEW_FOREGROUND_TAB;
1399 params.source_contents = tab1;
1400 content::WindowedNotificationObserver observer(
1401 content::NOTIFICATION_LOAD_STOP,
1402 content::NotificationService::AllSources());
1403 chrome::Navigate(&params);
1404 WebContents* tab2 = params.target_contents;
1405 observer.Wait();
1407 // Both tabs should have the same process.
1408 EXPECT_EQ(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
1410 // The new tab has insecure content.
1411 CheckAuthenticationBrokenState(
1412 tab2,
1413 CertError::NONE,
1414 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1416 // Which means the origin for the first tab has also been contaminated with
1417 // insecure content.
1418 CheckAuthenticationBrokenState(
1419 tab1, CertError::NONE, AuthState::RAN_INSECURE_CONTENT);
1422 // Visits a page with an image over http. Visits another page over https
1423 // referencing that same image over http (hoping it is coming from the webcore
1424 // memory cache).
1425 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysCachedInsecureContent) {
1426 ASSERT_TRUE(test_server()->Start());
1427 ASSERT_TRUE(https_server_.Start());
1429 std::string replacement_path;
1430 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1431 "files/ssl/page_displays_insecure_content.html",
1432 test_server()->host_port_pair(),
1433 &replacement_path));
1435 // Load original page over HTTP.
1436 const GURL url_http = test_server()->GetURL(replacement_path);
1437 ui_test_utils::NavigateToURL(browser(), url_http);
1438 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1439 CheckUnauthenticatedState(tab, AuthState::NONE);
1441 // Load again but over SSL. It should be marked as displaying insecure
1442 // content (even though the image comes from the WebCore memory cache).
1443 const GURL url_https = https_server_.GetURL(replacement_path);
1444 ui_test_utils::NavigateToURL(browser(), url_https);
1445 CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT);
1448 // http://crbug.com/84729
1449 #if defined(OS_CHROMEOS)
1450 #define MAYBE_TestRunsCachedInsecureContent \
1451 DISABLED_TestRunsCachedInsecureContent
1452 #else
1453 #define MAYBE_TestRunsCachedInsecureContent TestRunsCachedInsecureContent
1454 #endif // defined(OS_CHROMEOS)
1456 // Visits a page with script over http. Visits another page over https
1457 // referencing that same script over http (hoping it is coming from the webcore
1458 // memory cache).
1459 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRunsCachedInsecureContent) {
1460 ASSERT_TRUE(test_server()->Start());
1461 ASSERT_TRUE(https_server_.Start());
1463 std::string replacement_path;
1464 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1465 "files/ssl/page_runs_insecure_content.html",
1466 test_server()->host_port_pair(),
1467 &replacement_path));
1469 // Load original page over HTTP.
1470 const GURL url_http = test_server()->GetURL(replacement_path);
1471 ui_test_utils::NavigateToURL(browser(), url_http);
1472 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1473 CheckUnauthenticatedState(tab, AuthState::NONE);
1475 // Load again but over SSL. It should be marked as displaying insecure
1476 // content (even though the image comes from the WebCore memory cache).
1477 const GURL url_https = https_server_.GetURL(replacement_path);
1478 ui_test_utils::NavigateToURL(browser(), url_https);
1479 CheckAuthenticationBrokenState(
1480 tab,
1481 CertError::NONE,
1482 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1485 // This test ensures the CN invalid status does not 'stick' to a certificate
1486 // (see bug #1044942) and that it depends on the host-name.
1487 // Test if disabled due to flakiness http://crbug.com/368280 .
1488 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCNInvalidStickiness) {
1489 ASSERT_TRUE(https_server_.Start());
1490 ASSERT_TRUE(https_server_mismatched_.Start());
1492 // First we hit the server with hostname, this generates an invalid policy
1493 // error.
1494 ui_test_utils::NavigateToURL(browser(),
1495 https_server_mismatched_.GetURL("files/ssl/google.html"));
1497 // We get an interstitial page as a result.
1498 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1499 CheckAuthenticationBrokenState(tab,
1500 net::CERT_STATUS_COMMON_NAME_INVALID,
1501 AuthState::SHOWING_INTERSTITIAL);
1502 ProceedThroughInterstitial(tab);
1503 CheckAuthenticationBrokenState(
1504 tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE);
1506 // Now we try again with the right host name this time.
1507 GURL url(https_server_.GetURL("files/ssl/google.html"));
1508 ui_test_utils::NavigateToURL(browser(), url);
1510 // Security state should be OK.
1511 CheckAuthenticatedState(tab, AuthState::NONE);
1513 // Now try again the broken one to make sure it is still broken.
1514 ui_test_utils::NavigateToURL(browser(),
1515 https_server_mismatched_.GetURL("files/ssl/google.html"));
1517 // Since we OKed the interstitial last time, we get right to the page.
1518 CheckAuthenticationBrokenState(
1519 tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE);
1522 #if defined(OS_CHROMEOS)
1523 // This test seems to be flaky and hang on chromiumos.
1524 // http://crbug.com/84419
1525 #define MAYBE_TestRefNavigation DISABLED_TestRefNavigation
1526 #else
1527 #define MAYBE_TestRefNavigation TestRefNavigation
1528 #endif
1530 // Test that navigating to a #ref does not change a bad security state.
1531 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) {
1532 ASSERT_TRUE(https_server_expired_.Start());
1534 ui_test_utils::NavigateToURL(browser(),
1535 https_server_expired_.GetURL("files/ssl/page_with_refs.html"));
1537 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1538 CheckAuthenticationBrokenState(
1539 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1541 ProceedThroughInterstitial(tab);
1543 CheckAuthenticationBrokenState(
1544 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1545 // Now navigate to a ref in the page, the security state should not have
1546 // changed.
1547 ui_test_utils::NavigateToURL(browser(),
1548 https_server_expired_.GetURL("files/ssl/page_with_refs.html#jp"));
1550 CheckAuthenticationBrokenState(
1551 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1554 // Tests that closing a page that has a unsafe pop-up does not crash the
1555 // browser (bug #1966).
1556 // TODO(jcampan): http://crbug.com/2136 disabled because the popup is not
1557 // opened as it is not initiated by a user gesture.
1558 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) {
1559 ASSERT_TRUE(test_server()->Start());
1560 ASSERT_TRUE(https_server_expired_.Start());
1562 std::string replacement_path;
1563 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1564 "files/ssl/page_with_unsafe_popup.html",
1565 https_server_expired_.host_port_pair(),
1566 &replacement_path));
1568 ui_test_utils::NavigateToURL(browser(),
1569 test_server()->GetURL(replacement_path));
1571 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1572 // It is probably overkill to add a notification for a popup-opening, let's
1573 // just poll.
1574 for (int i = 0; i < 10; i++) {
1575 if (IsShowingWebContentsModalDialog())
1576 break;
1577 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1578 FROM_HERE, base::MessageLoop::QuitClosure(),
1579 base::TimeDelta::FromSeconds(1));
1580 content::RunMessageLoop();
1582 ASSERT_TRUE(IsShowingWebContentsModalDialog());
1584 // Let's add another tab to make sure the browser does not exit when we close
1585 // the first tab.
1586 GURL url = test_server()->GetURL("files/ssl/google.html");
1587 content::WindowedNotificationObserver observer(
1588 content::NOTIFICATION_LOAD_STOP,
1589 content::NotificationService::AllSources());
1590 chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED);
1591 observer.Wait();
1593 // Close the first tab.
1594 chrome::CloseWebContents(browser(), tab1, false);
1597 // Visit a page over bad https that is a redirect to a page with good https.
1598 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) {
1599 ASSERT_TRUE(https_server_.Start());
1600 ASSERT_TRUE(https_server_expired_.Start());
1602 GURL url1 = https_server_expired_.GetURL("server-redirect?");
1603 GURL url2 = https_server_.GetURL("files/ssl/google.html");
1605 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
1607 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1609 CheckAuthenticationBrokenState(
1610 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1612 ProceedThroughInterstitial(tab);
1614 // We have been redirected to the good page.
1615 CheckAuthenticatedState(tab, AuthState::NONE);
1618 // Flaky on Linux. http://crbug.com/368280.
1619 #if defined(OS_LINUX)
1620 #define MAYBE_TestRedirectGoodToBadHTTPS DISABLED_TestRedirectGoodToBadHTTPS
1621 #else
1622 #define MAYBE_TestRedirectGoodToBadHTTPS TestRedirectGoodToBadHTTPS
1623 #endif
1625 // Visit a page over good https that is a redirect to a page with bad https.
1626 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectGoodToBadHTTPS) {
1627 ASSERT_TRUE(https_server_.Start());
1628 ASSERT_TRUE(https_server_expired_.Start());
1630 GURL url1 = https_server_.GetURL("server-redirect?");
1631 GURL url2 = https_server_expired_.GetURL("files/ssl/google.html");
1632 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
1634 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1635 CheckAuthenticationBrokenState(
1636 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1638 ProceedThroughInterstitial(tab);
1640 CheckAuthenticationBrokenState(
1641 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1644 // Visit a page over http that is a redirect to a page with good HTTPS.
1645 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) {
1646 ASSERT_TRUE(test_server()->Start());
1647 ASSERT_TRUE(https_server_.Start());
1649 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1651 // HTTP redirects to good HTTPS.
1652 GURL http_url = test_server()->GetURL("server-redirect?");
1653 GURL good_https_url =
1654 https_server_.GetURL("files/ssl/google.html");
1656 ui_test_utils::NavigateToURL(browser(),
1657 GURL(http_url.spec() + good_https_url.spec()));
1658 CheckAuthenticatedState(tab, AuthState::NONE);
1661 // Flaky on Linux. http://crbug.com/368280.
1662 #if defined(OS_LINUX)
1663 #define MAYBE_TestRedirectHTTPToBadHTTPS DISABLED_TestRedirectHTTPToBadHTTPS
1664 #else
1665 #define MAYBE_TestRedirectHTTPToBadHTTPS TestRedirectHTTPToBadHTTPS
1666 #endif
1668 // Visit a page over http that is a redirect to a page with bad HTTPS.
1669 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectHTTPToBadHTTPS) {
1670 ASSERT_TRUE(test_server()->Start());
1671 ASSERT_TRUE(https_server_expired_.Start());
1673 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1675 GURL http_url = test_server()->GetURL("server-redirect?");
1676 GURL bad_https_url =
1677 https_server_expired_.GetURL("files/ssl/google.html");
1678 ui_test_utils::NavigateToURL(browser(),
1679 GURL(http_url.spec() + bad_https_url.spec()));
1680 CheckAuthenticationBrokenState(
1681 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1683 ProceedThroughInterstitial(tab);
1685 CheckAuthenticationBrokenState(
1686 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1689 // Visit a page over https that is a redirect to a page with http (to make sure
1690 // we don't keep the secure state).
1691 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) {
1692 ASSERT_TRUE(test_server()->Start());
1693 ASSERT_TRUE(https_server_.Start());
1695 GURL https_url = https_server_.GetURL("server-redirect?");
1696 GURL http_url = test_server()->GetURL("files/ssl/google.html");
1698 ui_test_utils::NavigateToURL(browser(),
1699 GURL(https_url.spec() + http_url.spec()));
1700 CheckUnauthenticatedState(
1701 browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE);
1704 // Visits a page to which we could not connect (bad port) over http and https
1705 // and make sure the security style is correct.
1706 IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) {
1707 ui_test_utils::NavigateToURL(browser(), GURL("http://localhost:17"));
1708 CheckUnauthenticatedState(
1709 browser()->tab_strip_model()->GetActiveWebContents(),
1710 AuthState::SHOWING_ERROR);
1712 // Same thing over HTTPS.
1713 ui_test_utils::NavigateToURL(browser(), GURL("https://localhost:17"));
1714 CheckUnauthenticatedState(
1715 browser()->tab_strip_model()->GetActiveWebContents(),
1716 AuthState::SHOWING_ERROR);
1720 // Frame navigation
1723 // From a good HTTPS top frame:
1724 // - navigate to an OK HTTPS frame
1725 // - navigate to a bad HTTPS (expect unsafe content and filtered frame), then
1726 // back
1727 // - navigate to HTTP (expect insecure content), then back
1728 IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) {
1729 ASSERT_TRUE(test_server()->Start());
1730 ASSERT_TRUE(https_server_.Start());
1731 ASSERT_TRUE(https_server_expired_.Start());
1733 std::string top_frame_path;
1734 ASSERT_TRUE(GetTopFramePath(*test_server(),
1735 https_server_,
1736 https_server_expired_,
1737 &top_frame_path));
1739 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1740 ui_test_utils::NavigateToURL(browser(),
1741 https_server_.GetURL(top_frame_path));
1743 CheckAuthenticatedState(tab, AuthState::NONE);
1745 bool success = false;
1746 // Now navigate inside the frame.
1748 content::WindowedNotificationObserver observer(
1749 content::NOTIFICATION_LOAD_STOP,
1750 content::Source<NavigationController>(&tab->GetController()));
1751 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1752 tab,
1753 "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1754 &success));
1755 ASSERT_TRUE(success);
1756 observer.Wait();
1759 // We should still be fine.
1760 CheckAuthenticatedState(tab, AuthState::NONE);
1762 // Now let's hit a bad page.
1764 content::WindowedNotificationObserver observer(
1765 content::NOTIFICATION_LOAD_STOP,
1766 content::Source<NavigationController>(&tab->GetController()));
1767 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1768 tab,
1769 "window.domAutomationController.send(clickLink('badHTTPSLink'));",
1770 &success));
1771 ASSERT_TRUE(success);
1772 observer.Wait();
1775 // The security style should still be secure.
1776 CheckAuthenticatedState(tab, AuthState::NONE);
1778 // And the frame should be blocked.
1779 bool is_content_evil = true;
1780 content::RenderFrameHost* content_frame = content::FrameMatchingPredicate(
1781 tab, base::Bind(&content::FrameMatchesName, "contentFrame"));
1782 std::string is_evil_js("window.domAutomationController.send("
1783 "document.getElementById('evilDiv') != null);");
1784 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame,
1785 is_evil_js,
1786 &is_content_evil));
1787 EXPECT_FALSE(is_content_evil);
1789 // Now go back, our state should still be OK.
1791 content::WindowedNotificationObserver observer(
1792 content::NOTIFICATION_LOAD_STOP,
1793 content::Source<NavigationController>(&tab->GetController()));
1794 tab->GetController().GoBack();
1795 observer.Wait();
1797 CheckAuthenticatedState(tab, AuthState::NONE);
1799 // Navigate to a page served over HTTP.
1801 content::WindowedNotificationObserver observer(
1802 content::NOTIFICATION_LOAD_STOP,
1803 content::Source<NavigationController>(&tab->GetController()));
1804 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1805 tab,
1806 "window.domAutomationController.send(clickLink('HTTPLink'));",
1807 &success));
1808 ASSERT_TRUE(success);
1809 observer.Wait();
1812 // Our state should be unathenticated (in the ran mixed script sense)
1813 CheckAuthenticationBrokenState(
1814 tab,
1815 CertError::NONE,
1816 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1818 // Go back, our state should be unchanged.
1820 content::WindowedNotificationObserver observer(
1821 content::NOTIFICATION_LOAD_STOP,
1822 content::Source<NavigationController>(&tab->GetController()));
1823 tab->GetController().GoBack();
1824 observer.Wait();
1827 CheckAuthenticationBrokenState(
1828 tab,
1829 CertError::NONE,
1830 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1833 // From a bad HTTPS top frame:
1834 // - navigate to an OK HTTPS frame (expected to be still authentication broken).
1835 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadFrameNavigation) {
1836 ASSERT_TRUE(https_server_.Start());
1837 ASSERT_TRUE(https_server_expired_.Start());
1839 std::string top_frame_path;
1840 ASSERT_TRUE(GetTopFramePath(*test_server(),
1841 https_server_,
1842 https_server_expired_,
1843 &top_frame_path));
1845 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1846 ui_test_utils::NavigateToURL(browser(),
1847 https_server_expired_.GetURL(top_frame_path));
1848 CheckAuthenticationBrokenState(
1849 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1851 ProceedThroughInterstitial(tab);
1853 // Navigate to a good frame.
1854 bool success = false;
1855 content::WindowedNotificationObserver observer(
1856 content::NOTIFICATION_LOAD_STOP,
1857 content::Source<NavigationController>(&tab->GetController()));
1858 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1859 tab,
1860 "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1861 &success));
1862 ASSERT_TRUE(success);
1863 observer.Wait();
1865 // We should still be authentication broken.
1866 CheckAuthenticationBrokenState(
1867 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1870 // From an HTTP top frame, navigate to good and bad HTTPS (security state should
1871 // stay unauthenticated).
1872 // Disabled, flakily exceeds test timeout, http://crbug.com/43437.
1873 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestUnauthenticatedFrameNavigation) {
1874 ASSERT_TRUE(test_server()->Start());
1875 ASSERT_TRUE(https_server_.Start());
1876 ASSERT_TRUE(https_server_expired_.Start());
1878 std::string top_frame_path;
1879 ASSERT_TRUE(GetTopFramePath(*test_server(),
1880 https_server_,
1881 https_server_expired_,
1882 &top_frame_path));
1884 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1885 ui_test_utils::NavigateToURL(browser(),
1886 test_server()->GetURL(top_frame_path));
1887 CheckUnauthenticatedState(tab, AuthState::NONE);
1889 // Now navigate inside the frame to a secure HTTPS frame.
1891 bool success = false;
1892 content::WindowedNotificationObserver observer(
1893 content::NOTIFICATION_LOAD_STOP,
1894 content::Source<NavigationController>(&tab->GetController()));
1895 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1896 tab,
1897 "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1898 &success));
1899 ASSERT_TRUE(success);
1900 observer.Wait();
1903 // We should still be unauthenticated.
1904 CheckUnauthenticatedState(tab, AuthState::NONE);
1906 // Now navigate to a bad HTTPS frame.
1908 bool success = false;
1909 content::WindowedNotificationObserver observer(
1910 content::NOTIFICATION_LOAD_STOP,
1911 content::Source<NavigationController>(&tab->GetController()));
1912 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1913 tab,
1914 "window.domAutomationController.send(clickLink('badHTTPSLink'));",
1915 &success));
1916 ASSERT_TRUE(success);
1917 observer.Wait();
1920 // State should not have changed.
1921 CheckUnauthenticatedState(tab, AuthState::NONE);
1923 // And the frame should have been blocked (see bug #2316).
1924 bool is_content_evil = true;
1925 content::RenderFrameHost* content_frame = content::FrameMatchingPredicate(
1926 tab, base::Bind(&content::FrameMatchesName, "contentFrame"));
1927 std::string is_evil_js("window.domAutomationController.send("
1928 "document.getElementById('evilDiv') != null);");
1929 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame,
1930 is_evil_js,
1931 &is_content_evil));
1932 EXPECT_FALSE(is_content_evil);
1935 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerFiltered) {
1936 ASSERT_TRUE(https_server_.Start());
1937 ASSERT_TRUE(https_server_expired_.Start());
1939 // This page will spawn a Worker which will try to load content from
1940 // BadCertServer.
1941 std::string page_with_unsafe_worker_path;
1942 ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_,
1943 &page_with_unsafe_worker_path));
1944 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
1945 page_with_unsafe_worker_path));
1946 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1947 // Expect Worker not to load insecure content.
1948 CheckWorkerLoadResult(tab, false);
1949 // The bad content is filtered, expect the state to be authenticated.
1950 CheckAuthenticatedState(tab, AuthState::NONE);
1953 // This test, and the related test TestUnsafeContentsWithUserException, verify
1954 // that if unsafe content is loaded but the host of that unsafe content has a
1955 // user exception, the content runs and the security style remains
1956 // authenticated. This is not necessarily the behavior that should exist, but it
1957 // is verification that it does behave that way. See https://crbug.com/477868
1958 // for more inforamtion on this.
1959 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerWithUserException) {
1960 ASSERT_TRUE(https_server_.Start());
1961 // Note that it is necessary to user https_server_mismatched_ here over the
1962 // other invalid cert servers. This is because the test relies on the two
1963 // servers having different hosts since SSL exceptions are per-host, not per
1964 // origin, and https_server_mismatched_ uses 'localhost' rather than
1965 // '127.0.0.1'.
1966 ASSERT_TRUE(https_server_mismatched_.Start());
1968 // Navigate to an unsafe site. Proceed with interstitial page to indicate
1969 // the user approves the bad certificate.
1970 ui_test_utils::NavigateToURL(
1971 browser(), https_server_mismatched_.GetURL("files/ssl/blank_page.html"));
1972 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1973 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
1974 AuthState::SHOWING_INTERSTITIAL);
1975 ProceedThroughInterstitial(tab);
1976 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
1977 AuthState::NONE);
1979 // Navigate to safe page that has Worker loading unsafe content.
1980 // Expect content to load but be marked as auth broken due to running insecure
1981 // content.
1982 std::string page_with_unsafe_worker_path;
1983 ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_mismatched_,
1984 &page_with_unsafe_worker_path));
1985 ui_test_utils::NavigateToURL(
1986 browser(), https_server_.GetURL(page_with_unsafe_worker_path));
1987 CheckWorkerLoadResult(tab, true); // Worker loads insecure content
1988 CheckAuthenticatedState(tab, CertError::NONE);
1991 // Visits a page with unsafe content and makes sure that if a user exception to
1992 // the certificate error is present, the image is loaded and script executes.
1994 // See the comment above SSLUITest.TestUnsafeContentsInWorkerWithUserException
1995 // for a discussion about the desired behavior.
1996 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsWithUserException) {
1997 ASSERT_TRUE(https_server_.Start());
1998 // Note that it is necessary to user https_server_mismatched_ here over the
1999 // other invalid cert servers. This is because the test relies on the two
2000 // servers having different hosts since SSL exceptions are per-host, not per
2001 // origin, and https_server_mismatched_ uses 'localhost' rather than
2002 // '127.0.0.1'.
2003 ASSERT_TRUE(https_server_mismatched_.Start());
2005 // Navigate to an unsafe site. Proceed with interstitial page to indicate
2006 // the user approves the bad certificate.
2007 ui_test_utils::NavigateToURL(
2008 browser(), https_server_mismatched_.GetURL("files/ssl/blank_page.html"));
2009 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2010 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
2011 AuthState::SHOWING_INTERSTITIAL);
2012 ProceedThroughInterstitial(tab);
2013 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
2014 AuthState::NONE);
2016 std::string replacement_path;
2017 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2018 "files/ssl/page_with_unsafe_contents.html",
2019 https_server_mismatched_.host_port_pair(), &replacement_path));
2020 ui_test_utils::NavigateToURL(browser(),
2021 https_server_.GetURL(replacement_path));
2023 // When the bad content is filtered, the state is expected to be
2024 // authenticated.
2025 CheckAuthenticatedState(tab, AuthState::NONE);
2027 int img_width;
2028 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
2029 tab, "window.domAutomationController.send(ImageWidth());", &img_width));
2030 // In order to check that the image was loaded, we check its width.
2031 // The actual image (Google logo) is 114 pixels wide, so we assume a good
2032 // image is greater than 100.
2033 EXPECT_GT(img_width, 100);
2035 bool js_result = false;
2036 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
2037 tab, "window.domAutomationController.send(IsFooSet());", &js_result));
2038 EXPECT_TRUE(js_result);
2039 CheckAuthenticatedState(tab, CertError::NONE);
2042 // Test that when the browser blocks displaying insecure content (images), the
2043 // indicator shows a secure page, because the blocking made the otherwise
2044 // unsafe page safe (the notification of this state is handled by other means).
2045 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureImage) {
2046 ASSERT_TRUE(test_server()->Start());
2047 ASSERT_TRUE(https_server_.Start());
2049 std::string replacement_path;
2050 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2051 "files/ssl/page_displays_insecure_content.html",
2052 test_server()->host_port_pair(),
2053 &replacement_path));
2055 ui_test_utils::NavigateToURL(browser(),
2056 https_server_.GetURL(replacement_path));
2058 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
2059 AuthState::NONE);
2062 // Test that when the browser blocks displaying insecure content (iframes), the
2063 // indicator shows a secure page, because the blocking made the otherwise
2064 // unsafe page safe (the notification of this state is handled by other means)
2065 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureIframe) {
2066 ASSERT_TRUE(test_server()->Start());
2067 ASSERT_TRUE(https_server_.Start());
2069 std::string replacement_path;
2070 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2071 "files/ssl/page_displays_insecure_iframe.html",
2072 test_server()->host_port_pair(),
2073 &replacement_path));
2075 ui_test_utils::NavigateToURL(browser(),
2076 https_server_.GetURL(replacement_path));
2078 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
2079 AuthState::NONE);
2082 // Test that when the browser blocks running insecure content, the
2083 // indicator shows a secure page, because the blocking made the otherwise
2084 // unsafe page safe (the notification of this state is handled by other means).
2085 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockRunningInsecureContent) {
2086 ASSERT_TRUE(test_server()->Start());
2087 ASSERT_TRUE(https_server_.Start());
2089 std::string replacement_path;
2090 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2091 "files/ssl/page_runs_insecure_content.html",
2092 test_server()->host_port_pair(),
2093 &replacement_path));
2095 ui_test_utils::NavigateToURL(browser(),
2096 https_server_.GetURL(replacement_path));
2098 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
2099 AuthState::NONE);
2102 // Visit a page and establish a WebSocket connection over bad https with
2103 // --ignore-certificate-errors. The connection should be established without
2104 // interstitial page showing.
2105 IN_PROC_BROWSER_TEST_F(SSLUITestIgnoreCertErrors, TestWSS) {
2106 ASSERT_TRUE(test_server()->Start());
2107 ASSERT_TRUE(wss_server_expired_.Start());
2109 // Setup page title observer.
2110 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2111 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
2112 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
2114 // Visit bad HTTPS page.
2115 GURL::Replacements replacements;
2116 replacements.SetSchemeStr("https");
2117 ui_test_utils::NavigateToURL(
2118 browser(),
2119 wss_server_expired_.GetURL(
2120 "connect_check.html").ReplaceComponents(replacements));
2122 // We shouldn't have an interstitial page showing here.
2124 // Test page run a WebSocket wss connection test. The result will be shown
2125 // as page title.
2126 const base::string16 result = watcher.WaitAndGetTitle();
2127 EXPECT_TRUE(base::LowerCaseEqualsASCII(result, "pass"));
2130 // Verifies that the interstitial can proceed, even if JavaScript is disabled.
2131 // http://crbug.com/322948
2132 #if defined(OS_LINUX)
2133 // flaky http://crbug.com/396458
2134 #define MAYBE_TestInterstitialJavaScriptProceeds \
2135 DISABLED_TestInterstitialJavaScriptProceeds
2136 #else
2137 #define MAYBE_TestInterstitialJavaScriptProceeds \
2138 TestInterstitialJavaScriptProceeds
2139 #endif
2140 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestInterstitialJavaScriptProceeds) {
2141 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
2142 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK);
2144 ASSERT_TRUE(https_server_expired_.Start());
2145 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2146 ui_test_utils::NavigateToURL(browser(),
2147 https_server_expired_.GetURL("files/ssl/google.html"));
2148 CheckAuthenticationBrokenState(
2149 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
2151 content::WindowedNotificationObserver observer(
2152 content::NOTIFICATION_LOAD_STOP,
2153 content::Source<NavigationController>(&tab->GetController()));
2154 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
2155 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
2156 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
2157 content::RenderViewHost* interstitial_rvh =
2158 interstitial_page->GetMainFrame()->GetRenderViewHost();
2159 int result = -1;
2160 std::string javascript = base::StringPrintf(
2161 "window.domAutomationController.send(%d);",
2162 SecurityInterstitialPage::CMD_PROCEED);
2163 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
2164 interstitial_rvh, javascript, &result));
2165 // The above will hang without the fix.
2166 EXPECT_EQ(1, result);
2167 observer.Wait();
2168 CheckAuthenticationBrokenState(
2169 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
2172 // Verifies that the interstitial can go back, even if JavaScript is disabled.
2173 // http://crbug.com/322948
2174 IN_PROC_BROWSER_TEST_F(SSLUITest, TestInterstitialJavaScriptGoesBack) {
2175 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
2176 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK);
2178 ASSERT_TRUE(https_server_expired_.Start());
2179 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2180 ui_test_utils::NavigateToURL(browser(),
2181 https_server_expired_.GetURL("files/ssl/google.html"));
2182 CheckAuthenticationBrokenState(
2183 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
2185 content::WindowedNotificationObserver observer(
2186 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
2187 content::NotificationService::AllSources());
2188 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
2189 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
2190 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
2191 content::RenderViewHost* interstitial_rvh =
2192 interstitial_page->GetMainFrame()->GetRenderViewHost();
2193 int result = -1;
2194 std::string javascript = base::StringPrintf(
2195 "window.domAutomationController.send(%d);",
2196 SecurityInterstitialPage::CMD_DONT_PROCEED);
2197 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
2198 interstitial_rvh, javascript, &result));
2199 // The above will hang without the fix.
2200 EXPECT_EQ(0, result);
2201 observer.Wait();
2202 EXPECT_EQ("about:blank", tab->GetVisibleURL().spec());
2205 // Verifies that switching tabs, while showing interstitial page, will not
2206 // affect the visibility of the interestitial.
2207 // https://crbug.com/381439
2208 IN_PROC_BROWSER_TEST_F(SSLUITest, InterstitialNotAffectedByHideShow) {
2209 ASSERT_TRUE(https_server_expired_.Start());
2210 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2211 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
2212 ui_test_utils::NavigateToURL(
2213 browser(), https_server_expired_.GetURL("files/ssl/google.html"));
2214 CheckAuthenticationBrokenState(
2215 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
2216 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
2218 AddTabAtIndex(0,
2219 https_server_.GetURL("files/ssl/google.html"),
2220 ui::PAGE_TRANSITION_TYPED);
2221 EXPECT_EQ(2, browser()->tab_strip_model()->count());
2222 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
2223 EXPECT_EQ(tab, browser()->tab_strip_model()->GetWebContentsAt(1));
2224 EXPECT_FALSE(tab->GetRenderWidgetHostView()->IsShowing());
2226 browser()->tab_strip_model()->ActivateTabAt(1, true);
2227 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
2230 // Verifies that if a bad certificate is seen for a host and the user proceeds
2231 // through the interstitial, the decision to proceed is initially remembered.
2232 // However, if this is followed by another visit, and a good certificate
2233 // is seen for the same host, the original exception is forgotten.
2234 IN_PROC_BROWSER_TEST_F(SSLUITest, BadCertFollowedByGoodCert) {
2235 // It is necessary to use |https_server_expired_| rather than
2236 // |https_server_mismatched| because the former shares a host with
2237 // |https_server_| and cert exceptions are per host.
2238 ASSERT_TRUE(https_server_expired_.Start());
2239 ASSERT_TRUE(https_server_.Start());
2241 std::string https_server_expired_host =
2242 https_server_.GetURL("files/ssl/google.html").host();
2243 std::string https_server_host =
2244 https_server_.GetURL("files/ssl/google.html").host();
2245 ASSERT_EQ(https_server_expired_host, https_server_host);
2247 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2249 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
2250 ChromeSSLHostStateDelegate* state =
2251 reinterpret_cast<ChromeSSLHostStateDelegate*>(
2252 profile->GetSSLHostStateDelegate());
2254 ui_test_utils::NavigateToURL(
2255 browser(), https_server_expired_.GetURL("files/ssl/google.html"));
2257 ProceedThroughInterstitial(tab);
2258 EXPECT_TRUE(state->HasAllowException(https_server_host));
2260 ui_test_utils::NavigateToURL(browser(),
2261 https_server_.GetURL("files/ssl/google.html"));
2262 ASSERT_FALSE(tab->GetInterstitialPage());
2263 EXPECT_FALSE(state->HasAllowException(https_server_host));
2266 class SSLBlockingPageIDNTest : public SecurityInterstitialIDNTest {
2267 protected:
2268 // SecurityInterstitialIDNTest implementation
2269 SecurityInterstitialPage* CreateInterstitial(
2270 content::WebContents* contents,
2271 const GURL& request_url) const override {
2272 net::SSLInfo ssl_info;
2273 ssl_info.cert = new net::X509Certificate(
2274 request_url.host(), "CA", base::Time::Max(), base::Time::Max());
2275 return new SSLBlockingPage(
2276 contents, net::ERR_CERT_CONTAINS_ERRORS, ssl_info, request_url, 0,
2277 base::Time::NowFromSystemTime(), nullptr, base::Callback<void(bool)>());
2281 IN_PROC_BROWSER_TEST_F(SSLBlockingPageIDNTest, SSLBlockingPageDecodesIDN) {
2282 EXPECT_TRUE(VerifyIDNDecoded());
2285 IN_PROC_BROWSER_TEST_F(CertVerifierBrowserTest, MockCertVerifierSmokeTest) {
2286 net::SpawnedTestServer https_server(
2287 net::SpawnedTestServer::TYPE_HTTPS,
2288 net::SpawnedTestServer::SSLOptions(
2289 net::SpawnedTestServer::SSLOptions::CERT_OK),
2290 base::FilePath(kDocRoot));
2291 ASSERT_TRUE(https_server.Start());
2293 mock_cert_verifier()->set_default_result(
2294 net::ERR_CERT_NAME_CONSTRAINT_VIOLATION);
2296 ui_test_utils::NavigateToURL(browser(),
2297 https_server.GetURL("files/ssl/google.html"));
2299 CheckSecurityState(browser()->tab_strip_model()->GetActiveWebContents(),
2300 net::CERT_STATUS_NAME_CONSTRAINT_VIOLATION,
2301 content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
2302 AuthState::SHOWING_INTERSTITIAL);
2305 // TODO(jcampan): more tests to do below.
2307 // Visit a page over https that contains a frame with a redirect.
2309 // XMLHttpRequest insecure content in synchronous mode.
2311 // XMLHttpRequest insecure content in asynchronous mode.
2313 // XMLHttpRequest over bad ssl in synchronous mode.
2315 // XMLHttpRequest over OK ssl in synchronous mode.