Home | History | Annotate | Download | only in ssl
      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 
     53 using base::ASCIIToUTF16;
     54 using content::InterstitialPage;
     55 using content::NavigationController;
     56 using content::NavigationEntry;
     57 using content::SSLStatus;
     58 using content::WebContents;
     59 using web_modal::WebContentsModalDialogManager;
     60 
     61 const base::FilePath::CharType kDocRoot[] =
     62     FILE_PATH_LITERAL("chrome/test/data");
     63 
     64 namespace {
     65 
     66 class 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 
     97 namespace AuthState {
     98 
     99 enum AuthStateFlags {
    100   NONE = 0,
    101   DISPLAYED_INSECURE_CONTENT = 1 << 0,
    102   RAN_INSECURE_CONTENT = 1 << 1,
    103   SHOWING_INTERSTITIAL = 1 << 2
    104 };
    105 
    106 void 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 
    126 namespace SecurityStyle {
    127 
    128 void 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 
    135 namespace CertError {
    136 
    137 enum CertErrorFlags {
    138   NONE = 0
    139 };
    140 
    141 void 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 
    155 void 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 
    169 class 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 
    357 class 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 
    367 class 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.
    378 IN_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!).
    392 IN_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 
    409 IN_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:
    441 IN_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:
    452 IN_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):
    479 IN_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.
    525 IN_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.
    562 IN_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.
    590 IN_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
    651 IN_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.
    693 IN_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
    730 IN_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).
    804 IN_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 
    819 IN_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.
    892 IN_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
    913 IN_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
    930 IN_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).
    974 IN_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.
   1004 IN_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.
   1045 IN_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).
   1095 IN_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).
   1129 IN_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.
   1163 IN_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.
   1206 IN_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.
   1233 IN_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.
   1274 IN_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.
   1295 IN_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.
   1314 IN_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.
   1331 IN_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).
   1353 IN_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.
   1368 IN_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
   1388 IN_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).
   1495 IN_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.
   1533 IN_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 
   1595 IN_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 
   1613 IN_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).
   1644 IN_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)
   1664 IN_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).
   1684 IN_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.
   1704 IN_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
   1732 IN_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
   1764 IN_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
   1796 IN_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