Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / ssl / ssl_browser_tests.cc
blob465d7ab86bd8de73a92f5a000bc5d94a97a1a100
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/test/simple_test_clock.h"
18 #include "base/thread_task_runner_handle.h"
19 #include "base/time/time.h"
20 #include "chrome/app/chrome_command_ids.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/ssl/bad_clock_blocking_page.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_reporting_test_utils.h"
29 #include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h"
30 #include "chrome/browser/ssl/common_name_mismatch_handler.h"
31 #include "chrome/browser/ssl/security_state_model.h"
32 #include "chrome/browser/ssl/ssl_blocking_page.h"
33 #include "chrome/browser/ssl/ssl_error_classification.h"
34 #include "chrome/browser/ssl/ssl_error_handler.h"
35 #include "chrome/browser/ui/browser.h"
36 #include "chrome/browser/ui/browser_commands.h"
37 #include "chrome/browser/ui/browser_navigator.h"
38 #include "chrome/browser/ui/browser_tabstrip.h"
39 #include "chrome/browser/ui/tabs/tab_strip_model.h"
40 #include "chrome/common/chrome_paths.h"
41 #include "chrome/common/chrome_switches.h"
42 #include "chrome/common/pref_names.h"
43 #include "chrome/test/base/in_process_browser_test.h"
44 #include "chrome/test/base/ui_test_utils.h"
45 #include "components/content_settings/core/browser/host_content_settings_map.h"
46 #include "components/security_interstitials/core/metrics_helper.h"
47 #include "components/variations/variations_associated_data.h"
48 #include "components/web_modal/web_contents_modal_dialog_manager.h"
49 #include "content/public/browser/browser_context.h"
50 #include "content/public/browser/interstitial_page.h"
51 #include "content/public/browser/navigation_controller.h"
52 #include "content/public/browser/navigation_entry.h"
53 #include "content/public/browser/notification_service.h"
54 #include "content/public/browser/render_frame_host.h"
55 #include "content/public/browser/render_view_host.h"
56 #include "content/public/browser/render_widget_host_view.h"
57 #include "content/public/browser/web_contents.h"
58 #include "content/public/browser/web_contents_observer.h"
59 #include "content/public/common/security_style.h"
60 #include "content/public/common/ssl_status.h"
61 #include "content/public/test/browser_test_utils.h"
62 #include "content/public/test/download_test_observer.h"
63 #include "content/public/test/test_navigation_observer.h"
64 #include "content/public/test/test_renderer_host.h"
65 #include "net/base/host_port_pair.h"
66 #include "net/base/net_errors.h"
67 #include "net/base/test_data_directory.h"
68 #include "net/cert/cert_status_flags.h"
69 #include "net/cert/mock_cert_verifier.h"
70 #include "net/cert/x509_certificate.h"
71 #include "net/dns/mock_host_resolver.h"
72 #include "net/ssl/ssl_info.h"
73 #include "net/test/cert_test_util.h"
74 #include "net/test/spawned_test_server/spawned_test_server.h"
75 #include "net/test/test_certificate_data.h"
76 #include "net/url_request/url_request_context.h"
78 #if defined(USE_NSS_CERTS)
79 #include "chrome/browser/net/nss_context.h"
80 #include "net/base/crypto_module.h"
81 #include "net/cert/nss_cert_database.h"
82 #endif // defined(USE_NSS_CERTS)
84 using base::ASCIIToUTF16;
85 using chrome_browser_interstitials::SecurityInterstitialIDNTest;
86 using content::InterstitialPage;
87 using content::NavigationController;
88 using content::NavigationEntry;
89 using content::SSLStatus;
90 using content::WebContents;
91 using web_modal::WebContentsModalDialogManager;
93 const base::FilePath::CharType kDocRoot[] =
94 FILE_PATH_LITERAL("chrome/test/data");
96 namespace {
98 enum ProceedDecision {
99 SSL_INTERSTITIAL_PROCEED,
100 SSL_INTERSTITIAL_DO_NOT_PROCEED
103 class ProvisionalLoadWaiter : public content::WebContentsObserver {
104 public:
105 explicit ProvisionalLoadWaiter(WebContents* tab)
106 : WebContentsObserver(tab), waiting_(false), seen_(false) {}
108 void Wait() {
109 if (seen_)
110 return;
112 waiting_ = true;
113 content::RunMessageLoop();
116 void DidFailProvisionalLoad(
117 content::RenderFrameHost* render_frame_host,
118 const GURL& validated_url,
119 int error_code,
120 const base::string16& error_description,
121 bool was_ignored_by_handler) override {
122 seen_ = true;
123 if (waiting_)
124 base::MessageLoopForUI::current()->Quit();
127 private:
128 bool waiting_;
129 bool seen_;
132 namespace AuthState {
134 enum AuthStateFlags {
135 NONE = 0,
136 DISPLAYED_INSECURE_CONTENT = 1 << 0,
137 RAN_INSECURE_CONTENT = 1 << 1,
138 SHOWING_INTERSTITIAL = 1 << 2,
139 SHOWING_ERROR = 1 << 3
142 void Check(const NavigationEntry& entry, int expected_authentication_state) {
143 if (expected_authentication_state == AuthState::SHOWING_ERROR) {
144 EXPECT_EQ(content::PAGE_TYPE_ERROR, entry.GetPageType());
145 } else {
146 EXPECT_EQ(
147 !!(expected_authentication_state & AuthState::SHOWING_INTERSTITIAL)
148 ? content::PAGE_TYPE_INTERSTITIAL
149 : content::PAGE_TYPE_NORMAL,
150 entry.GetPageType());
153 bool displayed_insecure_content =
154 !!(entry.GetSSL().content_status & SSLStatus::DISPLAYED_INSECURE_CONTENT);
155 EXPECT_EQ(
156 !!(expected_authentication_state & AuthState::DISPLAYED_INSECURE_CONTENT),
157 displayed_insecure_content);
159 bool ran_insecure_content =
160 !!(entry.GetSSL().content_status & SSLStatus::RAN_INSECURE_CONTENT);
161 EXPECT_EQ(!!(expected_authentication_state & AuthState::RAN_INSECURE_CONTENT),
162 ran_insecure_content);
165 } // namespace AuthState
167 namespace SecurityStyle {
169 void Check(const NavigationEntry& entry,
170 content::SecurityStyle expected_security_style) {
171 EXPECT_EQ(expected_security_style, entry.GetSSL().security_style);
174 } // namespace SecurityStyle
176 namespace CertError {
178 enum CertErrorFlags {
179 NONE = 0
182 void Check(const NavigationEntry& entry, net::CertStatus error) {
183 if (error) {
184 EXPECT_EQ(error, entry.GetSSL().cert_status & error);
185 net::CertStatus extra_cert_errors =
186 error ^ (entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS);
187 if (extra_cert_errors)
188 LOG(WARNING) << "Got unexpected cert error: " << extra_cert_errors;
189 } else {
190 EXPECT_EQ(0U, entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS);
194 } // namespace CertError
196 void CheckSecurityState(WebContents* tab,
197 net::CertStatus error,
198 content::SecurityStyle expected_security_style,
199 int expected_authentication_state) {
200 ASSERT_FALSE(tab->IsCrashed());
201 NavigationEntry* entry = tab->GetController().GetActiveEntry();
202 ASSERT_TRUE(entry);
203 CertError::Check(*entry, error);
204 SecurityStyle::Check(*entry, expected_security_style);
205 AuthState::Check(*entry, expected_authentication_state);
208 // This observer waits for the SSLErrorHandler to start an interstitial timer
209 // for the given web contents.
210 class SSLInterstitialTimerObserver {
211 public:
212 explicit SSLInterstitialTimerObserver(content::WebContents* web_contents)
213 : web_contents_(web_contents), message_loop_runner_(new base::RunLoop) {
214 callback_ = base::Bind(&SSLInterstitialTimerObserver::OnTimerStarted,
215 base::Unretained(this));
216 SSLErrorHandler::SetInterstitialTimerStartedCallbackForTest(&callback_);
219 ~SSLInterstitialTimerObserver() {
220 SSLErrorHandler::SetInterstitialTimerStartedCallbackForTest(nullptr);
223 // Waits until the interstitial delay timer in SSLErrorHandler is started.
224 void WaitForTimerStarted() { message_loop_runner_->Run(); }
226 private:
227 void OnTimerStarted(content::WebContents* web_contents) {
228 if (web_contents_ == web_contents)
229 message_loop_runner_->Quit();
232 const content::WebContents* web_contents_;
233 SSLErrorHandler::TimerStartedCallback callback_;
235 scoped_ptr<base::RunLoop> message_loop_runner_;
237 DISALLOW_COPY_AND_ASSIGN(SSLInterstitialTimerObserver);
240 } // namespace
242 class SSLUITest
243 : public certificate_reporting_test_utils::CertificateReportingTest {
244 public:
245 SSLUITest()
246 : https_server_(net::SpawnedTestServer::TYPE_HTTPS,
247 SSLOptions(SSLOptions::CERT_OK),
248 base::FilePath(kDocRoot)),
249 https_server_expired_(net::SpawnedTestServer::TYPE_HTTPS,
250 SSLOptions(SSLOptions::CERT_EXPIRED),
251 base::FilePath(kDocRoot)),
252 https_server_mismatched_(net::SpawnedTestServer::TYPE_HTTPS,
253 SSLOptions(SSLOptions::CERT_MISMATCHED_NAME),
254 base::FilePath(kDocRoot)),
255 wss_server_expired_(net::SpawnedTestServer::TYPE_WSS,
256 SSLOptions(SSLOptions::CERT_EXPIRED),
257 net::GetWebSocketTestDataDirectory()) {}
259 void SetUpCommandLine(base::CommandLine* command_line) override {
260 // Browser will both run and display insecure content.
261 command_line->AppendSwitch(switches::kAllowRunningInsecureContent);
262 // Use process-per-site so that navigating to a same-site page in a
263 // new tab will use the same process.
264 command_line->AppendSwitch(switches::kProcessPerSite);
267 void CheckAuthenticatedState(WebContents* tab,
268 int expected_authentication_state) {
269 CheckSecurityState(tab,
270 CertError::NONE,
271 content::SECURITY_STYLE_AUTHENTICATED,
272 expected_authentication_state);
275 void CheckUnauthenticatedState(WebContents* tab,
276 int expected_authentication_state) {
277 CheckSecurityState(tab,
278 CertError::NONE,
279 content::SECURITY_STYLE_UNAUTHENTICATED,
280 expected_authentication_state);
283 void CheckAuthenticationBrokenState(WebContents* tab,
284 net::CertStatus error,
285 int expected_authentication_state) {
286 CheckSecurityState(tab,
287 error,
288 content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
289 expected_authentication_state);
290 // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION doesn't lower the security style
291 // to SECURITY_STYLE_AUTHENTICATION_BROKEN.
292 ASSERT_NE(net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, error);
295 void CheckWorkerLoadResult(WebContents* tab, bool expected_load) {
296 // Workers are async and we don't have notifications for them passing
297 // messages since they do it between renderer and worker processes.
298 // So have a polling loop, check every 200ms, timeout at 30s.
299 const int kTimeoutMS = 200;
300 base::Time time_to_quit = base::Time::Now() +
301 base::TimeDelta::FromMilliseconds(30000);
303 while (base::Time::Now() < time_to_quit) {
304 bool worker_finished = false;
305 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
306 tab,
307 "window.domAutomationController.send(IsWorkerFinished());",
308 &worker_finished));
310 if (worker_finished)
311 break;
313 // Wait a bit.
314 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
315 FROM_HERE, base::MessageLoop::QuitClosure(),
316 base::TimeDelta::FromMilliseconds(kTimeoutMS));
317 content::RunMessageLoop();
320 bool actually_loaded_content = false;
321 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
322 tab,
323 "window.domAutomationController.send(IsContentLoaded());",
324 &actually_loaded_content));
325 EXPECT_EQ(expected_load, actually_loaded_content);
328 void ProceedThroughInterstitial(WebContents* tab) {
329 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
330 ASSERT_TRUE(interstitial_page);
331 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
332 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
333 content::WindowedNotificationObserver observer(
334 content::NOTIFICATION_LOAD_STOP,
335 content::Source<NavigationController>(&tab->GetController()));
336 interstitial_page->Proceed();
337 observer.Wait();
340 bool IsShowingWebContentsModalDialog() const {
341 return WebContentsModalDialogManager::FromWebContents(
342 browser()->tab_strip_model()->GetActiveWebContents())->
343 IsDialogActive();
346 static bool GetFilePathWithHostAndPortReplacement(
347 const std::string& original_file_path,
348 const net::HostPortPair& host_port_pair,
349 std::string* replacement_path) {
350 std::vector<net::SpawnedTestServer::StringPair> replacement_text;
351 replacement_text.push_back(
352 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
353 return net::SpawnedTestServer::GetFilePathWithReplacements(
354 original_file_path, replacement_text, replacement_path);
357 static bool GetTopFramePath(const net::SpawnedTestServer& http_server,
358 const net::SpawnedTestServer& good_https_server,
359 const net::SpawnedTestServer& bad_https_server,
360 std::string* top_frame_path) {
361 // The "frame_left.html" page contained in the top_frame.html page contains
362 // <a href>'s to three different servers. This sets up all of the
363 // replacement text to work with test servers which listen on ephemeral
364 // ports.
365 GURL http_url = http_server.GetURL("files/ssl/google.html");
366 GURL good_https_url = good_https_server.GetURL("files/ssl/google.html");
367 GURL bad_https_url = bad_https_server.GetURL(
368 "files/ssl/bad_iframe.html");
370 std::vector<net::SpawnedTestServer::StringPair> replacement_text_frame_left;
371 replacement_text_frame_left.push_back(
372 make_pair("REPLACE_WITH_HTTP_PAGE", http_url.spec()));
373 replacement_text_frame_left.push_back(
374 make_pair("REPLACE_WITH_GOOD_HTTPS_PAGE", good_https_url.spec()));
375 replacement_text_frame_left.push_back(
376 make_pair("REPLACE_WITH_BAD_HTTPS_PAGE", bad_https_url.spec()));
377 std::string frame_left_path;
378 if (!net::SpawnedTestServer::GetFilePathWithReplacements(
379 "frame_left.html",
380 replacement_text_frame_left,
381 &frame_left_path))
382 return false;
384 // Substitute the generated frame_left URL into the top_frame page.
385 std::vector<net::SpawnedTestServer::StringPair> replacement_text_top_frame;
386 replacement_text_top_frame.push_back(
387 make_pair("REPLACE_WITH_FRAME_LEFT_PATH", frame_left_path));
388 return net::SpawnedTestServer::GetFilePathWithReplacements(
389 "files/ssl/top_frame.html",
390 replacement_text_top_frame,
391 top_frame_path);
394 static bool GetPageWithUnsafeWorkerPath(
395 const net::SpawnedTestServer& https_server,
396 std::string* page_with_unsafe_worker_path) {
397 // Get the "imported.js" URL from the expired https server and
398 // substitute it into the unsafe_worker.js file.
399 GURL imported_js_url = https_server.GetURL("files/ssl/imported.js");
400 std::vector<net::SpawnedTestServer::StringPair>
401 replacement_text_for_unsafe_worker;
402 replacement_text_for_unsafe_worker.push_back(
403 make_pair("REPLACE_WITH_IMPORTED_JS_URL", imported_js_url.spec()));
404 std::string unsafe_worker_path;
405 if (!net::SpawnedTestServer::GetFilePathWithReplacements(
406 "unsafe_worker.js",
407 replacement_text_for_unsafe_worker,
408 &unsafe_worker_path))
409 return false;
411 // Now, substitute this into the page with unsafe worker.
412 std::vector<net::SpawnedTestServer::StringPair>
413 replacement_text_for_page_with_unsafe_worker;
414 replacement_text_for_page_with_unsafe_worker.push_back(
415 make_pair("REPLACE_WITH_UNSAFE_WORKER_PATH", unsafe_worker_path));
416 return net::SpawnedTestServer::GetFilePathWithReplacements(
417 "files/ssl/page_with_unsafe_worker.html",
418 replacement_text_for_page_with_unsafe_worker,
419 page_with_unsafe_worker_path);
422 // Helper function for testing invalid certificate chain reporting.
423 void TestBrokenHTTPSReporting(
424 certificate_reporting_test_utils::OptIn opt_in,
425 ProceedDecision proceed,
426 certificate_reporting_test_utils::ExpectReport expect_report,
427 Browser* browser) {
428 base::RunLoop run_loop;
429 ASSERT_TRUE(https_server_expired_.Start());
431 ASSERT_NO_FATAL_FAILURE(SetUpMockReporter());
433 // Opt in to sending reports for invalid certificate chains.
434 certificate_reporting_test_utils::SetCertReportingOptIn(browser, opt_in);
436 ui_test_utils::NavigateToURL(browser, https_server_expired_.GetURL("/"));
438 WebContents* tab = browser->tab_strip_model()->GetActiveWebContents();
439 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
440 AuthState::SHOWING_INTERSTITIAL);
442 scoped_ptr<SSLCertReporter> ssl_cert_reporter =
443 certificate_reporting_test_utils::SetUpMockSSLCertReporter(
444 &run_loop, expect_report);
446 SSLBlockingPage* interstitial_page = static_cast<SSLBlockingPage*>(
447 tab->GetInterstitialPage()->GetDelegateForTesting());
448 interstitial_page->SetSSLCertReporterForTesting(ssl_cert_reporter.Pass());
450 EXPECT_EQ(std::string(), GetLatestHostnameReported());
452 // Leave the interstitial (either by proceeding or going back)
453 if (proceed == SSL_INTERSTITIAL_PROCEED) {
454 ProceedThroughInterstitial(tab);
455 } else {
456 // Click "Take me back"
457 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
458 ASSERT_TRUE(interstitial_page);
459 interstitial_page->DontProceed();
462 if (expect_report ==
463 certificate_reporting_test_utils::CERT_REPORT_EXPECTED) {
464 // Check that the mock reporter received a request to send a report.
465 run_loop.Run();
466 EXPECT_EQ(https_server_expired_.GetURL("/").host(),
467 GetLatestHostnameReported());
468 } else {
469 EXPECT_EQ(std::string(), GetLatestHostnameReported());
473 net::SpawnedTestServer https_server_;
474 net::SpawnedTestServer https_server_expired_;
475 net::SpawnedTestServer https_server_mismatched_;
476 net::SpawnedTestServer wss_server_expired_;
478 private:
479 typedef net::SpawnedTestServer::SSLOptions SSLOptions;
481 DISALLOW_COPY_AND_ASSIGN(SSLUITest);
484 class SSLUITestBlock : public SSLUITest {
485 public:
486 SSLUITestBlock() : SSLUITest() {}
488 // Browser will neither run nor display insecure content.
489 void SetUpCommandLine(base::CommandLine* command_line) override {
490 command_line->AppendSwitch(switches::kNoDisplayingInsecureContent);
494 class SSLUITestIgnoreCertErrors : public SSLUITest {
495 public:
496 SSLUITestIgnoreCertErrors() : SSLUITest() {}
498 void SetUpCommandLine(base::CommandLine* command_line) override {
499 // Browser will ignore certificate errors.
500 command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
504 class SSLUITestIgnoreLocalhostCertErrors : public SSLUITest {
505 public:
506 SSLUITestIgnoreLocalhostCertErrors() : SSLUITest() {}
508 void SetUpCommandLine(base::CommandLine* command_line) override {
509 // Browser will ignore certificate errors on localhost.
510 command_line->AppendSwitch(switches::kAllowInsecureLocalhost);
514 class SSLUITestWithExtendedReporting : public SSLUITest {
515 public:
516 SSLUITestWithExtendedReporting() : SSLUITest() {}
519 // Visits a regular page over http.
520 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTP) {
521 ASSERT_TRUE(test_server()->Start());
523 ui_test_utils::NavigateToURL(browser(),
524 test_server()->GetURL("files/ssl/google.html"));
526 CheckUnauthenticatedState(
527 browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE);
530 // Visits a page over http which includes broken https resources (status should
531 // be OK).
532 // TODO(jcampan): test that bad HTTPS content is blocked (otherwise we'll give
533 // the secure cookies away!).
534 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) {
535 ASSERT_TRUE(test_server()->Start());
536 ASSERT_TRUE(https_server_expired_.Start());
538 std::string replacement_path;
539 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
540 "files/ssl/page_with_unsafe_contents.html",
541 https_server_expired_.host_port_pair(),
542 &replacement_path));
544 ui_test_utils::NavigateToURL(
545 browser(), test_server()->GetURL(replacement_path));
547 CheckUnauthenticatedState(
548 browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE);
551 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSWithInsecureContent) {
552 ASSERT_TRUE(test_server()->Start());
553 ASSERT_TRUE(https_server_expired_.Start());
555 std::string replacement_path;
556 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
557 "files/ssl/page_displays_insecure_content.html",
558 test_server()->host_port_pair(),
559 &replacement_path));
561 ui_test_utils::NavigateToURL(browser(),
562 https_server_expired_.GetURL(replacement_path));
564 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
565 CheckAuthenticationBrokenState(
566 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
568 ProceedThroughInterstitial(tab);
570 CheckAuthenticationBrokenState(tab,
571 net::CERT_STATUS_DATE_INVALID,
572 AuthState::DISPLAYED_INSECURE_CONTENT);
575 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSMetricsReporting_Proceed) {
576 ASSERT_TRUE(https_server_expired_.Start());
577 ASSERT_NO_FATAL_FAILURE(SetUpMockReporter());
578 base::HistogramTester histograms;
579 const std::string decision_histogram =
580 "interstitial.ssl_overridable.decision";
581 const std::string interaction_histogram =
582 "interstitial.ssl_overridable.interaction";
584 // Histograms should start off empty.
585 histograms.ExpectTotalCount(decision_histogram, 0);
586 histograms.ExpectTotalCount(interaction_histogram, 0);
588 // After navigating to the page, the totals should be set.
589 ui_test_utils::NavigateToURL(browser(), https_server_expired_.GetURL("/"));
590 content::WaitForInterstitialAttach(
591 browser()->tab_strip_model()->GetActiveWebContents());
592 histograms.ExpectTotalCount(decision_histogram, 1);
593 histograms.ExpectBucketCount(decision_histogram,
594 security_interstitials::MetricsHelper::SHOW, 1);
595 histograms.ExpectTotalCount(interaction_histogram, 1);
596 histograms.ExpectBucketCount(
597 interaction_histogram,
598 security_interstitials::MetricsHelper::TOTAL_VISITS, 1);
600 // Decision should be recorded.
601 ProceedThroughInterstitial(
602 browser()->tab_strip_model()->GetActiveWebContents());
603 histograms.ExpectTotalCount(decision_histogram, 2);
604 histograms.ExpectBucketCount(
605 decision_histogram, security_interstitials::MetricsHelper::PROCEED, 1);
606 histograms.ExpectTotalCount(interaction_histogram, 1);
607 histograms.ExpectBucketCount(
608 interaction_histogram,
609 security_interstitials::MetricsHelper::TOTAL_VISITS, 1);
612 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSMetricsReporting_DontProceed) {
613 ASSERT_TRUE(https_server_expired_.Start());
614 ASSERT_NO_FATAL_FAILURE(SetUpMockReporter());
615 base::HistogramTester histograms;
616 const std::string decision_histogram =
617 "interstitial.ssl_overridable.decision";
618 const std::string interaction_histogram =
619 "interstitial.ssl_overridable.interaction";
621 // Histograms should start off empty.
622 histograms.ExpectTotalCount(decision_histogram, 0);
623 histograms.ExpectTotalCount(interaction_histogram, 0);
625 // After navigating to the page, the totals should be set.
626 ui_test_utils::NavigateToURL(browser(), https_server_expired_.GetURL("/"));
627 content::WaitForInterstitialAttach(
628 browser()->tab_strip_model()->GetActiveWebContents());
629 histograms.ExpectTotalCount(decision_histogram, 1);
630 histograms.ExpectBucketCount(decision_histogram,
631 security_interstitials::MetricsHelper::SHOW, 1);
632 histograms.ExpectTotalCount(interaction_histogram, 1);
633 histograms.ExpectBucketCount(
634 interaction_histogram,
635 security_interstitials::MetricsHelper::TOTAL_VISITS, 1);
637 // Decision should be recorded.
638 InterstitialPage* interstitial_page = browser()
639 ->tab_strip_model()
640 ->GetActiveWebContents()
641 ->GetInterstitialPage();
642 interstitial_page->DontProceed();
643 histograms.ExpectTotalCount(decision_histogram, 2);
644 histograms.ExpectBucketCount(
645 decision_histogram, security_interstitials::MetricsHelper::DONT_PROCEED,
647 histograms.ExpectTotalCount(interaction_histogram, 1);
648 histograms.ExpectBucketCount(
649 interaction_histogram,
650 security_interstitials::MetricsHelper::TOTAL_VISITS, 1);
653 // http://crbug.com/91745
654 #if defined(OS_CHROMEOS)
655 #define MAYBE_TestOKHTTPS DISABLED_TestOKHTTPS
656 #else
657 #define MAYBE_TestOKHTTPS TestOKHTTPS
658 #endif
660 // Visits a page over OK https:
661 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestOKHTTPS) {
662 ASSERT_TRUE(https_server_.Start());
664 ui_test_utils::NavigateToURL(browser(),
665 https_server_.GetURL("files/ssl/google.html"));
667 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
668 AuthState::NONE);
671 // Visits a page with https error and proceed:
672 #if defined(OS_LINUX)
673 // flaky http://crbug.com/396462
674 #define MAYBE_TestHTTPSExpiredCertAndProceed \
675 DISABLED_TestHTTPSExpiredCertAndProceed
676 #else
677 #define MAYBE_TestHTTPSExpiredCertAndProceed TestHTTPSExpiredCertAndProceed
678 #endif
679 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndProceed) {
680 ASSERT_TRUE(https_server_expired_.Start());
682 ui_test_utils::NavigateToURL(browser(),
683 https_server_expired_.GetURL("files/ssl/google.html"));
685 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
686 CheckAuthenticationBrokenState(
687 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
689 ProceedThroughInterstitial(tab);
691 CheckAuthenticationBrokenState(
692 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
695 #ifndef NEDBUG
696 // Flaky on Windows debug (http://crbug.com/280537).
697 #define MAYBE_TestHTTPSExpiredCertAndDontProceed \
698 DISABLED_TestHTTPSExpiredCertAndDontProceed
699 #else
700 #define MAYBE_TestHTTPSExpiredCertAndDontProceed \
701 TestHTTPSExpiredCertAndDontProceed
702 #endif
704 // Visits a page with https error and don't proceed (and ensure we can still
705 // navigate at that point):
706 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndDontProceed) {
707 ASSERT_TRUE(test_server()->Start());
708 ASSERT_TRUE(https_server_.Start());
709 ASSERT_TRUE(https_server_expired_.Start());
711 // First navigate to an OK page.
712 ui_test_utils::NavigateToURL(browser(),
713 https_server_.GetURL("files/ssl/google.html"));
715 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
716 NavigationEntry* entry = tab->GetController().GetActiveEntry();
717 ASSERT_TRUE(entry);
719 GURL cross_site_url =
720 https_server_expired_.GetURL("files/ssl/google.html");
721 // Change the host name from 127.0.0.1 to localhost so it triggers a
722 // cross-site navigation so we can test http://crbug.com/5800 is gone.
723 ASSERT_EQ("127.0.0.1", cross_site_url.host());
724 GURL::Replacements replacements;
725 replacements.SetHostStr("localhost");
726 cross_site_url = cross_site_url.ReplaceComponents(replacements);
728 // Now go to a bad HTTPS page.
729 ui_test_utils::NavigateToURL(browser(), cross_site_url);
731 // An interstitial should be showing.
732 CheckAuthenticationBrokenState(tab,
733 net::CERT_STATUS_COMMON_NAME_INVALID,
734 AuthState::SHOWING_INTERSTITIAL);
736 // Simulate user clicking "Take me back".
737 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
738 ASSERT_TRUE(interstitial_page);
739 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
740 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
741 interstitial_page->DontProceed();
743 // We should be back to the original good page.
744 CheckAuthenticatedState(tab, AuthState::NONE);
746 // Try to navigate to a new page. (to make sure bug 5800 is fixed).
747 ui_test_utils::NavigateToURL(browser(),
748 test_server()->GetURL("files/ssl/google.html"));
749 CheckUnauthenticatedState(tab, AuthState::NONE);
752 // Test that localhost pages don't show an interstitial.
753 IN_PROC_BROWSER_TEST_F(SSLUITestIgnoreLocalhostCertErrors,
754 TestNoInterstitialOnLocalhost) {
755 ASSERT_TRUE(https_server_.Start());
757 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
759 // Navigate to a localhost page.
760 GURL url = https_server_.GetURL("files/ssl/page_with_subresource.html");
761 GURL::Replacements replacements;
762 std::string new_host("localhost");
763 replacements.SetHostStr(new_host);
764 url = url.ReplaceComponents(replacements);
766 ui_test_utils::NavigateToURL(browser(), url);
768 // We should see no interstitial, but we should have an error
769 // (red-crossed-out-https) in the URL bar.
770 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
771 AuthState::NONE);
773 // We should see that the script tag in the page loaded and ran (and
774 // wasn't blocked by the certificate error).
775 base::string16 title;
776 base::string16 expected_title = base::ASCIIToUTF16("This script has loaded");
777 ui_test_utils::GetCurrentTabTitle(browser(), &title);
778 EXPECT_EQ(title, expected_title);
781 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSErrorCausedByClock) {
782 ASSERT_TRUE(https_server_expired_.Start());
784 // Set up the build and current clock times to be more than a year apart.
785 scoped_ptr<base::SimpleTestClock> mock_clock(new base::SimpleTestClock());
786 mock_clock->SetNow(base::Time::NowFromSystemTime());
787 mock_clock->Advance(base::TimeDelta::FromDays(367));
788 SSLErrorHandler::SetClockForTest(mock_clock.get());
789 SSLErrorClassification::SetBuildTimeForTesting(
790 base::Time::NowFromSystemTime());
792 ui_test_utils::NavigateToURL(browser(), https_server_expired_.GetURL("/"));
793 WebContents* clock_tab = browser()->tab_strip_model()->GetActiveWebContents();
794 content::WaitForInterstitialAttach(clock_tab);
795 InterstitialPage* clock_interstitial = clock_tab->GetInterstitialPage();
796 ASSERT_TRUE(clock_interstitial);
797 EXPECT_EQ(BadClockBlockingPage::kTypeForTesting,
798 clock_interstitial->GetDelegateForTesting()->GetTypeForTesting());
801 // Visits a page with https error and then goes back using Browser::GoBack.
802 IN_PROC_BROWSER_TEST_F(SSLUITest,
803 TestHTTPSExpiredCertAndGoBackViaButton) {
804 ASSERT_TRUE(test_server()->Start());
805 ASSERT_TRUE(https_server_expired_.Start());
807 // First navigate to an HTTP page.
808 ui_test_utils::NavigateToURL(browser(),
809 test_server()->GetURL("files/ssl/google.html"));
810 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
811 NavigationEntry* entry = tab->GetController().GetActiveEntry();
812 ASSERT_TRUE(entry);
814 // Now go to a bad HTTPS page that shows an interstitial.
815 ui_test_utils::NavigateToURL(browser(),
816 https_server_expired_.GetURL("files/ssl/google.html"));
817 CheckAuthenticationBrokenState(
818 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
820 ProvisionalLoadWaiter load_failed_observer(tab);
822 // Simulate user clicking on back button (crbug.com/39248).
823 chrome::GoBack(browser(), CURRENT_TAB);
825 // Wait until we hear the load failure, and make sure we haven't swapped out
826 // the previous page. Prevents regression of http://crbug.com/82667.
827 // TODO(creis/nick): Move the swapped-out part of this test into content
828 // and remove IsRenderViewHostSwappedOut from the public API.
829 load_failed_observer.Wait();
830 EXPECT_FALSE(content::RenderFrameHostTester::IsRenderFrameHostSwappedOut(
831 tab->GetMainFrame()));
833 // We should be back at the original good page.
834 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()->
835 GetInterstitialPage());
836 CheckUnauthenticatedState(tab, AuthState::NONE);
839 // Visits a page with https error and then goes back using GoToOffset.
840 // Disabled because its flaky: http://crbug.com/40932, http://crbug.com/43575.
841 IN_PROC_BROWSER_TEST_F(SSLUITest,
842 TestHTTPSExpiredCertAndGoBackViaMenu) {
843 ASSERT_TRUE(test_server()->Start());
844 ASSERT_TRUE(https_server_expired_.Start());
846 // First navigate to an HTTP page.
847 ui_test_utils::NavigateToURL(browser(),
848 test_server()->GetURL("files/ssl/google.html"));
849 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
850 NavigationEntry* entry = tab->GetController().GetActiveEntry();
851 ASSERT_TRUE(entry);
853 // Now go to a bad HTTPS page that shows an interstitial.
854 ui_test_utils::NavigateToURL(browser(),
855 https_server_expired_.GetURL("files/ssl/google.html"));
856 CheckAuthenticationBrokenState(
857 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
859 // Simulate user clicking and holding on back button (crbug.com/37215).
860 tab->GetController().GoToOffset(-1);
862 // We should be back at the original good page.
863 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()->
864 GetInterstitialPage());
865 CheckUnauthenticatedState(tab, AuthState::NONE);
868 // Visits a page with https error and then goes forward using GoToOffset.
869 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndGoForward) {
870 ASSERT_TRUE(test_server()->Start());
871 ASSERT_TRUE(https_server_expired_.Start());
873 // First navigate to two HTTP pages.
874 ui_test_utils::NavigateToURL(browser(),
875 test_server()->GetURL("files/ssl/google.html"));
876 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
877 NavigationEntry* entry1 = tab->GetController().GetActiveEntry();
878 ASSERT_TRUE(entry1);
879 ui_test_utils::NavigateToURL(browser(),
880 test_server()->GetURL("files/ssl/blank_page.html"));
881 NavigationEntry* entry2 = tab->GetController().GetActiveEntry();
882 ASSERT_TRUE(entry2);
884 // Now go back so that a page is in the forward history.
886 content::WindowedNotificationObserver observer(
887 content::NOTIFICATION_LOAD_STOP,
888 content::Source<NavigationController>(&tab->GetController()));
889 tab->GetController().GoBack();
890 observer.Wait();
892 ASSERT_TRUE(tab->GetController().CanGoForward());
893 NavigationEntry* entry3 = tab->GetController().GetActiveEntry();
894 ASSERT_TRUE(entry1 == entry3);
896 // Now go to a bad HTTPS page that shows an interstitial.
897 ui_test_utils::NavigateToURL(browser(),
898 https_server_expired_.GetURL("files/ssl/google.html"));
899 CheckAuthenticationBrokenState(
900 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
902 // Simulate user clicking and holding on forward button.
904 content::WindowedNotificationObserver observer(
905 content::NOTIFICATION_LOAD_STOP,
906 content::Source<NavigationController>(&tab->GetController()));
907 tab->GetController().GoToOffset(1);
908 observer.Wait();
911 // We should be showing the second good page.
912 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()->
913 GetInterstitialPage());
914 CheckUnauthenticatedState(tab, AuthState::NONE);
915 EXPECT_FALSE(tab->GetController().CanGoForward());
916 NavigationEntry* entry4 = tab->GetController().GetActiveEntry();
917 EXPECT_TRUE(entry2 == entry4);
920 // Visit a HTTP page which request WSS connection to a server providing invalid
921 // certificate. Close the page while WSS connection waits for SSLManager's
922 // response from UI thread.
923 // Disabled on Windows because it was flaking on XP Tests (1). crbug.com/165258
924 #if defined(OS_WIN)
925 #define MAYBE_TestWSSInvalidCertAndClose DISABLED_TestWSSInvalidCertAndClose
926 #else
927 #define MAYBE_TestWSSInvalidCertAndClose TestWSSInvalidCertAndClose
928 #endif
929 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestWSSInvalidCertAndClose) {
930 ASSERT_TRUE(test_server()->Start());
931 ASSERT_TRUE(wss_server_expired_.Start());
933 // Setup page title observer.
934 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
935 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
936 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
938 // Create GURLs to test pages.
939 std::string master_url_path = base::StringPrintf("%s?%d",
940 test_server()->GetURL("files/ssl/wss_close.html").spec().c_str(),
941 wss_server_expired_.host_port_pair().port());
942 GURL master_url(master_url_path);
943 std::string slave_url_path = base::StringPrintf("%s?%d",
944 test_server()->GetURL("files/ssl/wss_close_slave.html").spec().c_str(),
945 wss_server_expired_.host_port_pair().port());
946 GURL slave_url(slave_url_path);
948 // Create tabs and visit pages which keep on creating wss connections.
949 WebContents* tabs[16];
950 for (int i = 0; i < 16; ++i) {
951 tabs[i] = chrome::AddSelectedTabWithURL(browser(), slave_url,
952 ui::PAGE_TRANSITION_LINK);
954 chrome::SelectNextTab(browser());
956 // Visit a page which waits for one TLS handshake failure.
957 // The title will be changed to 'PASS'.
958 ui_test_utils::NavigateToURL(browser(), master_url);
959 const base::string16 result = watcher.WaitAndGetTitle();
960 EXPECT_TRUE(base::LowerCaseEqualsASCII(result, "pass"));
962 // Close tabs which contains the test page.
963 for (int i = 0; i < 16; ++i)
964 chrome::CloseWebContents(browser(), tabs[i], false);
965 chrome::CloseWebContents(browser(), tab, false);
968 // Visit a HTTPS page and proceeds despite an invalid certificate. The page
969 // requests WSS connection to the same origin host to check if WSS connection
970 // share certificates policy with HTTPS correcly.
971 IN_PROC_BROWSER_TEST_F(SSLUITest, TestWSSInvalidCertAndGoForward) {
972 ASSERT_TRUE(test_server()->Start());
973 ASSERT_TRUE(wss_server_expired_.Start());
975 // Setup page title observer.
976 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
977 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
978 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
980 // Visit bad HTTPS page.
981 GURL::Replacements replacements;
982 replacements.SetSchemeStr("https");
983 ui_test_utils::NavigateToURL(
984 browser(),
985 wss_server_expired_.GetURL(
986 "connect_check.html").ReplaceComponents(replacements));
987 CheckAuthenticationBrokenState(
988 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
990 // Proceed anyway.
991 ProceedThroughInterstitial(tab);
993 // Test page run a WebSocket wss connection test. The result will be shown
994 // as page title.
995 const base::string16 result = watcher.WaitAndGetTitle();
996 EXPECT_TRUE(base::LowerCaseEqualsASCII(result, "pass"));
999 // Ensure that non-standard origins are marked correctly when the
1000 // MarkNonSecureAs field trial is enabled.
1001 IN_PROC_BROWSER_TEST_F(SSLUITest, TestMarkNonSecureAs) {
1002 scoped_refptr<base::FieldTrial> trial =
1003 base::FieldTrialList::CreateFieldTrial(
1004 "MarkNonSecureAs", switches::kMarkNonSecureAsNonSecure);
1006 content::WebContents* contents =
1007 browser()->tab_strip_model()->GetActiveWebContents();
1008 ASSERT_TRUE(contents);
1010 SecurityStateModel* model = SecurityStateModel::FromWebContents(contents);
1011 ASSERT_TRUE(model);
1013 ui_test_utils::NavigateToURL(browser(), GURL("file:/"));
1014 EXPECT_EQ(SecurityStateModel::NONE, model->security_info().security_level);
1016 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
1017 EXPECT_EQ(SecurityStateModel::NONE, model->security_info().security_level);
1019 ui_test_utils::NavigateToURL(browser(), GURL("data:text/plain,hello"));
1020 EXPECT_EQ(SecurityStateModel::NONE, model->security_info().security_level);
1022 ui_test_utils::NavigateToURL(
1023 browser(),
1024 GURL("blob:chrome%3A//newtab/49a463bb-fac8-476c-97bf-5d7076c3ea1a"));
1025 EXPECT_EQ(SecurityStateModel::NONE, model->security_info().security_level);
1028 #if defined(USE_NSS_CERTS)
1029 class SSLUITestWithClientCert : public SSLUITest {
1030 public:
1031 SSLUITestWithClientCert() : cert_db_(NULL) {}
1033 void SetUpOnMainThread() override {
1034 SSLUITest::SetUpOnMainThread();
1036 base::RunLoop loop;
1037 GetNSSCertDatabaseForProfile(
1038 browser()->profile(),
1039 base::Bind(&SSLUITestWithClientCert::DidGetCertDatabase,
1040 base::Unretained(this),
1041 &loop));
1042 loop.Run();
1045 protected:
1046 void DidGetCertDatabase(base::RunLoop* loop, net::NSSCertDatabase* cert_db) {
1047 cert_db_ = cert_db;
1048 loop->Quit();
1051 net::NSSCertDatabase* cert_db_;
1054 // SSL client certificate tests are only enabled when using NSS for private key
1055 // storage, as only NSS can avoid modifying global machine state when testing.
1056 // See http://crbug.com/51132
1058 // Visit a HTTPS page which requires client cert authentication. The client
1059 // cert will be selected automatically, then a test which uses WebSocket runs.
1060 IN_PROC_BROWSER_TEST_F(SSLUITestWithClientCert, TestWSSClientCert) {
1061 // Import a client cert for test.
1062 scoped_refptr<net::CryptoModule> crypt_module = cert_db_->GetPublicModule();
1063 std::string pkcs12_data;
1064 base::FilePath cert_path = net::GetTestCertsDirectory().Append(
1065 FILE_PATH_LITERAL("websocket_client_cert.p12"));
1066 EXPECT_TRUE(base::ReadFileToString(cert_path, &pkcs12_data));
1067 EXPECT_EQ(net::OK,
1068 cert_db_->ImportFromPKCS12(
1069 crypt_module.get(), pkcs12_data, base::string16(), true, NULL));
1071 // Start WebSocket test server with TLS and client cert authentication.
1072 net::SpawnedTestServer::SSLOptions options(
1073 net::SpawnedTestServer::SSLOptions::CERT_OK);
1074 options.request_client_certificate = true;
1075 base::FilePath ca_path = net::GetTestCertsDirectory().Append(
1076 FILE_PATH_LITERAL("websocket_cacert.pem"));
1077 options.client_authorities.push_back(ca_path);
1078 net::SpawnedTestServer wss_server(net::SpawnedTestServer::TYPE_WSS,
1079 options,
1080 net::GetWebSocketTestDataDirectory());
1081 ASSERT_TRUE(wss_server.Start());
1082 GURL::Replacements replacements;
1083 replacements.SetSchemeStr("https");
1084 GURL url = wss_server.GetURL("connect_check.html").ReplaceComponents(
1085 replacements);
1087 // Setup page title observer.
1088 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1089 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
1090 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
1092 // Add an entry into AutoSelectCertificateForUrls policy for automatic client
1093 // cert selection.
1094 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
1095 DCHECK(profile);
1096 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
1097 dict->SetString("ISSUER.CN", "pywebsocket");
1098 profile->GetHostContentSettingsMap()->SetWebsiteSetting(
1099 ContentSettingsPattern::FromURL(url),
1100 ContentSettingsPattern::FromURL(url),
1101 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
1102 std::string(),
1103 dict.release());
1105 // Visit a HTTPS page which requires client certs.
1106 ui_test_utils::NavigateToURL(browser(), url);
1107 CheckAuthenticatedState(tab, AuthState::NONE);
1109 // Test page runs a WebSocket wss connection test. The result will be shown
1110 // as page title.
1111 const base::string16 result = watcher.WaitAndGetTitle();
1112 EXPECT_TRUE(base::LowerCaseEqualsASCII(result, "pass"));
1114 #endif // defined(USE_NSS_CERTS)
1116 // Flaky on CrOS http://crbug.com/92292
1117 #if defined(OS_CHROMEOS)
1118 #define MAYBE_TestHTTPSErrorWithNoNavEntry \
1119 DISABLED_TestHTTPSErrorWithNoNavEntry
1120 #else
1121 #define MAYBE_TestHTTPSErrorWithNoNavEntry TestHTTPSErrorWithNoNavEntry
1122 #endif // defined(OS_CHROMEOS)
1124 // Open a page with a HTTPS error in a tab with no prior navigation (through a
1125 // link with a blank target). This is to test that the lack of navigation entry
1126 // does not cause any problems (it was causing a crasher, see
1127 // http://crbug.com/19941).
1128 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSErrorWithNoNavEntry) {
1129 ASSERT_TRUE(https_server_expired_.Start());
1131 GURL url = https_server_expired_.GetURL("files/ssl/google.htm");
1132 WebContents* tab2 = chrome::AddSelectedTabWithURL(
1133 browser(), url, ui::PAGE_TRANSITION_TYPED);
1134 content::WaitForLoadStop(tab2);
1136 // Verify our assumption that there was no prior navigation.
1137 EXPECT_FALSE(chrome::CanGoBack(browser()));
1139 // We should have an interstitial page showing.
1140 ASSERT_TRUE(tab2->GetInterstitialPage());
1141 ASSERT_EQ(SSLBlockingPage::kTypeForTesting, tab2->GetInterstitialPage()
1142 ->GetDelegateForTesting()
1143 ->GetTypeForTesting());
1146 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadHTTPSDownload) {
1147 ASSERT_TRUE(test_server()->Start());
1148 ASSERT_TRUE(https_server_expired_.Start());
1149 GURL url_non_dangerous = test_server()->GetURL(std::string());
1150 GURL url_dangerous =
1151 https_server_expired_.GetURL("files/downloads/dangerous/dangerous.exe");
1152 base::ScopedTempDir downloads_directory_;
1154 // Need empty temp dir to avoid having Chrome ask us for a new filename
1155 // when we've downloaded dangerous.exe one hundred times.
1156 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
1158 browser()->profile()->GetPrefs()->SetFilePath(
1159 prefs::kDownloadDefaultDirectory,
1160 downloads_directory_.path());
1162 // Visit a non-dangerous page.
1163 ui_test_utils::NavigateToURL(browser(), url_non_dangerous);
1165 // Now, start a transition to dangerous download.
1167 content::WindowedNotificationObserver observer(
1168 content::NOTIFICATION_LOAD_STOP,
1169 content::NotificationService::AllSources());
1170 chrome::NavigateParams navigate_params(browser(), url_dangerous,
1171 ui::PAGE_TRANSITION_TYPED);
1172 chrome::Navigate(&navigate_params);
1173 observer.Wait();
1176 // To exit the browser cleanly (and this test) we need to complete the
1177 // download after completing this test.
1178 content::DownloadTestObserverTerminal dangerous_download_observer(
1179 content::BrowserContext::GetDownloadManager(browser()->profile()),
1181 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT);
1183 // Proceed through the SSL interstitial. This doesn't use
1184 // |ProceedThroughInterstitial| since no page load will commit.
1185 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1186 ASSERT_TRUE(tab != NULL);
1187 ASSERT_TRUE(tab->GetInterstitialPage() != NULL);
1188 ASSERT_EQ(
1189 SSLBlockingPage::kTypeForTesting,
1190 tab->GetInterstitialPage()->GetDelegateForTesting()->GetTypeForTesting());
1192 content::WindowedNotificationObserver observer(
1193 chrome::NOTIFICATION_DOWNLOAD_INITIATED,
1194 content::NotificationService::AllSources());
1195 tab->GetInterstitialPage()->Proceed();
1196 observer.Wait();
1199 // There should still be an interstitial at this point. Press the
1200 // back button on the browser. Note that this doesn't wait for a
1201 // NAV_ENTRY_COMMITTED notification because going back with an
1202 // active interstitial simply hides the interstitial.
1203 ASSERT_TRUE(tab->GetInterstitialPage() != NULL);
1204 ASSERT_EQ(
1205 SSLBlockingPage::kTypeForTesting,
1206 tab->GetInterstitialPage()->GetDelegateForTesting()->GetTypeForTesting());
1207 EXPECT_TRUE(chrome::CanGoBack(browser()));
1208 chrome::GoBack(browser(), CURRENT_TAB);
1210 dangerous_download_observer.WaitForFinished();
1214 // Insecure content
1217 #if defined(OS_WIN)
1218 // http://crbug.com/152940 Flaky on win.
1219 #define MAYBE_TestDisplaysInsecureContent DISABLED_TestDisplaysInsecureContent
1220 #else
1221 #define MAYBE_TestDisplaysInsecureContent TestDisplaysInsecureContent
1222 #endif
1224 // Visits a page that displays insecure content.
1225 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestDisplaysInsecureContent) {
1226 ASSERT_TRUE(test_server()->Start());
1227 ASSERT_TRUE(https_server_.Start());
1229 std::string replacement_path;
1230 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1231 "files/ssl/page_displays_insecure_content.html",
1232 test_server()->host_port_pair(),
1233 &replacement_path));
1235 // Load a page that displays insecure content.
1236 ui_test_utils::NavigateToURL(browser(),
1237 https_server_.GetURL(replacement_path));
1239 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
1240 AuthState::DISPLAYED_INSECURE_CONTENT);
1243 // Test that if the user proceeds and the checkbox is checked, a report
1244 // is sent or not sent depending on the Finch config.
1245 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1246 TestBrokenHTTPSProceedReporting) {
1247 certificate_reporting_test_utils::ExpectReport expect_report =
1248 certificate_reporting_test_utils::GetReportExpectedFromFinch();
1249 TestBrokenHTTPSReporting(
1250 certificate_reporting_test_utils::EXTENDED_REPORTING_OPT_IN,
1251 SSL_INTERSTITIAL_PROCEED, expect_report, browser());
1254 // Test that if the user goes back and the checkbox is checked, a report
1255 // is sent or not sent depending on the Finch config.
1256 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1257 TestBrokenHTTPSGoBackReporting) {
1258 certificate_reporting_test_utils::ExpectReport expect_report =
1259 certificate_reporting_test_utils::GetReportExpectedFromFinch();
1260 TestBrokenHTTPSReporting(
1261 certificate_reporting_test_utils::EXTENDED_REPORTING_OPT_IN,
1262 SSL_INTERSTITIAL_DO_NOT_PROCEED, expect_report, browser());
1265 // User proceeds, checkbox is shown but unchecked. Reports should never
1266 // be sent, regardless of Finch config.
1267 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1268 TestBrokenHTTPSProceedReportingWithNoOptIn) {
1269 TestBrokenHTTPSReporting(
1270 certificate_reporting_test_utils::EXTENDED_REPORTING_DO_NOT_OPT_IN,
1271 SSL_INTERSTITIAL_PROCEED,
1272 certificate_reporting_test_utils::CERT_REPORT_NOT_EXPECTED, browser());
1275 // User goes back, checkbox is shown but unchecked. Reports should never
1276 // be sent, regardless of Finch config.
1277 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1278 TestBrokenHTTPSGoBackShowYesCheckNoParamYesReportNo) {
1279 TestBrokenHTTPSReporting(
1280 certificate_reporting_test_utils::EXTENDED_REPORTING_DO_NOT_OPT_IN,
1281 SSL_INTERSTITIAL_DO_NOT_PROCEED,
1282 certificate_reporting_test_utils::CERT_REPORT_NOT_EXPECTED, browser());
1285 // User proceeds, checkbox is not shown but checked -> we expect no
1286 // report.
1287 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1288 TestBrokenHTTPSProceedShowNoCheckYesReportNo) {
1289 if (base::FieldTrialList::FindFullName(
1290 CertReportHelper::kFinchExperimentName) ==
1291 CertReportHelper::kFinchGroupDontShowDontSend) {
1292 TestBrokenHTTPSReporting(
1293 certificate_reporting_test_utils::EXTENDED_REPORTING_OPT_IN,
1294 SSL_INTERSTITIAL_PROCEED,
1295 certificate_reporting_test_utils::CERT_REPORT_NOT_EXPECTED, browser());
1299 // Browser is incognito, user proceeds, checkbox has previously opted in
1300 // -> no report, regardless of Finch config.
1301 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1302 TestBrokenHTTPSInIncognitoReportNo) {
1303 TestBrokenHTTPSReporting(
1304 certificate_reporting_test_utils::EXTENDED_REPORTING_OPT_IN,
1305 SSL_INTERSTITIAL_PROCEED,
1306 certificate_reporting_test_utils::CERT_REPORT_NOT_EXPECTED,
1307 CreateIncognitoBrowser());
1310 // Test that reports don't get sent when extended reporting opt-in is
1311 // disabled by policy.
1312 IN_PROC_BROWSER_TEST_F(SSLUITestWithExtendedReporting,
1313 TestBrokenHTTPSNoReportingWhenDisallowed) {
1314 browser()->profile()->GetPrefs()->SetBoolean(
1315 prefs::kSafeBrowsingExtendedReportingOptInAllowed, false);
1316 TestBrokenHTTPSReporting(
1317 certificate_reporting_test_utils::EXTENDED_REPORTING_OPT_IN,
1318 SSL_INTERSTITIAL_PROCEED,
1319 certificate_reporting_test_utils::CERT_REPORT_NOT_EXPECTED, browser());
1322 // Visits a page that runs insecure content and tries to suppress the insecure
1323 // content warnings by randomizing location.hash.
1324 // Based on http://crbug.com/8706
1325 IN_PROC_BROWSER_TEST_F(SSLUITest,
1326 TestRunsInsecuredContentRandomizeHash) {
1327 ASSERT_TRUE(test_server()->Start());
1328 ASSERT_TRUE(https_server_.Start());
1330 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
1331 "files/ssl/page_runs_insecure_content.html"));
1333 CheckAuthenticationBrokenState(
1334 browser()->tab_strip_model()->GetActiveWebContents(),
1335 CertError::NONE,
1336 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1339 // Visits a page with unsafe content and make sure that:
1340 // - frames content is replaced with warning
1341 // - images and scripts are filtered out entirely
1342 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContents) {
1343 ASSERT_TRUE(https_server_.Start());
1344 ASSERT_TRUE(https_server_expired_.Start());
1346 std::string replacement_path;
1347 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1348 "files/ssl/page_with_unsafe_contents.html",
1349 https_server_expired_.host_port_pair(),
1350 &replacement_path));
1351 ui_test_utils::NavigateToURL(browser(),
1352 https_server_.GetURL(replacement_path));
1354 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1355 // When the bad content is filtered, the state is expected to be
1356 // authenticated.
1357 CheckAuthenticatedState(tab, AuthState::NONE);
1359 // Because of cross-frame scripting restrictions, we cannot access the iframe
1360 // content. So to know if the frame was loaded, we just check if a popup was
1361 // opened (the iframe content opens one).
1362 // Note: because of bug 1115868, no web contents modal dialog is opened right
1363 // now. Once the bug is fixed, this will do the real check.
1364 EXPECT_FALSE(IsShowingWebContentsModalDialog());
1366 int img_width;
1367 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
1368 tab,
1369 "window.domAutomationController.send(ImageWidth());",
1370 &img_width));
1371 // In order to check that the image was not loaded, we check its width.
1372 // The actual image (Google logo) is 114 pixels wide, we assume the broken
1373 // image is less than 100.
1374 EXPECT_LT(img_width, 100);
1376 bool js_result = false;
1377 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1378 tab,
1379 "window.domAutomationController.send(IsFooSet());",
1380 &js_result));
1381 EXPECT_FALSE(js_result);
1384 // Visits a page with insecure content loaded by JS (after the initial page
1385 // load).
1386 #if defined(OS_LINUX)
1387 // flaky http://crbug.com/396462
1388 #define MAYBE_TestDisplaysInsecureContentLoadedFromJS \
1389 DISABLED_TestDisplaysInsecureContentLoadedFromJS
1390 #else
1391 #define MAYBE_TestDisplaysInsecureContentLoadedFromJS \
1392 TestDisplaysInsecureContentLoadedFromJS
1393 #endif
1394 IN_PROC_BROWSER_TEST_F(SSLUITest,
1395 MAYBE_TestDisplaysInsecureContentLoadedFromJS) {
1396 ASSERT_TRUE(test_server()->Start());
1397 ASSERT_TRUE(https_server_.Start());
1399 std::string replacement_path;
1400 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1401 "files/ssl/page_with_dynamic_insecure_content.html",
1402 test_server()->host_port_pair(),
1403 &replacement_path));
1404 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
1405 replacement_path));
1407 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1408 CheckAuthenticatedState(tab, AuthState::NONE);
1410 // Load the insecure image.
1411 bool js_result = false;
1412 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1413 tab,
1414 "loadBadImage();",
1415 &js_result));
1416 EXPECT_TRUE(js_result);
1418 // We should now have insecure content.
1419 CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT);
1422 // Visits two pages from the same origin: one that displays insecure content and
1423 // one that doesn't. The test checks that we do not propagate the insecure
1424 // content state from one to the other.
1425 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentTwoTabs) {
1426 ASSERT_TRUE(test_server()->Start());
1427 ASSERT_TRUE(https_server_.Start());
1429 ui_test_utils::NavigateToURL(browser(),
1430 https_server_.GetURL("files/ssl/blank_page.html"));
1432 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1434 // This tab should be fine.
1435 CheckAuthenticatedState(tab1, AuthState::NONE);
1437 // Create a new tab.
1438 std::string replacement_path;
1439 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1440 "files/ssl/page_displays_insecure_content.html",
1441 test_server()->host_port_pair(),
1442 &replacement_path));
1444 GURL url = https_server_.GetURL(replacement_path);
1445 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED);
1446 params.disposition = NEW_FOREGROUND_TAB;
1447 params.tabstrip_index = 0;
1448 params.source_contents = tab1;
1449 content::WindowedNotificationObserver observer(
1450 content::NOTIFICATION_LOAD_STOP,
1451 content::NotificationService::AllSources());
1452 chrome::Navigate(&params);
1453 WebContents* tab2 = params.target_contents;
1454 observer.Wait();
1456 // The new tab has insecure content.
1457 CheckAuthenticatedState(tab2, AuthState::DISPLAYED_INSECURE_CONTENT);
1459 // The original tab should not be contaminated.
1460 CheckAuthenticatedState(tab1, AuthState::NONE);
1463 // Visits two pages from the same origin: one that runs insecure content and one
1464 // that doesn't. The test checks that we propagate the insecure content state
1465 // from one to the other.
1466 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsInsecureContentTwoTabs) {
1467 ASSERT_TRUE(test_server()->Start());
1468 ASSERT_TRUE(https_server_.Start());
1470 ui_test_utils::NavigateToURL(browser(),
1471 https_server_.GetURL("files/ssl/blank_page.html"));
1473 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1475 // This tab should be fine.
1476 CheckAuthenticatedState(tab1, AuthState::NONE);
1478 std::string replacement_path;
1479 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1480 "files/ssl/page_runs_insecure_content.html",
1481 test_server()->host_port_pair(),
1482 &replacement_path));
1484 // Create a new tab in the same process. Using a NEW_FOREGROUND_TAB
1485 // disposition won't usually stay in the same process, but this works
1486 // because we are using process-per-site in SetUpCommandLine.
1487 GURL url = https_server_.GetURL(replacement_path);
1488 chrome::NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED);
1489 params.disposition = NEW_FOREGROUND_TAB;
1490 params.source_contents = tab1;
1491 content::WindowedNotificationObserver observer(
1492 content::NOTIFICATION_LOAD_STOP,
1493 content::NotificationService::AllSources());
1494 chrome::Navigate(&params);
1495 WebContents* tab2 = params.target_contents;
1496 observer.Wait();
1498 // Both tabs should have the same process.
1499 EXPECT_EQ(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
1501 // The new tab has insecure content.
1502 CheckAuthenticationBrokenState(
1503 tab2,
1504 CertError::NONE,
1505 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1507 // Which means the origin for the first tab has also been contaminated with
1508 // insecure content.
1509 CheckAuthenticationBrokenState(
1510 tab1, CertError::NONE, AuthState::RAN_INSECURE_CONTENT);
1513 // Visits a page with an image over http. Visits another page over https
1514 // referencing that same image over http (hoping it is coming from the webcore
1515 // memory cache).
1516 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysCachedInsecureContent) {
1517 ASSERT_TRUE(test_server()->Start());
1518 ASSERT_TRUE(https_server_.Start());
1520 std::string replacement_path;
1521 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1522 "files/ssl/page_displays_insecure_content.html",
1523 test_server()->host_port_pair(),
1524 &replacement_path));
1526 // Load original page over HTTP.
1527 const GURL url_http = test_server()->GetURL(replacement_path);
1528 ui_test_utils::NavigateToURL(browser(), url_http);
1529 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1530 CheckUnauthenticatedState(tab, AuthState::NONE);
1532 // Load again but over SSL. It should be marked as displaying insecure
1533 // content (even though the image comes from the WebCore memory cache).
1534 const GURL url_https = https_server_.GetURL(replacement_path);
1535 ui_test_utils::NavigateToURL(browser(), url_https);
1536 CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT);
1539 // http://crbug.com/84729
1540 #if defined(OS_CHROMEOS)
1541 #define MAYBE_TestRunsCachedInsecureContent \
1542 DISABLED_TestRunsCachedInsecureContent
1543 #else
1544 #define MAYBE_TestRunsCachedInsecureContent TestRunsCachedInsecureContent
1545 #endif // defined(OS_CHROMEOS)
1547 // Visits a page with script over http. Visits another page over https
1548 // referencing that same script over http (hoping it is coming from the webcore
1549 // memory cache).
1550 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRunsCachedInsecureContent) {
1551 ASSERT_TRUE(test_server()->Start());
1552 ASSERT_TRUE(https_server_.Start());
1554 std::string replacement_path;
1555 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1556 "files/ssl/page_runs_insecure_content.html",
1557 test_server()->host_port_pair(),
1558 &replacement_path));
1560 // Load original page over HTTP.
1561 const GURL url_http = test_server()->GetURL(replacement_path);
1562 ui_test_utils::NavigateToURL(browser(), url_http);
1563 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1564 CheckUnauthenticatedState(tab, AuthState::NONE);
1566 // Load again but over SSL. It should be marked as displaying insecure
1567 // content (even though the image comes from the WebCore memory cache).
1568 const GURL url_https = https_server_.GetURL(replacement_path);
1569 ui_test_utils::NavigateToURL(browser(), url_https);
1570 CheckAuthenticationBrokenState(
1571 tab,
1572 CertError::NONE,
1573 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1576 // This test ensures the CN invalid status does not 'stick' to a certificate
1577 // (see bug #1044942) and that it depends on the host-name.
1578 // Test if disabled due to flakiness http://crbug.com/368280 .
1579 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCNInvalidStickiness) {
1580 ASSERT_TRUE(https_server_.Start());
1581 ASSERT_TRUE(https_server_mismatched_.Start());
1583 // First we hit the server with hostname, this generates an invalid policy
1584 // error.
1585 ui_test_utils::NavigateToURL(browser(),
1586 https_server_mismatched_.GetURL("files/ssl/google.html"));
1588 // We get an interstitial page as a result.
1589 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1590 CheckAuthenticationBrokenState(tab,
1591 net::CERT_STATUS_COMMON_NAME_INVALID,
1592 AuthState::SHOWING_INTERSTITIAL);
1593 ProceedThroughInterstitial(tab);
1594 CheckAuthenticationBrokenState(
1595 tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE);
1597 // Now we try again with the right host name this time.
1598 GURL url(https_server_.GetURL("files/ssl/google.html"));
1599 ui_test_utils::NavigateToURL(browser(), url);
1601 // Security state should be OK.
1602 CheckAuthenticatedState(tab, AuthState::NONE);
1604 // Now try again the broken one to make sure it is still broken.
1605 ui_test_utils::NavigateToURL(browser(),
1606 https_server_mismatched_.GetURL("files/ssl/google.html"));
1608 // Since we OKed the interstitial last time, we get right to the page.
1609 CheckAuthenticationBrokenState(
1610 tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE);
1613 #if defined(OS_CHROMEOS)
1614 // This test seems to be flaky and hang on chromiumos.
1615 // http://crbug.com/84419
1616 #define MAYBE_TestRefNavigation DISABLED_TestRefNavigation
1617 #else
1618 #define MAYBE_TestRefNavigation TestRefNavigation
1619 #endif
1621 // Test that navigating to a #ref does not change a bad security state.
1622 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) {
1623 ASSERT_TRUE(https_server_expired_.Start());
1625 ui_test_utils::NavigateToURL(browser(),
1626 https_server_expired_.GetURL("files/ssl/page_with_refs.html"));
1628 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1629 CheckAuthenticationBrokenState(
1630 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1632 ProceedThroughInterstitial(tab);
1634 CheckAuthenticationBrokenState(
1635 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1636 // Now navigate to a ref in the page, the security state should not have
1637 // changed.
1638 ui_test_utils::NavigateToURL(browser(),
1639 https_server_expired_.GetURL("files/ssl/page_with_refs.html#jp"));
1641 CheckAuthenticationBrokenState(
1642 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1645 // Tests that closing a page that has a unsafe pop-up does not crash the
1646 // browser (bug #1966).
1647 // TODO(jcampan): http://crbug.com/2136 disabled because the popup is not
1648 // opened as it is not initiated by a user gesture.
1649 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) {
1650 ASSERT_TRUE(test_server()->Start());
1651 ASSERT_TRUE(https_server_expired_.Start());
1653 std::string replacement_path;
1654 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1655 "files/ssl/page_with_unsafe_popup.html",
1656 https_server_expired_.host_port_pair(),
1657 &replacement_path));
1659 ui_test_utils::NavigateToURL(browser(),
1660 test_server()->GetURL(replacement_path));
1662 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1663 // It is probably overkill to add a notification for a popup-opening, let's
1664 // just poll.
1665 for (int i = 0; i < 10; i++) {
1666 if (IsShowingWebContentsModalDialog())
1667 break;
1668 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1669 FROM_HERE, base::MessageLoop::QuitClosure(),
1670 base::TimeDelta::FromSeconds(1));
1671 content::RunMessageLoop();
1673 ASSERT_TRUE(IsShowingWebContentsModalDialog());
1675 // Let's add another tab to make sure the browser does not exit when we close
1676 // the first tab.
1677 GURL url = test_server()->GetURL("files/ssl/google.html");
1678 content::WindowedNotificationObserver observer(
1679 content::NOTIFICATION_LOAD_STOP,
1680 content::NotificationService::AllSources());
1681 chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED);
1682 observer.Wait();
1684 // Close the first tab.
1685 chrome::CloseWebContents(browser(), tab1, false);
1688 // Visit a page over bad https that is a redirect to a page with good https.
1689 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) {
1690 ASSERT_TRUE(https_server_.Start());
1691 ASSERT_TRUE(https_server_expired_.Start());
1693 GURL url1 = https_server_expired_.GetURL("server-redirect?");
1694 GURL url2 = https_server_.GetURL("files/ssl/google.html");
1696 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
1698 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1700 CheckAuthenticationBrokenState(
1701 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1703 ProceedThroughInterstitial(tab);
1705 // We have been redirected to the good page.
1706 CheckAuthenticatedState(tab, AuthState::NONE);
1709 // Flaky on Linux. http://crbug.com/368280.
1710 #if defined(OS_LINUX)
1711 #define MAYBE_TestRedirectGoodToBadHTTPS DISABLED_TestRedirectGoodToBadHTTPS
1712 #else
1713 #define MAYBE_TestRedirectGoodToBadHTTPS TestRedirectGoodToBadHTTPS
1714 #endif
1716 // Visit a page over good https that is a redirect to a page with bad https.
1717 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectGoodToBadHTTPS) {
1718 ASSERT_TRUE(https_server_.Start());
1719 ASSERT_TRUE(https_server_expired_.Start());
1721 GURL url1 = https_server_.GetURL("server-redirect?");
1722 GURL url2 = https_server_expired_.GetURL("files/ssl/google.html");
1723 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
1725 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1726 CheckAuthenticationBrokenState(
1727 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1729 ProceedThroughInterstitial(tab);
1731 CheckAuthenticationBrokenState(
1732 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1735 // Visit a page over http that is a redirect to a page with good HTTPS.
1736 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) {
1737 ASSERT_TRUE(test_server()->Start());
1738 ASSERT_TRUE(https_server_.Start());
1740 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1742 // HTTP redirects to good HTTPS.
1743 GURL http_url = test_server()->GetURL("server-redirect?");
1744 GURL good_https_url =
1745 https_server_.GetURL("files/ssl/google.html");
1747 ui_test_utils::NavigateToURL(browser(),
1748 GURL(http_url.spec() + good_https_url.spec()));
1749 CheckAuthenticatedState(tab, AuthState::NONE);
1752 // Flaky on Linux. http://crbug.com/368280.
1753 #if defined(OS_LINUX)
1754 #define MAYBE_TestRedirectHTTPToBadHTTPS DISABLED_TestRedirectHTTPToBadHTTPS
1755 #else
1756 #define MAYBE_TestRedirectHTTPToBadHTTPS TestRedirectHTTPToBadHTTPS
1757 #endif
1759 // Visit a page over http that is a redirect to a page with bad HTTPS.
1760 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectHTTPToBadHTTPS) {
1761 ASSERT_TRUE(test_server()->Start());
1762 ASSERT_TRUE(https_server_expired_.Start());
1764 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1766 GURL http_url = test_server()->GetURL("server-redirect?");
1767 GURL bad_https_url =
1768 https_server_expired_.GetURL("files/ssl/google.html");
1769 ui_test_utils::NavigateToURL(browser(),
1770 GURL(http_url.spec() + bad_https_url.spec()));
1771 CheckAuthenticationBrokenState(
1772 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1774 ProceedThroughInterstitial(tab);
1776 CheckAuthenticationBrokenState(
1777 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1780 // Visit a page over https that is a redirect to a page with http (to make sure
1781 // we don't keep the secure state).
1782 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) {
1783 ASSERT_TRUE(test_server()->Start());
1784 ASSERT_TRUE(https_server_.Start());
1786 GURL https_url = https_server_.GetURL("server-redirect?");
1787 GURL http_url = test_server()->GetURL("files/ssl/google.html");
1789 ui_test_utils::NavigateToURL(browser(),
1790 GURL(https_url.spec() + http_url.spec()));
1791 CheckUnauthenticatedState(
1792 browser()->tab_strip_model()->GetActiveWebContents(), AuthState::NONE);
1795 // Visits a page to which we could not connect (bad port) over http and https
1796 // and make sure the security style is correct.
1797 IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) {
1798 ui_test_utils::NavigateToURL(browser(), GURL("http://localhost:17"));
1799 CheckUnauthenticatedState(
1800 browser()->tab_strip_model()->GetActiveWebContents(),
1801 AuthState::SHOWING_ERROR);
1803 // Same thing over HTTPS.
1804 ui_test_utils::NavigateToURL(browser(), GURL("https://localhost:17"));
1805 CheckUnauthenticatedState(
1806 browser()->tab_strip_model()->GetActiveWebContents(),
1807 AuthState::SHOWING_ERROR);
1811 // Frame navigation
1814 // From a good HTTPS top frame:
1815 // - navigate to an OK HTTPS frame
1816 // - navigate to a bad HTTPS (expect unsafe content and filtered frame), then
1817 // back
1818 // - navigate to HTTP (expect insecure content), then back
1819 IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) {
1820 ASSERT_TRUE(test_server()->Start());
1821 ASSERT_TRUE(https_server_.Start());
1822 ASSERT_TRUE(https_server_expired_.Start());
1824 std::string top_frame_path;
1825 ASSERT_TRUE(GetTopFramePath(*test_server(),
1826 https_server_,
1827 https_server_expired_,
1828 &top_frame_path));
1830 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1831 ui_test_utils::NavigateToURL(browser(),
1832 https_server_.GetURL(top_frame_path));
1834 CheckAuthenticatedState(tab, AuthState::NONE);
1836 bool success = false;
1837 // Now navigate inside the frame.
1839 content::WindowedNotificationObserver observer(
1840 content::NOTIFICATION_LOAD_STOP,
1841 content::Source<NavigationController>(&tab->GetController()));
1842 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1843 tab,
1844 "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1845 &success));
1846 ASSERT_TRUE(success);
1847 observer.Wait();
1850 // We should still be fine.
1851 CheckAuthenticatedState(tab, AuthState::NONE);
1853 // Now let's hit a bad page.
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('badHTTPSLink'));",
1861 &success));
1862 ASSERT_TRUE(success);
1863 observer.Wait();
1866 // The security style should still be secure.
1867 CheckAuthenticatedState(tab, AuthState::NONE);
1869 // And the frame should be blocked.
1870 bool is_content_evil = true;
1871 content::RenderFrameHost* content_frame = content::FrameMatchingPredicate(
1872 tab, base::Bind(&content::FrameMatchesName, "contentFrame"));
1873 std::string is_evil_js("window.domAutomationController.send("
1874 "document.getElementById('evilDiv') != null);");
1875 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame,
1876 is_evil_js,
1877 &is_content_evil));
1878 EXPECT_FALSE(is_content_evil);
1880 // Now go back, our state should still be OK.
1882 content::WindowedNotificationObserver observer(
1883 content::NOTIFICATION_LOAD_STOP,
1884 content::Source<NavigationController>(&tab->GetController()));
1885 tab->GetController().GoBack();
1886 observer.Wait();
1888 CheckAuthenticatedState(tab, AuthState::NONE);
1890 // Navigate to a page served over HTTP.
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('HTTPLink'));",
1898 &success));
1899 ASSERT_TRUE(success);
1900 observer.Wait();
1903 // Our state should be unathenticated (in the ran mixed script sense)
1904 CheckAuthenticationBrokenState(
1905 tab,
1906 CertError::NONE,
1907 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1909 // Go back, our state should be unchanged.
1911 content::WindowedNotificationObserver observer(
1912 content::NOTIFICATION_LOAD_STOP,
1913 content::Source<NavigationController>(&tab->GetController()));
1914 tab->GetController().GoBack();
1915 observer.Wait();
1918 CheckAuthenticationBrokenState(
1919 tab,
1920 CertError::NONE,
1921 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1924 // From a bad HTTPS top frame:
1925 // - navigate to an OK HTTPS frame (expected to be still authentication broken).
1926 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadFrameNavigation) {
1927 ASSERT_TRUE(https_server_.Start());
1928 ASSERT_TRUE(https_server_expired_.Start());
1930 std::string top_frame_path;
1931 ASSERT_TRUE(GetTopFramePath(*test_server(),
1932 https_server_,
1933 https_server_expired_,
1934 &top_frame_path));
1936 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1937 ui_test_utils::NavigateToURL(browser(),
1938 https_server_expired_.GetURL(top_frame_path));
1939 CheckAuthenticationBrokenState(
1940 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1942 ProceedThroughInterstitial(tab);
1944 // Navigate to a good frame.
1945 bool success = false;
1946 content::WindowedNotificationObserver observer(
1947 content::NOTIFICATION_LOAD_STOP,
1948 content::Source<NavigationController>(&tab->GetController()));
1949 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1950 tab,
1951 "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1952 &success));
1953 ASSERT_TRUE(success);
1954 observer.Wait();
1956 // We should still be authentication broken.
1957 CheckAuthenticationBrokenState(
1958 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1961 // From an HTTP top frame, navigate to good and bad HTTPS (security state should
1962 // stay unauthenticated).
1963 // Disabled, flakily exceeds test timeout, http://crbug.com/43437.
1964 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestUnauthenticatedFrameNavigation) {
1965 ASSERT_TRUE(test_server()->Start());
1966 ASSERT_TRUE(https_server_.Start());
1967 ASSERT_TRUE(https_server_expired_.Start());
1969 std::string top_frame_path;
1970 ASSERT_TRUE(GetTopFramePath(*test_server(),
1971 https_server_,
1972 https_server_expired_,
1973 &top_frame_path));
1975 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1976 ui_test_utils::NavigateToURL(browser(),
1977 test_server()->GetURL(top_frame_path));
1978 CheckUnauthenticatedState(tab, AuthState::NONE);
1980 // Now navigate inside the frame to a secure HTTPS frame.
1982 bool success = false;
1983 content::WindowedNotificationObserver observer(
1984 content::NOTIFICATION_LOAD_STOP,
1985 content::Source<NavigationController>(&tab->GetController()));
1986 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1987 tab,
1988 "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1989 &success));
1990 ASSERT_TRUE(success);
1991 observer.Wait();
1994 // We should still be unauthenticated.
1995 CheckUnauthenticatedState(tab, AuthState::NONE);
1997 // Now navigate to a bad HTTPS frame.
1999 bool success = false;
2000 content::WindowedNotificationObserver observer(
2001 content::NOTIFICATION_LOAD_STOP,
2002 content::Source<NavigationController>(&tab->GetController()));
2003 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
2004 tab,
2005 "window.domAutomationController.send(clickLink('badHTTPSLink'));",
2006 &success));
2007 ASSERT_TRUE(success);
2008 observer.Wait();
2011 // State should not have changed.
2012 CheckUnauthenticatedState(tab, AuthState::NONE);
2014 // And the frame should have been blocked (see bug #2316).
2015 bool is_content_evil = true;
2016 content::RenderFrameHost* content_frame = content::FrameMatchingPredicate(
2017 tab, base::Bind(&content::FrameMatchesName, "contentFrame"));
2018 std::string is_evil_js("window.domAutomationController.send("
2019 "document.getElementById('evilDiv') != null);");
2020 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame,
2021 is_evil_js,
2022 &is_content_evil));
2023 EXPECT_FALSE(is_content_evil);
2026 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerFiltered) {
2027 ASSERT_TRUE(https_server_.Start());
2028 ASSERT_TRUE(https_server_expired_.Start());
2030 // This page will spawn a Worker which will try to load content from
2031 // BadCertServer.
2032 std::string page_with_unsafe_worker_path;
2033 ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_,
2034 &page_with_unsafe_worker_path));
2035 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
2036 page_with_unsafe_worker_path));
2037 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2038 // Expect Worker not to load insecure content.
2039 CheckWorkerLoadResult(tab, false);
2040 // The bad content is filtered, expect the state to be authenticated.
2041 CheckAuthenticatedState(tab, AuthState::NONE);
2044 // This test, and the related test TestUnsafeContentsWithUserException, verify
2045 // that if unsafe content is loaded but the host of that unsafe content has a
2046 // user exception, the content runs and the security style remains
2047 // authenticated. This is not necessarily the behavior that should exist, but it
2048 // is verification that it does behave that way. See https://crbug.com/477868
2049 // for more inforamtion on this.
2050 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerWithUserException) {
2051 ASSERT_TRUE(https_server_.Start());
2052 // Note that it is necessary to user https_server_mismatched_ here over the
2053 // other invalid cert servers. This is because the test relies on the two
2054 // servers having different hosts since SSL exceptions are per-host, not per
2055 // origin, and https_server_mismatched_ uses 'localhost' rather than
2056 // '127.0.0.1'.
2057 ASSERT_TRUE(https_server_mismatched_.Start());
2059 // Navigate to an unsafe site. Proceed with interstitial page to indicate
2060 // the user approves the bad certificate.
2061 ui_test_utils::NavigateToURL(
2062 browser(), https_server_mismatched_.GetURL("files/ssl/blank_page.html"));
2063 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2064 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
2065 AuthState::SHOWING_INTERSTITIAL);
2066 ProceedThroughInterstitial(tab);
2067 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
2068 AuthState::NONE);
2070 // Navigate to safe page that has Worker loading unsafe content.
2071 // Expect content to load but be marked as auth broken due to running insecure
2072 // content.
2073 std::string page_with_unsafe_worker_path;
2074 ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_mismatched_,
2075 &page_with_unsafe_worker_path));
2076 ui_test_utils::NavigateToURL(
2077 browser(), https_server_.GetURL(page_with_unsafe_worker_path));
2078 CheckWorkerLoadResult(tab, true); // Worker loads insecure content
2079 CheckAuthenticatedState(tab, CertError::NONE);
2082 // Visits a page with unsafe content and makes sure that if a user exception to
2083 // the certificate error is present, the image is loaded and script executes.
2085 // See the comment above SSLUITest.TestUnsafeContentsInWorkerWithUserException
2086 // for a discussion about the desired behavior.
2087 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsWithUserException) {
2088 ASSERT_TRUE(https_server_.Start());
2089 // Note that it is necessary to user https_server_mismatched_ here over the
2090 // other invalid cert servers. This is because the test relies on the two
2091 // servers having different hosts since SSL exceptions are per-host, not per
2092 // origin, and https_server_mismatched_ uses 'localhost' rather than
2093 // '127.0.0.1'.
2094 ASSERT_TRUE(https_server_mismatched_.Start());
2096 // Navigate to an unsafe site. Proceed with interstitial page to indicate
2097 // the user approves the bad certificate.
2098 ui_test_utils::NavigateToURL(
2099 browser(), https_server_mismatched_.GetURL("files/ssl/blank_page.html"));
2100 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2101 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
2102 AuthState::SHOWING_INTERSTITIAL);
2103 ProceedThroughInterstitial(tab);
2104 CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
2105 AuthState::NONE);
2107 std::string replacement_path;
2108 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2109 "files/ssl/page_with_unsafe_contents.html",
2110 https_server_mismatched_.host_port_pair(), &replacement_path));
2111 ui_test_utils::NavigateToURL(browser(),
2112 https_server_.GetURL(replacement_path));
2114 // When the bad content is filtered, the state is expected to be
2115 // authenticated.
2116 CheckAuthenticatedState(tab, AuthState::NONE);
2118 int img_width;
2119 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
2120 tab, "window.domAutomationController.send(ImageWidth());", &img_width));
2121 // In order to check that the image was loaded, we check its width.
2122 // The actual image (Google logo) is 114 pixels wide, so we assume a good
2123 // image is greater than 100.
2124 EXPECT_GT(img_width, 100);
2126 bool js_result = false;
2127 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
2128 tab, "window.domAutomationController.send(IsFooSet());", &js_result));
2129 EXPECT_TRUE(js_result);
2130 CheckAuthenticatedState(tab, CertError::NONE);
2133 // Test that when the browser blocks displaying insecure content (images), the
2134 // indicator shows a secure page, because the blocking made the otherwise
2135 // unsafe page safe (the notification of this state is handled by other means).
2136 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureImage) {
2137 ASSERT_TRUE(test_server()->Start());
2138 ASSERT_TRUE(https_server_.Start());
2140 std::string replacement_path;
2141 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2142 "files/ssl/page_displays_insecure_content.html",
2143 test_server()->host_port_pair(),
2144 &replacement_path));
2146 ui_test_utils::NavigateToURL(browser(),
2147 https_server_.GetURL(replacement_path));
2149 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
2150 AuthState::NONE);
2153 // Test that when the browser blocks displaying insecure content (iframes), the
2154 // indicator shows a secure page, because the blocking made the otherwise
2155 // unsafe page safe (the notification of this state is handled by other means)
2156 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureIframe) {
2157 ASSERT_TRUE(test_server()->Start());
2158 ASSERT_TRUE(https_server_.Start());
2160 std::string replacement_path;
2161 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2162 "files/ssl/page_displays_insecure_iframe.html",
2163 test_server()->host_port_pair(),
2164 &replacement_path));
2166 ui_test_utils::NavigateToURL(browser(),
2167 https_server_.GetURL(replacement_path));
2169 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
2170 AuthState::NONE);
2173 // Test that when the browser blocks running insecure content, the
2174 // indicator shows a secure page, because the blocking made the otherwise
2175 // unsafe page safe (the notification of this state is handled by other means).
2176 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockRunningInsecureContent) {
2177 ASSERT_TRUE(test_server()->Start());
2178 ASSERT_TRUE(https_server_.Start());
2180 std::string replacement_path;
2181 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2182 "files/ssl/page_runs_insecure_content.html",
2183 test_server()->host_port_pair(),
2184 &replacement_path));
2186 ui_test_utils::NavigateToURL(browser(),
2187 https_server_.GetURL(replacement_path));
2189 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
2190 AuthState::NONE);
2193 // Visit a page and establish a WebSocket connection over bad https with
2194 // --ignore-certificate-errors. The connection should be established without
2195 // interstitial page showing.
2196 IN_PROC_BROWSER_TEST_F(SSLUITestIgnoreCertErrors, TestWSS) {
2197 ASSERT_TRUE(test_server()->Start());
2198 ASSERT_TRUE(wss_server_expired_.Start());
2200 // Setup page title observer.
2201 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2202 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
2203 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
2205 // Visit bad HTTPS page.
2206 GURL::Replacements replacements;
2207 replacements.SetSchemeStr("https");
2208 ui_test_utils::NavigateToURL(
2209 browser(),
2210 wss_server_expired_.GetURL(
2211 "connect_check.html").ReplaceComponents(replacements));
2213 // We shouldn't have an interstitial page showing here.
2215 // Test page run a WebSocket wss connection test. The result will be shown
2216 // as page title.
2217 const base::string16 result = watcher.WaitAndGetTitle();
2218 EXPECT_TRUE(base::LowerCaseEqualsASCII(result, "pass"));
2221 // Verifies that the interstitial can proceed, even if JavaScript is disabled.
2222 // http://crbug.com/322948
2223 #if defined(OS_LINUX)
2224 // flaky http://crbug.com/396458
2225 #define MAYBE_TestInterstitialJavaScriptProceeds \
2226 DISABLED_TestInterstitialJavaScriptProceeds
2227 #else
2228 #define MAYBE_TestInterstitialJavaScriptProceeds \
2229 TestInterstitialJavaScriptProceeds
2230 #endif
2231 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestInterstitialJavaScriptProceeds) {
2232 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
2233 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK);
2235 ASSERT_TRUE(https_server_expired_.Start());
2236 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2237 ui_test_utils::NavigateToURL(browser(),
2238 https_server_expired_.GetURL("files/ssl/google.html"));
2239 CheckAuthenticationBrokenState(
2240 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
2242 content::WindowedNotificationObserver observer(
2243 content::NOTIFICATION_LOAD_STOP,
2244 content::Source<NavigationController>(&tab->GetController()));
2245 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
2246 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
2247 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
2248 content::RenderViewHost* interstitial_rvh =
2249 interstitial_page->GetMainFrame()->GetRenderViewHost();
2250 int result = -1;
2251 std::string javascript = base::StringPrintf(
2252 "window.domAutomationController.send(%d);",
2253 SecurityInterstitialPage::CMD_PROCEED);
2254 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
2255 interstitial_rvh, javascript, &result));
2256 // The above will hang without the fix.
2257 EXPECT_EQ(1, result);
2258 observer.Wait();
2259 CheckAuthenticationBrokenState(
2260 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
2263 // Verifies that the interstitial can go back, even if JavaScript is disabled.
2264 // http://crbug.com/322948
2265 IN_PROC_BROWSER_TEST_F(SSLUITest, TestInterstitialJavaScriptGoesBack) {
2266 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
2267 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK);
2269 ASSERT_TRUE(https_server_expired_.Start());
2270 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2271 ui_test_utils::NavigateToURL(browser(),
2272 https_server_expired_.GetURL("files/ssl/google.html"));
2273 CheckAuthenticationBrokenState(
2274 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
2276 content::WindowedNotificationObserver observer(
2277 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
2278 content::NotificationService::AllSources());
2279 InterstitialPage* interstitial_page = tab->GetInterstitialPage();
2280 ASSERT_EQ(SSLBlockingPage::kTypeForTesting,
2281 interstitial_page->GetDelegateForTesting()->GetTypeForTesting());
2282 content::RenderViewHost* interstitial_rvh =
2283 interstitial_page->GetMainFrame()->GetRenderViewHost();
2284 int result = -1;
2285 std::string javascript = base::StringPrintf(
2286 "window.domAutomationController.send(%d);",
2287 SecurityInterstitialPage::CMD_DONT_PROCEED);
2288 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
2289 interstitial_rvh, javascript, &result));
2290 // The above will hang without the fix.
2291 EXPECT_EQ(0, result);
2292 observer.Wait();
2293 EXPECT_EQ("about:blank", tab->GetVisibleURL().spec());
2296 // Verifies that switching tabs, while showing interstitial page, will not
2297 // affect the visibility of the interestitial.
2298 // https://crbug.com/381439
2299 IN_PROC_BROWSER_TEST_F(SSLUITest, InterstitialNotAffectedByHideShow) {
2300 ASSERT_TRUE(https_server_expired_.Start());
2301 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2302 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
2303 ui_test_utils::NavigateToURL(
2304 browser(), https_server_expired_.GetURL("files/ssl/google.html"));
2305 CheckAuthenticationBrokenState(
2306 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
2307 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
2309 AddTabAtIndex(0,
2310 https_server_.GetURL("files/ssl/google.html"),
2311 ui::PAGE_TRANSITION_TYPED);
2312 EXPECT_EQ(2, browser()->tab_strip_model()->count());
2313 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
2314 EXPECT_EQ(tab, browser()->tab_strip_model()->GetWebContentsAt(1));
2315 EXPECT_FALSE(tab->GetRenderWidgetHostView()->IsShowing());
2317 browser()->tab_strip_model()->ActivateTabAt(1, true);
2318 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
2321 // Verifies that if a bad certificate is seen for a host and the user proceeds
2322 // through the interstitial, the decision to proceed is initially remembered.
2323 // However, if this is followed by another visit, and a good certificate
2324 // is seen for the same host, the original exception is forgotten.
2325 IN_PROC_BROWSER_TEST_F(SSLUITest, BadCertFollowedByGoodCert) {
2326 // It is necessary to use |https_server_expired_| rather than
2327 // |https_server_mismatched| because the former shares a host with
2328 // |https_server_| and cert exceptions are per host.
2329 ASSERT_TRUE(https_server_expired_.Start());
2330 ASSERT_TRUE(https_server_.Start());
2332 std::string https_server_expired_host =
2333 https_server_.GetURL("files/ssl/google.html").host();
2334 std::string https_server_host =
2335 https_server_.GetURL("files/ssl/google.html").host();
2336 ASSERT_EQ(https_server_expired_host, https_server_host);
2338 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2340 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
2341 ChromeSSLHostStateDelegate* state =
2342 reinterpret_cast<ChromeSSLHostStateDelegate*>(
2343 profile->GetSSLHostStateDelegate());
2345 ui_test_utils::NavigateToURL(
2346 browser(), https_server_expired_.GetURL("files/ssl/google.html"));
2348 ProceedThroughInterstitial(tab);
2349 EXPECT_TRUE(state->HasAllowException(https_server_host));
2351 ui_test_utils::NavigateToURL(browser(),
2352 https_server_.GetURL("files/ssl/google.html"));
2353 ASSERT_FALSE(tab->GetInterstitialPage());
2354 EXPECT_FALSE(state->HasAllowException(https_server_host));
2357 class CommonNameMismatchBrowserTest : public CertVerifierBrowserTest {
2358 public:
2359 CommonNameMismatchBrowserTest() : CertVerifierBrowserTest() {}
2360 ~CommonNameMismatchBrowserTest() override {}
2362 void SetUpCommandLine(base::CommandLine* command_line) override {
2363 // Enable finch experiment for SSL common name mismatch handling.
2364 command_line->AppendSwitchASCII(switches::kForceFieldTrials,
2365 "SSLCommonNameMismatchHandling/Enabled/");
2369 // Visit the URL www.mail.example.com on a server that presents a valid
2370 // certificate for mail.example.com. Verify that the page navigates to
2371 // mail.example.com.
2372 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
2373 ShouldShowWWWSubdomainMismatchInterstitial) {
2374 net::SpawnedTestServer https_server_example_domain_(
2375 net::SpawnedTestServer::TYPE_HTTPS,
2376 net::SpawnedTestServer::SSLOptions(
2377 net::SpawnedTestServer::SSLOptions::CERT_OK),
2378 base::FilePath(kDocRoot));
2379 ASSERT_TRUE(https_server_example_domain_.Start());
2381 host_resolver()->AddRule(
2382 "mail.example.com", https_server_example_domain_.host_port_pair().host());
2383 host_resolver()->AddRule(
2384 "www.mail.example.com",
2385 https_server_example_domain_.host_port_pair().host());
2387 scoped_refptr<net::X509Certificate> cert =
2388 https_server_example_domain_.GetCertificate();
2390 // Use the "spdy_pooling.pem" cert which has "mail.example.com"
2391 // as one of its SANs.
2392 net::CertVerifyResult verify_result;
2393 verify_result.verified_cert =
2394 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2395 verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
2397 // Request to "www.mail.example.com" should result in
2398 // |net::ERR_CERT_COMMON_NAME_INVALID| error.
2399 mock_cert_verifier()->AddResultForCertAndHost(
2400 cert.get(), "www.mail.example.com", verify_result,
2401 net::ERR_CERT_COMMON_NAME_INVALID);
2403 net::CertVerifyResult verify_result_valid;
2404 verify_result_valid.verified_cert =
2405 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2406 // Request to "www.mail.example.com" should not result in any error.
2407 mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "mail.example.com",
2408 verify_result_valid, net::OK);
2410 // Use a complex URL to ensure the path, etc., are preserved. The path itself
2411 // does not matter.
2412 GURL https_server_url =
2413 https_server_example_domain_.GetURL("files/ssl/google.html?a=b#anchor");
2414 GURL::Replacements replacements;
2415 replacements.SetHostStr("www.mail.example.com");
2416 GURL https_server_mismatched_url =
2417 https_server_url.ReplaceComponents(replacements);
2419 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
2420 content::TestNavigationObserver observer(contents, 2);
2421 ui_test_utils::NavigateToURL(browser(), https_server_mismatched_url);
2422 observer.Wait();
2424 CheckSecurityState(contents, CertError::NONE,
2425 content::SECURITY_STYLE_AUTHENTICATED, AuthState::NONE);
2426 replacements.SetHostStr("mail.example.com");
2427 GURL https_server_new_url = https_server_url.ReplaceComponents(replacements);
2428 // Verify that the current URL is the suggested URL.
2429 EXPECT_EQ(https_server_new_url.spec(),
2430 contents->GetLastCommittedURL().spec());
2433 // Visit the URL example.org on a server that presents a valid certificate
2434 // for www.example.org. Verify that the page redirects to www.example.org.
2435 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
2436 CheckWWWSubdomainMismatchInverse) {
2437 net::SpawnedTestServer https_server_example_domain_(
2438 net::SpawnedTestServer::TYPE_HTTPS,
2439 net::SpawnedTestServer::SSLOptions(
2440 net::SpawnedTestServer::SSLOptions::CERT_OK),
2441 base::FilePath(kDocRoot));
2442 ASSERT_TRUE(https_server_example_domain_.Start());
2444 host_resolver()->AddRule(
2445 "www.example.org", https_server_example_domain_.host_port_pair().host());
2446 host_resolver()->AddRule(
2447 "example.org", https_server_example_domain_.host_port_pair().host());
2449 scoped_refptr<net::X509Certificate> cert =
2450 https_server_example_domain_.GetCertificate();
2452 net::CertVerifyResult verify_result;
2453 verify_result.verified_cert =
2454 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2455 verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
2457 mock_cert_verifier()->AddResultForCertAndHost(
2458 cert.get(), "example.org", verify_result,
2459 net::ERR_CERT_COMMON_NAME_INVALID);
2461 net::CertVerifyResult verify_result_valid;
2462 verify_result_valid.verified_cert =
2463 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2464 mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "www.example.org",
2465 verify_result_valid, net::OK);
2467 GURL https_server_url =
2468 https_server_example_domain_.GetURL("files/ssl/google.html?a=b");
2469 GURL::Replacements replacements;
2470 replacements.SetHostStr("example.org");
2471 GURL https_server_mismatched_url =
2472 https_server_url.ReplaceComponents(replacements);
2474 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
2475 content::TestNavigationObserver observer(contents, 2);
2476 ui_test_utils::NavigateToURL(browser(), https_server_mismatched_url);
2477 observer.Wait();
2479 CheckSecurityState(contents, CertError::NONE,
2480 content::SECURITY_STYLE_AUTHENTICATED, AuthState::NONE);
2483 // Tests this scenario:
2484 // - |CommonNameMismatchHandler| does not give a callback as it's set into the
2485 // state |IGNORE_REQUESTS_FOR_TESTING|. So no suggested URL check result can
2486 // arrive.
2487 // - A cert error triggers an interstitial timer with a very long timeout.
2488 // - No suggested URL check results arrive, causing the tab to appear as loading
2489 // indefinitely (also because the timer has a long timeout).
2490 // - Stopping the page load shouldn't result in any interstitials.
2491 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
2492 InterstitialStopNavigationWhileLoading) {
2493 net::SpawnedTestServer https_server_example_domain_(
2494 net::SpawnedTestServer::TYPE_HTTPS,
2495 net::SpawnedTestServer::SSLOptions(
2496 net::SpawnedTestServer::SSLOptions::CERT_OK),
2497 base::FilePath(kDocRoot));
2498 ASSERT_TRUE(https_server_example_domain_.Start());
2500 host_resolver()->AddRule(
2501 "mail.example.com", https_server_example_domain_.host_port_pair().host());
2502 host_resolver()->AddRule(
2503 "www.mail.example.com",
2504 https_server_example_domain_.host_port_pair().host());
2506 scoped_refptr<net::X509Certificate> cert =
2507 https_server_example_domain_.GetCertificate();
2509 net::CertVerifyResult verify_result;
2510 verify_result.verified_cert =
2511 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2512 verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
2514 mock_cert_verifier()->AddResultForCertAndHost(
2515 cert.get(), "www.mail.example.com", verify_result,
2516 net::ERR_CERT_COMMON_NAME_INVALID);
2518 net::CertVerifyResult verify_result_valid;
2519 verify_result_valid.verified_cert =
2520 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2521 mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "mail.example.com",
2522 verify_result_valid, net::OK);
2524 GURL https_server_url =
2525 https_server_example_domain_.GetURL("files/ssl/google.html?a=b");
2526 GURL::Replacements replacements;
2527 replacements.SetHostStr("www.mail.example.com");
2528 GURL https_server_mismatched_url =
2529 https_server_url.ReplaceComponents(replacements);
2531 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
2532 CommonNameMismatchHandler::set_state_for_testing(
2533 CommonNameMismatchHandler::IGNORE_REQUESTS_FOR_TESTING);
2534 // Set delay long enough so that the page appears loading.
2535 SSLErrorHandler::SetInterstitialDelayForTest(base::TimeDelta::FromHours(1));
2536 SSLInterstitialTimerObserver interstitial_timer_observer(contents);
2538 ui_test_utils::NavigateToURLWithDisposition(
2539 browser(), https_server_mismatched_url, CURRENT_TAB,
2540 ui_test_utils::BROWSER_TEST_NONE);
2541 interstitial_timer_observer.WaitForTimerStarted();
2543 EXPECT_TRUE(contents->IsLoading());
2544 content::WindowedNotificationObserver observer(
2545 content::NOTIFICATION_LOAD_STOP,
2546 content::NotificationService::AllSources());
2547 contents->Stop();
2548 observer.Wait();
2550 SSLErrorHandler* ssl_error_handler =
2551 SSLErrorHandler::FromWebContents(contents);
2552 // Make sure that the |SSLErrorHandler| is deleted.
2553 EXPECT_FALSE(ssl_error_handler);
2554 EXPECT_FALSE(contents->ShowingInterstitialPage());
2555 EXPECT_FALSE(contents->IsLoading());
2558 // Same as above, but instead of stopping, the loading page is reloaded. The end
2559 // result is the same. (i.e. page load stops, no interstitials shown)
2560 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
2561 InterstitialReloadNavigationWhileLoading) {
2562 net::SpawnedTestServer https_server_example_domain_(
2563 net::SpawnedTestServer::TYPE_HTTPS,
2564 net::SpawnedTestServer::SSLOptions(
2565 net::SpawnedTestServer::SSLOptions::CERT_OK),
2566 base::FilePath(kDocRoot));
2567 ASSERT_TRUE(https_server_example_domain_.Start());
2569 host_resolver()->AddRule(
2570 "mail.example.com", https_server_example_domain_.host_port_pair().host());
2571 host_resolver()->AddRule(
2572 "www.mail.example.com",
2573 https_server_example_domain_.host_port_pair().host());
2575 scoped_refptr<net::X509Certificate> cert =
2576 https_server_example_domain_.GetCertificate();
2578 net::CertVerifyResult verify_result;
2579 verify_result.verified_cert =
2580 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2581 verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
2583 mock_cert_verifier()->AddResultForCertAndHost(
2584 cert.get(), "www.mail.example.com", verify_result,
2585 net::ERR_CERT_COMMON_NAME_INVALID);
2587 net::CertVerifyResult verify_result_valid;
2588 verify_result_valid.verified_cert =
2589 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2590 mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "mail.example.com",
2591 verify_result_valid, net::OK);
2593 GURL https_server_url =
2594 https_server_example_domain_.GetURL("files/ssl/google.html?a=b");
2595 GURL::Replacements replacements;
2596 replacements.SetHostStr("www.mail.example.com");
2597 GURL https_server_mismatched_url =
2598 https_server_url.ReplaceComponents(replacements);
2600 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
2601 CommonNameMismatchHandler::set_state_for_testing(
2602 CommonNameMismatchHandler::IGNORE_REQUESTS_FOR_TESTING);
2603 // Set delay long enough so that the page appears loading.
2604 SSLErrorHandler::SetInterstitialDelayForTest(base::TimeDelta::FromHours(1));
2605 SSLInterstitialTimerObserver interstitial_timer_observer(contents);
2607 ui_test_utils::NavigateToURLWithDisposition(
2608 browser(), https_server_mismatched_url, CURRENT_TAB,
2609 ui_test_utils::BROWSER_TEST_NONE);
2610 interstitial_timer_observer.WaitForTimerStarted();
2612 EXPECT_TRUE(contents->IsLoading());
2613 content::TestNavigationObserver observer(contents, 1);
2614 chrome::Reload(browser(), CURRENT_TAB);
2615 observer.Wait();
2617 SSLErrorHandler* ssl_error_handler =
2618 SSLErrorHandler::FromWebContents(contents);
2619 // Make sure that the |SSLErrorHandler| is deleted.
2620 EXPECT_FALSE(ssl_error_handler);
2621 EXPECT_FALSE(contents->ShowingInterstitialPage());
2622 EXPECT_FALSE(contents->IsLoading());
2625 // Same as above, but instead of reloading, the page is navigated away. The
2626 // new page should load, and no interstitials should be shown.
2627 IN_PROC_BROWSER_TEST_F(CommonNameMismatchBrowserTest,
2628 InterstitialNavigateAwayWhileLoading) {
2629 net::SpawnedTestServer https_server_example_domain_(
2630 net::SpawnedTestServer::TYPE_HTTPS,
2631 net::SpawnedTestServer::SSLOptions(
2632 net::SpawnedTestServer::SSLOptions::CERT_OK),
2633 base::FilePath(kDocRoot));
2634 ASSERT_TRUE(https_server_example_domain_.Start());
2636 host_resolver()->AddRule(
2637 "mail.example.com", https_server_example_domain_.host_port_pair().host());
2638 host_resolver()->AddRule(
2639 "www.mail.example.com",
2640 https_server_example_domain_.host_port_pair().host());
2642 scoped_refptr<net::X509Certificate> cert =
2643 https_server_example_domain_.GetCertificate();
2645 net::CertVerifyResult verify_result;
2646 verify_result.verified_cert =
2647 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2648 verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
2650 mock_cert_verifier()->AddResultForCertAndHost(
2651 cert.get(), "www.mail.example.com", verify_result,
2652 net::ERR_CERT_COMMON_NAME_INVALID);
2654 net::CertVerifyResult verify_result_valid;
2655 verify_result_valid.verified_cert =
2656 net::ImportCertFromFile(net::GetTestCertsDirectory(), "spdy_pooling.pem");
2657 mock_cert_verifier()->AddResultForCertAndHost(cert.get(), "mail.example.com",
2658 verify_result_valid, net::OK);
2660 GURL https_server_url =
2661 https_server_example_domain_.GetURL("files/ssl/google.html?a=b");
2662 GURL::Replacements replacements;
2663 replacements.SetHostStr("www.mail.example.com");
2664 GURL https_server_mismatched_url =
2665 https_server_url.ReplaceComponents(replacements);
2667 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
2668 CommonNameMismatchHandler::set_state_for_testing(
2669 CommonNameMismatchHandler::IGNORE_REQUESTS_FOR_TESTING);
2670 // Set delay long enough so that the page appears loading.
2671 SSLErrorHandler::SetInterstitialDelayForTest(base::TimeDelta::FromHours(1));
2672 SSLInterstitialTimerObserver interstitial_timer_observer(contents);
2674 ui_test_utils::NavigateToURLWithDisposition(
2675 browser(), https_server_mismatched_url, CURRENT_TAB,
2676 ui_test_utils::BROWSER_TEST_NONE);
2677 interstitial_timer_observer.WaitForTimerStarted();
2679 EXPECT_TRUE(contents->IsLoading());
2680 content::TestNavigationObserver observer(contents, 1);
2681 browser()->OpenURL(content::OpenURLParams(GURL("https://google.com"),
2682 content::Referrer(), CURRENT_TAB,
2683 ui::PAGE_TRANSITION_TYPED, false));
2684 observer.Wait();
2686 SSLErrorHandler* ssl_error_handler =
2687 SSLErrorHandler::FromWebContents(contents);
2688 // Make sure that the |SSLErrorHandler| is deleted.
2689 EXPECT_FALSE(ssl_error_handler);
2690 EXPECT_FALSE(contents->ShowingInterstitialPage());
2691 EXPECT_FALSE(contents->IsLoading());
2694 class SSLBlockingPageIDNTest : public SecurityInterstitialIDNTest {
2695 protected:
2696 // SecurityInterstitialIDNTest implementation
2697 SecurityInterstitialPage* CreateInterstitial(
2698 content::WebContents* contents,
2699 const GURL& request_url) const override {
2700 net::SSLInfo ssl_info;
2701 ssl_info.cert = new net::X509Certificate(
2702 request_url.host(), "CA", base::Time::Max(), base::Time::Max());
2703 return new SSLBlockingPage(
2704 contents, net::ERR_CERT_CONTAINS_ERRORS, ssl_info, request_url, 0,
2705 base::Time::NowFromSystemTime(), nullptr, base::Callback<void(bool)>());
2709 IN_PROC_BROWSER_TEST_F(SSLBlockingPageIDNTest, SSLBlockingPageDecodesIDN) {
2710 EXPECT_TRUE(VerifyIDNDecoded());
2713 IN_PROC_BROWSER_TEST_F(CertVerifierBrowserTest, MockCertVerifierSmokeTest) {
2714 net::SpawnedTestServer https_server(
2715 net::SpawnedTestServer::TYPE_HTTPS,
2716 net::SpawnedTestServer::SSLOptions(
2717 net::SpawnedTestServer::SSLOptions::CERT_OK),
2718 base::FilePath(kDocRoot));
2719 ASSERT_TRUE(https_server.Start());
2721 mock_cert_verifier()->set_default_result(
2722 net::ERR_CERT_NAME_CONSTRAINT_VIOLATION);
2724 ui_test_utils::NavigateToURL(browser(),
2725 https_server.GetURL("files/ssl/google.html"));
2727 CheckSecurityState(browser()->tab_strip_model()->GetActiveWebContents(),
2728 net::CERT_STATUS_NAME_CONSTRAINT_VIOLATION,
2729 content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
2730 AuthState::SHOWING_INTERSTITIAL);
2733 // TODO(jcampan): more tests to do below.
2735 // Visit a page over https that contains a frame with a redirect.
2737 // XMLHttpRequest insecure content in synchronous mode.
2739 // XMLHttpRequest insecure content in asynchronous mode.
2741 // XMLHttpRequest over bad ssl in synchronous mode.
2743 // XMLHttpRequest over OK ssl in synchronous mode.