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

#include "path_builder.h"

#include <cstdint>

#include <openssl/pool.h>
#include "cert_issuer_source_static.h"
#include "common_cert_errors.h"
#include "crl.h"
#include "encode_values.h"
#include "input.h"
#include "parse_certificate.h"
#include "parsed_certificate.h"
#include "simple_path_builder_delegate.h"
#include "trust_store_in_memory.h"
#include "verify_certificate_chain.h"

#include "nist_pkits_unittest.h"

constexpr int64_t kOneYear = 60 * 60 * 24 * 365;

namespace bssl {

namespace {

class CrlCheckingPathBuilderDelegate : public SimplePathBuilderDelegate {
 public:
  CrlCheckingPathBuilderDelegate(const std::vector<std::string> &der_crls,
                                 int64_t verify_time, int64_t max_age,
                                 size_t min_rsa_modulus_length_bits,
                                 DigestPolicy digest_policy)
      : SimplePathBuilderDelegate(min_rsa_modulus_length_bits, digest_policy),
        der_crls_(der_crls),
        verify_time_(verify_time),
        max_age_(max_age) {}

  void CheckPathAfterVerification(const CertPathBuilder &path_builder,
                                  CertPathBuilderResultPath *path) override {
    SimplePathBuilderDelegate::CheckPathAfterVerification(path_builder, path);

    if (!path->IsValid()) {
      return;
    }

    // It would be preferable if this test could use
    // CheckValidatedChainRevocation somehow, but that only supports getting
    // CRLs by http distributionPoints. So this just settles for writing a
    // little bit of wrapper code to test CheckCRL directly.
    const ParsedCertificateList &certs = path->certs;
    for (size_t reverse_i = 0; reverse_i < certs.size(); ++reverse_i) {
      size_t i = certs.size() - reverse_i - 1;

      // Trust anchors bypass OCSP/CRL revocation checks. (The only way to
      // revoke trust anchors is via CRLSet or the built-in SPKI block list).
      if (reverse_i == 0 && path->last_cert_trust.IsTrustAnchor()) {
        continue;
      }

      // RFC 5280 6.3.3.  [If the CRL was not specified in a distribution
      //                  point], assume a DP with both the reasons and the
      //                  cRLIssuer fields omitted and a distribution point
      //                  name of the certificate issuer.
      // Since this implementation only supports URI names in distribution
      // points, this means a default-initialized ParsedDistributionPoint is
      // sufficient.
      ParsedDistributionPoint fake_cert_dp;
      const ParsedDistributionPoint *cert_dp = &fake_cert_dp;

      // If the target cert does have a distribution point, use it.
      std::vector<ParsedDistributionPoint> distribution_points;
      ParsedExtension crl_dp_extension;
      if (certs[i]->GetExtension(der::Input(kCrlDistributionPointsOid),
                                 &crl_dp_extension)) {
        ASSERT_TRUE(ParseCrlDistributionPoints(crl_dp_extension.value,
                                               &distribution_points));
        // TODO(mattm): some test cases (some of the 4.14.* onlySomeReasons
        // tests)) have two CRLs and two distribution points, one point
        // corresponding to each CRL.  Should select the matching point for
        // each CRL.  (Doesn't matter currently since we don't support
        // reasons.)

        // Look for a DistributionPoint without reasons.
        for (const auto &dp : distribution_points) {
          if (!dp.reasons) {
            cert_dp = &dp;
            break;
          }
        }
        // If there were only DistributionPoints with reasons, just use the
        // first one.
        if (cert_dp == &fake_cert_dp && !distribution_points.empty()) {
          cert_dp = &distribution_points[0];
        }
      }

      bool cert_good = false;

      for (const auto &der_crl : der_crls_) {
        CRLRevocationStatus crl_status =
            CheckCRL(der_crl, certs, i, *cert_dp, verify_time_, max_age_);
        if (crl_status == CRLRevocationStatus::REVOKED) {
          path->errors.GetErrorsForCert(i)->AddError(
              cert_errors::kCertificateRevoked);
          return;
        }
        if (crl_status == CRLRevocationStatus::GOOD) {
          cert_good = true;
          break;
        }
      }
      if (!cert_good) {
        // PKITS tests assume hard-fail revocation checking.
        // From PKITS 4.4: "When running the tests in this section, the
        // application should be configured in such a way that the
        // certification path is not accepted unless valid, up-to-date
        // revocation data is available for every certificate in the path."
        path->errors.GetErrorsForCert(i)->AddError(
            cert_errors::kUnableToCheckRevocation);
      }
    }
  }

 private:
  std::vector<std::string> der_crls_;
  int64_t verify_time_;
  int64_t max_age_;
};

class PathBuilderPkitsTestDelegate {
 public:
  static void RunTest(std::vector<std::string> cert_ders,
                      std::vector<std::string> crl_ders,
                      const PkitsTestInfo &orig_info) {
    PkitsTestInfo info = orig_info;

    ASSERT_FALSE(cert_ders.empty());
    ParsedCertificateList certs;
    for (const std::string &der : cert_ders) {
      CertErrors errors;
      ASSERT_TRUE(ParsedCertificate::CreateAndAddToVector(
          bssl::UniquePtr<CRYPTO_BUFFER>(
              CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t *>(der.data()),
                                der.size(), nullptr)),
          {}, &certs, &errors))
          << errors.ToDebugString();
    }
    // First entry in the PKITS chain is the trust anchor.
    // TODO(mattm): test with all possible trust anchors in the trust store?
    TrustStoreInMemory trust_store;

    trust_store.AddTrustAnchor(certs[0]);

