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

#include "crl.h"

#include <string_view>

#include <gtest/gtest.h>
#include <openssl/pool.h>
#include "cert_errors.h"
#include "parsed_certificate.h"
#include "string_util.h"
#include "test_helpers.h"

namespace bssl {

namespace {

constexpr int64_t kAgeOneWeek = 7 * 24 * 60 * 60;

std::string GetFilePath(std::string_view file_name) {
  return std::string("testdata/crl_unittest/") + std::string(file_name);
}

std::shared_ptr<const ParsedCertificate> ParseCertificate(
    std::string_view data) {
  CertErrors errors;
  return ParsedCertificate::Create(
      bssl::UniquePtr<CRYPTO_BUFFER>(
          CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t *>(data.data()),
                            data.size(), nullptr)),
      {}, &errors);
}

class CheckCRLTest : public ::testing::TestWithParam<const char *> {};

// Test prefix naming scheme:
//   good = valid CRL, cert affirmatively not revoked
//   revoked = valid CRL, cert affirmatively revoked
//   bad = valid CRL, but cert status is unknown (cases like unhandled features,
//           mismatching issuer or signature, etc)
//   invalid = corrupt or violates some spec requirement
constexpr char const *kTestParams[] = {
    "good.pem",
    "good_issuer_name_normalization.pem",
    "good_issuer_no_keyusage.pem",
    "good_no_nextupdate.pem",
    "good_fake_extension.pem",
    "good_fake_extension_no_nextupdate.pem",
    "good_generalizedtime.pem",
    "good_no_version.pem",
    "good_no_crldp.pem",
    "good_key_rollover.pem",
    "good_idp_contains_uri.pem",
    "good_idp_onlycontainsusercerts.pem",
    "good_idp_onlycontainsusercerts_no_basic_constraints.pem",
    "good_idp_onlycontainscacerts.pem",
    "good_idp_uri_and_onlycontainsusercerts.pem",
    "good_idp_uri_and_onlycontainscacerts.pem",
    "revoked.pem",
    "revoked_no_nextupdate.pem",
    "revoked_fake_crlentryextension.pem",
    "revoked_generalized_revocationdate.pem",
    "revoked_key_rollover.pem",
    "bad_crldp_has_crlissuer.pem",
    "bad_fake_critical_extension.pem",
    "bad_fake_critical_crlentryextension.pem",
    "bad_signature.pem",
    "bad_thisupdate_in_future.pem",
    "bad_thisupdate_too_old.pem",
    "bad_nextupdate_too_old.pem",
    "bad_wrong_issuer.pem",
    "bad_key_rollover_signature.pem",
    "bad_idp_contains_wrong_uri.pem",
    "bad_idp_indirectcrl.pem",
    "bad_idp_onlycontainsusercerts.pem",
    "bad_idp_onlycontainscacerts.pem",
    "bad_idp_onlycontainscacerts_no_basic_constraints.pem",
    "bad_idp_uri_and_onlycontainsusercerts.pem",
    "bad_idp_uri_and_onlycontainscacerts.pem",
    "invalid_mismatched_signature_algorithm.pem",
    "invalid_revoked_empty_sequence.pem",
    "invalid_v1_with_extension.pem",
    "invalid_v1_with_crlentryextension.pem",
    "invalid_v1_explicit.pem",
    "invalid_v3.pem",
    "invalid_issuer_keyusage_no_crlsign.pem",
    "invalid_key_rollover_issuer_keyusage_no_crlsign.pem",
    "invalid_garbage_version.pem",
    "invalid_garbage_tbs_signature_algorithm.pem",
    "invalid_garbage_issuer_name.pem",
    "invalid_garbage_thisupdate.pem",
    "invalid_garbage_after_thisupdate.pem",
    "invalid_garbage_after_nextupdate.pem",
    "invalid_garbage_after_revokedcerts.pem",
    "invalid_garbage_after_extensions.pem",
    "invalid_garbage_tbscertlist.pem",
    "invalid_garbage_signaturealgorithm.pem",
    "invalid_garbage_signaturevalue.pem",
    "invalid_garbage_after_signaturevalue.pem",
    "invalid_garbage_revoked_serial_number.pem",
    "invalid_garbage_revocationdate.pem",
    "invalid_garbage_after_revocationdate.pem",
    "invalid_garbage_after_crlentryextensions.pem",
    "invalid_garbage_crlentry.pem",
    "invalid_idp_dpname_choice_extra_data.pem",
    "invalid_idp_empty_sequence.pem",
    "invalid_idp_onlycontains_user_and_ca_certs.pem",
    "invalid_idp_onlycontainsusercerts_v1_leaf.pem",
};

struct PrintTestName {
  std::string operator()(
      const testing::TestParamInfo<const char *> &info) const {
    std::string_view name(info.param);
    // Strip ".pem" from the end as GTest names cannot contain period.
    name.remove_suffix(4);
    return std::string(name);
  }
};

INSTANTIATE_TEST_SUITE_P(All, CheckCRLTest, ::testing::ValuesIn(kTestParams),
                         PrintTestName());

TEST_P(CheckCRLTest, FromFile) {
  std::string_view file_name(GetParam());

  std::string crl_data;
  std::string ca_data_2;
  std::string ca_data;
  std::string cert_data;
  const PemBlockMapping mappings[] = {
      {"CRL", &crl_data},
      {"CA CERTIFICATE 2", &ca_data_2, /*optional=*/true},
      {"CA CERTIFICATE", &ca_data},
      {"CERTIFICATE", &cert_data},
  };

  ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));

  std::shared_ptr<const ParsedCertificate> cert = ParseCertificate(cert_data);
  ASSERT_TRUE(cert);
  std::shared_ptr<const ParsedCertificate> issuer_cert =
      ParseCertificate(ca_data);
  ASSERT_TRUE(issuer_cert);
  ParsedCertificateList certs = {cert, issuer_cert};
  if (!ca_data_2.empty()) {
    std::shared_ptr<const ParsedCertificate> issuer_cert_2 =
        ParseCertificate(ca_data_2);
    ASSERT_TRUE(issuer_cert_2);
    certs.push_back(issuer_cert_2);
  }

  // Assumes that all the target certs in the test data certs have at most 1
  // CRL distributionPoint. If the cert has a CRL distributionPoint, it is
  // used for verifying the CRL, otherwise the CRL is verified with a
  // synthesized distributionPoint. This is allowed since there are some
  // conditions that require a V1 certificate to test, which cannot have a
  // crlDistributionPoints extension.
  // TODO(https://crbug.com/749276): This seems slightly hacky. Maybe the
  // distribution point to use should be specified separately in the test PEM?
  ParsedDistributionPoint fake_cert_dp;
  ParsedDistributionPoint *cert_dp = &fake_cert_dp;
  std::vector<ParsedDistributionPoint> distribution_points;
  ParsedExtension crl_dp_extension;
  if (cert->GetExtension(der::Input(kCrlDistributionPointsOid),
                         &crl_dp_extension)) {
    ASSERT_TRUE(ParseCrlDistributionPoints(crl_dp_extension.value,
                                           &distribution_points));
    ASSERT_LE(distribution_points.size(), 1U);
    if (!distribution_points.empty()) {
      cert_dp = &distribution_points[0];
    }
  }
  ASSERT_TRUE(cert_dp);

  // Mar 9 00:00:00 2017 GMT
  int64_t kVerifyTime = 1489017600;

  CRLRevocationStatus expected_revocation_status = CRLRevocationStatus::UNKNOWN;
  if (string_util::StartsWith(file_name, "good")) {
    expected_revocation_status = CRLRevocationStatus::GOOD;
  } else if (string_util::StartsWith(file_name, "revoked")) {
    expected_revocation_status = CRLRevocationStatus::REVOKED;
  }

  CRLRevocationStatus revocation_status =
      CheckCRL(crl_data, certs, /*target_cert_index=*/0, *cert_dp, kVerifyTime,
               kAgeOneWeek);
  EXPECT_EQ(expected_revocation_status, revocation_status);

  // Test with a random cert added to the front of the chain and
  // |target_cert_index=1|. This is a hacky way to verify that
  // target_cert_index is actually being honored.
  ParsedCertificateList other_certs;
  ASSERT_TRUE(ReadCertChainFromFile(
      "testdata/parse_certificate_unittest/cert_version3.pem", &other_certs));
  ASSERT_FALSE(other_certs.empty());
  certs.insert(certs.begin(), other_certs[0]);
  revocation_status = CheckCRL(crl_data, certs, /*target_cert_index=*/1,
                               *cert_dp, kVerifyTime, kAgeOneWeek);
  EXPECT_EQ(expected_revocation_status, revocation_status);
}

}  // namespace

}  // namespace bssl
