// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h"

#include <stdint.h>

#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/simple_test_clock.h"
#include "chrome/browser/browsing_data/browsing_data_helper.h"
#include "chrome/browser/browsing_data/browsing_data_remover.h"
#include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ssl/chrome_ssl_host_state_delegate_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/ssl_host_state_delegate.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/test_data_directory.h"
#include "net/test/cert_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const char kGoogleCertFile[] = "google.single.der";

const char kWWWGoogleHost[] = "www.google.com";
const char kGoogleHost[] = "google.com";
const char kExampleHost[] = "example.com";

const char kForgetAtSessionEnd[] = "-1";
const char kForgetInstantly[] = "0";
const char kDeltaSecondsString[] = "86400";
const uint64_t kDeltaOneDayInSeconds = UINT64_C(86400);

scoped_refptr<net::X509Certificate> GetGoogleCert() {
  return net::ImportCertFromFile(net::GetTestCertsDirectory(), kGoogleCertFile);
}

}  // namespace

class ChromeSSLHostStateDelegateTest : public InProcessBrowserTest {};

// ChromeSSLHostStateDelegateTest tests basic unit test functionality of the
// SSLHostStateDelegate class.  For example, tests that if a certificate is
// accepted, then it is added to queryable, and if it is revoked, it is not
// queryable. Even though it is effectively a unit test, in needs to be an
// InProcessBrowserTest because the actual functionality is provided by
// ChromeSSLHostStateDelegate which is provided per-profile.
//
// QueryPolicy unit tests the expected behavior of calling QueryPolicy on the
// SSLHostStateDelegate class after various SSL cert decisions have been made.
IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, QueryPolicy) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool unused_value;

  // Verifying that all three of the certs we will be looking at are denied
  // before any action has been taken.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kExampleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));

  // Simulate a user decision to allow an invalid certificate exception for
  // kWWWGoogleHost.
  state->AllowCert(
      kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);

  // Verify that only kWWWGoogleHost is allowed and that the other two certs
  // being tested still are denied.
  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kExampleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));

  // Simulate a user decision to allow an invalid certificate exception for
  // kExampleHost.
  state->AllowCert(
      kExampleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);

  // Verify that both kWWWGoogleHost and kExampleHost have allow exceptions
  // while kGoogleHost still is denied.
  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            state->QueryPolicy(kExampleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
}

// HasPolicyAndRevoke unit tests the expected behavior of calling
// HasAllowException before and after calling RevokeUserAllowExceptions on the
// SSLHostStateDelegate class.
IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, HasPolicyAndRevoke) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  ChromeSSLHostStateDelegate* state =
      ChromeSSLHostStateDelegateFactory::GetForProfile(profile);
  bool unused_value;

  // Simulate a user decision to allow an invalid certificate exception for
  // kWWWGoogleHost and for kExampleHost.
  state->AllowCert(
      kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
  state->AllowCert(
      kExampleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);

  // Verify that HasAllowException correctly acknowledges that a user decision
  // has been made about kWWWGoogleHost. Then verify that HasAllowException
  // correctly identifies that the decision has been revoked.
  EXPECT_TRUE(state->HasAllowException(kWWWGoogleHost));
  state->RevokeUserAllowExceptions(kWWWGoogleHost);
  EXPECT_FALSE(state->HasAllowException(kWWWGoogleHost));
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));

  // Verify that the revocation of the kWWWGoogleHost decision does not affect
  // the Allow for kExampleHost.
  EXPECT_TRUE(state->HasAllowException(kExampleHost));

  // Verify the revocation of the kWWWGoogleHost decision does not affect the
  // non-decision for kGoogleHost. Then verify that a revocation of a URL with
  // no decision has no effect.
  EXPECT_FALSE(state->HasAllowException(kGoogleHost));
  state->RevokeUserAllowExceptions(kGoogleHost);
  EXPECT_FALSE(state->HasAllowException(kGoogleHost));
}

