ssl_browser_tests.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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.
4
5#include "base/command_line.h"
6#include "base/path_service.h"
7#include "base/prefs/pref_service.h"
8#include "base/strings/string_util.h"
9#include "base/strings/stringprintf.h"
10#include "base/strings/utf_string_conversions.h"
11#include "base/time/time.h"
12#include "chrome/app/chrome_command_ids.h"
13#include "chrome/browser/chrome_notification_types.h"
14#include "chrome/browser/content_settings/host_content_settings_map.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/ssl/ssl_blocking_page.h"
17#include "chrome/browser/ui/browser.h"
18#include "chrome/browser/ui/browser_commands.h"
19#include "chrome/browser/ui/browser_navigator.h"
20#include "chrome/browser/ui/browser_tabstrip.h"
21#include "chrome/browser/ui/tabs/tab_strip_model.h"
22#include "chrome/common/chrome_paths.h"
23#include "chrome/common/chrome_switches.h"
24#include "chrome/common/pref_names.h"
25#include "chrome/test/base/in_process_browser_test.h"
26#include "chrome/test/base/ui_test_utils.h"
27#include "components/web_modal/web_contents_modal_dialog_manager.h"
28#include "content/public/browser/browser_context.h"
29#include "content/public/browser/interstitial_page.h"
30#include "content/public/browser/navigation_controller.h"
31#include "content/public/browser/navigation_entry.h"
32#include "content/public/browser/notification_service.h"
33#include "content/public/browser/render_view_host.h"
34#include "content/public/browser/render_widget_host_view.h"
35#include "content/public/browser/web_contents.h"
36#include "content/public/browser/web_contents_observer.h"
37#include "content/public/common/security_style.h"
38#include "content/public/common/ssl_status.h"
39#include "content/public/test/browser_test_utils.h"
40#include "content/public/test/download_test_observer.h"
41#include "content/public/test/test_renderer_host.h"
42#include "crypto/nss_util.h"
43#include "net/base/crypto_module.h"
44#include "net/base/net_errors.h"
45#include "net/base/test_data_directory.h"
46#include "net/cert/cert_status_flags.h"
47#include "net/test/spawned_test_server/spawned_test_server.h"
48
49#if defined(USE_NSS)
50#include "net/cert/nss_cert_database.h"
51#endif  // defined(USE_NSS)
52
53using base::ASCIIToUTF16;
54using content::InterstitialPage;
55using content::NavigationController;
56using content::NavigationEntry;
57using content::SSLStatus;
58using content::WebContents;
59using web_modal::WebContentsModalDialogManager;
60
61const base::FilePath::CharType kDocRoot[] =
62    FILE_PATH_LITERAL("chrome/test/data");
63
64namespace {
65
66class ProvisionalLoadWaiter : public content::WebContentsObserver {
67 public:
68  explicit ProvisionalLoadWaiter(WebContents* tab)
69    : WebContentsObserver(tab), waiting_(false), seen_(false) {}
70
71  void Wait() {
72    if (seen_)
73      return;
74
75    waiting_ = true;
76    content::RunMessageLoop();
77  }
78
79  virtual void DidFailProvisionalLoad(
80      content::RenderFrameHost* render_frame_host,
81      const GURL& validated_url,
82      int error_code,
83      const base::string16& error_description) OVERRIDE {
84    seen_ = true;
85    if (waiting_)
86      base::MessageLoopForUI::current()->Quit();
87  }
88
89 private:
90  bool waiting_;
91  bool seen_;
92};
93
94namespace AuthState {
95
96enum AuthStateFlags {
97  NONE = 0,
98  DISPLAYED_INSECURE_CONTENT = 1 << 0,
99  RAN_INSECURE_CONTENT = 1 << 1,
100  SHOWING_INTERSTITIAL = 1 << 2
101};
102
103void Check(const NavigationEntry& entry, int expected_authentication_state) {
104  EXPECT_EQ(!!(expected_authentication_state & AuthState::SHOWING_INTERSTITIAL)
105                ? content::PAGE_TYPE_INTERSTITIAL
106                : content::PAGE_TYPE_NORMAL,
107            entry.GetPageType());
108
109  bool displayed_insecure_content =
110      !!(entry.GetSSL().content_status & SSLStatus::DISPLAYED_INSECURE_CONTENT);
111  EXPECT_EQ(
112      !!(expected_authentication_state & AuthState::DISPLAYED_INSECURE_CONTENT),
113      displayed_insecure_content);
114
115  bool ran_insecure_content =
116      !!(entry.GetSSL().content_status & SSLStatus::RAN_INSECURE_CONTENT);
117  EXPECT_EQ(!!(expected_authentication_state & AuthState::RAN_INSECURE_CONTENT),
118            ran_insecure_content);
119}
120
121}  // namespace AuthState
122
123namespace SecurityStyle {
124
125void Check(const NavigationEntry& entry,
126           content::SecurityStyle expected_security_style) {
127  EXPECT_EQ(expected_security_style, entry.GetSSL().security_style);
128}
129
130}  // namespace SecurityStyle
131
132namespace CertError {
133
134enum CertErrorFlags {
135  NONE = 0
136};
137
138void Check(const NavigationEntry& entry, net::CertStatus error) {
139  if (error) {
140    EXPECT_EQ(error, entry.GetSSL().cert_status & error);
141    net::CertStatus extra_cert_errors =
142        error ^ (entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS);
143    if (extra_cert_errors)
144      LOG(WARNING) << "Got unexpected cert error: " << extra_cert_errors;
145  } else {
146    EXPECT_EQ(0U, entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS);
147  }
148}
149
150}  // namespace CertError
151
152void CheckSecurityState(WebContents* tab,
153                        net::CertStatus error,
154                        content::SecurityStyle expected_security_style,
155                        int expected_authentication_state) {
156  ASSERT_FALSE(tab->IsCrashed());
157  NavigationEntry* entry = tab->GetController().GetActiveEntry();
158  ASSERT_TRUE(entry);
159  CertError::Check(*entry, error);
160  SecurityStyle::Check(*entry, expected_security_style);
161  AuthState::Check(*entry, expected_authentication_state);
162}
163
164}  // namespace
165
166class SSLUITest : public InProcessBrowserTest {
167 public:
168  SSLUITest()
169      : https_server_(net::SpawnedTestServer::TYPE_HTTPS,
170                      SSLOptions(SSLOptions::CERT_OK),
171                      base::FilePath(kDocRoot)),
172        https_server_expired_(net::SpawnedTestServer::TYPE_HTTPS,
173                              SSLOptions(SSLOptions::CERT_EXPIRED),
174                              base::FilePath(kDocRoot)),
175        https_server_mismatched_(net::SpawnedTestServer::TYPE_HTTPS,
176                                 SSLOptions(SSLOptions::CERT_MISMATCHED_NAME),
177                                 base::FilePath(kDocRoot)),
178        wss_server_expired_(net::SpawnedTestServer::TYPE_WSS,
179                            SSLOptions(SSLOptions::CERT_EXPIRED),
180                            net::GetWebSocketTestDataDirectory()) {}
181
182  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
183    // Browser will both run and display insecure content.
184    command_line->AppendSwitch(switches::kAllowRunningInsecureContent);
185    // Use process-per-site so that navigating to a same-site page in a
186    // new tab will use the same process.
187    command_line->AppendSwitch(switches::kProcessPerSite);
188  }
189
190  void CheckAuthenticatedState(WebContents* tab,
191                               int expected_authentication_state) {
192    CheckSecurityState(tab,
193                       CertError::NONE,
194                       content::SECURITY_STYLE_AUTHENTICATED,
195                       expected_authentication_state);
196  }
197
198  void CheckUnauthenticatedState(WebContents* tab) {
199    CheckSecurityState(tab,
200                       CertError::NONE,
201                       content::SECURITY_STYLE_UNAUTHENTICATED,
202                       AuthState::NONE);
203  }
204
205  void CheckAuthenticationBrokenState(WebContents* tab,
206                                      net::CertStatus error,
207                                      int expected_authentication_state) {
208    CheckSecurityState(tab,
209                       error,
210                       content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
211                       expected_authentication_state);
212    // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION doesn't lower the security style
213    // to SECURITY_STYLE_AUTHENTICATION_BROKEN.
214    ASSERT_NE(net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, error);
215  }
216
217  void CheckWorkerLoadResult(WebContents* tab, bool expected_load) {
218    // Workers are async and we don't have notifications for them passing
219    // messages since they do it between renderer and worker processes.
220    // So have a polling loop, check every 200ms, timeout at 30s.
221    const int kTimeoutMS = 200;
222    base::Time time_to_quit = base::Time::Now() +
223        base::TimeDelta::FromMilliseconds(30000);
224
225    while (base::Time::Now() < time_to_quit) {
226      bool worker_finished = false;
227      ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
228          tab,
229          "window.domAutomationController.send(IsWorkerFinished());",
230          &worker_finished));
231
232      if (worker_finished)
233        break;
234
235      // Wait a bit.
236      base::MessageLoop::current()->PostDelayedTask(
237          FROM_HERE,
238          base::MessageLoop::QuitClosure(),
239          base::TimeDelta::FromMilliseconds(kTimeoutMS));
240      content::RunMessageLoop();
241    }
242
243    bool actually_loaded_content = false;
244    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
245        tab,
246        "window.domAutomationController.send(IsContentLoaded());",
247        &actually_loaded_content));
248    EXPECT_EQ(expected_load, actually_loaded_content);
249  }
250
251  void ProceedThroughInterstitial(WebContents* tab) {
252    InterstitialPage* interstitial_page = tab->GetInterstitialPage();
253    ASSERT_TRUE(interstitial_page);
254    content::WindowedNotificationObserver observer(
255        content::NOTIFICATION_LOAD_STOP,
256        content::Source<NavigationController>(&tab->GetController()));
257    interstitial_page->Proceed();
258    observer.Wait();
259  }
260
261  bool IsShowingWebContentsModalDialog() const {
262    return WebContentsModalDialogManager::FromWebContents(
263        browser()->tab_strip_model()->GetActiveWebContents())->
264            IsDialogActive();
265  }
266
267  static bool GetFilePathWithHostAndPortReplacement(
268      const std::string& original_file_path,
269      const net::HostPortPair& host_port_pair,
270      std::string* replacement_path) {
271    std::vector<net::SpawnedTestServer::StringPair> replacement_text;
272    replacement_text.push_back(
273        make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
274    return net::SpawnedTestServer::GetFilePathWithReplacements(
275        original_file_path, replacement_text, replacement_path);
276  }
277
278  static bool GetTopFramePath(const net::SpawnedTestServer& http_server,
279                              const net::SpawnedTestServer& good_https_server,
280                              const net::SpawnedTestServer& bad_https_server,
281                              std::string* top_frame_path) {
282    // The "frame_left.html" page contained in the top_frame.html page contains
283    // <a href>'s to three different servers. This sets up all of the
284    // replacement text to work with test servers which listen on ephemeral
285    // ports.
286    GURL http_url = http_server.GetURL("files/ssl/google.html");
287    GURL good_https_url = good_https_server.GetURL("files/ssl/google.html");
288    GURL bad_https_url = bad_https_server.GetURL(
289        "files/ssl/bad_iframe.html");
290
291    std::vector<net::SpawnedTestServer::StringPair> replacement_text_frame_left;
292    replacement_text_frame_left.push_back(
293        make_pair("REPLACE_WITH_HTTP_PAGE", http_url.spec()));
294    replacement_text_frame_left.push_back(
295        make_pair("REPLACE_WITH_GOOD_HTTPS_PAGE", good_https_url.spec()));
296    replacement_text_frame_left.push_back(
297        make_pair("REPLACE_WITH_BAD_HTTPS_PAGE", bad_https_url.spec()));
298    std::string frame_left_path;
299    if (!net::SpawnedTestServer::GetFilePathWithReplacements(
300            "frame_left.html",
301            replacement_text_frame_left,
302            &frame_left_path))
303      return false;
304
305    // Substitute the generated frame_left URL into the top_frame page.
306    std::vector<net::SpawnedTestServer::StringPair> replacement_text_top_frame;
307    replacement_text_top_frame.push_back(
308        make_pair("REPLACE_WITH_FRAME_LEFT_PATH", frame_left_path));
309    return net::SpawnedTestServer::GetFilePathWithReplacements(
310        "files/ssl/top_frame.html",
311        replacement_text_top_frame,
312        top_frame_path);
313  }
314
315  static bool GetPageWithUnsafeWorkerPath(
316      const net::SpawnedTestServer& expired_https_server,
317      std::string* page_with_unsafe_worker_path) {
318    // Get the "imported.js" URL from the expired https server and
319    // substitute it into the unsafe_worker.js file.
320    GURL imported_js_url = expired_https_server.GetURL("files/ssl/imported.js");
321    std::vector<net::SpawnedTestServer::StringPair>
322        replacement_text_for_unsafe_worker;
323    replacement_text_for_unsafe_worker.push_back(
324        make_pair("REPLACE_WITH_IMPORTED_JS_URL", imported_js_url.spec()));
325    std::string unsafe_worker_path;
326    if (!net::SpawnedTestServer::GetFilePathWithReplacements(
327        "unsafe_worker.js",
328        replacement_text_for_unsafe_worker,
329        &unsafe_worker_path))
330      return false;
331
332    // Now, substitute this into the page with unsafe worker.
333    std::vector<net::SpawnedTestServer::StringPair>
334        replacement_text_for_page_with_unsafe_worker;
335    replacement_text_for_page_with_unsafe_worker.push_back(
336        make_pair("REPLACE_WITH_UNSAFE_WORKER_PATH", unsafe_worker_path));
337    return net::SpawnedTestServer::GetFilePathWithReplacements(
338        "files/ssl/page_with_unsafe_worker.html",
339        replacement_text_for_page_with_unsafe_worker,
340        page_with_unsafe_worker_path);
341  }
342
343  net::SpawnedTestServer https_server_;
344  net::SpawnedTestServer https_server_expired_;
345  net::SpawnedTestServer https_server_mismatched_;
346  net::SpawnedTestServer wss_server_expired_;
347
348 private:
349  typedef net::SpawnedTestServer::SSLOptions SSLOptions;
350
351  DISALLOW_COPY_AND_ASSIGN(SSLUITest);
352};
353
354class SSLUITestBlock : public SSLUITest {
355 public:
356  SSLUITestBlock() : SSLUITest() {}
357
358  // Browser will neither run nor display insecure content.
359  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
360    command_line->AppendSwitch(switches::kNoDisplayingInsecureContent);
361  }
362};
363
364class SSLUITestIgnoreCertErrors : public SSLUITest {
365 public:
366  SSLUITestIgnoreCertErrors() : SSLUITest() {}
367
368  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
369    // Browser will ignore certificate errors.
370    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
371  }
372};
373
374// Visits a regular page over http.
375IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTP) {
376  ASSERT_TRUE(test_server()->Start());
377
378  ui_test_utils::NavigateToURL(browser(),
379                               test_server()->GetURL("files/ssl/google.html"));
380
381  CheckUnauthenticatedState(
382      browser()->tab_strip_model()->GetActiveWebContents());
383}
384
385// Visits a page over http which includes broken https resources (status should
386// be OK).
387// TODO(jcampan): test that bad HTTPS content is blocked (otherwise we'll give
388//                the secure cookies away!).
389IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) {
390  ASSERT_TRUE(test_server()->Start());
391  ASSERT_TRUE(https_server_expired_.Start());
392
393  std::string replacement_path;
394  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
395      "files/ssl/page_with_unsafe_contents.html",
396      https_server_expired_.host_port_pair(),
397      &replacement_path));
398
399  ui_test_utils::NavigateToURL(
400      browser(), test_server()->GetURL(replacement_path));
401
402  CheckUnauthenticatedState(
403      browser()->tab_strip_model()->GetActiveWebContents());
404}
405
406IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSWithInsecureContent) {
407  ASSERT_TRUE(test_server()->Start());
408  ASSERT_TRUE(https_server_expired_.Start());
409
410  std::string replacement_path;
411  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
412      "files/ssl/page_displays_insecure_content.html",
413      test_server()->host_port_pair(),
414      &replacement_path));
415
416  ui_test_utils::NavigateToURL(browser(),
417                               https_server_expired_.GetURL(replacement_path));
418
419  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
420  CheckAuthenticationBrokenState(
421      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
422
423  ProceedThroughInterstitial(tab);
424
425  CheckAuthenticationBrokenState(tab,
426                                 net::CERT_STATUS_DATE_INVALID,
427                                 AuthState::DISPLAYED_INSECURE_CONTENT);
428}
429
430// http://crbug.com/91745
431#if defined(OS_CHROMEOS)
432#define MAYBE_TestOKHTTPS DISABLED_TestOKHTTPS
433#else
434#define MAYBE_TestOKHTTPS TestOKHTTPS
435#endif
436
437// Visits a page over OK https:
438IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestOKHTTPS) {
439  ASSERT_TRUE(https_server_.Start());
440
441  ui_test_utils::NavigateToURL(browser(),
442                               https_server_.GetURL("files/ssl/google.html"));
443
444  CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
445                          AuthState::NONE);
446}
447
448// Visits a page with https error and proceed:
449IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndProceed) {
450  ASSERT_TRUE(https_server_expired_.Start());
451
452  ui_test_utils::NavigateToURL(browser(),
453      https_server_expired_.GetURL("files/ssl/google.html"));
454
455  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
456  CheckAuthenticationBrokenState(
457      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
458
459  ProceedThroughInterstitial(tab);
460
461  CheckAuthenticationBrokenState(
462      tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
463}
464
465#ifndef NEDBUG
466// Flaky on Windows debug (http://crbug.com/280537).
467#define MAYBE_TestHTTPSExpiredCertAndDontProceed \
468        DISABLED_TestHTTPSExpiredCertAndDontProceed
469#else
470#define MAYBE_TestHTTPSExpiredCertAndDontProceed \
471        TestHTTPSExpiredCertAndDontProceed
472#endif
473
474// Visits a page with https error and don't proceed (and ensure we can still
475// navigate at that point):
476IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndDontProceed) {
477  ASSERT_TRUE(test_server()->Start());
478  ASSERT_TRUE(https_server_.Start());
479  ASSERT_TRUE(https_server_expired_.Start());
480
481  // First navigate to an OK page.
482  ui_test_utils::NavigateToURL(browser(),
483                               https_server_.GetURL("files/ssl/google.html"));
484
485  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
486  NavigationEntry* entry = tab->GetController().GetActiveEntry();
487  ASSERT_TRUE(entry);
488
489  GURL cross_site_url =
490      https_server_expired_.GetURL("files/ssl/google.html");
491  // Change the host name from 127.0.0.1 to localhost so it triggers a
492  // cross-site navigation so we can test http://crbug.com/5800 is gone.
493  ASSERT_EQ("127.0.0.1", cross_site_url.host());
494  GURL::Replacements replacements;
495  std::string new_host("localhost");
496  replacements.SetHostStr(new_host);
497  cross_site_url = cross_site_url.ReplaceComponents(replacements);
498
499  // Now go to a bad HTTPS page.
500  ui_test_utils::NavigateToURL(browser(), cross_site_url);
501
502  // An interstitial should be showing.
503  CheckAuthenticationBrokenState(tab,
504                                 net::CERT_STATUS_COMMON_NAME_INVALID,
505                                 AuthState::SHOWING_INTERSTITIAL);
506
507  // Simulate user clicking "Take me back".
508  InterstitialPage* interstitial_page = tab->GetInterstitialPage();
509  ASSERT_TRUE(interstitial_page);
510  interstitial_page->DontProceed();
511
512  // We should be back to the original good page.
513  CheckAuthenticatedState(tab, AuthState::NONE);
514
515  // Try to navigate to a new page. (to make sure bug 5800 is fixed).
516  ui_test_utils::NavigateToURL(browser(),
517                               test_server()->GetURL("files/ssl/google.html"));
518  CheckUnauthenticatedState(tab);
519}
520
521// Visits a page with https error and then goes back using Browser::GoBack.
522IN_PROC_BROWSER_TEST_F(SSLUITest,
523                       TestHTTPSExpiredCertAndGoBackViaButton) {
524  ASSERT_TRUE(test_server()->Start());
525  ASSERT_TRUE(https_server_expired_.Start());
526
527  // First navigate to an HTTP page.
528  ui_test_utils::NavigateToURL(browser(),
529      test_server()->GetURL("files/ssl/google.html"));
530  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
531  NavigationEntry* entry = tab->GetController().GetActiveEntry();
532  ASSERT_TRUE(entry);
533
534  // Now go to a bad HTTPS page that shows an interstitial.
535  ui_test_utils::NavigateToURL(browser(),
536      https_server_expired_.GetURL("files/ssl/google.html"));
537  CheckAuthenticationBrokenState(
538      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
539
540  ProvisionalLoadWaiter load_failed_observer(tab);
541
542  // Simulate user clicking on back button (crbug.com/39248).
543  chrome::GoBack(browser(), CURRENT_TAB);
544
545  // Wait until we hear the load failure, and make sure we haven't swapped out
546  // the previous page.  Prevents regression of http://crbug.com/82667.
547  load_failed_observer.Wait();
548  EXPECT_FALSE(content::RenderViewHostTester::IsRenderViewHostSwappedOut(
549      tab->GetRenderViewHost()));
550
551  // We should be back at the original good page.
552  EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()->
553                   GetInterstitialPage());
554  CheckUnauthenticatedState(tab);
555}
556
557// Visits a page with https error and then goes back using GoToOffset.
558// Disabled because its flaky: http://crbug.com/40932, http://crbug.com/43575.
559IN_PROC_BROWSER_TEST_F(SSLUITest,
560                       TestHTTPSExpiredCertAndGoBackViaMenu) {
561  ASSERT_TRUE(test_server()->Start());
562  ASSERT_TRUE(https_server_expired_.Start());
563
564  // First navigate to an HTTP page.
565  ui_test_utils::NavigateToURL(browser(),
566      test_server()->GetURL("files/ssl/google.html"));
567  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
568  NavigationEntry* entry = tab->GetController().GetActiveEntry();
569  ASSERT_TRUE(entry);
570
571  // Now go to a bad HTTPS page that shows an interstitial.
572  ui_test_utils::NavigateToURL(browser(),
573      https_server_expired_.GetURL("files/ssl/google.html"));
574  CheckAuthenticationBrokenState(
575      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
576
577  // Simulate user clicking and holding on back button (crbug.com/37215).
578  tab->GetController().GoToOffset(-1);
579
580  // We should be back at the original good page.
581  EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()->
582                   GetInterstitialPage());
583  CheckUnauthenticatedState(tab);
584}
585
586// Visits a page with https error and then goes forward using GoToOffset.
587IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndGoForward) {
588  ASSERT_TRUE(test_server()->Start());
589  ASSERT_TRUE(https_server_expired_.Start());
590
591  // First navigate to two HTTP pages.
592  ui_test_utils::NavigateToURL(browser(),
593      test_server()->GetURL("files/ssl/google.html"));
594  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
595  NavigationEntry* entry1 = tab->GetController().GetActiveEntry();
596  ASSERT_TRUE(entry1);
597  ui_test_utils::NavigateToURL(browser(),
598      test_server()->GetURL("files/ssl/blank_page.html"));
599  NavigationEntry* entry2 = tab->GetController().GetActiveEntry();
600  ASSERT_TRUE(entry2);
601
602  // Now go back so that a page is in the forward history.
603  {
604    content::WindowedNotificationObserver observer(
605        content::NOTIFICATION_LOAD_STOP,
606        content::Source<NavigationController>(&tab->GetController()));
607    tab->GetController().GoBack();
608    observer.Wait();
609  }
610  ASSERT_TRUE(tab->GetController().CanGoForward());
611  NavigationEntry* entry3 = tab->GetController().GetActiveEntry();
612  ASSERT_TRUE(entry1 == entry3);
613
614  // Now go to a bad HTTPS page that shows an interstitial.
615  ui_test_utils::NavigateToURL(browser(),
616      https_server_expired_.GetURL("files/ssl/google.html"));
617  CheckAuthenticationBrokenState(
618      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
619
620  // Simulate user clicking and holding on forward button.
621  {
622    content::WindowedNotificationObserver observer(
623        content::NOTIFICATION_LOAD_STOP,
624        content::Source<NavigationController>(&tab->GetController()));
625    tab->GetController().GoToOffset(1);
626    observer.Wait();
627  }
628
629  // We should be showing the second good page.
630  EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()->
631                   GetInterstitialPage());
632  CheckUnauthenticatedState(tab);
633  EXPECT_FALSE(tab->GetController().CanGoForward());
634  NavigationEntry* entry4 = tab->GetController().GetActiveEntry();
635  EXPECT_TRUE(entry2 == entry4);
636}
637
638// Visit a HTTP page which request WSS connection to a server providing invalid
639// certificate. Close the page while WSS connection waits for SSLManager's
640// response from UI thread.
641// Disabled on Windows because it was flaking on XP Tests (1). crbug.com/165258
642// Disabled under LeakSanitizer due to memory leaks. http://crbug.com/317363
643#if defined(OS_WIN) || defined(LEAK_SANITIZER)
644#define MAYBE_TestWSSInvalidCertAndClose DISABLED_TestWSSInvalidCertAndClose
645#else
646#define MAYBE_TestWSSInvalidCertAndClose TestWSSInvalidCertAndClose
647#endif
648IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestWSSInvalidCertAndClose) {
649  ASSERT_TRUE(test_server()->Start());
650  ASSERT_TRUE(wss_server_expired_.Start());
651
652  // Setup page title observer.
653  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
654  content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
655  watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
656
657  // Create GURLs to test pages.
658  std::string master_url_path = base::StringPrintf("%s?%d",
659      test_server()->GetURL("files/ssl/wss_close.html").spec().c_str(),
660      wss_server_expired_.host_port_pair().port());
661  GURL master_url(master_url_path);
662  std::string slave_url_path = base::StringPrintf("%s?%d",
663      test_server()->GetURL("files/ssl/wss_close_slave.html").spec().c_str(),
664      wss_server_expired_.host_port_pair().port());
665  GURL slave_url(slave_url_path);
666
667  // Create tabs and visit pages which keep on creating wss connections.
668  WebContents* tabs[16];
669  for (int i = 0; i < 16; ++i) {
670    tabs[i] = chrome::AddSelectedTabWithURL(browser(), slave_url,
671                                            content::PAGE_TRANSITION_LINK);
672  }
673  chrome::SelectNextTab(browser());
674
675  // Visit a page which waits for one TLS handshake failure.
676  // The title will be changed to 'PASS'.
677  ui_test_utils::NavigateToURL(browser(), master_url);
678  const base::string16 result = watcher.WaitAndGetTitle();
679  EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass"));
680
681  // Close tabs which contains the test page.
682  for (int i = 0; i < 16; ++i)
683    chrome::CloseWebContents(browser(), tabs[i], false);
684  chrome::CloseWebContents(browser(), tab, false);
685}
686
687// Visit a HTTPS page and proceeds despite an invalid certificate. The page
688// requests WSS connection to the same origin host to check if WSS connection
689// share certificates policy with HTTPS correcly.
690IN_PROC_BROWSER_TEST_F(SSLUITest, TestWSSInvalidCertAndGoForward) {
691  ASSERT_TRUE(test_server()->Start());
692  ASSERT_TRUE(wss_server_expired_.Start());
693
694  // Setup page title observer.
695  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
696  content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
697  watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
698
699  // Visit bad HTTPS page.
700  std::string scheme("https");
701  GURL::Replacements replacements;
702  replacements.SetSchemeStr(scheme);
703  ui_test_utils::NavigateToURL(
704      browser(),
705      wss_server_expired_.GetURL(
706          "connect_check.html").ReplaceComponents(replacements));
707  CheckAuthenticationBrokenState(
708      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
709
710  // Proceed anyway.
711  ProceedThroughInterstitial(tab);
712
713  // Test page run a WebSocket wss connection test. The result will be shown
714  // as page title.
715  const base::string16 result = watcher.WaitAndGetTitle();
716  EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass"));
717}
718
719#if defined(USE_NSS)
720// SSL client certificate tests are only enabled when using NSS for private key
721// storage, as only NSS can avoid modifying global machine state when testing.
722// See http://crbug.com/51132
723
724// Visit a HTTPS page which requires client cert authentication. The client
725// cert will be selected automatically, then a test which uses WebSocket runs.
726// Disabled:  http://crbug.com/159985
727IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestWSSClientCert) {
728  // Open a temporary NSS DB for testing.
729  crypto::ScopedTestNSSDB test_nssdb;
730  ASSERT_TRUE(test_nssdb.is_open());
731
732  // Import client cert for test. These interfaces require NSS.
733  net::NSSCertDatabase* cert_db = net::NSSCertDatabase::GetInstance();
734  scoped_refptr<net::CryptoModule> crypt_module = cert_db->GetPublicModule();
735  std::string pkcs12_data;
736  base::FilePath cert_path = net::GetTestCertsDirectory().Append(
737      FILE_PATH_LITERAL("websocket_client_cert.p12"));
738  EXPECT_TRUE(base::ReadFileToString(cert_path, &pkcs12_data));
739  EXPECT_EQ(net::OK,
740            cert_db->ImportFromPKCS12(
741                crypt_module.get(), pkcs12_data, base::string16(), true, NULL));
742
743  // Start WebSocket test server with TLS and client cert authentication.
744  net::SpawnedTestServer::SSLOptions options(
745      net::SpawnedTestServer::SSLOptions::CERT_OK);
746  options.request_client_certificate = true;
747  base::FilePath ca_path = net::GetTestCertsDirectory().Append(
748      FILE_PATH_LITERAL("websocket_cacert.pem"));
749  options.client_authorities.push_back(ca_path);
750  net::SpawnedTestServer wss_server(net::SpawnedTestServer::TYPE_WSS,
751                             options,
752                             net::GetWebSocketTestDataDirectory());
753  ASSERT_TRUE(wss_server.Start());
754  std::string scheme("https");
755  GURL::Replacements replacements;
756  replacements.SetSchemeStr(scheme);
757  GURL url = wss_server.GetURL("connect_check.html").ReplaceComponents(
758      replacements);
759
760  // Setup page title observer.
761  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
762  content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
763  watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
764
765  // Add an entry into AutoSelectCertificateForUrls policy for automatic client
766  // cert selection.
767  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
768  DCHECK(profile);
769  scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
770  dict->SetString("ISSUER.CN", "pywebsocket");
771  profile->GetHostContentSettingsMap()->SetWebsiteSetting(
772      ContentSettingsPattern::FromURL(url),
773      ContentSettingsPattern::FromURL(url),
774      CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
775      std::string(),
776      dict.release());
777
778  // Visit a HTTPS page which requires client certs.
779  ui_test_utils::NavigateToURL(browser(), url);
780  CheckAuthenticatedState(tab, AuthState::NONE);
781
782  // Test page runs a WebSocket wss connection test. The result will be shown
783  // as page title.
784  const base::string16 result = watcher.WaitAndGetTitle();
785  EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass"));
786}
787#endif  // defined(USE_NSS)
788
789// Flaky on CrOS http://crbug.com/92292
790#if defined(OS_CHROMEOS)
791#define MAYBE_TestHTTPSErrorWithNoNavEntry \
792    DISABLED_TestHTTPSErrorWithNoNavEntry
793#else
794#define MAYBE_TestHTTPSErrorWithNoNavEntry TestHTTPSErrorWithNoNavEntry
795#endif  // defined(OS_CHROMEOS)
796
797// Open a page with a HTTPS error in a tab with no prior navigation (through a
798// link with a blank target).  This is to test that the lack of navigation entry
799// does not cause any problems (it was causing a crasher, see
800// http://crbug.com/19941).
801IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSErrorWithNoNavEntry) {
802  ASSERT_TRUE(https_server_expired_.Start());
803
804  GURL url = https_server_expired_.GetURL("files/ssl/google.htm");
805  WebContents* tab2 = chrome::AddSelectedTabWithURL(
806      browser(), url, content::PAGE_TRANSITION_TYPED);
807  content::WaitForLoadStop(tab2);
808
809  // Verify our assumption that there was no prior navigation.
810  EXPECT_FALSE(chrome::CanGoBack(browser()));
811
812  // We should have an interstitial page showing.
813  ASSERT_TRUE(tab2->GetInterstitialPage());
814}
815
816IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadHTTPSDownload) {
817  ASSERT_TRUE(test_server()->Start());
818  ASSERT_TRUE(https_server_expired_.Start());
819  GURL url_non_dangerous = test_server()->GetURL(std::string());
820  GURL url_dangerous =
821      https_server_expired_.GetURL("files/downloads/dangerous/dangerous.exe");
822  base::ScopedTempDir downloads_directory_;
823
824  // Need empty temp dir to avoid having Chrome ask us for a new filename
825  // when we've downloaded dangerous.exe one hundred times.
826  ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
827
828  browser()->profile()->GetPrefs()->SetFilePath(
829      prefs::kDownloadDefaultDirectory,
830      downloads_directory_.path());
831
832  // Visit a non-dangerous page.
833  ui_test_utils::NavigateToURL(browser(), url_non_dangerous);
834
835  // Now, start a transition to dangerous download.
836  {
837    content::WindowedNotificationObserver observer(
838        content::NOTIFICATION_LOAD_STOP,
839        content::NotificationService::AllSources());
840    chrome::NavigateParams navigate_params(browser(), url_dangerous,
841                                           content::PAGE_TRANSITION_TYPED);
842    chrome::Navigate(&navigate_params);
843    observer.Wait();
844  }
845
846  // To exit the browser cleanly (and this test) we need to complete the
847  // download after completing this test.
848  content::DownloadTestObserverTerminal dangerous_download_observer(
849      content::BrowserContext::GetDownloadManager(browser()->profile()),
850      1,
851      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT);
852
853  // Proceed through the SSL interstitial. This doesn't use
854  // |ProceedThroughInterstitial| since no page load will commit.
855  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
856  ASSERT_TRUE(tab != NULL);
857  ASSERT_TRUE(tab->GetInterstitialPage() != NULL);
858  {
859    content::WindowedNotificationObserver observer(
860        chrome::NOTIFICATION_DOWNLOAD_INITIATED,
861        content::NotificationService::AllSources());
862    tab->GetInterstitialPage()->Proceed();
863    observer.Wait();
864  }
865
866  // There should still be an interstitial at this point. Press the
867  // back button on the browser. Note that this doesn't wait for a
868  // NAV_ENTRY_COMMITTED notification because going back with an
869  // active interstitial simply hides the interstitial.
870  ASSERT_TRUE(tab->GetInterstitialPage() != NULL);
871  EXPECT_TRUE(chrome::CanGoBack(browser()));
872  chrome::GoBack(browser(), CURRENT_TAB);
873
874  dangerous_download_observer.WaitForFinished();
875}
876
877//
878// Insecure content
879//
880
881#if defined(OS_WIN)
882// http://crbug.com/152940 Flaky on win.
883#define MAYBE_TestDisplaysInsecureContent DISABLED_TestDisplaysInsecureContent
884#else
885#define MAYBE_TestDisplaysInsecureContent TestDisplaysInsecureContent
886#endif
887
888// Visits a page that displays insecure content.
889IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestDisplaysInsecureContent) {
890  ASSERT_TRUE(test_server()->Start());
891  ASSERT_TRUE(https_server_.Start());
892
893  std::string replacement_path;
894  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
895      "files/ssl/page_displays_insecure_content.html",
896      test_server()->host_port_pair(),
897      &replacement_path));
898
899  // Load a page that displays insecure content.
900  ui_test_utils::NavigateToURL(browser(),
901                               https_server_.GetURL(replacement_path));
902
903  CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
904                          AuthState::DISPLAYED_INSECURE_CONTENT);
905}
906
907// Visits a page that runs insecure content and tries to suppress the insecure
908// content warnings by randomizing location.hash.
909// Based on http://crbug.com/8706
910IN_PROC_BROWSER_TEST_F(SSLUITest,
911                       TestRunsInsecuredContentRandomizeHash) {
912  ASSERT_TRUE(test_server()->Start());
913  ASSERT_TRUE(https_server_.Start());
914
915  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
916      "files/ssl/page_runs_insecure_content.html"));
917
918  CheckAuthenticationBrokenState(
919      browser()->tab_strip_model()->GetActiveWebContents(),
920      CertError::NONE,
921      AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
922}
923
924// Visits a page with unsafe content and make sure that:
925// - frames content is replaced with warning
926// - images and scripts are filtered out entirely
927IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContents) {
928  ASSERT_TRUE(https_server_.Start());
929  ASSERT_TRUE(https_server_expired_.Start());
930
931  std::string replacement_path;
932  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
933      "files/ssl/page_with_unsafe_contents.html",
934      https_server_expired_.host_port_pair(),
935      &replacement_path));
936  ui_test_utils::NavigateToURL(browser(),
937                               https_server_.GetURL(replacement_path));
938
939  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
940  // When the bad content is filtered, the state is expected to be
941  // authenticated.
942  CheckAuthenticatedState(tab, AuthState::NONE);
943
944  // Because of cross-frame scripting restrictions, we cannot access the iframe
945  // content.  So to know if the frame was loaded, we just check if a popup was
946  // opened (the iframe content opens one).
947  // Note: because of bug 1115868, no web contents modal dialog is opened right
948  //       now.  Once the bug is fixed, this will do the real check.
949  EXPECT_FALSE(IsShowingWebContentsModalDialog());
950
951  int img_width;
952  EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
953      tab,
954      "window.domAutomationController.send(ImageWidth());",
955      &img_width));
956  // In order to check that the image was not loaded, we check its width.
957  // The actual image (Google logo) is 114 pixels wide, we assume the broken
958  // image is less than 100.
959  EXPECT_LT(img_width, 100);
960
961  bool js_result = false;
962  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
963      tab,
964      "window.domAutomationController.send(IsFooSet());",
965      &js_result));
966  EXPECT_FALSE(js_result);
967}
968
969// Visits a page with insecure content loaded by JS (after the initial page
970// load).
971IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentLoadedFromJS) {
972  ASSERT_TRUE(test_server()->Start());
973  ASSERT_TRUE(https_server_.Start());
974
975  std::string replacement_path;
976  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
977      "files/ssl/page_with_dynamic_insecure_content.html",
978      test_server()->host_port_pair(),
979      &replacement_path));
980  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
981      replacement_path));
982
983  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
984  CheckAuthenticatedState(tab, AuthState::NONE);
985
986  // Load the insecure image.
987  bool js_result = false;
988  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
989      tab,
990      "loadBadImage();",
991      &js_result));
992  EXPECT_TRUE(js_result);
993
994  // We should now have insecure content.
995  CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT);
996}
997
998// Visits two pages from the same origin: one that displays insecure content and
999// one that doesn't.  The test checks that we do not propagate the insecure
1000// content state from one to the other.
1001IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentTwoTabs) {
1002  ASSERT_TRUE(test_server()->Start());
1003  ASSERT_TRUE(https_server_.Start());
1004
1005  ui_test_utils::NavigateToURL(browser(),
1006      https_server_.GetURL("files/ssl/blank_page.html"));
1007
1008  WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1009
1010  // This tab should be fine.
1011  CheckAuthenticatedState(tab1, AuthState::NONE);
1012
1013  // Create a new tab.
1014  std::string replacement_path;
1015  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1016      "files/ssl/page_displays_insecure_content.html",
1017      test_server()->host_port_pair(),
1018      &replacement_path));
1019
1020  GURL url = https_server_.GetURL(replacement_path);
1021  chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_TYPED);
1022  params.disposition = NEW_FOREGROUND_TAB;
1023  params.tabstrip_index = 0;
1024  params.source_contents = tab1;
1025  content::WindowedNotificationObserver observer(
1026      content::NOTIFICATION_LOAD_STOP,
1027      content::NotificationService::AllSources());
1028  chrome::Navigate(&params);
1029  WebContents* tab2 = params.target_contents;
1030  observer.Wait();
1031
1032  // The new tab has insecure content.
1033  CheckAuthenticatedState(tab2, AuthState::DISPLAYED_INSECURE_CONTENT);
1034
1035  // The original tab should not be contaminated.
1036  CheckAuthenticatedState(tab1, AuthState::NONE);
1037}
1038
1039// Visits two pages from the same origin: one that runs insecure content and one
1040// that doesn't.  The test checks that we propagate the insecure content state
1041// from one to the other.
1042IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsInsecureContentTwoTabs) {
1043  ASSERT_TRUE(test_server()->Start());
1044  ASSERT_TRUE(https_server_.Start());
1045
1046  ui_test_utils::NavigateToURL(browser(),
1047      https_server_.GetURL("files/ssl/blank_page.html"));
1048
1049  WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1050
1051  // This tab should be fine.
1052  CheckAuthenticatedState(tab1, AuthState::NONE);
1053
1054  std::string replacement_path;
1055  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1056      "files/ssl/page_runs_insecure_content.html",
1057      test_server()->host_port_pair(),
1058      &replacement_path));
1059
1060  // Create a new tab in the same process.  Using a NEW_FOREGROUND_TAB
1061  // disposition won't usually stay in the same process, but this works
1062  // because we are using process-per-site in SetUpCommandLine.
1063  GURL url = https_server_.GetURL(replacement_path);
1064  chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_TYPED);
1065  params.disposition = NEW_FOREGROUND_TAB;
1066  params.source_contents = tab1;
1067  content::WindowedNotificationObserver observer(
1068      content::NOTIFICATION_LOAD_STOP,
1069      content::NotificationService::AllSources());
1070  chrome::Navigate(&params);
1071  WebContents* tab2 = params.target_contents;
1072  observer.Wait();
1073
1074  // Both tabs should have the same process.
1075  EXPECT_EQ(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
1076
1077  // The new tab has insecure content.
1078  CheckAuthenticationBrokenState(
1079      tab2,
1080      CertError::NONE,
1081      AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1082
1083  // Which means the origin for the first tab has also been contaminated with
1084  // insecure content.
1085  CheckAuthenticationBrokenState(
1086      tab1, CertError::NONE, AuthState::RAN_INSECURE_CONTENT);
1087}
1088
1089// Visits a page with an image over http.  Visits another page over https
1090// referencing that same image over http (hoping it is coming from the webcore
1091// memory cache).
1092IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysCachedInsecureContent) {
1093  ASSERT_TRUE(test_server()->Start());
1094  ASSERT_TRUE(https_server_.Start());
1095
1096  std::string replacement_path;
1097  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1098      "files/ssl/page_displays_insecure_content.html",
1099      test_server()->host_port_pair(),
1100      &replacement_path));
1101
1102  // Load original page over HTTP.
1103  const GURL url_http = test_server()->GetURL(replacement_path);
1104  ui_test_utils::NavigateToURL(browser(), url_http);
1105  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1106  CheckUnauthenticatedState(tab);
1107
1108  // Load again but over SSL.  It should be marked as displaying insecure
1109  // content (even though the image comes from the WebCore memory cache).
1110  const GURL url_https = https_server_.GetURL(replacement_path);
1111  ui_test_utils::NavigateToURL(browser(), url_https);
1112  CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT);
1113}
1114
1115// http://crbug.com/84729
1116#if defined(OS_CHROMEOS)
1117#define MAYBE_TestRunsCachedInsecureContent \
1118    DISABLED_TestRunsCachedInsecureContent
1119#else
1120#define MAYBE_TestRunsCachedInsecureContent TestRunsCachedInsecureContent
1121#endif  // defined(OS_CHROMEOS)
1122
1123// Visits a page with script over http.  Visits another page over https
1124// referencing that same script over http (hoping it is coming from the webcore
1125// memory cache).
1126IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRunsCachedInsecureContent) {
1127  ASSERT_TRUE(test_server()->Start());
1128  ASSERT_TRUE(https_server_.Start());
1129
1130  std::string replacement_path;
1131  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1132      "files/ssl/page_runs_insecure_content.html",
1133      test_server()->host_port_pair(),
1134      &replacement_path));
1135
1136  // Load original page over HTTP.
1137  const GURL url_http = test_server()->GetURL(replacement_path);
1138  ui_test_utils::NavigateToURL(browser(), url_http);
1139  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1140  CheckUnauthenticatedState(tab);
1141
1142  // Load again but over SSL.  It should be marked as displaying insecure
1143  // content (even though the image comes from the WebCore memory cache).
1144  const GURL url_https = https_server_.GetURL(replacement_path);
1145  ui_test_utils::NavigateToURL(browser(), url_https);
1146  CheckAuthenticationBrokenState(
1147      tab,
1148      CertError::NONE,
1149      AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1150}
1151
1152// This test ensures the CN invalid status does not 'stick' to a certificate
1153// (see bug #1044942) and that it depends on the host-name.
1154// Test if disabled due to flakiness http://crbug.com/368280 .
1155IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCNInvalidStickiness) {
1156  ASSERT_TRUE(https_server_.Start());
1157  ASSERT_TRUE(https_server_mismatched_.Start());
1158
1159  // First we hit the server with hostname, this generates an invalid policy
1160  // error.
1161  ui_test_utils::NavigateToURL(browser(),
1162      https_server_mismatched_.GetURL("files/ssl/google.html"));
1163
1164  // We get an interstitial page as a result.
1165  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1166  CheckAuthenticationBrokenState(tab,
1167                                 net::CERT_STATUS_COMMON_NAME_INVALID,
1168                                 AuthState::SHOWING_INTERSTITIAL);
1169  ProceedThroughInterstitial(tab);
1170  CheckAuthenticationBrokenState(
1171      tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE);
1172
1173  // Now we try again with the right host name this time.
1174  GURL url(https_server_.GetURL("files/ssl/google.html"));
1175  ui_test_utils::NavigateToURL(browser(), url);
1176
1177  // Security state should be OK.
1178  CheckAuthenticatedState(tab, AuthState::NONE);
1179
1180  // Now try again the broken one to make sure it is still broken.
1181  ui_test_utils::NavigateToURL(browser(),
1182      https_server_mismatched_.GetURL("files/ssl/google.html"));
1183
1184  // Since we OKed the interstitial last time, we get right to the page.
1185  CheckAuthenticationBrokenState(
1186      tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE);
1187}
1188
1189#if defined(OS_CHROMEOS)
1190// This test seems to be flaky and hang on chromiumos.
1191// http://crbug.com/84419
1192#define MAYBE_TestRefNavigation DISABLED_TestRefNavigation
1193#else
1194#define MAYBE_TestRefNavigation TestRefNavigation
1195#endif
1196
1197// Test that navigating to a #ref does not change a bad security state.
1198IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) {
1199  ASSERT_TRUE(https_server_expired_.Start());
1200
1201  ui_test_utils::NavigateToURL(browser(),
1202      https_server_expired_.GetURL("files/ssl/page_with_refs.html"));
1203
1204  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1205  CheckAuthenticationBrokenState(
1206      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1207
1208  ProceedThroughInterstitial(tab);
1209
1210  CheckAuthenticationBrokenState(
1211      tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1212  // Now navigate to a ref in the page, the security state should not have
1213  // changed.
1214  ui_test_utils::NavigateToURL(browser(),
1215      https_server_expired_.GetURL("files/ssl/page_with_refs.html#jp"));
1216
1217  CheckAuthenticationBrokenState(
1218      tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1219}
1220
1221// Tests that closing a page that has a unsafe pop-up does not crash the
1222// browser (bug #1966).
1223// TODO(jcampan): http://crbug.com/2136 disabled because the popup is not
1224//                opened as it is not initiated by a user gesture.
1225IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) {
1226  ASSERT_TRUE(test_server()->Start());
1227  ASSERT_TRUE(https_server_expired_.Start());
1228
1229  std::string replacement_path;
1230  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1231      "files/ssl/page_with_unsafe_popup.html",
1232      https_server_expired_.host_port_pair(),
1233      &replacement_path));
1234
1235  ui_test_utils::NavigateToURL(browser(),
1236                               test_server()->GetURL(replacement_path));
1237
1238  WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1239  // It is probably overkill to add a notification for a popup-opening, let's
1240  // just poll.
1241  for (int i = 0; i < 10; i++) {
1242    if (IsShowingWebContentsModalDialog())
1243      break;
1244    base::MessageLoop::current()->PostDelayedTask(
1245        FROM_HERE,
1246        base::MessageLoop::QuitClosure(),
1247        base::TimeDelta::FromSeconds(1));
1248    content::RunMessageLoop();
1249  }
1250  ASSERT_TRUE(IsShowingWebContentsModalDialog());
1251
1252  // Let's add another tab to make sure the browser does not exit when we close
1253  // the first tab.
1254  GURL url = test_server()->GetURL("files/ssl/google.html");
1255  content::WindowedNotificationObserver observer(
1256      content::NOTIFICATION_LOAD_STOP,
1257      content::NotificationService::AllSources());
1258  chrome::AddSelectedTabWithURL(browser(), url, content::PAGE_TRANSITION_TYPED);
1259  observer.Wait();
1260
1261  // Close the first tab.
1262  chrome::CloseWebContents(browser(), tab1, false);
1263}
1264
1265// Visit a page over bad https that is a redirect to a page with good https.
1266IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) {
1267  ASSERT_TRUE(https_server_.Start());
1268  ASSERT_TRUE(https_server_expired_.Start());
1269
1270  GURL url1 = https_server_expired_.GetURL("server-redirect?");
1271  GURL url2 = https_server_.GetURL("files/ssl/google.html");
1272
1273  ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
1274
1275  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1276
1277  CheckAuthenticationBrokenState(
1278      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1279
1280  ProceedThroughInterstitial(tab);
1281
1282  // We have been redirected to the good page.
1283  CheckAuthenticatedState(tab, AuthState::NONE);
1284}
1285
1286// Flaky on Linux. http://crbug.com/368280.
1287#if defined(OS_LINUX)
1288#define MAYBE_TestRedirectGoodToBadHTTPS DISABLED_TestRedirectGoodToBadHTTPS
1289#else
1290#define MAYBE_TestRedirectGoodToBadHTTPS TestRedirectGoodToBadHTTPS
1291#endif
1292
1293// Visit a page over good https that is a redirect to a page with bad https.
1294IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectGoodToBadHTTPS) {
1295  ASSERT_TRUE(https_server_.Start());
1296  ASSERT_TRUE(https_server_expired_.Start());
1297
1298  GURL url1 = https_server_.GetURL("server-redirect?");
1299  GURL url2 = https_server_expired_.GetURL("files/ssl/google.html");
1300  ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
1301
1302  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1303  CheckAuthenticationBrokenState(
1304      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1305
1306  ProceedThroughInterstitial(tab);
1307
1308  CheckAuthenticationBrokenState(
1309      tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1310}
1311
1312// Visit a page over http that is a redirect to a page with good HTTPS.
1313IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) {
1314  ASSERT_TRUE(test_server()->Start());
1315  ASSERT_TRUE(https_server_.Start());
1316
1317  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1318
1319  // HTTP redirects to good HTTPS.
1320  GURL http_url = test_server()->GetURL("server-redirect?");
1321  GURL good_https_url =
1322      https_server_.GetURL("files/ssl/google.html");
1323
1324  ui_test_utils::NavigateToURL(browser(),
1325                               GURL(http_url.spec() + good_https_url.spec()));
1326  CheckAuthenticatedState(tab, AuthState::NONE);
1327}
1328
1329// Flaky on Linux. http://crbug.com/368280.
1330#if defined(OS_LINUX)
1331#define MAYBE_TestRedirectHTTPToBadHTTPS DISABLED_TestRedirectHTTPToBadHTTPS
1332#else
1333#define MAYBE_TestRedirectHTTPToBadHTTPS TestRedirectHTTPToBadHTTPS
1334#endif
1335
1336// Visit a page over http that is a redirect to a page with bad HTTPS.
1337IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRedirectHTTPToBadHTTPS) {
1338  ASSERT_TRUE(test_server()->Start());
1339  ASSERT_TRUE(https_server_expired_.Start());
1340
1341  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1342
1343  GURL http_url = test_server()->GetURL("server-redirect?");
1344  GURL bad_https_url =
1345      https_server_expired_.GetURL("files/ssl/google.html");
1346  ui_test_utils::NavigateToURL(browser(),
1347                               GURL(http_url.spec() + bad_https_url.spec()));
1348  CheckAuthenticationBrokenState(
1349      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1350
1351  ProceedThroughInterstitial(tab);
1352
1353  CheckAuthenticationBrokenState(
1354      tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1355}
1356
1357// Visit a page over https that is a redirect to a page with http (to make sure
1358// we don't keep the secure state).
1359IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) {
1360  ASSERT_TRUE(test_server()->Start());
1361  ASSERT_TRUE(https_server_.Start());
1362
1363  GURL https_url = https_server_.GetURL("server-redirect?");
1364  GURL http_url = test_server()->GetURL("files/ssl/google.html");
1365
1366  ui_test_utils::NavigateToURL(browser(),
1367                               GURL(https_url.spec() + http_url.spec()));
1368  CheckUnauthenticatedState(
1369      browser()->tab_strip_model()->GetActiveWebContents());
1370}
1371
1372// Visits a page to which we could not connect (bad port) over http and https
1373// and make sure the security style is correct.
1374IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) {
1375  ui_test_utils::NavigateToURL(browser(), GURL("http://localhost:17"));
1376  CheckUnauthenticatedState(
1377      browser()->tab_strip_model()->GetActiveWebContents());
1378
1379  // Same thing over HTTPS.
1380  ui_test_utils::NavigateToURL(browser(), GURL("https://localhost:17"));
1381  CheckUnauthenticatedState(
1382      browser()->tab_strip_model()->GetActiveWebContents());
1383}
1384
1385//
1386// Frame navigation
1387//
1388
1389// From a good HTTPS top frame:
1390// - navigate to an OK HTTPS frame
1391// - navigate to a bad HTTPS (expect unsafe content and filtered frame), then
1392//   back
1393// - navigate to HTTP (expect insecure content), then back
1394IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) {
1395  ASSERT_TRUE(test_server()->Start());
1396  ASSERT_TRUE(https_server_.Start());
1397  ASSERT_TRUE(https_server_expired_.Start());
1398
1399  std::string top_frame_path;
1400  ASSERT_TRUE(GetTopFramePath(*test_server(),
1401                              https_server_,
1402                              https_server_expired_,
1403                              &top_frame_path));
1404
1405  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1406  ui_test_utils::NavigateToURL(browser(),
1407                               https_server_.GetURL(top_frame_path));
1408
1409  CheckAuthenticatedState(tab, AuthState::NONE);
1410
1411  bool success = false;
1412  // Now navigate inside the frame.
1413  {
1414    content::WindowedNotificationObserver observer(
1415        content::NOTIFICATION_LOAD_STOP,
1416        content::Source<NavigationController>(&tab->GetController()));
1417    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1418        tab,
1419        "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1420        &success));
1421    ASSERT_TRUE(success);
1422    observer.Wait();
1423  }
1424
1425  // We should still be fine.
1426  CheckAuthenticatedState(tab, AuthState::NONE);
1427
1428  // Now let's hit a bad page.
1429  {
1430    content::WindowedNotificationObserver observer(
1431        content::NOTIFICATION_LOAD_STOP,
1432        content::Source<NavigationController>(&tab->GetController()));
1433    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1434        tab,
1435        "window.domAutomationController.send(clickLink('badHTTPSLink'));",
1436        &success));
1437    ASSERT_TRUE(success);
1438    observer.Wait();
1439  }
1440
1441  // The security style should still be secure.
1442  CheckAuthenticatedState(tab, AuthState::NONE);
1443
1444  // And the frame should be blocked.
1445  bool is_content_evil = true;
1446  content::RenderFrameHost* content_frame = content::FrameMatchingPredicate(
1447        tab, base::Bind(&content::FrameMatchesName, "contentFrame"));
1448  std::string is_evil_js("window.domAutomationController.send("
1449                         "document.getElementById('evilDiv') != null);");
1450  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame,
1451                                                   is_evil_js,
1452                                                   &is_content_evil));
1453  EXPECT_FALSE(is_content_evil);
1454
1455  // Now go back, our state should still be OK.
1456  {
1457    content::WindowedNotificationObserver observer(
1458        content::NOTIFICATION_LOAD_STOP,
1459        content::Source<NavigationController>(&tab->GetController()));
1460    tab->GetController().GoBack();
1461    observer.Wait();
1462  }
1463  CheckAuthenticatedState(tab, AuthState::NONE);
1464
1465  // Navigate to a page served over HTTP.
1466  {
1467    content::WindowedNotificationObserver observer(
1468        content::NOTIFICATION_LOAD_STOP,
1469        content::Source<NavigationController>(&tab->GetController()));
1470    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1471        tab,
1472        "window.domAutomationController.send(clickLink('HTTPLink'));",
1473        &success));
1474    ASSERT_TRUE(success);
1475    observer.Wait();
1476  }
1477
1478  // Our state should be unathenticated (in the ran mixed script sense)
1479  CheckAuthenticationBrokenState(
1480      tab,
1481      CertError::NONE,
1482      AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1483
1484  // Go back, our state should be unchanged.
1485  {
1486    content::WindowedNotificationObserver observer(
1487        content::NOTIFICATION_LOAD_STOP,
1488        content::Source<NavigationController>(&tab->GetController()));
1489    tab->GetController().GoBack();
1490    observer.Wait();
1491  }
1492
1493  CheckAuthenticationBrokenState(
1494      tab,
1495      CertError::NONE,
1496      AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT);
1497}
1498
1499// From a bad HTTPS top frame:
1500// - navigate to an OK HTTPS frame (expected to be still authentication broken).
1501IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadFrameNavigation) {
1502  ASSERT_TRUE(https_server_.Start());
1503  ASSERT_TRUE(https_server_expired_.Start());
1504
1505  std::string top_frame_path;
1506  ASSERT_TRUE(GetTopFramePath(*test_server(),
1507                              https_server_,
1508                              https_server_expired_,
1509                              &top_frame_path));
1510
1511  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1512  ui_test_utils::NavigateToURL(browser(),
1513                               https_server_expired_.GetURL(top_frame_path));
1514  CheckAuthenticationBrokenState(
1515      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1516
1517  ProceedThroughInterstitial(tab);
1518
1519  // Navigate to a good frame.
1520  bool success = false;
1521  content::WindowedNotificationObserver observer(
1522        content::NOTIFICATION_LOAD_STOP,
1523        content::Source<NavigationController>(&tab->GetController()));
1524  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1525      tab,
1526      "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1527      &success));
1528  ASSERT_TRUE(success);
1529  observer.Wait();
1530
1531  // We should still be authentication broken.
1532  CheckAuthenticationBrokenState(
1533      tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1534}
1535
1536// From an HTTP top frame, navigate to good and bad HTTPS (security state should
1537// stay unauthenticated).
1538// Disabled, flakily exceeds test timeout, http://crbug.com/43437.
1539IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestUnauthenticatedFrameNavigation) {
1540  ASSERT_TRUE(test_server()->Start());
1541  ASSERT_TRUE(https_server_.Start());
1542  ASSERT_TRUE(https_server_expired_.Start());
1543
1544  std::string top_frame_path;
1545  ASSERT_TRUE(GetTopFramePath(*test_server(),
1546                              https_server_,
1547                              https_server_expired_,
1548                              &top_frame_path));
1549
1550  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1551  ui_test_utils::NavigateToURL(browser(),
1552                               test_server()->GetURL(top_frame_path));
1553  CheckUnauthenticatedState(tab);
1554
1555  // Now navigate inside the frame to a secure HTTPS frame.
1556  {
1557    bool success = false;
1558    content::WindowedNotificationObserver observer(
1559        content::NOTIFICATION_LOAD_STOP,
1560        content::Source<NavigationController>(&tab->GetController()));
1561    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1562        tab,
1563        "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1564        &success));
1565    ASSERT_TRUE(success);
1566    observer.Wait();
1567  }
1568
1569  // We should still be unauthenticated.
1570  CheckUnauthenticatedState(tab);
1571
1572  // Now navigate to a bad HTTPS frame.
1573  {
1574    bool success = false;
1575    content::WindowedNotificationObserver observer(
1576        content::NOTIFICATION_LOAD_STOP,
1577        content::Source<NavigationController>(&tab->GetController()));
1578    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1579        tab,
1580        "window.domAutomationController.send(clickLink('badHTTPSLink'));",
1581        &success));
1582    ASSERT_TRUE(success);
1583    observer.Wait();
1584  }
1585
1586  // State should not have changed.
1587  CheckUnauthenticatedState(tab);
1588
1589  // And the frame should have been blocked (see bug #2316).
1590  bool is_content_evil = true;
1591  content::RenderFrameHost* content_frame = content::FrameMatchingPredicate(
1592        tab, base::Bind(&content::FrameMatchesName, "contentFrame"));
1593  std::string is_evil_js("window.domAutomationController.send("
1594                         "document.getElementById('evilDiv') != null);");
1595  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame,
1596                                                   is_evil_js,
1597                                                   &is_content_evil));
1598  EXPECT_FALSE(is_content_evil);
1599}
1600
1601IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerFiltered) {
1602  ASSERT_TRUE(https_server_.Start());
1603  ASSERT_TRUE(https_server_expired_.Start());
1604
1605  // This page will spawn a Worker which will try to load content from
1606  // BadCertServer.
1607  std::string page_with_unsafe_worker_path;
1608  ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_,
1609                                          &page_with_unsafe_worker_path));
1610  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
1611      page_with_unsafe_worker_path));
1612  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1613  // Expect Worker not to load insecure content.
1614  CheckWorkerLoadResult(tab, false);
1615  // The bad content is filtered, expect the state to be authenticated.
1616  CheckAuthenticatedState(tab, AuthState::NONE);
1617}
1618
1619IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorker) {
1620  ASSERT_TRUE(https_server_.Start());
1621  ASSERT_TRUE(https_server_expired_.Start());
1622
1623  // Navigate to an unsafe site. Proceed with interstitial page to indicate
1624  // the user approves the bad certificate.
1625  ui_test_utils::NavigateToURL(browser(),
1626      https_server_expired_.GetURL("files/ssl/blank_page.html"));
1627  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1628  CheckAuthenticationBrokenState(
1629      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1630  ProceedThroughInterstitial(tab);
1631  CheckAuthenticationBrokenState(
1632      tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1633
1634  // Navigate to safe page that has Worker loading unsafe content.
1635  // Expect content to load but be marked as auth broken due to running insecure
1636  // content.
1637  std::string page_with_unsafe_worker_path;
1638  ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_,
1639                                          &page_with_unsafe_worker_path));
1640  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
1641      page_with_unsafe_worker_path));
1642  CheckWorkerLoadResult(tab, true);  // Worker loads insecure content
1643  CheckAuthenticationBrokenState(
1644      tab, CertError::NONE, AuthState::RAN_INSECURE_CONTENT);
1645}
1646
1647// Test that when the browser blocks displaying insecure content (images), the
1648// indicator shows a secure page, because the blocking made the otherwise
1649// unsafe page safe (the notification of this state is handled by other means).
1650IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureImage) {
1651  ASSERT_TRUE(test_server()->Start());
1652  ASSERT_TRUE(https_server_.Start());
1653
1654  std::string replacement_path;
1655  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1656      "files/ssl/page_displays_insecure_content.html",
1657      test_server()->host_port_pair(),
1658      &replacement_path));
1659
1660  ui_test_utils::NavigateToURL(browser(),
1661                               https_server_.GetURL(replacement_path));
1662
1663  CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
1664                          AuthState::NONE);
1665}
1666
1667// Test that when the browser blocks displaying insecure content (iframes), the
1668// indicator shows a secure page, because the blocking made the otherwise
1669// unsafe page safe (the notification of this state is handled by other means)
1670IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureIframe) {
1671  ASSERT_TRUE(test_server()->Start());
1672  ASSERT_TRUE(https_server_.Start());
1673
1674  std::string replacement_path;
1675  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1676      "files/ssl/page_displays_insecure_iframe.html",
1677      test_server()->host_port_pair(),
1678      &replacement_path));
1679
1680  ui_test_utils::NavigateToURL(browser(),
1681                               https_server_.GetURL(replacement_path));
1682
1683  CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
1684                          AuthState::NONE);
1685}
1686
1687// Test that when the browser blocks running insecure content, the
1688// indicator shows a secure page, because the blocking made the otherwise
1689// unsafe page safe (the notification of this state is handled by other means).
1690IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockRunningInsecureContent) {
1691  ASSERT_TRUE(test_server()->Start());
1692  ASSERT_TRUE(https_server_.Start());
1693
1694  std::string replacement_path;
1695  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1696      "files/ssl/page_runs_insecure_content.html",
1697      test_server()->host_port_pair(),
1698      &replacement_path));
1699
1700  ui_test_utils::NavigateToURL(browser(),
1701                               https_server_.GetURL(replacement_path));
1702
1703  CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(),
1704                          AuthState::NONE);
1705}
1706
1707// Visit a page and establish a WebSocket connection over bad https with
1708// --ignore-certificate-errors. The connection should be established without
1709// interstitial page showing.
1710IN_PROC_BROWSER_TEST_F(SSLUITestIgnoreCertErrors, TestWSS) {
1711  ASSERT_TRUE(test_server()->Start());
1712  ASSERT_TRUE(wss_server_expired_.Start());
1713
1714  // Setup page title observer.
1715  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1716  content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
1717  watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
1718
1719  // Visit bad HTTPS page.
1720  std::string scheme("https");
1721  GURL::Replacements replacements;
1722  replacements.SetSchemeStr(scheme);
1723  ui_test_utils::NavigateToURL(
1724      browser(),
1725      wss_server_expired_.GetURL(
1726          "connect_check.html").ReplaceComponents(replacements));
1727
1728  // We shouldn't have an interstitial page showing here.
1729
1730  // Test page run a WebSocket wss connection test. The result will be shown
1731  // as page title.
1732  const base::string16 result = watcher.WaitAndGetTitle();
1733  EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass"));
1734}
1735
1736// Verifies that the interstitial can proceed, even if JavaScript is disabled.
1737// http://crbug.com/322948
1738IN_PROC_BROWSER_TEST_F(SSLUITest, TestInterstitialJavaScriptProceeds) {
1739  browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
1740      CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK);
1741
1742  ASSERT_TRUE(https_server_expired_.Start());
1743  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1744  ui_test_utils::NavigateToURL(browser(),
1745      https_server_expired_.GetURL("files/ssl/google.html"));
1746  CheckAuthenticationBrokenState(
1747      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1748
1749  content::WindowedNotificationObserver observer(
1750      content::NOTIFICATION_LOAD_STOP,
1751      content::Source<NavigationController>(&tab->GetController()));
1752  InterstitialPage* interstitial_page = tab->GetInterstitialPage();
1753  content::RenderViewHost* interstitial_rvh =
1754      interstitial_page->GetRenderViewHostForTesting();
1755  int result = -1;
1756  std::string javascript = base::StringPrintf(
1757      "window.domAutomationController.send(%d);",
1758      SSLBlockingPage::CMD_PROCEED);
1759  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1760              interstitial_rvh, javascript, &result));
1761  // The above will hang without the fix.
1762  EXPECT_EQ(1, result);
1763  observer.Wait();
1764  CheckAuthenticationBrokenState(
1765      tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE);
1766}
1767
1768// Verifies that the interstitial can go back, even if JavaScript is disabled.
1769// http://crbug.com/322948
1770IN_PROC_BROWSER_TEST_F(SSLUITest, TestInterstitialJavaScriptGoesBack) {
1771  browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
1772      CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK);
1773
1774  ASSERT_TRUE(https_server_expired_.Start());
1775  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1776  ui_test_utils::NavigateToURL(browser(),
1777      https_server_expired_.GetURL("files/ssl/google.html"));
1778  CheckAuthenticationBrokenState(
1779      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1780
1781  content::WindowedNotificationObserver observer(
1782      content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
1783      content::NotificationService::AllSources());
1784  InterstitialPage* interstitial_page = tab->GetInterstitialPage();
1785  content::RenderViewHost* interstitial_rvh =
1786      interstitial_page->GetRenderViewHostForTesting();
1787  int result = -1;
1788  std::string javascript = base::StringPrintf(
1789      "window.domAutomationController.send(%d);",
1790      SSLBlockingPage::CMD_DONT_PROCEED);
1791  ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
1792      interstitial_rvh, javascript, &result));
1793  // The above will hang without the fix.
1794  EXPECT_EQ(0, result);
1795  observer.Wait();
1796  EXPECT_EQ("about:blank", tab->GetVisibleURL().spec());
1797}
1798
1799// Verifies that switching tabs, while showing interstitial page, will not
1800// affect the visibility of the interestitial.
1801// https://crbug.com/381439
1802IN_PROC_BROWSER_TEST_F(SSLUITest, InterstitialNotAffectedByHideShow) {
1803  ASSERT_TRUE(https_server_expired_.Start());
1804  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1805  EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
1806  ui_test_utils::NavigateToURL(
1807      browser(), https_server_expired_.GetURL("files/ssl/google.html"));
1808  CheckAuthenticationBrokenState(
1809      tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL);
1810  EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
1811
1812  AddTabAtIndex(0,
1813                https_server_.GetURL("files/ssl/google.html"),
1814                content::PAGE_TRANSITION_TYPED);
1815  EXPECT_EQ(2, browser()->tab_strip_model()->count());
1816  EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
1817  EXPECT_EQ(tab, browser()->tab_strip_model()->GetWebContentsAt(1));
1818  EXPECT_FALSE(tab->GetRenderWidgetHostView()->IsShowing());
1819
1820  browser()->tab_strip_model()->ActivateTabAt(1, true);
1821  EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing());
1822}
1823
1824// TODO(jcampan): more tests to do below.
1825
1826// Visit a page over https that contains a frame with a redirect.
1827
1828// XMLHttpRequest insecure content in synchronous mode.
1829
1830// XMLHttpRequest insecure content in asynchronous mode.
1831
1832// XMLHttpRequest over bad ssl in synchronous mode.
1833
1834// XMLHttpRequest over OK ssl in synchronous mode.
1835