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