// 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 "tsp/timestamp_verifier.h"

#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/log/absl_log.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/time.h"
#include "absl/types/span.h"
#include "crypto/algorithms.h"
#include "crypto/default/hasher.h"
#include "crypto/hash.h"
#include "openssl/asn1.h"
#include "openssl/base.h"
#include "openssl/bytestring.h"
#include "openssl/mem.h"
#include "openssl/nid.h"
#include "openssl/obj.h"
#include "openssl/pki/verify.h"
#include "openssl/pki/verify_error.h"
#include "openssl/stack.h"
#include "openssl/x509.h"
#include "tsp/parsed_timestamp_token.h"
#include "tsp/timestamp_parsing.h"
#include "tsp/verified_timestamp.h"
namespace credentio {

namespace {

// Represents the `EssCertIdV2` SEQUENCE, part of the `SigningCertificateV2`
// attribute as defined in RFC 5035.
struct EssCertIdV2 {
  HashAlgorithm hash_algorithm;
  std::string cert_hash;
};

absl::Status CertMatchesEssCertId(absl::string_view cert, EssCertIdV2 id) {
  auto hasher = CreateHasher(id.hash_algorithm);
  if (!hasher.ok()) {
    return absl::Status(
        absl::StatusCode::kFailedPrecondition,
        absl::StrCat("Invalid HashAlgorithm value: ", id.hash_algorithm, "; ",
                     hasher.status().message()));
  }
  (*hasher)->Update(cert);
  if ((*hasher)->Digest() == id.cert_hash) {
    return absl::OkStatus();
  } else {
    return absl::UnauthenticatedError(
        R"(certificate does not match EssCertIDV2 value)");
  }
}

absl::Status CheckTsaCertificateTrust(
    const bssl::VerifyTrustStore& tsa_roots,
    const VerifiedTimestamp& verified_timestamp,
    absl::Span<const EssCertIdV2> ess_cert_ids) {
  if (ess_cert_ids.empty()) {
    return absl::InvalidArgumentError(
        R"(SigningCertificateV2 signed attribute is empty; at minimum, TSAs must record their own leaf certificate in this attribute)");
  }
  absl::Status status = CertMatchesEssCertId(
      verified_timestamp.tsa_certificate(), ess_cert_ids[0]);
  if (!status.ok()) {
    return absl::Status(
        status.code(),
        absl::StrCat("TSA cert does not match SigningCertificateV2 attribute: ",
                     status.message()));
  }

  auto intermediate_certs_der =
      verified_timestamp.certificate_chain().subspan(1);
  if (intermediate_certs_der.size() > 2) {
    return absl::UnauthenticatedError(
        absl::StrCat("excessive timestamp certificate chain length: ",
                     intermediate_certs_der.size() + 1));
  }

  bssl::CertificateVerifyOptions opts;

  opts.key_purpose =
      bssl::CertificateVerifyOptions::KeyPurpose::C2PA_TIMESTAMPING;
  opts.leaf_cert = verified_timestamp.tsa_certificate();
  opts.intermediates.insert(opts.intermediates.end(),
                            intermediate_certs_der.begin(),
                            intermediate_certs_der.end());
  // Timestamp cert chain validity periods are evaluated with respect to the
  // attested time, per
  // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_validate_the_time_stamp:
  // "Validate that the attested time, as found in the genTime field (in the
  // timeStampToken), falls within the validity period of the TSA’s signing
  // certificate."
  opts.time = absl::ToTimeT(verified_timestamp.asserted_time());
  opts.trust_store = &tsa_roots;
  bssl::VerifyError error;
  if (!bssl::CertificateVerify(opts, &error)) {
    if (error.Code() == bssl::VerifyError::StatusCode::CERTIFICATE_EXPIRED ||
        error.Code() ==
            bssl::VerifyError::StatusCode::CERTIFICATE_NOT_YET_VALID) {
      return absl::OutOfRangeError(error.DiagnosticString());
    }
    return absl::UnauthenticatedError(
        absl::StrCat("timestamp certificate chain could not be validated: ",
                     error.DiagnosticString()));
  }
  return absl::OkStatus();
}

// Extracts the `certs` field of the `SigningCertificateV2` attribute (attribute
// defined in RFC 5035).
absl::StatusOr<std::vector<EssCertIdV2>> GetEssCertIds(
    absl::string_view signing_certificate_v2_bytes) {
  std::vector<EssCertIdV2> out;
  CBS signing_certificate_cbs;
  CBS_init(
      &signing_certificate_cbs,
      reinterpret_cast<const uint8_t*>(signing_certificate_v2_bytes.data()),
      signing_certificate_v2_bytes.size());

  CBS signing_certificate_sequence;
  if (!CBS_get_asn1(&signing_certificate_cbs, &signing_certificate_sequence,
                    CBS_ASN1_SEQUENCE)) {
    return absl::InvalidArgumentError(
        R"(could not parse DER SEQUENCE for SigningCertificateV2 attribute value)");
  }

  CBS certs_sequence;
  if (!CBS_get_asn1(&signing_certificate_sequence, &certs_sequence,
                    CBS_ASN1_SEQUENCE)) {
    return absl::InvalidArgumentError(
        R"(could not parse `certs` field (DER SEQUENCE) of SigningCertificateV2 attribute value)");
  }

  CBS ess_cert_id_cbs;
  while (CBS_get_asn1(&certs_sequence, &ess_cert_id_cbs, CBS_ASN1_SEQUENCE)) {
    // The hash algorithm is an optional field, if it is not present it defaults
    // to SHA-256.
    int algorithm_nid = NID_sha256;
    CBS original = ess_cert_id_cbs;
    CBS oid_cbs;
    if (CBS_get_asn1(&ess_cert_id_cbs, &oid_cbs, CBS_ASN1_OBJECT)) {
      algorithm_nid = OBJ_cbs2nid(&oid_cbs);
      if (algorithm_nid == NID_undef) {
        bssl::UniquePtr<char> oid_txt_uniq(CBS_asn1_oid_to_text(&oid_cbs));
        absl::string_view oid_txt;
        if (oid_txt_uniq != nullptr) {
          oid_txt = oid_txt_uniq.get();
        } else {
          oid_txt = "<unprintable OID>";
        }
        return absl::InvalidArgumentError(absl::StrCat(
            R"(unrecognized OID in `certs.hashAlgorithm` field of SigningCertificateV2 attribute value; OID value: )",
            oid_txt));
      }
    } else {
      ess_cert_id_cbs = original;
    }
    auto hash_algorithm = NidToHashAlgorithm(algorithm_nid);
    if (!hash_algorithm.ok()) {
      return absl::Status(
          hash_algorithm.status().code(),
          absl::StrCat(
              "unsupported hash algorithm in `certs.hashAlgorithm` field of "
              "SigningCertificateV2 attribute value: ",
              hash_algorithm.status().message()));
    }

    CBS hash_cbs;
    if (!CBS_get_asn1(&ess_cert_id_cbs, &hash_cbs, CBS_ASN1_OCTETSTRING)) {
      return absl::InvalidArgumentError(
          R"(could not parse `certs.hash` field (DER OCTETSTRING) of SigningCertificateV2 attribute value)");
    }
    out.push_back(EssCertIdV2{
        .hash_algorithm = *hash_algorithm,
        .cert_hash =
            std::string(reinterpret_cast<const char*>(CBS_data(&hash_cbs)),
                        CBS_len(&hash_cbs))});
  }

  return out;
}

}  // namespace

absl::StatusOr<VerifiedTimestamp> TimestampVerifier::VerifyTimestampToken(
    const ParsedTimestampToken& parsed_token) const {
  ABSL_ASSIGN_OR_RETURN(auto chain, parsed_token.GetCertificateChain());

  // CMS supports more digest algorithms than C2PA, so we need to check that the
  // digest algorithm is supported.
  ABSL_RETURN_IF_ERROR(parsed_token.GetMessageImprintHashAlgorithm().status());

  if (chain.empty()) {
    // This would indicate a bug in the CMS library.
    return absl::InternalError("TSA leaf cert missing");
  }

  absl::Status verify_status = parsed_token.VerifySignature();
  if (!verify_status.ok()) {
    return absl::UnauthenticatedError(
        absl::StrCat("the timestamp signature could not be verified: ",
                     verify_status.message()));
  }

  ABSL_ASSIGN_OR_RETURN(auto signing_certificate_v2_bytes,
                        parsed_token.GetSigningCertificateV2Bytes());

  ABSL_ASSIGN_OR_RETURN(auto ess_cert_ids,
                        GetEssCertIds(signing_certificate_v2_bytes));

  ABSL_ASSIGN_OR_RETURN(auto tst_info_bytes, parsed_token.GetTstInfoBytes());
  CBS cbs;
  CBS_init(&cbs, reinterpret_cast<const uint8_t*>(tst_info_bytes.data()),
           tst_info_bytes.size());

  absl::Time time;
  std::string message_imprint_hash;
  HashAlgorithm hash_algorithm;
  std::string nonce;
  ABSL_RETURN_IF_ERROR(
      ParseTstInfo(cbs, &time, &message_imprint_hash, &hash_algorithm, &nonce));

  ABSL_ASSIGN_OR_RETURN(
      VerifiedTimestamp verified_timestamp,
      VerifiedTimestamp::Create(time, std::move(chain),
                                std::move(message_imprint_hash), hash_algorithm,
                                nonce));

  if (tsa_roots_ == nullptr) {
    ABSL_LOG_EVERY_N_SEC(INFO, 60)
        << "Bypassing C2PA TSA certificate trust check.";
  } else {
    ABSL_RETURN_IF_ERROR(CheckTsaCertificateTrust(
        *tsa_roots_, verified_timestamp, ess_cert_ids));
  }
  ABSL_VLOG(1) << "Verified timestamp: " << verified_timestamp.asserted_time();
  return verified_timestamp;
}

}  // namespace credentio
