// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "crypto/default/default_crypto_read_handler.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <ctime>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/log/absl_check.h"
#include "absl/log/absl_log.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock_interface.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "cose/simple_cms_parser.h"
#include "crypto/algorithms.h"
#include "crypto/crypto_read_handler.h"
#include "crypto/default/eku_verifier.h"
#include "crypto/default/trust_store.h"
#include "crypto/default/x509_certificate.h"
#include "openssl/bytestring.h"
#include "openssl/pki/ocsp.h"
#include "openssl/pki/verify.h"
#include "openssl/pki/verify_error.h"
#include "openssl/posix_time.h"
#include "tsp/timestamp_verifier.h"
#include "tsp/verified_timestamp.h"

namespace credentio {
namespace {

// Maximum clock skew tolerated when checking `current_time >= thisUpdate`.
constexpr absl::Duration kOcspClockSkewTolerance = absl::Minutes(10);

// Extracts the `thisUpdate` time from the first `SingleResponse` in a
// DER-encoded `OCSPResponse` (RFC 6960 Section 4.2.1), or returns
// `std::nullopt` if the response cannot be parsed.
std::optional<absl::Time> ParseOcspThisUpdate(
    absl::string_view ocsp_response_der) {
  CBS cbs;
  CBS_init(&cbs, reinterpret_cast<const uint8_t*>(ocsp_response_der.data()),
           ocsp_response_der.size());
  CBS response_seq, response_bytes_wrapper, response_bytes,
      basic_response_octets, basic_response, tbs_response_data;
  if (!CBS_get_asn1(&cbs, &response_seq, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&response_seq, /*out=*/nullptr, CBS_ASN1_ENUMERATED) ||
      !CBS_get_asn1(&response_seq, &response_bytes_wrapper,
                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
      !CBS_get_asn1(&response_bytes_wrapper, &response_bytes,
                    CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&response_bytes, /*out=*/nullptr, CBS_ASN1_OBJECT) ||
      !CBS_get_asn1(&response_bytes, &basic_response_octets,
                    CBS_ASN1_OCTETSTRING) ||
      !CBS_get_asn1(&basic_response_octets, &basic_response,
                    CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&basic_response, &tbs_response_data, CBS_ASN1_SEQUENCE)) {
    return std::nullopt;
  }

  CBS responses, single_response, this_update_cbs;
  if (!CBS_get_optional_asn1(
          &tbs_response_data, /*out=*/nullptr, /*out_present=*/nullptr,
          CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
      !CBS_get_any_asn1(&tbs_response_data, /*out=*/nullptr,
                        /*out_tag=*/nullptr) ||
      !CBS_get_asn1(&tbs_response_data, /*out=*/nullptr,
                    CBS_ASN1_GENERALIZEDTIME) ||
      !CBS_get_asn1(&tbs_response_data, &responses, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&responses, &single_response, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&single_response, /*out=*/nullptr, CBS_ASN1_SEQUENCE) ||
      !CBS_get_any_asn1(&single_response, /*out=*/nullptr,
                        /*out_tag=*/nullptr) ||
      !CBS_get_asn1(&single_response, &this_update_cbs,
                    CBS_ASN1_GENERALIZEDTIME)) {
    return std::nullopt;
  }

  struct tm tm;
  int64_t this_update_posix;
  if (!CBS_parse_generalized_time(&this_update_cbs, &tm,
                                  /*allow_timezone_offset=*/0) ||
      !OPENSSL_tm_to_posix(&tm, &this_update_posix)) {
    return std::nullopt;
  }
  return absl::FromUnixSeconds(this_update_posix);
}

class DefaultParsedCertificates : public ParsedCertificates {
 public:
  DefaultParsedCertificates() = default;
  ~DefaultParsedCertificates() override = default;
  // If `all_claim_signer_roots_` is nullptr, VerifyClaimSignerTrust skips trust
  // checks. If `legacy_claim_signer_roots_` is nullptr, VerifyClaimSignerTrust
  // accepts only the C2PA EKU.
  explicit DefaultParsedCertificates(
      std::vector<std::unique_ptr<X509Certificate>> certificate_chain_x509,
      std::vector<std::string> certificate_chain_der,
      bssl::VerifyTrustStore* absl_nullable all_claim_signer_roots,
      bssl::VerifyTrustStore* absl_nullable legacy_claim_signer_roots)
      : certificate_chain_x509_(std::move(certificate_chain_x509)),
        certificate_chain_der_(std::move(certificate_chain_der)),
        all_claim_signer_roots_(all_claim_signer_roots),
        legacy_claim_signer_roots_(legacy_claim_signer_roots) {
    ABSL_CHECK(!certificate_chain_x509_.empty());
    ABSL_CHECK_EQ(certificate_chain_der_.size(),
                  certificate_chain_x509_.size());
  }

  absl::StatusOr<std::vector<std::string>> VerifyClaimSignerTrust(
      absl::Time content_time) const override {
    if (all_claim_signer_roots_ == nullptr) {
      ABSL_LOG_EVERY_N_SEC(INFO, 60)
          << "Bypassing C2PA claim signer certificate trust check.";
      return std::vector<std::string>();
    }
    if (certificate_chain_der_.size() > 3) {
      return absl::UnauthenticatedError(
          absl::StrCat("Excessive certificate chain length: ",
                       certificate_chain_der_.size()));
    }

    bssl::CertificateVerifyOptions opts;
    opts.leaf_cert = certificate_chain_der_.at(0);
    if (EkuVerifier::CheckLeafCertEku(opts.leaf_cert)) {
      // `EkuVerifier::CheckLeafCertEku` returns true iff the version 2.2
      // requirements are met:
      // 1. The leaf certificate asserts the `digitalSignature` KU bit.
      // 2. The leaf certificate has the C2PA claim signing EKU.
      // 3. The leaf certificate does not have the `anyExtendedKeyUsage` EKU.
      // So, we can skip the EKU checks in BoringSSL.
      opts.key_purpose = bssl::CertificateVerifyOptions::KeyPurpose::ANY_EKU;
      opts.trust_store = all_claim_signer_roots_;
    } else {
      // Version 2.2 requirements are not met. Fall back to version 2.1 checks
      // in BoringSSL.
      opts.key_purpose =
          bssl::CertificateVerifyOptions::KeyPurpose::C2PA_MANIFEST;
      if (legacy_claim_signer_roots_ == nullptr) {
        return absl::InvalidArgumentError(
            "Extended Key Usage c2pa-kp-claimSigning not present");
      }
      opts.trust_store = legacy_claim_signer_roots_;
    }
    for (int i = 1; i < certificate_chain_der_.size(); ++i) {
      opts.intermediates.push_back(certificate_chain_der_.at(i));
    }
    opts.time = absl::ToTimeT(content_time);
    bssl::VerifyError error;
    // This check only verifies that there is a valid chain from the leaf
    // certificate to one of the trusted root certificates. Note that this is
    // a relaxed version of the requirement in
    // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#x509_certificates
    // which requires the certificates in the chain to be ordered starting with
    // the certificate containing the end-entity key (i.e., the leaf
    // certificate) followed by the certificate that signed it, and so on.
    auto chain = bssl::CertificateVerify(opts, &error);
    if (!chain) {
      switch (error.Code()) {
        case bssl::VerifyError::StatusCode::CERTIFICATE_NOT_YET_VALID:
        case bssl::VerifyError::StatusCode::CERTIFICATE_EXPIRED:
          return absl::OutOfRangeError(
              absl::StrCat("certificate outside validity period: ",
                           error.DiagnosticString()));
        case bssl::VerifyError::StatusCode::PATH_NOT_FOUND:
          return absl::UnauthenticatedError(absl::StrCat(
              "untrusted claim signer: ", error.DiagnosticString()));
        default:
          return absl::InvalidArgumentError(absl::StrCat(
              "Failed to verify the trust chain: ", error.DiagnosticString()));
      }
    }
    return *chain;
  }

  absl::Status VerifySignature(absl::string_view signature,
                               absl::string_view data,
                               SigningAlgorithm algorithm) const override {
    return leaf().VerifySignature(signature, data, algorithm);
  }

  size_t GetCertificateCount() const override {
    return certificate_chain_x509_.size();
  }

  absl::StatusOr<std::string> GetSubject(size_t index) const override {
    if (index >= certificate_chain_x509_.size()) {
      return absl::OutOfRangeError("Certificate index out of bounds");
    }
    return certificate_chain_x509_[index]->GetSubject();
  }

  absl::StatusOr<std::string> GetIssuer(size_t index) const override {
    if (index >= certificate_chain_x509_.size()) {
      return absl::OutOfRangeError("Certificate index out of bounds");
    }
    return certificate_chain_x509_[index]->GetIssuer();
  }

  absl::StatusOr<absl::Time> GetStartTime(size_t index) const override {
    if (index >= certificate_chain_x509_.size()) {
      return absl::OutOfRangeError("Certificate index out of bounds");
    }
    return certificate_chain_x509_[index]->StartTime();
  }

  absl::StatusOr<absl::Time> GetEndTime(size_t index) const override {
    if (index >= certificate_chain_x509_.size()) {
      return absl::OutOfRangeError("Certificate index out of bounds");
    }
    return certificate_chain_x509_[index]->EndTime();
  }

  absl::StatusOr<std::string> GetSerialNumberHex(size_t index) const override {
    if (index >= certificate_chain_x509_.size()) {
      return absl::OutOfRangeError("Certificate index out of bounds");
    }
    return certificate_chain_x509_[index]->GetSerialNumberHex();
  }

  absl::StatusOr<std::string> GetAssuranceLevel(size_t index) const override {
    if (index >= certificate_chain_x509_.size()) {
      return absl::OutOfRangeError("Certificate index out of bounds");
    }
    return certificate_chain_x509_[index]->GetAssuranceLevel();
  }

  absl::StatusOr<std::string> GetConformingProductId(
      size_t index) const override {
    if (index >= certificate_chain_x509_.size()) {
      return absl::OutOfRangeError("Certificate index out of bounds");
    }
    return certificate_chain_x509_[index]->GetConformingProductId();
  }

  const X509Certificate& leaf() const {
    return *certificate_chain_x509_.front();
  }

#ifndef NDEBUG
  [[maybe_unused]] std::string CertChainDebugString() const {
    std::string s;
    for (const auto& cert : certificate_chain_x509_) {
      absl::StrAppend(&s, cert->DebugString());
    }
    return s;
  }
#endif

 private:
  std::vector<std::unique_ptr<X509Certificate>> certificate_chain_x509_;
  std::vector<std::string> certificate_chain_der_;
  bssl::VerifyTrustStore* absl_nullable all_claim_signer_roots_;
  bssl::VerifyTrustStore* absl_nullable legacy_claim_signer_roots_;
};

// An implementation of CryptoReadHandler intended for use in production.
// It uses Tink, BoringSSL, and SimpleCMS.
class DefaultCryptoReadHandler : public CryptoReadHandler {
 public:
  DefaultCryptoReadHandler(
      absl_nullable std::unique_ptr<bssl::VerifyTrustStore>
          all_claim_signer_roots,
      absl_nullable std::unique_ptr<bssl::VerifyTrustStore>
          legacy_claim_signer_roots,
      absl_nullable std::unique_ptr<bssl::VerifyTrustStore> tsa_roots,
      TrustEnvironment trust_environment, absl::Clock* absl_nonnull clock)
      : all_claim_signer_roots_(std::move(all_claim_signer_roots)),
        legacy_claim_signer_roots_(std::move(legacy_claim_signer_roots)),
        tsa_roots_(std::move(tsa_roots)),
        timestamp_verifier_(
            std::make_unique<TimestampVerifier>(tsa_roots_.get())),
        cms_parser_(std::make_unique<SimpleCmsParser>()),
        trust_environment_(trust_environment),
        clock_(*clock) {}
  ~DefaultCryptoReadHandler() override = default;

  absl::StatusOr<std::unique_ptr<ParsedCertificates>> ParseCertificatesDer(
      absl::Span<const absl::string_view> certificates) const override;

  absl::StatusOr<OCSPRevocationStatus> VerifyOcspResponse(
      absl::string_view ocsp_response_der, absl::string_view certificate_der,
      absl::string_view issuer_certificate_der,
      absl::Time asserted_time) const override {
    absl::Time verify_time = asserted_time;
    if (std::optional<absl::Time> this_update =
            ParseOcspThisUpdate(ocsp_response_der);
        this_update.has_value()) {
      // Per C2PA 2.4 Section 15.9.1, an OCSP response is valid if:
      // 1. `current_time >= thisUpdate` (with `kOcspClockSkewTolerance`
      //    tolerance for clock skew), and
      // 2. `asserted_time < thisUpdate` OR `asserted_time` falls within
      //    `[thisUpdate, nextUpdate)`.
      if (clock_.TimeNow() + kOcspClockSkewTolerance < *this_update) {
        return absl::OutOfRangeError(
            "current_time is earlier than the OCSP response's thisUpdate.");
      }
      // `bssl::CheckOCSP` checks `thisUpdate <= verify_time < nextUpdate`, so
      // clamping `verify_time` to at least `thisUpdate` allows
      // `asserted_time < thisUpdate` while still checking
      // `asserted_time < nextUpdate`.
      verify_time = std::max(asserted_time, *this_update);
    }
    bssl::OCSPVerifyResult::ResponseStatus response_status;
    bssl::OCSPRevocationStatus revocation_status = bssl::CheckOCSP(
        ocsp_response_der, certificate_der, issuer_certificate_der,
        absl::ToUnixSeconds(verify_time), std::nullopt, &response_status);

    switch (response_status) {
      case bssl::OCSPVerifyResult::PROVIDED:
        switch (revocation_status) {
          case bssl::OCSPRevocationStatus::GOOD:
            return OCSPRevocationStatus::kGood;
          case bssl::OCSPRevocationStatus::REVOKED:
            return OCSPRevocationStatus::kRevoked;
          case bssl::OCSPRevocationStatus::UNKNOWN:
            return OCSPRevocationStatus::kUnknown;
          default:
            return absl::InternalError("Unknown revocation status");
        }
      case bssl::OCSPVerifyResult::NO_MATCHING_RESPONSE:
        return absl::UnauthenticatedError(
            "OCSP response signature failed verification or no matching "
            "response found.");
      case bssl::OCSPVerifyResult::INVALID_DATE:
      case bssl::OCSPVerifyResult::BAD_PRODUCED_AT:
        return absl::OutOfRangeError(
            "verify_time is outside the valid time window of the OCSP "
            "response.");
      default:
        return absl::InvalidArgumentError(
            "OCSP response is malformed or invalid.");
    }
  }

  absl::StatusOr<VerifiedTimestamp> VerifyTimestamp(
      absl::string_view cms) const override {
    ABSL_ASSIGN_OR_RETURN(auto parsed_token,
                          cms_parser_->ParseTimestampToken(cms));
    return timestamp_verifier_->VerifyTimestampToken(*parsed_token);
  }

  TrustEnvironment trust_environment() const override {
    return trust_environment_;
  }

 private:
  absl_nullable std::unique_ptr<bssl::VerifyTrustStore> all_claim_signer_roots_;
  absl_nullable std::unique_ptr<bssl::VerifyTrustStore>
      legacy_claim_signer_roots_;
  absl_nullable std::unique_ptr<bssl::VerifyTrustStore> tsa_roots_;
  std::unique_ptr<TimestampVerifier> timestamp_verifier_;
  std::unique_ptr<SimpleCmsParser> cms_parser_;
  TrustEnvironment trust_environment_;
  absl::Clock& clock_;
};

}  // namespace

absl::StatusOr<std::unique_ptr<ParsedCertificates>>
DefaultCryptoReadHandler::ParseCertificatesDer(
    absl::Span<const absl::string_view> certificates) const {
  if (certificates.empty()) {
    return absl::InvalidArgumentError("No leaf certificate provided");
  }
  // Construct the X.509 public key certificate from DER bytes.
  // The first element of the certificate chain is the signer's public key DER
  // bytes. The certificate chain starts with the signer's certificate and the
  // following elements constitute the rest of the chain.
  std::vector<std::unique_ptr<X509Certificate>> certificates_x509;
  std::vector<std::string> certificates_der;
  certificates_der.reserve(certificates.size());
  for (int i = 0; i < certificates.size(); ++i) {
    const auto& cert_der = certificates[i];
    certificates_der.push_back(std::string(cert_der));
    ABSL_ASSIGN_OR_RETURN(auto x509, X509Certificate::Create(/*der=*/cert_der));
    ABSL_DVLOG(1) << "Cert validity start time = " << x509->StartTime();
    ABSL_DVLOG(1) << "Cert validity end time = " << x509->EndTime();
    if (x509 == nullptr) {
      return absl::InternalError("X509Certificate::Create returned nullptr");
    }
    ABSL_RETURN_IF_ERROR(x509->IsValidC2paCertificate(/*is_leaf=*/(i == 0)));
    certificates_x509.push_back(std::move(x509));
  }
  return std::make_unique<DefaultParsedCertificates>(
      std::move(certificates_x509), std::move(certificates_der),
      all_claim_signer_roots_.get(), legacy_claim_signer_roots_.get());
}

absl::StatusOr<std::unique_ptr<CryptoReadHandler>>
CreateDefaultCryptoReadHandler(const DefaultCryptoReadHandlerOptions& options) {
  if (options.clock == nullptr) {
    return absl::InvalidArgumentError("clock must not be null");
  }
  std::unique_ptr<bssl::VerifyTrustStore> all_claim_signer_roots;
  std::unique_ptr<bssl::VerifyTrustStore> legacy_claim_signer_roots;
  if (!options.skip_claim_signer_trust_checks_for_test &&
      options.trust_environment != CryptoReadHandler::TrustEnvironment::kAny) {
    if (!options.legacy_claim_signer_trust_anchors_pem.empty()) {
      // If the string is nonempty, it must contain at least one cert.
      ABSL_ASSIGN_OR_RETURN(
          legacy_claim_signer_roots,
          LoadTrustStore(options.legacy_claim_signer_trust_anchors_pem));
    }
    ABSL_ASSIGN_OR_RETURN(all_claim_signer_roots,
                          LoadTrustStore(absl::StrCat(
                              options.claim_signer_trust_anchors_pem,
                              options.legacy_claim_signer_trust_anchors_pem)));
  }
  std::unique_ptr<bssl::VerifyTrustStore> tsa_roots;
  if (!options.skip_tsa_trust_checks_for_test &&
      options.trust_environment != CryptoReadHandler::TrustEnvironment::kAny) {
    ABSL_ASSIGN_OR_RETURN(tsa_roots,
                          LoadTrustStore(options.tsa_trust_anchors_pem));
  }
  return std::make_unique<DefaultCryptoReadHandler>(
      /*all_claim_signer_roots=*/std::move(all_claim_signer_roots),
      /*legacy_claim_signer_roots=*/std::move(legacy_claim_signer_roots),
      std::move(tsa_roots), options.trust_environment, options.clock);
}

}  // namespace credentio
