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