// 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 "net/cert/cert_policy_enforcer.h"

#include <string>

#include "base/memory/scoped_ptr.h"
#include "net/base/test_data_directory.h"
#include "net/cert/ct_ev_whitelist.h"
#include "net/cert/ct_verify_result.h"
#include "net/cert/x509_certificate.h"
#include "net/test/cert_test_util.h"
#include "net/test/ct_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

class DummyEVCertsWhitelist : public ct::EVCertsWhitelist {
 public:
  DummyEVCertsWhitelist(bool is_valid_response, bool contains_hash_response)
      : canned_is_valid_(is_valid_response),
        canned_contains_response_(contains_hash_response) {}

  bool IsValid() const override { return canned_is_valid_; }

  bool ContainsCertificateHash(
      const std::string& certificate_hash) const override {
    return canned_contains_response_;
  }

 protected:
  ~DummyEVCertsWhitelist() override {}

 private:
  bool canned_is_valid_;
  bool canned_contains_response_;
};

class CertPolicyEnforcerTest : public ::testing::Test {
 public:
  virtual void SetUp() override {
    policy_enforcer_.reset(new CertPolicyEnforcer(5, true));

    std::string der_test_cert(ct::GetDerEncodedX509Cert());
    chain_ = X509Certificate::CreateFromBytes(der_test_cert.data(),
                                              der_test_cert.size());
    ASSERT_TRUE(chain_.get());
  }

  void FillResultWithSCTsOfOrigin(
      ct::SignedCertificateTimestamp::Origin desired_origin,
      int num_scts,
      ct::CTVerifyResult* result) {
    for (int i = 0; i < num_scts; ++i) {
      scoped_refptr<ct::SignedCertificateTimestamp> sct(
          new ct::SignedCertificateTimestamp());
      sct->origin = desired_origin;
      result->verified_scts.push_back(sct);
    }
  }

 protected:
  scoped_ptr<CertPolicyEnforcer> policy_enforcer_;
  scoped_refptr<X509Certificate> chain_;
};

TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithNonEmbeddedSCTs) {
  ct::CTVerifyResult result;
  FillResultWithSCTsOfOrigin(
      ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION, 2, &result);

  EXPECT_TRUE(
      policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, result));
}

TEST_F(CertPolicyEnforcerTest, ConformsToCTEVPolicyWithEmbeddedSCTs) {
  // This chain_ is valid for 10 years - over 121 months - so requires 5 SCTs.
  ct::CTVerifyResult result;
  FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 5,
                             &result);

  EXPECT_TRUE(
      policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, result));
}

TEST_F(CertPolicyEnforcerTest, DoesNotConformToCTEVPolicyNotEnoughSCTs) {
  scoped_refptr<ct::EVCertsWhitelist> non_including_whitelist(
      new DummyEVCertsWhitelist(true, false));
  // This chain_ is valid for 10 years - over 121 months - so requires 5 SCTs.
  // However, as there are only two logs, two SCTs will be required - supply one
  // to guarantee the test fails.
  ct::CTVerifyResult result;
  FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
                             &result);

  EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(
      chain_.get(), non_including_whitelist.get(), result));

  // ... but should be OK if whitelisted.
  scoped_refptr<ct::EVCertsWhitelist> whitelist(
      new DummyEVCertsWhitelist(true, true));
  EXPECT_TRUE(policy_enforcer_->DoesConformToCTEVPolicy(
      chain_.get(), whitelist.get(), result));
}

TEST_F(CertPolicyEnforcerTest, DoesNotEnforceCTPolicyIfNotRequired) {
  scoped_ptr<CertPolicyEnforcer> enforcer(new CertPolicyEnforcer(3, false));

  ct::CTVerifyResult result;
  FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
                             &result);
  // Expect true despite the chain not having enough SCTs as the policy
  // is not enforced.
  EXPECT_TRUE(enforcer->DoesConformToCTEVPolicy(chain_.get(), nullptr, result));
}