// Clear unit tests the expected behavior of calling Clear to forget all cert
// decision state on the SSLHostStateDelegate class.
IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, Clear) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  ChromeSSLHostStateDelegate* state =
      ChromeSSLHostStateDelegateFactory::GetForProfile(profile);
  bool unused_value;

  // Simulate a user decision to allow an invalid certificate exception for
  // kWWWGoogleHost and for kExampleHost.
  state->AllowCert(
      kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);

  // Do a full clear, then make sure that both kWWWGoogleHost, which had a
  // decision made, and kExampleHost, which was untouched, are now in a denied
  // state.
  state->Clear();
  EXPECT_FALSE(state->HasAllowException(kWWWGoogleHost));
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
  EXPECT_FALSE(state->HasAllowException(kExampleHost));
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kExampleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
}

// DidHostRunInsecureContent unit tests the expected behavior of calling
// DidHostRunInsecureContent as well as HostRanInsecureContent to check if
// insecure content has been run and to mark it as such.
IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest,
                       DidHostRunInsecureContent) {
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 42));
  EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 191));
  EXPECT_FALSE(state->DidHostRunInsecureContent("example.com", 42));

  state->HostRanInsecureContent("www.google.com", 42);

  EXPECT_TRUE(state->DidHostRunInsecureContent("www.google.com", 42));
  EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 191));
  EXPECT_FALSE(state->DidHostRunInsecureContent("example.com", 42));

  state->HostRanInsecureContent("example.com", 42);

  EXPECT_TRUE(state->DidHostRunInsecureContent("www.google.com", 42));
  EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 191));
  EXPECT_TRUE(state->DidHostRunInsecureContent("example.com", 42));
}

// QueryPolicyExpired unit tests to make sure that if a certificate decision has
// expired, the return value from QueryPolicy returns the correct vaule.
IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, PRE_QueryPolicyExpired) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool expired_previous_decision;

  // The certificate has never been seen before, so it should be UNKNOWN and
  // should also indicate that it hasn't expired.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &expired_previous_decision));
  EXPECT_FALSE(expired_previous_decision);

  // After allowing the certificate, a query should say that it is allowed and
  // also specify that it hasn't expired.
  state->AllowCert(
      kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &expired_previous_decision));
  EXPECT_FALSE(expired_previous_decision);
}

// Since this is being checked on a browser instance that expires security
// decisions after restart, the test needs to  wait until after a restart to
// verify that the expiration state is correct.
IN_PROC_BROWSER_TEST_F(ChromeSSLHostStateDelegateTest, QueryPolicyExpired) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool expired_previous_decision;

  // The browser content has restart thus expiring the user decision made above,
  // so it should indicate that the certificate and error are DENIED but also
  // that they expired since the last query.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &expired_previous_decision));
  EXPECT_TRUE(expired_previous_decision);

  // However, with a new query, it should indicate that no new expiration has
  // occurred.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &expired_previous_decision));
  EXPECT_FALSE(expired_previous_decision);
}

// Tests the basic behavior of cert memory in incognito.
class IncognitoSSLHostStateDelegateTest
    : public ChromeSSLHostStateDelegateTest {
 protected:
  void SetUpCommandLine(CommandLine* command_line) override {
    ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
                                    kDeltaSecondsString);
  }
};

IN_PROC_BROWSER_TEST_F(IncognitoSSLHostStateDelegateTest, PRE_AfterRestart) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool unused_value;

  // Add a cert exception to the profile and then verify that it still exists
  // in the incognito profile.
  state->AllowCert(
      kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);

  scoped_ptr<Profile> incognito(profile->CreateOffTheRecordProfile());
  content::SSLHostStateDelegate* incognito_state =
      incognito->GetSSLHostStateDelegate();

  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            incognito_state->QueryPolicy(kWWWGoogleHost,
                                         *google_cert.get(),
                                         net::CERT_STATUS_DATE_INVALID,
                                         &unused_value));

  // Add a cert exception to the incognito profile. It will be checked after
  // restart that this exception does not exist. Note the different cert URL and
  // error than above thus mapping to a second exception. Also validate that it
  // was not added as an exception to the regular profile.
  incognito_state->AllowCert(
      kGoogleHost, *google_cert.get(), net::CERT_STATUS_COMMON_NAME_INVALID);

  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_COMMON_NAME_INVALID,
                               &unused_value));
}

