Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ssl / ssl_browser_tests.cc
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.