// 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 VerifyCoseSignature(absl::string_view signature,
                                   absl::string_view data,
                                   SigningAlgorithm algorithm) const override {
    return leaf().VerifyCoseSignature(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> absl_nonnull>
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
