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