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.
5 #include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h"
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"
30 const char kOkCertFile
[] = "ok_cert.pem";
32 const char kWWWGoogleHost
[] = "www.google.com";
33 const char kGoogleHost
[] = "google.com";
34 const char kExampleHost
[] = "example.com";
36 const char kForgetAtSessionEnd
[] = "-1";
37 const char kForgetInstantly
[] = "0";
38 const char kDeltaSecondsString
[] = "86400";
39 const uint64_t kDeltaOneDayInSeconds
= UINT64_C(86400);
41 scoped_refptr
<net::X509Certificate
> GetOkCert() {
42 return net::ImportCertFromFile(net::GetTestCertsDirectory(), kOkCertFile
);
47 class ChromeSSLHostStateDelegateTest
: public InProcessBrowserTest
{};
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.
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
> cert
= GetOkCert();
60 content::WebContents
* tab
=
61 browser()->tab_strip_model()->GetActiveWebContents();
62 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
63 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
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
, *cert
,
70 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
71 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
72 state
->QueryPolicy(kGoogleHost
, *cert
,
73 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
74 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
75 state
->QueryPolicy(kExampleHost
, *cert
,
76 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
78 // Simulate a user decision to allow an invalid certificate exception for
80 state
->AllowCert(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
82 // Verify that only kWWWGoogleHost is allowed and that the other two certs
83 // being tested still are denied.
84 EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED
,
85 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
86 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
87 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
88 state
->QueryPolicy(kGoogleHost
, *cert
,
89 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
90 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
91 state
->QueryPolicy(kExampleHost
, *cert
,
92 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
94 // Simulate a user decision to allow an invalid certificate exception for
96 state
->AllowCert(kExampleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
98 // Verify that both kWWWGoogleHost and kExampleHost have allow exceptions
99 // while kGoogleHost still is denied.
100 EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED
,
101 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
102 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
103 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
104 state
->QueryPolicy(kGoogleHost
, *cert
,
105 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
106 EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED
,
107 state
->QueryPolicy(kExampleHost
, *cert
,
108 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
111 // HasPolicyAndRevoke unit tests the expected behavior of calling
112 // HasAllowException before and after calling RevokeUserAllowExceptions on the
113 // SSLHostStateDelegate class.
114 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest
, HasPolicyAndRevoke
) {
115 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
116 content::WebContents
* tab
=
117 browser()->tab_strip_model()->GetActiveWebContents();
118 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
119 ChromeSSLHostStateDelegate
* state
=
120 ChromeSSLHostStateDelegateFactory::GetForProfile(profile
);
123 // Simulate a user decision to allow an invalid certificate exception for
124 // kWWWGoogleHost and for kExampleHost.
125 state
->AllowCert(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
126 state
->AllowCert(kExampleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
128 // Verify that HasAllowException correctly acknowledges that a user decision
129 // has been made about kWWWGoogleHost. Then verify that HasAllowException
130 // correctly identifies that the decision has been revoked.
131 EXPECT_TRUE(state
->HasAllowException(kWWWGoogleHost
));
132 state
->RevokeUserAllowExceptions(kWWWGoogleHost
);
133 EXPECT_FALSE(state
->HasAllowException(kWWWGoogleHost
));
134 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
135 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
136 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
138 // Verify that the revocation of the kWWWGoogleHost decision does not affect
139 // the Allow for kExampleHost.
140 EXPECT_TRUE(state
->HasAllowException(kExampleHost
));
142 // Verify the revocation of the kWWWGoogleHost decision does not affect the
143 // non-decision for kGoogleHost. Then verify that a revocation of a URL with
144 // no decision has no effect.
145 EXPECT_FALSE(state
->HasAllowException(kGoogleHost
));
146 state
->RevokeUserAllowExceptions(kGoogleHost
);
147 EXPECT_FALSE(state
->HasAllowException(kGoogleHost
));
150 // Clear unit tests the expected behavior of calling Clear to forget all cert
151 // decision state on the SSLHostStateDelegate class.
152 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest
, Clear
) {
153 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
154 content::WebContents
* tab
=
155 browser()->tab_strip_model()->GetActiveWebContents();
156 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
157 ChromeSSLHostStateDelegate
* state
=
158 ChromeSSLHostStateDelegateFactory::GetForProfile(profile
);
161 // Simulate a user decision to allow an invalid certificate exception for
162 // kWWWGoogleHost and for kExampleHost.
163 state
->AllowCert(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
165 // Do a full clear, then make sure that both kWWWGoogleHost, which had a
166 // decision made, and kExampleHost, which was untouched, are now in a denied
169 EXPECT_FALSE(state
->HasAllowException(kWWWGoogleHost
));
170 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
171 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
172 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
173 EXPECT_FALSE(state
->HasAllowException(kExampleHost
));
174 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
175 state
->QueryPolicy(kExampleHost
, *cert
,
176 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
179 // DidHostRunInsecureContent unit tests the expected behavior of calling
180 // DidHostRunInsecureContent as well as HostRanInsecureContent to check if
181 // insecure content has been run and to mark it as such.
182 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest
,
183 DidHostRunInsecureContent
) {
184 content::WebContents
* tab
=
185 browser()->tab_strip_model()->GetActiveWebContents();
186 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
187 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
189 EXPECT_FALSE(state
->DidHostRunInsecureContent("www.google.com", 42));
190 EXPECT_FALSE(state
->DidHostRunInsecureContent("www.google.com", 191));
191 EXPECT_FALSE(state
->DidHostRunInsecureContent("example.com", 42));
193 state
->HostRanInsecureContent("www.google.com", 42);
195 EXPECT_TRUE(state
->DidHostRunInsecureContent("www.google.com", 42));
196 EXPECT_FALSE(state
->DidHostRunInsecureContent("www.google.com", 191));
197 EXPECT_FALSE(state
->DidHostRunInsecureContent("example.com", 42));
199 state
->HostRanInsecureContent("example.com", 42);
201 EXPECT_TRUE(state
->DidHostRunInsecureContent("www.google.com", 42));
202 EXPECT_FALSE(state
->DidHostRunInsecureContent("www.google.com", 191));
203 EXPECT_TRUE(state
->DidHostRunInsecureContent("example.com", 42));
206 // QueryPolicyExpired unit tests to make sure that if a certificate decision has
207 // expired, the return value from QueryPolicy returns the correct vaule.
208 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest
, PRE_QueryPolicyExpired
) {
209 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
210 content::WebContents
* tab
=
211 browser()->tab_strip_model()->GetActiveWebContents();
212 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
213 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
214 bool expired_previous_decision
;
216 // The certificate has never been seen before, so it should be UNKNOWN and
217 // should also indicate that it hasn't expired.
219 content::SSLHostStateDelegate::DENIED
,
220 state
->QueryPolicy(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
,
221 &expired_previous_decision
));
222 EXPECT_FALSE(expired_previous_decision
);
224 // After allowing the certificate, a query should say that it is allowed and
225 // also specify that it hasn't expired.
226 state
->AllowCert(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
228 content::SSLHostStateDelegate::ALLOWED
,
229 state
->QueryPolicy(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
,
230 &expired_previous_decision
));
231 EXPECT_FALSE(expired_previous_decision
);
234 // Since this is being checked on a browser instance that expires security
235 // decisions after restart, the test needs to wait until after a restart to
236 // verify that the expiration state is correct.
237 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest
, QueryPolicyExpired
) {
238 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
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
;
245 // The browser content has restart thus expiring the user decision made above,
246 // so it should indicate that the certificate and error are DENIED but also
247 // that they expired since the last query.
249 content::SSLHostStateDelegate::DENIED
,
250 state
->QueryPolicy(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
,
251 &expired_previous_decision
));
252 EXPECT_TRUE(expired_previous_decision
);
254 // However, with a new query, it should indicate that no new expiration has
257 content::SSLHostStateDelegate::DENIED
,
258 state
->QueryPolicy(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
,
259 &expired_previous_decision
));
260 EXPECT_FALSE(expired_previous_decision
);
263 // Tests the basic behavior of cert memory in incognito.
264 class IncognitoSSLHostStateDelegateTest
265 : public ChromeSSLHostStateDelegateTest
{
267 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
268 ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line
);
269 command_line
->AppendSwitchASCII(switches::kRememberCertErrorDecisions
,
270 kDeltaSecondsString
);
274 IN_PROC_BROWSER_TEST_F(IncognitoSSLHostStateDelegateTest
, PRE_AfterRestart
) {
275 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
276 content::WebContents
* tab
=
277 browser()->tab_strip_model()->GetActiveWebContents();
278 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
279 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
282 // Add a cert exception to the profile and then verify that it still exists
283 // in the incognito profile.
284 state
->AllowCert(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
286 scoped_ptr
<Profile
> incognito(profile
->CreateOffTheRecordProfile());
287 content::SSLHostStateDelegate
* incognito_state
=
288 incognito
->GetSSLHostStateDelegate();
291 content::SSLHostStateDelegate::ALLOWED
,
292 incognito_state
->QueryPolicy(
293 kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
, &unused_value
));
295 // Add a cert exception to the incognito profile. It will be checked after
296 // restart that this exception does not exist. Note the different cert URL and
297 // error than above thus mapping to a second exception. Also validate that it
298 // was not added as an exception to the regular profile.
299 incognito_state
->AllowCert(kGoogleHost
, *cert
,
300 net::CERT_STATUS_COMMON_NAME_INVALID
);
303 content::SSLHostStateDelegate::DENIED
,
304 state
->QueryPolicy(kGoogleHost
, *cert
,
305 net::CERT_STATUS_COMMON_NAME_INVALID
, &unused_value
));
308 // AfterRestart ensures that any cert decisions made in an incognito profile are
309 // forgetten after a session restart even if given a command line flag to
310 // remember cert decisions after restart.
311 IN_PROC_BROWSER_TEST_F(IncognitoSSLHostStateDelegateTest
, AfterRestart
) {
312 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
313 content::WebContents
* tab
=
314 browser()->tab_strip_model()->GetActiveWebContents();
315 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
316 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
319 // Verify that the exception added before restart to the regular
320 // (non-incognito) profile still exists and was not cleared after the
321 // incognito session ended.
322 EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED
,
323 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
324 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
326 scoped_ptr
<Profile
> incognito(profile
->CreateOffTheRecordProfile());
327 content::SSLHostStateDelegate
* incognito_state
=
328 incognito
->GetSSLHostStateDelegate();
330 // Verify that the exception added before restart to the incognito profile was
331 // cleared when the incognito session ended.
332 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
333 incognito_state
->QueryPolicy(kGoogleHost
, *cert
,
334 net::CERT_STATUS_COMMON_NAME_INVALID
,
338 // Tests to make sure that if the remember value is set to -1, any decisions
339 // won't be remembered over a restart.
340 class ForGetSSLHostStateDelegateTest
: public ChromeSSLHostStateDelegateTest
{
342 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
343 ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line
);
344 command_line
->AppendSwitchASCII(switches::kRememberCertErrorDecisions
,
345 kForgetAtSessionEnd
);
349 IN_PROC_BROWSER_TEST_F(ForGetSSLHostStateDelegateTest
, PRE_AfterRestart
) {
350 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
351 content::WebContents
* tab
=
352 browser()->tab_strip_model()->GetActiveWebContents();
353 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
354 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
357 state
->AllowCert(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
358 EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED
,
359 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
360 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
363 IN_PROC_BROWSER_TEST_F(ForGetSSLHostStateDelegateTest
, AfterRestart
) {
364 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
365 content::WebContents
* tab
=
366 browser()->tab_strip_model()->GetActiveWebContents();
367 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
368 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
371 // The cert should now be |DENIED| because the profile is set to forget cert
372 // exceptions after session end.
373 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
374 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
375 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
378 // Tests to make sure that if the remember value is set to 0, any decisions made
379 // will be forgetten immediately.
380 class ForgetInstantlySSLHostStateDelegateTest
381 : public ChromeSSLHostStateDelegateTest
{
383 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
384 ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line
);
385 command_line
->AppendSwitchASCII(switches::kRememberCertErrorDecisions
,
390 IN_PROC_BROWSER_TEST_F(ForgetInstantlySSLHostStateDelegateTest
,
391 MakeAndForgetException
) {
392 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
393 content::WebContents
* tab
=
394 browser()->tab_strip_model()->GetActiveWebContents();
395 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
396 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
399 // chrome_state takes ownership of this clock
400 base::SimpleTestClock
* clock
= new base::SimpleTestClock();
401 ChromeSSLHostStateDelegate
* chrome_state
=
402 static_cast<ChromeSSLHostStateDelegate
*>(state
);
403 chrome_state
->SetClock(scoped_ptr
<base::Clock
>(clock
));
405 // Start the clock at standard system time but do not advance at all to
406 // emphasize that instant forget works.
407 clock
->SetNow(base::Time::NowFromSystemTime());
409 state
->AllowCert(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
410 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
411 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
412 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
415 // Tests to make sure that if the remember value is set to a non-zero value,
416 // any decisions will be remembered over a restart, but only for the length
418 class RememberSSLHostStateDelegateTest
: public ChromeSSLHostStateDelegateTest
{
420 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
421 ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line
);
422 command_line
->AppendSwitchASCII(switches::kRememberCertErrorDecisions
,
423 kDeltaSecondsString
);
427 IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDelegateTest
, PRE_AfterRestart
) {
428 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
429 content::WebContents
* tab
=
430 browser()->tab_strip_model()->GetActiveWebContents();
431 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
432 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
435 state
->AllowCert(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
436 EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED
,
437 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
438 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
441 IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDelegateTest
, AfterRestart
) {
442 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
443 content::WebContents
* tab
=
444 browser()->tab_strip_model()->GetActiveWebContents();
445 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
446 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
449 // chrome_state takes ownership of this clock
450 base::SimpleTestClock
* clock
= new base::SimpleTestClock();
451 ChromeSSLHostStateDelegate
* chrome_state
=
452 static_cast<ChromeSSLHostStateDelegate
*>(state
);
453 chrome_state
->SetClock(scoped_ptr
<base::Clock
>(clock
));
455 // Start the clock at standard system time.
456 clock
->SetNow(base::Time::NowFromSystemTime());
458 // This should only pass if the cert was allowed before the test was restart
459 // and thus has now been rememebered across browser restarts.
460 EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED
,
461 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
462 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
464 // Simulate the clock advancing by the specified delta.
465 clock
->Advance(base::TimeDelta::FromSeconds(kDeltaOneDayInSeconds
+ 1));
467 // The cert should now be |DENIED| because the specified delta has passed.
468 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
469 state
->QueryPolicy(kWWWGoogleHost
, *cert
,
470 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
473 // The same test as ChromeSSLHostStateDelegateTest.QueryPolicyExpired but now
474 // applied to a browser context that expires based on time, not restart. This
475 // unit tests to make sure that if a certificate decision has expired, the
476 // return value from QueryPolicy returns the correct vaule.
477 IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDelegateTest
, QueryPolicyExpired
) {
478 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
479 content::WebContents
* tab
=
480 browser()->tab_strip_model()->GetActiveWebContents();
481 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
482 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
483 bool expired_previous_decision
;
485 // chrome_state takes ownership of this clock
486 base::SimpleTestClock
* clock
= new base::SimpleTestClock();
487 ChromeSSLHostStateDelegate
* chrome_state
=
488 static_cast<ChromeSSLHostStateDelegate
*>(state
);
489 chrome_state
->SetClock(scoped_ptr
<base::Clock
>(clock
));
491 // Start the clock at standard system time but do not advance at all to
492 // emphasize that instant forget works.
493 clock
->SetNow(base::Time::NowFromSystemTime());
495 // The certificate has never been seen before, so it should be UNKONWN and
496 // should also indicate that it hasn't expired.
498 content::SSLHostStateDelegate::DENIED
,
499 state
->QueryPolicy(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
,
500 &expired_previous_decision
));
501 EXPECT_FALSE(expired_previous_decision
);
503 // After allowing the certificate, a query should say that it is allowed and
504 // also specify that it hasn't expired.
505 state
->AllowCert(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
507 content::SSLHostStateDelegate::ALLOWED
,
508 state
->QueryPolicy(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
,
509 &expired_previous_decision
));
510 EXPECT_FALSE(expired_previous_decision
);
512 // Simulate the clock advancing by the specified delta.
513 clock
->Advance(base::TimeDelta::FromSeconds(kDeltaOneDayInSeconds
+ 1));
515 // The decision expiration time has come, so it should indicate that the
516 // certificate and error are DENIED but also that they expired since the last
519 content::SSLHostStateDelegate::DENIED
,
520 state
->QueryPolicy(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
,
521 &expired_previous_decision
));
522 EXPECT_TRUE(expired_previous_decision
);
524 // However, with a new query, it should indicate that no new expiration has
527 content::SSLHostStateDelegate::DENIED
,
528 state
->QueryPolicy(kWWWGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
,
529 &expired_previous_decision
));
530 EXPECT_FALSE(expired_previous_decision
);
533 // Tests to make sure that if the user deletes their browser history, SSL
534 // exceptions will be deleted as well.
535 class RemoveBrowsingHistorySSLHostStateDelegateTest
536 : public ChromeSSLHostStateDelegateTest
{
538 void RemoveAndWait(Profile
* profile
) {
539 BrowsingDataRemover
* remover
= BrowsingDataRemover::CreateForPeriod(
540 profile
, BrowsingDataRemover::LAST_HOUR
);
541 BrowsingDataRemoverCompletionObserver
completion_observer(remover
);
542 remover
->Remove(BrowsingDataRemover::REMOVE_HISTORY
,
543 BrowsingDataHelper::UNPROTECTED_WEB
);
544 completion_observer
.BlockUntilCompletion();
548 IN_PROC_BROWSER_TEST_F(RemoveBrowsingHistorySSLHostStateDelegateTest
,
550 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
551 content::WebContents
* tab
=
552 browser()->tab_strip_model()->GetActiveWebContents();
553 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
554 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
557 // Add an exception for an invalid certificate. Then remove the last hour's
558 // worth of browsing history and verify that the exception has been deleted.
559 state
->AllowCert(kGoogleHost
, *cert
, net::CERT_STATUS_DATE_INVALID
);
560 RemoveAndWait(profile
);
561 EXPECT_EQ(content::SSLHostStateDelegate::DENIED
,
562 state
->QueryPolicy(kGoogleHost
, *cert
,
563 net::CERT_STATUS_DATE_INVALID
, &unused_value
));
566 // Tests to make sure that localhost certificate errors are treated as
567 // normal errors or ignored, depending on whether the
568 // kAllowInsecureLocalhost flag is set.
570 // When the flag isn't set, requests to localhost with invalid
571 // certificates should be denied.
572 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest
,
573 LocalhostErrorWithoutFlag
) {
574 // Serve the Google cert for localhost to generate an error.
575 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
576 content::WebContents
* tab
=
577 browser()->tab_strip_model()->GetActiveWebContents();
578 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
579 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
583 content::SSLHostStateDelegate::DENIED
,
584 state
->QueryPolicy("localhost", *cert
,
585 net::CERT_STATUS_COMMON_NAME_INVALID
, &unused_value
));
588 content::SSLHostStateDelegate::DENIED
,
589 state
->QueryPolicy("127.0.0.1", *cert
,
590 net::CERT_STATUS_COMMON_NAME_INVALID
, &unused_value
));
593 // When the flag is set, requests to localhost with invalid certificates
594 // should be allowed.
595 class AllowLocalhostErrorsSSLHostStateDelegateTest
596 : public ChromeSSLHostStateDelegateTest
{
598 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
599 ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line
);
600 command_line
->AppendSwitch(switches::kAllowInsecureLocalhost
);
604 IN_PROC_BROWSER_TEST_F(AllowLocalhostErrorsSSLHostStateDelegateTest
,
605 LocalhostErrorWithFlag
) {
606 // Serve the Google cert for localhost to generate an error.
607 scoped_refptr
<net::X509Certificate
> cert
= GetOkCert();
608 content::WebContents
* tab
=
609 browser()->tab_strip_model()->GetActiveWebContents();
610 Profile
* profile
= Profile::FromBrowserContext(tab
->GetBrowserContext());
611 content::SSLHostStateDelegate
* state
= profile
->GetSSLHostStateDelegate();
615 content::SSLHostStateDelegate::ALLOWED
,
616 state
->QueryPolicy("localhost", *cert
,
617 net::CERT_STATUS_COMMON_NAME_INVALID
, &unused_value
));
620 content::SSLHostStateDelegate::ALLOWED
,
621 state
->QueryPolicy("127.0.0.1", *cert
,
622 net::CERT_STATUS_COMMON_NAME_INVALID
, &unused_value
));