    // TODO(mattm): test with other irrelevant certs in cert_issuer_sources?
    CertIssuerSourceStatic cert_issuer_source;
    for (size_t i = 1; i < cert_ders.size() - 1; ++i) {
      cert_issuer_source.AddCert(certs[i]);
    }

    std::shared_ptr<const ParsedCertificate> target_cert(certs.back());

    int64_t verify_time;
    ASSERT_TRUE(der::GeneralizedTimeToPosixTime(info.time, &verify_time));
    CrlCheckingPathBuilderDelegate path_builder_delegate(
        crl_ders, verify_time, /*max_age=*/kOneYear * 2, 1024,
        SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);

    std::string_view test_number = info.test_number;
    if (test_number == "4.4.19" || test_number == "4.5.3" ||
        test_number == "4.5.4" || test_number == "4.5.6") {
      // 4.4.19 - fails since CRL is signed by a certificate that is not part
      //          of the verified chain, which is not supported.
      // 4.5.3 - fails since non-URI distribution point names are not supported
      // 4.5.4, 4.5.6 - fails since CRL is signed by a certificate that is not
      //                part of verified chain, and also non-URI distribution
      //                point names not supported
      info.should_validate = false;
    } else if (test_number == "4.14.1" || test_number == "4.14.4" ||
               test_number == "4.14.5" || test_number == "4.14.7" ||
               test_number == "4.14.18" || test_number == "4.14.19" ||
               test_number == "4.14.22" || test_number == "4.14.24" ||
               test_number == "4.14.25" || test_number == "4.14.28" ||
               test_number == "4.14.29" || test_number == "4.14.30" ||
               test_number == "4.14.33") {
      // 4.14 tests:
      // .1 - fails since non-URI distribution point names not supported
      // .2, .3 - fails since non-URI distribution point names not supported
      //          (but test is expected to fail for other reason)
      // .4, .5 - fails since non-URI distribution point names not supported,
      //          also uses nameRelativeToCRLIssuer which is not supported
      // .6 - fails since non-URI distribution point names not supported, also
      //      uses nameRelativeToCRLIssuer which is not supported (but test is
      //      expected to fail for other reason)
      // .7 - fails since relative distributionPointName not supported
      // .8, .9 - fails since relative distributionPointName not supported (but
      //          test is expected to fail for other reason)
      // .10, .11, .12, .13, .14, .27, .35 - PASS
      // .15, .16, .17, .20, .21 - fails since onlySomeReasons is not supported
      //                           (but test is expected to fail for other
      //                           reason)
      // .18, .19 - fails since onlySomeReasons is not supported
      // .22, .24, .25, .28, .29, .30, .33 - fails since indirect CRLs are not
      //                                     supported
      // .23, .26, .31, .32, .34 - fails since indirect CRLs are not supported
      //                           (but test is expected to fail for other
      //                           reason)
      info.should_validate = false;
    } else if (test_number == "4.15.1" || test_number == "4.15.5") {
      // 4.15 tests:
      // .1 - fails due to unhandled critical deltaCRLIndicator extension
      // .2, .3, .6, .7, .8, .9, .10 - PASS since expected cert status is
      //                               reflected in base CRL and delta CRL is
      //                               ignored
      // .5 - fails, cert status is "on hold" in base CRL but the delta CRL
      //      which removes the cert from CRL is ignored
      info.should_validate = false;
    } else if (test_number == "4.15.4") {
      // 4.15.4 - Invalid delta-CRL Test4 has the target cert marked revoked in
      // a delta-CRL. Since delta-CRLs are not supported, the chain validates
      // successfully.
      info.should_validate = true;
    }

    CertPathBuilder path_builder(
        std::move(target_cert), &trust_store, &path_builder_delegate, info.time,
        KeyPurpose::ANY_EKU, info.initial_explicit_policy,
        info.initial_policy_set, info.initial_policy_mapping_inhibit,
        info.initial_inhibit_any_policy);
    path_builder.AddCertIssuerSource(&cert_issuer_source);

    CertPathBuilder::Result result = path_builder.Run();

    if (info.should_validate != result.HasValidPath()) {
      testing::Message msg;
      for (size_t i = 0; i < result.paths.size(); ++i) {
        const bssl::CertPathBuilderResultPath *result_path =
            result.paths[i].get();
        msg << "path " << i << " errors:\n"
            << result_path->errors.ToDebugString(result_path->certs) << "\n";
      }
      ASSERT_EQ(info.should_validate, result.HasValidPath()) << msg;
    }

    if (result.HasValidPath()) {
      EXPECT_EQ(info.user_constrained_policy_set,
                result.GetBestValidPath()->user_constrained_policy_set);
    }
  }
};

}  // namespace

INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest01SignatureVerification,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest02ValidityPeriods,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest03VerifyingNameChaining,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder,
                               PkitsTest04BasicCertificateRevocationTests,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(
    PathBuilder, PkitsTest05VerifyingPathswithSelfIssuedCertificates,
    PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder,
                               PkitsTest06VerifyingBasicConstraints,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest07KeyUsage,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest08CertificatePolicies,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest09RequireExplicitPolicy,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest10PolicyMappings,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest11InhibitPolicyMapping,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest12InhibitAnyPolicy,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest13NameConstraints,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest14DistributionPoints,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder, PkitsTest15DeltaCRLs,
                               PathBuilderPkitsTestDelegate);
INSTANTIATE_TYPED_TEST_SUITE_P(PathBuilder,
                               PkitsTest16PrivateCertificateExtensions,
                               PathBuilderPkitsTestDelegate);

}  // namespace bssl
