Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ssl / chrome_ssl_host_state_delegate_test.cc
1 // Copyright 2014 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 "chrome/browser/ssl/chrome_ssl_host_state_delegate.h"
6
7 #include <stdint.h>
8
9 #include "base/command_line.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/test/simple_test_clock.h"
12 #include "chrome/browser/browsing_data/browsing_data_helper.h"
13 #include "chrome/browser/browsing_data/browsing_data_remover.h"
14 #include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ssl/chrome_ssl_host_state_delegate_factory.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "content/public/browser/ssl_host_state_delegate.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "net/base/test_data_directory.h"
25 #include "net/test/cert_test_util.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace {
29
30 const char kGoogleCertFile[] = "google.single.der";
31
32 const char kWWWGoogleHost[] = "www.google.com";
33 const char kGoogleHost[] = "google.com";
34 const char kExampleHost[] = "example.com";
35
36 const char kForgetAtSessionEnd[] = "-1";
37 const char kForgetInstantly[] = "0";
38 const char kDeltaSecondsString[] = "86400";
39 const uint64_t kDeltaOneDayInSeconds = UINT64_C(86400);
40
41 scoped_refptr<net::X509Certificate> GetGoogleCert() {
42   return net::ImportCertFromFile(net::GetTestCertsDirectory(), kGoogleCertFile);
43 }
44
45 }  // namespace
46
47 class ChromeSSLHostStateDelegateTest : public InProcessBrowserTest {};
48
49 // ChromeSSLHostStateDelegateTest tests basic unit test functionality of the
50 // SSLHostStateDelegate class.  For example, tests that if a certificate is
51 // accepted, then it is added to queryable, and if it is revoked, it is not
52 // queryable. Even though it is effectively a unit test, in needs to be an
53 // InProcessBrowserTest because the actual functionality is provided by
54 // ChromeSSLHostStateDelegate which is provided per-profile.
55 //
56 // QueryPolicy unit tests the expected behavior of calling QueryPolicy on the
57 // SSLHostStateDelegate class after various SSL cert decisions have been made.
58 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, QueryPolicy) {
59   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
60   content::WebContents* tab =
61       browser()->tab_strip_model()->GetActiveWebContents();
62   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
63   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
64   bool unused_value;
65
66   // Verifying that all three of the certs we will be looking at are denied
67   // before any action has been taken.
68   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
69             state->QueryPolicy(kWWWGoogleHost,
70                                *google_cert.get(),
71                                net::CERT_STATUS_DATE_INVALID,
72                                &unused_value));
73   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
74             state->QueryPolicy(kGoogleHost,
75                                *google_cert.get(),
76                                net::CERT_STATUS_DATE_INVALID,
77                                &unused_value));
78   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
79             state->QueryPolicy(kExampleHost,
80                                *google_cert.get(),
81                                net::CERT_STATUS_DATE_INVALID,
82                                &unused_value));
83
84   // Simulate a user decision to allow an invalid certificate exception for
85   // kWWWGoogleHost.
86   state->AllowCert(
87       kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
88
89   // Verify that only kWWWGoogleHost is allowed and that the other two certs
90   // being tested still are denied.
91   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
92             state->QueryPolicy(kWWWGoogleHost,
93                                *google_cert.get(),
94                                net::CERT_STATUS_DATE_INVALID,
95                                &unused_value));
96   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
97             state->QueryPolicy(kGoogleHost,
98                                *google_cert.get(),
99                                net::CERT_STATUS_DATE_INVALID,
100                                &unused_value));
101   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
102             state->QueryPolicy(kExampleHost,
103                                *google_cert.get(),
104                                net::CERT_STATUS_DATE_INVALID,
105                                &unused_value));
106
107   // Simulate a user decision to allow an invalid certificate exception for
108   // kExampleHost.
109   state->AllowCert(
110       kExampleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
111
112   // Verify that both kWWWGoogleHost and kExampleHost have allow exceptions
113   // while kGoogleHost still is denied.
114   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
115             state->QueryPolicy(kWWWGoogleHost,
116                                *google_cert.get(),
117                                net::CERT_STATUS_DATE_INVALID,
118                                &unused_value));
119   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
120             state->QueryPolicy(kGoogleHost,
121                                *google_cert.get(),
122                                net::CERT_STATUS_DATE_INVALID,
123                                &unused_value));
124   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
125             state->QueryPolicy(kExampleHost,
126                                *google_cert.get(),
127                                net::CERT_STATUS_DATE_INVALID,
128                                &unused_value));
129 }
130
131 // HasPolicyAndRevoke unit tests the expected behavior of calling
132 // HasAllowException before and after calling RevokeUserAllowExceptions on the
133 // SSLHostStateDelegate class.
134 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, HasPolicyAndRevoke) {
135   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
136   content::WebContents* tab =
137       browser()->tab_strip_model()->GetActiveWebContents();
138   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
139   ChromeSSLHostStateDelegate* state =
140       ChromeSSLHostStateDelegateFactory::GetForProfile(profile);
141   bool unused_value;
142
143   // Simulate a user decision to allow an invalid certificate exception for
144   // kWWWGoogleHost and for kExampleHost.
145   state->AllowCert(
146       kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
147   state->AllowCert(
148       kExampleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
149
150   // Verify that HasAllowException correctly acknowledges that a user decision
151   // has been made about kWWWGoogleHost. Then verify that HasAllowException
152   // correctly identifies that the decision has been revoked.
153   EXPECT_TRUE(state->HasAllowException(kWWWGoogleHost));
154   state->RevokeUserAllowExceptions(kWWWGoogleHost);
155   EXPECT_FALSE(state->HasAllowException(kWWWGoogleHost));
156   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
157             state->QueryPolicy(kWWWGoogleHost,
158                                *google_cert.get(),
159                                net::CERT_STATUS_DATE_INVALID,
160                                &unused_value));
161
162   // Verify that the revocation of the kWWWGoogleHost decision does not affect
163   // the Allow for kExampleHost.
164   EXPECT_TRUE(state->HasAllowException(kExampleHost));
165
166   // Verify the revocation of the kWWWGoogleHost decision does not affect the
167   // non-decision for kGoogleHost. Then verify that a revocation of a URL with
168   // no decision has no effect.
169   EXPECT_FALSE(state->HasAllowException(kGoogleHost));
170   state->RevokeUserAllowExceptions(kGoogleHost);
171   EXPECT_FALSE(state->HasAllowException(kGoogleHost));
172 }
173
174 // Clear unit tests the expected behavior of calling Clear to forget all cert
175 // decision state on the SSLHostStateDelegate class.
176 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, Clear) {
177   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
178   content::WebContents* tab =
179       browser()->tab_strip_model()->GetActiveWebContents();
180   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
181   ChromeSSLHostStateDelegate* state =
182       ChromeSSLHostStateDelegateFactory::GetForProfile(profile);
183   bool unused_value;
184
185   // Simulate a user decision to allow an invalid certificate exception for
186   // kWWWGoogleHost and for kExampleHost.
187   state->AllowCert(
188       kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
189
190   // Do a full clear, then make sure that both kWWWGoogleHost, which had a
191   // decision made, and kExampleHost, which was untouched, are now in a denied
192   // state.
193   state->Clear();
194   EXPECT_FALSE(state->HasAllowException(kWWWGoogleHost));
195   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
196             state->QueryPolicy(kWWWGoogleHost,
197                                *google_cert.get(),
198                                net::CERT_STATUS_DATE_INVALID,
199                                &unused_value));
200   EXPECT_FALSE(state->HasAllowException(kExampleHost));
201   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
202             state->QueryPolicy(kExampleHost,
203                                *google_cert.get(),
204                                net::CERT_STATUS_DATE_INVALID,
205                                &unused_value));
206 }
207
208 // DidHostRunInsecureContent unit tests the expected behavior of calling
209 // DidHostRunInsecureContent as well as HostRanInsecureContent to check if
210 // insecure content has been run and to mark it as such.
211 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest,
212                        DidHostRunInsecureContent) {
213   content::WebContents* tab =
214       browser()->tab_strip_model()->GetActiveWebContents();
215   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
216   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
217
218   EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 42));
219   EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 191));
220   EXPECT_FALSE(state->DidHostRunInsecureContent("example.com", 42));
221
222   state->HostRanInsecureContent("www.google.com", 42);
223
224   EXPECT_TRUE(state->DidHostRunInsecureContent("www.google.com", 42));
225   EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 191));
226   EXPECT_FALSE(state->DidHostRunInsecureContent("example.com", 42));
227
228   state->HostRanInsecureContent("example.com", 42);
229
230   EXPECT_TRUE(state->DidHostRunInsecureContent("www.google.com", 42));
231   EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 191));
232   EXPECT_TRUE(state->DidHostRunInsecureContent("example.com", 42));
233 }
234
235 // QueryPolicyExpired unit tests to make sure that if a certificate decision has
236 // expired, the return value from QueryPolicy returns the correct vaule.
237 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, PRE_QueryPolicyExpired) {
238   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
239   content::WebContents* tab =
240       browser()->tab_strip_model()->GetActiveWebContents();
241   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
242   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
243   bool expired_previous_decision;
244
245   // The certificate has never been seen before, so it should be UNKNOWN and
246   // should also indicate that it hasn't expired.
247   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
248             state->QueryPolicy(kWWWGoogleHost,
249                                *google_cert.get(),
250                                net::CERT_STATUS_DATE_INVALID,
251                                &expired_previous_decision));
252   EXPECT_FALSE(expired_previous_decision);
253
254   // After allowing the certificate, a query should say that it is allowed and
255   // also specify that it hasn't expired.
256   state->AllowCert(
257       kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
258   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
259             state->QueryPolicy(kWWWGoogleHost,
260                                *google_cert.get(),
261                                net::CERT_STATUS_DATE_INVALID,
262                                &expired_previous_decision));
263   EXPECT_FALSE(expired_previous_decision);
264 }
265
266 // Since this is being checked on a browser instance that expires security
267 // decisions after restart, the test needs to  wait until after a restart to
268 // verify that the expiration state is correct.
269 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, QueryPolicyExpired) {
270   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
271   content::WebContents* tab =
272       browser()->tab_strip_model()->GetActiveWebContents();
273   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
274   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
275   bool expired_previous_decision;
276
277   // The browser content has restart thus expiring the user decision made above,
278   // so it should indicate that the certificate and error are DENIED but also
279   // that they expired since the last query.
280   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
281             state->QueryPolicy(kWWWGoogleHost,
282                                *google_cert.get(),
283                                net::CERT_STATUS_DATE_INVALID,
284                                &expired_previous_decision));
285   EXPECT_TRUE(expired_previous_decision);
286
287   // However, with a new query, it should indicate that no new expiration has
288   // occurred.
289   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
290             state->QueryPolicy(kWWWGoogleHost,
291                                *google_cert.get(),
292                                net::CERT_STATUS_DATE_INVALID,
293                                &expired_previous_decision));
294   EXPECT_FALSE(expired_previous_decision);
295 }
296
297 // Tests the basic behavior of cert memory in incognito.
298 class IncognitoSSLHostStateDelegateTest
299     : public ChromeSSLHostStateDelegateTest {
300  protected:
301   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
302     ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line);
303     command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
304                                     kDeltaSecondsString);
305   }
306 };
307
308 IN_PROC_BROWSER_TEST_F(IncognitoSSLHostStateDelegateTest, PRE_AfterRestart) {
309   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
310   content::WebContents* tab =
311       browser()->tab_strip_model()->GetActiveWebContents();
312   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
313   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
314   bool unused_value;
315
316   // Add a cert exception to the profile and then verify that it still exists
317   // in the incognito profile.
318   state->AllowCert(
319       kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
320
321   scoped_ptr<Profile> incognito(profile->CreateOffTheRecordProfile());
322   content::SSLHostStateDelegate* incognito_state =
323       incognito->GetSSLHostStateDelegate();
324
325   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
326             incognito_state->QueryPolicy(kWWWGoogleHost,
327                                          *google_cert.get(),
328                                          net::CERT_STATUS_DATE_INVALID,
329                                          &unused_value));
330
331   // Add a cert exception to the incognito profile. It will be checked after
332   // restart that this exception does not exist. Note the different cert URL and
333   // error than above thus mapping to a second exception. Also validate that it
334   // was not added as an exception to the regular profile.
335   incognito_state->AllowCert(
336       kGoogleHost, *google_cert.get(), net::CERT_STATUS_COMMON_NAME_INVALID);
337
338   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
339             state->QueryPolicy(kGoogleHost,
340                                *google_cert.get(),
341                                net::CERT_STATUS_COMMON_NAME_INVALID,
342                                &unused_value));
343 }
344
345 // AfterRestart ensures that any cert decisions made in an incognito profile are
346 // forgetten after a session restart even if given a command line flag to
347 // remember cert decisions after restart.
348 IN_PROC_BROWSER_TEST_F(IncognitoSSLHostStateDelegateTest, AfterRestart) {
349   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
350   content::WebContents* tab =
351       browser()->tab_strip_model()->GetActiveWebContents();
352   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
353   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
354   bool unused_value;
355
356   // Verify that the exception added before restart to the regular
357   // (non-incognito) profile still exists and was not cleared after the
358   // incognito session ended.
359   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
360             state->QueryPolicy(kWWWGoogleHost,
361                                *google_cert.get(),
362                                net::CERT_STATUS_DATE_INVALID,
363                                &unused_value));
364
365   scoped_ptr<Profile> incognito(profile->CreateOffTheRecordProfile());
366   content::SSLHostStateDelegate* incognito_state =
367       incognito->GetSSLHostStateDelegate();
368
369   // Verify that the exception added before restart to the incognito profile was
370   // cleared when the incognito session ended.
371   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
372             incognito_state->QueryPolicy(kGoogleHost,
373                                          *google_cert.get(),
374                                          net::CERT_STATUS_COMMON_NAME_INVALID,
375                                          &unused_value));
376 }
377
378 // Tests to make sure that if the remember value is set to -1, any decisions
379 // won't be remembered over a restart.
380 class ForGetSSLHostStateDelegateTest : public ChromeSSLHostStateDelegateTest {
381  protected:
382   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
383     ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line);
384     command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
385                                     kForgetAtSessionEnd);
386   }
387 };
388
389 IN_PROC_BROWSER_TEST_F(ForGetSSLHostStateDelegateTest, PRE_AfterRestart) {
390   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
391   content::WebContents* tab =
392       browser()->tab_strip_model()->GetActiveWebContents();
393   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
394   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
395   bool unused_value;
396
397   state->AllowCert(
398       kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
399   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
400             state->QueryPolicy(kWWWGoogleHost,
401                                *google_cert.get(),
402                                net::CERT_STATUS_DATE_INVALID,
403                                &unused_value));
404 }
405
406 IN_PROC_BROWSER_TEST_F(ForGetSSLHostStateDelegateTest, AfterRestart) {
407   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
408   content::WebContents* tab =
409       browser()->tab_strip_model()->GetActiveWebContents();
410   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
411   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
412   bool unused_value;
413
414   // The cert should now be |DENIED| because the profile is set to forget cert
415   // exceptions after session end.
416   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
417             state->QueryPolicy(kWWWGoogleHost,
418                                *google_cert.get(),
419                                net::CERT_STATUS_DATE_INVALID,
420                                &unused_value));
421 }
422
423 // Tests to make sure that if the remember value is set to 0, any decisions made
424 // will be forgetten immediately.
425 class ForgetInstantlySSLHostStateDelegateTest
426     : public ChromeSSLHostStateDelegateTest {
427  protected:
428   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
429     ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line);
430     command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
431                                     kForgetInstantly);
432   }
433 };
434
435 IN_PROC_BROWSER_TEST_F(ForgetInstantlySSLHostStateDelegateTest,
436                        MakeAndForgetException) {
437   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
438   content::WebContents* tab =
439       browser()->tab_strip_model()->GetActiveWebContents();
440   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
441   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
442   bool unused_value;
443
444   // chrome_state takes ownership of this clock
445   base::SimpleTestClock* clock = new base::SimpleTestClock();
446   ChromeSSLHostStateDelegate* chrome_state =
447       static_cast<ChromeSSLHostStateDelegate*>(state);
448   chrome_state->SetClock(scoped_ptr<base::Clock>(clock));
449
450   // Start the clock at standard system time but do not advance at all to
451   // emphasize that instant forget works.
452   clock->SetNow(base::Time::NowFromSystemTime());
453
454   state->AllowCert(
455       kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
456   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
457             state->QueryPolicy(kWWWGoogleHost,
458                                *google_cert.get(),
459                                net::CERT_STATUS_DATE_INVALID,
460                                &unused_value));
461 }
462
463 // Tests to make sure that if the remember value is set to a non-zero value,
464 // any decisions will be remembered over a restart, but only for the length
465 // specified.
466 class RememberSSLHostStateDelegateTest : public ChromeSSLHostStateDelegateTest {
467  protected:
468   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
469     ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line);
470     command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
471                                     kDeltaSecondsString);
472   }
473 };
474
475 IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDelegateTest, PRE_AfterRestart) {
476   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
477   content::WebContents* tab =
478       browser()->tab_strip_model()->GetActiveWebContents();
479   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
480   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
481   bool unused_value;
482
483   state->AllowCert(
484       kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
485   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
486             state->QueryPolicy(kWWWGoogleHost,
487                                *google_cert.get(),
488                                net::CERT_STATUS_DATE_INVALID,
489                                &unused_value));
490 }
491
492 IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDelegateTest, AfterRestart) {
493   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
494   content::WebContents* tab =
495       browser()->tab_strip_model()->GetActiveWebContents();
496   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
497   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
498   bool unused_value;
499
500   // chrome_state takes ownership of this clock
501   base::SimpleTestClock* clock = new base::SimpleTestClock();
502   ChromeSSLHostStateDelegate* chrome_state =
503       static_cast<ChromeSSLHostStateDelegate*>(state);
504   chrome_state->SetClock(scoped_ptr<base::Clock>(clock));
505
506   // Start the clock at standard system time.
507   clock->SetNow(base::Time::NowFromSystemTime());
508
509   // This should only pass if the cert was allowed before the test was restart
510   // and thus has now been rememebered across browser restarts.
511   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
512             state->QueryPolicy(kWWWGoogleHost,
513                                *google_cert.get(),
514                                net::CERT_STATUS_DATE_INVALID,
515                                &unused_value));
516
517   // Simulate the clock advancing by the specified delta.
518   clock->Advance(base::TimeDelta::FromSeconds(kDeltaOneDayInSeconds + 1));
519
520   // The cert should now be |DENIED| because the specified delta has passed.
521   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
522             state->QueryPolicy(kWWWGoogleHost,
523                                *google_cert.get(),
524                                net::CERT_STATUS_DATE_INVALID,
525                                &unused_value));
526 }
527
528 // The same test as ChromeSSLHostStateDelegateTest.QueryPolicyExpired but now
529 // applied to a browser context that expires based on time, not restart. This
530 // unit tests to make sure that if a certificate decision has expired, the
531 // return value from QueryPolicy returns the correct vaule.
532 IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDelegateTest, QueryPolicyExpired) {
533   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
534   content::WebContents* tab =
535       browser()->tab_strip_model()->GetActiveWebContents();
536   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
537   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
538   bool expired_previous_decision;
539
540   // chrome_state takes ownership of this clock
541   base::SimpleTestClock* clock = new base::SimpleTestClock();
542   ChromeSSLHostStateDelegate* chrome_state =
543       static_cast<ChromeSSLHostStateDelegate*>(state);
544   chrome_state->SetClock(scoped_ptr<base::Clock>(clock));
545
546   // Start the clock at standard system time but do not advance at all to
547   // emphasize that instant forget works.
548   clock->SetNow(base::Time::NowFromSystemTime());
549
550   // The certificate has never been seen before, so it should be UNKONWN and
551   // should also indicate that it hasn't expired.
552   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
553             state->QueryPolicy(kWWWGoogleHost,
554                                *google_cert.get(),
555                                net::CERT_STATUS_DATE_INVALID,
556                                &expired_previous_decision));
557   EXPECT_FALSE(expired_previous_decision);
558
559   // After allowing the certificate, a query should say that it is allowed and
560   // also specify that it hasn't expired.
561   state->AllowCert(
562       kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
563   EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
564             state->QueryPolicy(kWWWGoogleHost,
565                                *google_cert.get(),
566                                net::CERT_STATUS_DATE_INVALID,
567                                &expired_previous_decision));
568   EXPECT_FALSE(expired_previous_decision);
569
570   // Simulate the clock advancing by the specified delta.
571   clock->Advance(base::TimeDelta::FromSeconds(kDeltaOneDayInSeconds + 1));
572
573   // The decision expiration time has come, so it should indicate that the
574   // certificate and error are DENIED but also that they expired since the last
575   // query.
576   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
577             state->QueryPolicy(kWWWGoogleHost,
578                                *google_cert.get(),
579                                net::CERT_STATUS_DATE_INVALID,
580                                &expired_previous_decision));
581   EXPECT_TRUE(expired_previous_decision);
582
583   // However, with a new query, it should indicate that no new expiration has
584   // occurred.
585   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
586             state->QueryPolicy(kWWWGoogleHost,
587                                *google_cert.get(),
588                                net::CERT_STATUS_DATE_INVALID,
589                                &expired_previous_decision));
590   EXPECT_FALSE(expired_previous_decision);
591 }
592
593 // Tests to make sure that if the user deletes their browser history, SSL
594 // exceptions will be deleted as well.
595 class RemoveBrowsingHistorySSLHostStateDelegateTest
596     : public ChromeSSLHostStateDelegateTest {
597  public:
598   void RemoveAndWait(Profile* profile) {
599     BrowsingDataRemover* remover = BrowsingDataRemover::CreateForPeriod(
600         profile, BrowsingDataRemover::LAST_HOUR);
601     BrowsingDataRemoverCompletionObserver completion_observer(remover);
602     remover->Remove(BrowsingDataRemover::REMOVE_HISTORY,
603                     BrowsingDataHelper::UNPROTECTED_WEB);
604     completion_observer.BlockUntilCompletion();
605   }
606 };
607
608 IN_PROC_BROWSER_TEST_F(RemoveBrowsingHistorySSLHostStateDelegateTest,
609                        DeleteHistory) {
610   scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
611   content::WebContents* tab =
612       browser()->tab_strip_model()->GetActiveWebContents();
613   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
614   content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
615   bool unused_value;
616
617   // Add an exception for an invalid certificate. Then remove the last hour's
618   // worth of browsing history and verify that the exception has been deleted.
619   state->AllowCert(
620       kGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
621   RemoveAndWait(profile);
622   EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
623             state->QueryPolicy(kGoogleHost,
624                                *google_cert.get(),
625                                net::CERT_STATUS_DATE_INVALID,
626                                &unused_value));
627 }