// AfterRestart ensures that any cert decisions made in an incognito profile are
// forgetten after a session restart even if given a command line flag to
// remember cert decisions after restart.
IN_PROC_BROWSER_TEST_F(IncognitoSSLHostStateDelegateTest, AfterRestart) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool unused_value;

  // Verify that the exception added before restart to the regular
  // (non-incognito) profile still exists and was not cleared after the
  // incognito session ended.
  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));

  scoped_ptr<Profile> incognito(profile->CreateOffTheRecordProfile());
  content::SSLHostStateDelegate* incognito_state =
      incognito->GetSSLHostStateDelegate();

  // Verify that the exception added before restart to the incognito profile was
  // cleared when the incognito session ended.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            incognito_state->QueryPolicy(kGoogleHost,
                                         *google_cert.get(),
                                         net::CERT_STATUS_COMMON_NAME_INVALID,
                                         &unused_value));
}

// Tests to make sure that if the remember value is set to -1, any decisions
// won't be remembered over a restart.
class ForGetSSLHostStateDelegateTest : public ChromeSSLHostStateDelegateTest {
 protected:
  void SetUpCommandLine(CommandLine* command_line) override {
    ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
                                    kForgetAtSessionEnd);
  }
};

IN_PROC_BROWSER_TEST_F(ForGetSSLHostStateDelegateTest, PRE_AfterRestart) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool unused_value;

  state->AllowCert(
      kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
}

IN_PROC_BROWSER_TEST_F(ForGetSSLHostStateDelegateTest, AfterRestart) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool unused_value;

  // The cert should now be |DENIED| because the profile is set to forget cert
  // exceptions after session end.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
}

// Tests to make sure that if the remember value is set to 0, any decisions made
// will be forgetten immediately.
class ForgetInstantlySSLHostStateDelegateTest
    : public ChromeSSLHostStateDelegateTest {
 protected:
  void SetUpCommandLine(CommandLine* command_line) override {
    ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
                                    kForgetInstantly);
  }
};

IN_PROC_BROWSER_TEST_F(ForgetInstantlySSLHostStateDelegateTest,
                       MakeAndForgetException) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool unused_value;

  // chrome_state takes ownership of this clock
  base::SimpleTestClock* clock = new base::SimpleTestClock();
  ChromeSSLHostStateDelegate* chrome_state =
      static_cast<ChromeSSLHostStateDelegate*>(state);
  chrome_state->SetClock(scoped_ptr<base::Clock>(clock));

  // Start the clock at standard system time but do not advance at all to
  // emphasize that instant forget works.
  clock->SetNow(base::Time::NowFromSystemTime());

  state->AllowCert(
      kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
}

// Tests to make sure that if the remember value is set to a non-zero value,
// any decisions will be remembered over a restart, but only for the length
// specified.
class RememberSSLHostStateDelegateTest : public ChromeSSLHostStateDelegateTest {
 protected:
  void SetUpCommandLine(CommandLine* command_line) override {
    ChromeSSLHostStateDelegateTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(switches::kRememberCertErrorDecisions,
                                    kDeltaSecondsString);
  }
};

IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDelegateTest, PRE_AfterRestart) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool unused_value;

  state->AllowCert(
      kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
}

IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDelegateTest, AfterRestart) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool unused_value;

  // chrome_state takes ownership of this clock
  base::SimpleTestClock* clock = new base::SimpleTestClock();
  ChromeSSLHostStateDelegate* chrome_state =
      static_cast<ChromeSSLHostStateDelegate*>(state);
  chrome_state->SetClock(scoped_ptr<base::Clock>(clock));

  // Start the clock at standard system time.
  clock->SetNow(base::Time::NowFromSystemTime());

  // This should only pass if the cert was allowed before the test was restart
  // and thus has now been rememebered across browser restarts.
  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));

  // Simulate the clock advancing by the specified delta.
  clock->Advance(base::TimeDelta::FromSeconds(kDeltaOneDayInSeconds + 1));

  // The cert should now be |DENIED| because the specified delta has passed.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
}

// The same test as ChromeSSLHostStateDelegateTest.QueryPolicyExpired but now
// applied to a browser context that expires based on time, not restart. This
// unit tests to make sure that if a certificate decision has expired, the
// return value from QueryPolicy returns the correct vaule.
IN_PROC_BROWSER_TEST_F(RememberSSLHostStateDelegateTest, QueryPolicyExpired) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool expired_previous_decision;

  // chrome_state takes ownership of this clock
  base::SimpleTestClock* clock = new base::SimpleTestClock();
  ChromeSSLHostStateDelegate* chrome_state =
      static_cast<ChromeSSLHostStateDelegate*>(state);
  chrome_state->SetClock(scoped_ptr<base::Clock>(clock));

  // Start the clock at standard system time but do not advance at all to
  // emphasize that instant forget works.
  clock->SetNow(base::Time::NowFromSystemTime());

  // The certificate has never been seen before, so it should be UNKONWN and
  // should also indicate that it hasn't expired.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &expired_previous_decision));
  EXPECT_FALSE(expired_previous_decision);

  // After allowing the certificate, a query should say that it is allowed and
  // also specify that it hasn't expired.
  state->AllowCert(
      kWWWGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
  EXPECT_EQ(content::SSLHostStateDelegate::ALLOWED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &expired_previous_decision));
  EXPECT_FALSE(expired_previous_decision);

  // Simulate the clock advancing by the specified delta.
  clock->Advance(base::TimeDelta::FromSeconds(kDeltaOneDayInSeconds + 1));

  // The decision expiration time has come, so it should indicate that the
  // certificate and error are DENIED but also that they expired since the last
  // query.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &expired_previous_decision));
  EXPECT_TRUE(expired_previous_decision);

  // However, with a new query, it should indicate that no new expiration has
  // occurred.
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kWWWGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &expired_previous_decision));
  EXPECT_FALSE(expired_previous_decision);
}

// Tests to make sure that if the user deletes their browser history, SSL
// exceptions will be deleted as well.
class RemoveBrowsingHistorySSLHostStateDelegateTest
    : public ChromeSSLHostStateDelegateTest {
 public:
  void RemoveAndWait(Profile* profile) {
    BrowsingDataRemover* remover = BrowsingDataRemover::CreateForPeriod(
        profile, BrowsingDataRemover::LAST_HOUR);
    BrowsingDataRemoverCompletionObserver completion_observer(remover);
    remover->Remove(BrowsingDataRemover::REMOVE_HISTORY,
                    BrowsingDataHelper::UNPROTECTED_WEB);
    completion_observer.BlockUntilCompletion();
  }
};

IN_PROC_BROWSER_TEST_F(RemoveBrowsingHistorySSLHostStateDelegateTest,
                       DeleteHistory) {
  scoped_refptr<net::X509Certificate> google_cert = GetGoogleCert();
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  bool unused_value;

  // Add an exception for an invalid certificate. Then remove the last hour's
  // worth of browsing history and verify that the exception has been deleted.
  state->AllowCert(
      kGoogleHost, *google_cert.get(), net::CERT_STATUS_DATE_INVALID);
  RemoveAndWait(profile);
  EXPECT_EQ(content::SSLHostStateDelegate::DENIED,
            state->QueryPolicy(kGoogleHost,
                               *google_cert.get(),
                               net::CERT_STATUS_DATE_INVALID,
                               &unused_value));
}