TEST_F(CertPolicyEnforcerTest, DoesNotConformToPolicyInvalidDates) {
  scoped_refptr<X509Certificate> no_valid_dates_cert(new X509Certificate(
      "subject", "issuer", base::Time(), base::Time::Now()));
  ct::CTVerifyResult result;
  FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 5,
                             &result);
  EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(
      no_valid_dates_cert.get(), nullptr, result));
  // ... but should be OK if whitelisted.
  scoped_refptr<ct::EVCertsWhitelist> whitelist(
      new DummyEVCertsWhitelist(true, true));
  EXPECT_TRUE(policy_enforcer_->DoesConformToCTEVPolicy(
      chain_.get(), whitelist.get(), result));
}

TEST_F(CertPolicyEnforcerTest,
       ConformsToPolicyExactNumberOfSCTsForValidityPeriod) {
  // Test multiple validity periods: Over 27 months, Over 15 months (but less
  // than 27 months),
  // Less than 15 months.
  const size_t validity_period[] = {12, 19, 30, 50};
  const size_t needed_scts[] = {2, 3, 4, 5};

  for (int i = 0; i < 3; ++i) {
    size_t curr_validity = validity_period[i];
    scoped_refptr<X509Certificate> cert(new X509Certificate(
        "subject", "issuer", base::Time::Now(),
        base::Time::Now() + base::TimeDelta::FromDays(31 * curr_validity)));
    size_t curr_required_scts = needed_scts[i];
    ct::CTVerifyResult result;
    for (size_t j = 0; j < curr_required_scts - 1; ++j) {
      FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                                 1, &result);
      EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(cert.get(),
                                                             nullptr, result))
          << " for: " << curr_validity << " and " << curr_required_scts
          << " scts=" << result.verified_scts.size() << " j=" << j;
    }
    FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
                               &result);
    EXPECT_TRUE(
        policy_enforcer_->DoesConformToCTEVPolicy(cert.get(), nullptr, result));
  }
}

TEST_F(CertPolicyEnforcerTest,
       ConformsToPolicyButDoesNotRequireMoreThanNumLogs) {
  scoped_ptr<CertPolicyEnforcer> enforcer(new CertPolicyEnforcer(2, true));

  ct::CTVerifyResult result;
  FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 2,
                             &result);
  // Expect true despite the chain not having enough SCTs according to the
  // policy
  // since we only have 2 logs.
  EXPECT_TRUE(enforcer->DoesConformToCTEVPolicy(chain_.get(), nullptr, result));
}

TEST_F(CertPolicyEnforcerTest, ConformsToPolicyByEVWhitelistPresence) {
  scoped_refptr<ct::EVCertsWhitelist> whitelist(
      new DummyEVCertsWhitelist(true, true));

  ct::CTVerifyResult result;
  FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
                             &result);
  EXPECT_TRUE(policy_enforcer_->DoesConformToCTEVPolicy(
      chain_.get(), whitelist.get(), result));
}

TEST_F(CertPolicyEnforcerTest, IgnoresInvalidEVWhitelist) {
  scoped_refptr<ct::EVCertsWhitelist> whitelist(
      new DummyEVCertsWhitelist(false, true));

  ct::CTVerifyResult result;
  FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
                             &result);
  EXPECT_FALSE(policy_enforcer_->DoesConformToCTEVPolicy(
      chain_.get(), whitelist.get(), result));
}

TEST_F(CertPolicyEnforcerTest, IgnoresNullEVWhitelist) {
  ct::CTVerifyResult result;
  FillResultWithSCTsOfOrigin(ct::SignedCertificateTimestamp::SCT_EMBEDDED, 1,
                             &result);
  EXPECT_FALSE(
      policy_enforcer_->DoesConformToCTEVPolicy(chain_.get(), nullptr, result));
}

}  // namespace

}  // namespace net
