Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Side by Side Diff: chrome/browser/ssl/chrome_ssl_host_state_decisions_test.cc

Issue 369703002: Remember user decisions on invalid certificates behind a flag (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated with experimental groups Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 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 <stdint.h>
6
7 #include "base/command_line.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/test/simple_test_clock.h"
10 #include "chrome/browser/browsing_data/browsing_data_helper.h"
11 #include "chrome/browser/browsing_data/browsing_data_remover.h"
12 #include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ssl/chrome_ssl_host_state_decisions.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/test/base/in_process_browser_test.h"
19 #include "content/public/browser/ssl_host_state_decisions.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/test/browser_test_utils.h"
22 #include "net/test/test_certificate_data.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "url/gurl.h"
25
26 namespace {
27
28 const char www_google_url[] = "https://www.google.com";
29 const char google_url[] = "https://google.com";
30 const char example_url[] = "https://example.com";
31
32 const char* kForgetAtSessionEnd = "-1";
33 const char* kForgetInstantly = "0";
34 const char* kDeltaSecondsString = "86400";
35 const uint64_t kDeltaOneDayInSeconds = UINT64_C(86400);
36
37 } // namespace
38
39 class ChromeSSLHostStateDecisionsTest : public InProcessBrowserTest {};
40
41 // ChromeSSLHostStateDecisionsTest tests basic unit test functionality of the
42 // SSLHostStateDecisions class. For example, tests that if a certificate is
43 // accepted, then it is added to queryable, and if it is revoked, it is not
44 // queryable. Even though it is effectively a unit test, in needs to be an
45 // InProcessBrowserTest because the actual functionality is provided by
46 // ChromeSSLHostStateDecisions which is provided per-profile.
47 //
48 // QueryPolicy unit tests the expected behavior of calling QueryPolicy on the
49 // SSLHostStateDecisions class after various SSL cert decisions have been made.
50 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDecisionsTest, QueryPolicy) {
51 GURL www_google_gurl(www_google_url);
52 GURL google_gurl(google_url);
53 GURL example_gurl(example_url);
54 scoped_refptr<net::X509Certificate> google_cert(
55 net::X509Certificate::CreateFromBytes(
56 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
Ryan Sleevi 2014/07/31 00:31:28 Not your fault, but bonus points if you want to us
jww 2014/07/31 05:57:00 Done.
57 content::WebContents* tab =
58 browser()->tab_strip_model()->GetActiveWebContents();
59 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
60 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
61
62 // Verifying that all three of the certs we will be looking at are unknown
63 // before any action has been taken.
64 EXPECT_EQ(
65 net::CertPolicy::UNKNOWN,
66 state->QueryPolicy(
67 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
68 EXPECT_EQ(net::CertPolicy::UNKNOWN,
69 state->QueryPolicy(
70 google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
71 EXPECT_EQ(
72 net::CertPolicy::UNKNOWN,
73 state->QueryPolicy(
74 example_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
75
76 // Simulate a user decision to allow an invalid certificate exception for
77 // www_google_url.
78 state->AllowCert(
79 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
80
81 // Verify that only www_google_url is allowed and that the other two certs
82 // being tested still have no decision associated with them.
83 EXPECT_EQ(
84 net::CertPolicy::ALLOWED,
85 state->QueryPolicy(
86 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
87 EXPECT_EQ(net::CertPolicy::UNKNOWN,
88 state->QueryPolicy(
89 google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
90 EXPECT_EQ(
91 net::CertPolicy::UNKNOWN,
92 state->QueryPolicy(
93 example_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
94
95 // Simulate a user decision to allow an invalid certificate exception for
96 // example_url.
97 state->AllowCert(
98 example_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
99
100 // Verify that both www_google_url and example_url have allow exceptions while
101 // google_url still has no associated decision.
102 EXPECT_EQ(
103 net::CertPolicy::ALLOWED,
104 state->QueryPolicy(
105 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
106 EXPECT_EQ(net::CertPolicy::UNKNOWN,
107 state->QueryPolicy(
108 google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
109 EXPECT_EQ(
110 net::CertPolicy::ALLOWED,
111 state->QueryPolicy(
112 example_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
113
114 // Simulate a user decision to deny an invalid certificate for example_url.
115 state->DenyCert(
116 example_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
117
118 // Verify that www_google_url is allowed and example_url is denied while
119 // google_url still has no associated decision.
120 EXPECT_EQ(
121 net::CertPolicy::ALLOWED,
122 state->QueryPolicy(
123 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
124 EXPECT_EQ(net::CertPolicy::UNKNOWN,
125 state->QueryPolicy(
126 google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
127 EXPECT_EQ(
128 net::CertPolicy::DENIED,
129 state->QueryPolicy(
130 example_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
131 }
132
133 // HasPolicyAndRevoke unit tests the expected behavior of calling
134 // HasAllowedOrDeniedCert before and after calling RevokeAllowAndDenyPreferences
135 // on the SSLHostStateDecisions class.
136 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDecisionsTest, HasPolicyAndRevoke) {
137 GURL www_google_gurl(www_google_url);
138 GURL google_gurl(google_url);
139 GURL example_gurl(example_url);
140 scoped_refptr<net::X509Certificate> google_cert(
141 net::X509Certificate::CreateFromBytes(
142 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
143 content::WebContents* tab =
144 browser()->tab_strip_model()->GetActiveWebContents();
145 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
146 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
147
148 // Simulate a user decision to allow an invalid certificate exception for
149 // www_google_url and for example_url.
150 state->AllowCert(
151 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
152 state->AllowCert(
153 example_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
154
155 // Verify that HasAllowedOrDeniedCert correctly acknowledges that a user
156 // decision has been made about www_google_url. Then verify that
157 // HasAllowedOrDeniedCert correctly identifies that the decision has been
158 // revoked.
159 EXPECT_TRUE(state->HasAllowedOrDeniedCert(www_google_gurl));
160 state->RevokeAllowAndDenyPreferences(www_google_gurl);
161 EXPECT_FALSE(state->HasAllowedOrDeniedCert(www_google_gurl));
162 EXPECT_EQ(
163 net::CertPolicy::UNKNOWN,
164 state->QueryPolicy(
165 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
166
167 // Verify that the revocation of the www_google_url decision does not affect
168 // the Allow for example_url.
169 EXPECT_TRUE(state->HasAllowedOrDeniedCert(example_gurl));
170
171 // Verify the rovaction of the www_google_url decision does not affect the
Ryan Sleevi 2014/07/31 00:31:28 Revocation
jww 2014/07/31 05:57:00 Done.
172 // non-decision for google_url. Then verify that a revocation of a URL with no
173 // decision has no effect.
174 EXPECT_FALSE(state->HasAllowedOrDeniedCert(google_gurl));
175 state->RevokeAllowAndDenyPreferences(google_gurl);
176 EXPECT_FALSE(state->HasAllowedOrDeniedCert(google_gurl));
177 }
178
179 // Clear unit tests the expected behavior of calling Clear to forget all cert
180 // decision state on the SSLHostStateDecisions class.
181 IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDecisionsTest, Clear) {
182 GURL www_google_gurl(www_google_url);
183 GURL example_gurl(example_url);
184 scoped_refptr<net::X509Certificate> google_cert(
185 net::X509Certificate::CreateFromBytes(
186 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
187 content::WebContents* tab =
188 browser()->tab_strip_model()->GetActiveWebContents();
189 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
190 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
191
192 // Simulate a user decision to allow an invalid certificate exception for
193 // www_google_url and for example_url.
194 state->AllowCert(
195 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
196
197 // Do a full clear, then make sure that both www_google_url, which had a
198 // decision made, and example_url, which was untouched, are now in a
199 // non-decision state.
200 state->Clear();
201 EXPECT_FALSE(state->HasAllowedOrDeniedCert(www_google_gurl));
202 EXPECT_EQ(
203 net::CertPolicy::UNKNOWN,
204 state->QueryPolicy(
205 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
206 EXPECT_FALSE(state->HasAllowedOrDeniedCert(example_gurl));
207 EXPECT_EQ(
208 net::CertPolicy::UNKNOWN,
209 state->QueryPolicy(
210 example_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
211 }
212
213 // Tests the basic behavior of cert memory in incognito.
214 class IncognitoSSLHostStateDecisionsTest
215 : public ChromeSSLHostStateDecisionsTest {
216 protected:
217 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
218 ChromeSSLHostStateDecisionsTest::SetUpCommandLine(command_line);
219 command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
220 kDeltaSecondsString);
221 }
222 };
223
224 IN_PROC_BROWSER_TEST_F(IncognitoSSLHostStateDecisionsTest, PRE_AfterRestart) {
225 GURL www_google_gurl(www_google_url);
226 GURL google_gurl(google_url);
227 scoped_refptr<net::X509Certificate> google_cert(
228 net::X509Certificate::CreateFromBytes(
229 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
230 content::WebContents* tab =
231 browser()->tab_strip_model()->GetActiveWebContents();
232 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
233 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
234
235 // Add a cert exception to the profile and then verify that it still exists
236 // in the incognito profile.
237 state->AllowCert(
238 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
239
240 scoped_ptr<Profile> incognito(profile->CreateOffTheRecordProfile());
241 content::SSLHostStateDecisions* incognito_state =
242 incognito->GetSSLHostStateDecisions();
243
244 EXPECT_EQ(
245 net::CertPolicy::ALLOWED,
246 incognito_state->QueryPolicy(
247 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
248
249 // Add a cert exception to the incognito profile. It will be checked after
250 // restart that this exception does not exist. Note the different cert URL and
251 // error than above thus mapping to a second exception. Also validate that it
252 // was not added as an exception to the regular profile.
253 incognito_state->AllowCert(
254 google_gurl, google_cert.get(), net::CERT_STATUS_COMMON_NAME_INVALID);
255
256 EXPECT_EQ(net::CertPolicy::UNKNOWN,
257 state->QueryPolicy(google_gurl,
258 google_cert.get(),
259 net::CERT_STATUS_COMMON_NAME_INVALID));
260 }
261
262 // AfterRestart ensures that any cert decisions made in an incognito profile are
263 // forgetten after a session restart even if given a command line flag to
264 // remember cert decisions after restart.
265 IN_PROC_BROWSER_TEST_F(IncognitoSSLHostStateDecisionsTest, AfterRestart) {
266 GURL www_google_gurl(www_google_url);
267 GURL google_gurl(google_url);
268 scoped_refptr<net::X509Certificate> google_cert(
269 net::X509Certificate::CreateFromBytes(
270 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
271 content::WebContents* tab =
272 browser()->tab_strip_model()->GetActiveWebContents();
273 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
274 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
275
276 // Verify that the exception added before restart to the regular
277 // (non-incognito) profile still exists and was not cleared after the
278 // incognito session ended.
279 EXPECT_EQ(
280 net::CertPolicy::ALLOWED,
281 state->QueryPolicy(
282 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
283
284 scoped_ptr<Profile> incognito(profile->CreateOffTheRecordProfile());
285 content::SSLHostStateDecisions* incognito_state =
286 incognito->GetSSLHostStateDecisions();
287
288 // Verify that the exception added before restart to the incognito profile was
289 // cleared when the incognito session ended.
290 EXPECT_EQ(net::CertPolicy::UNKNOWN,
291 incognito_state->QueryPolicy(google_gurl,
292 google_cert.get(),
293 net::CERT_STATUS_COMMON_NAME_INVALID));
294 }
295
296 // Tests to make sure that if the remember value is set to -1, any decisions
297 // won't be remembered over a restart.
298 class ForgetSSLHostStateDecisionsTest : public ChromeSSLHostStateDecisionsTest {
299 protected:
300 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
301 ChromeSSLHostStateDecisionsTest::SetUpCommandLine(command_line);
302 command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
303 kForgetAtSessionEnd);
304 }
305 };
306
307 IN_PROC_BROWSER_TEST_F(ForgetSSLHostStateDecisionsTest, PRE_AfterRestart) {
308 GURL www_google_gurl(www_google_url);
309 scoped_refptr<net::X509Certificate> google_cert(
310 net::X509Certificate::CreateFromBytes(
311 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
312 content::WebContents* tab =
313 browser()->tab_strip_model()->GetActiveWebContents();
314 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
315 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
316
317 state->AllowCert(
318 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
319 EXPECT_EQ(
320 net::CertPolicy::ALLOWED,
321 state->QueryPolicy(
322 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
323 }
324
325 IN_PROC_BROWSER_TEST_F(ForgetSSLHostStateDecisionsTest, AfterRestart) {
326 GURL www_google_gurl(www_google_url);
327 scoped_refptr<net::X509Certificate> google_cert(
328 net::X509Certificate::CreateFromBytes(
329 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
330 content::WebContents* tab =
331 browser()->tab_strip_model()->GetActiveWebContents();
332 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
333 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
334
335 // The cert should now be |UNKONWN| because the profile is set to forget cert
336 // exceptions after session end.
337 EXPECT_EQ(
338 net::CertPolicy::UNKNOWN,
339 state->QueryPolicy(
340 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
341 }
342
343 // Tests to make sure that if the remember value is set to 0, any decisions made
344 // will be forgetten immediately.
345 class ForgetInstantlySSLHostStateDecisionsTest
346 : public ChromeSSLHostStateDecisionsTest {
347 protected:
348 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
349 ChromeSSLHostStateDecisionsTest::SetUpCommandLine(command_line);
350 command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
351 kForgetInstantly);
352 }
353 };
354
355 IN_PROC_BROWSER_TEST_F(ForgetInstantlySSLHostStateDecisionsTest,
356 MakeAndForgetException) {
357 GURL www_google_gurl(www_google_url);
358 scoped_refptr<net::X509Certificate> google_cert(
359 net::X509Certificate::CreateFromBytes(
360 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
361 content::WebContents* tab =
362 browser()->tab_strip_model()->GetActiveWebContents();
363 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
364 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
365
366 // chrome_state takes ownership of this clock
367 base::SimpleTestClock* clock = new base::SimpleTestClock();
368 ChromeSSLHostStateDecisions* chrome_state =
369 static_cast<ChromeSSLHostStateDecisions*>(state);
370 chrome_state->SetClock(scoped_ptr<base::Clock>(clock));
371
372 // Start the clock at standard system time but do not advance at all to
373 // emphasize that instant forget works.
374 clock->SetNow(base::Time::NowFromSystemTime());
375
376 state->AllowCert(
377 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
378 EXPECT_EQ(
379 net::CertPolicy::UNKNOWN,
380 state->QueryPolicy(
381 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
382 }
383
384 // Tests to make sure that if the remember value is set to a non-zero value0,
385 // any decisions will be remembered over a restart, but only for the length
386 // specified.
387 class RememberSSLHostStateDecisionsTest
388 : public ChromeSSLHostStateDecisionsTest {
389 protected:
390 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
391 ChromeSSLHostStateDecisionsTest::SetUpCommandLine(command_line);
392 command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
393 kDeltaSecondsString);
394 }
395 };
396
397 IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDecisionsTest, PRE_AfterRestart) {
398 GURL www_google_gurl(www_google_url);
399 scoped_refptr<net::X509Certificate> google_cert(
400 net::X509Certificate::CreateFromBytes(
401 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
402 content::WebContents* tab =
403 browser()->tab_strip_model()->GetActiveWebContents();
404 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
405 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
406
407 state->AllowCert(
408 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
409 EXPECT_EQ(
410 net::CertPolicy::ALLOWED,
411 state->QueryPolicy(
412 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
413 }
414
415 IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDecisionsTest, AfterRestart) {
416 GURL www_google_gurl(www_google_url);
417 scoped_refptr<net::X509Certificate> google_cert(
418 net::X509Certificate::CreateFromBytes(
419 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
420 content::WebContents* tab =
421 browser()->tab_strip_model()->GetActiveWebContents();
422 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
423 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
424
425 // chrome_state takes ownership of this clock
426 base::SimpleTestClock* clock = new base::SimpleTestClock();
427 ChromeSSLHostStateDecisions* chrome_state =
428 static_cast<ChromeSSLHostStateDecisions*>(state);
429 chrome_state->SetClock(scoped_ptr<base::Clock>(clock));
430
431 // Start the clock at standard system time.
432 clock->SetNow(base::Time::NowFromSystemTime());
433
434 // This should only pass if the cert was allowed before the test was restart
435 // and thus has now been rememebered across browser restarts.
436 EXPECT_EQ(
437 net::CertPolicy::ALLOWED,
438 state->QueryPolicy(
439 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
440
441 // Simulate the clock advancing by the specified delta.
442 clock->Advance(base::TimeDelta::FromSeconds(kDeltaOneDayInSeconds + 1));
443
444 // The cert should now be |UNKONWN| because the specified delta has passed.
445 EXPECT_EQ(
446 net::CertPolicy::UNKNOWN,
447 state->QueryPolicy(
448 www_google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
449 }
450
451 // Tests to make sure that if the user deletes their browser history, SSL
452 // exceptions will be deleted as well.
453 class RemoveBrowsingHistorySSLHostStateDecisionsTest
454 : public ChromeSSLHostStateDecisionsTest {
455 public:
456 void RemoveAndWait(Profile* profile) {
457 BrowsingDataRemover* remover = BrowsingDataRemover::CreateForPeriod(
458 profile, BrowsingDataRemover::LAST_HOUR);
459 BrowsingDataRemoverCompletionObserver completion_observer(remover);
460 remover->Remove(BrowsingDataRemover::REMOVE_HISTORY,
461 BrowsingDataHelper::UNPROTECTED_WEB);
462 completion_observer.BlockUntilCompletion();
463 }
464 };
465
466 IN_PROC_BROWSER_TEST_F(RemoveBrowsingHistorySSLHostStateDecisionsTest,
467 DeleteHistory) {
468 GURL google_gurl(google_url);
469 scoped_refptr<net::X509Certificate> google_cert(
470 net::X509Certificate::CreateFromBytes(
471 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
472 content::WebContents* tab =
473 browser()->tab_strip_model()->GetActiveWebContents();
474 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
475 content::SSLHostStateDecisions* state = profile->GetSSLHostStateDecisions();
476
477 // Add an exception for an invalid certificate. Then remove the last hour's
478 // worth of browsing history and verify that the exception has been deleted.
479 state->AllowCert(
480 google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID);
481 RemoveAndWait(profile);
482 EXPECT_EQ(net::CertPolicy::UNKNOWN,
483 state->QueryPolicy(
484 google_gurl, google_cert.get(), net::CERT_STATUS_DATE_INVALID));
485 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698