// 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 "cose/cose_sign1.h"

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

#include "absl/base/nullability.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/memory/memory.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/strings/substitute.h"
#include "absl/time/clock_interface.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "constants/labels.h"
#include "constants/status_codes.h"
#include "cose/ocsp_verifier.h"
#include "cose/sig_structure.h"
#include "cose/validation_status_util.h"
#include "crypto/crypto_read_handler.h"
#include "crypto/hash.h"
#include "google/protobuf/timestamp.pb.h"
#include "proto/assurance_level.pb.h"
#include "proto/signature_info.pb.h"
#include "proto/validation_status.pb.h"
#include "tsp/timestamp_parsing.h"
#include "tsp/verified_timestamp.h"

namespace credentio {
namespace {

std::vector<absl::string_view> StringViewVector(
    absl::Span<const std::string> v) {
  std::vector<absl::string_view> result;
  result.reserve(v.size());
  for (const auto& e : v) {
    result.push_back(e);
  }
  return result;
}

// Validators shall accept the header from either the protected or unprotected
// bucket, to maintain compatibility with previous versions of this
// specification. In compliance with Section 14.2, “Identity of Signers”, if
// this header appears in both the protected and unprotected buckets with the
// same label, a validator shall reject the claim signature as malformed due to
// the presence of multiple credentials.
// See
// https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#x509_certificates.
absl::StatusOr<std::vector<std::string>> GetCertificateChain(
    const ProtectedHeader& protected_header,
    const UnprotectedHeader& unprotected_header) {
  if (!protected_header.certificate_chain.empty() &&
      !unprotected_header.certificate_chain.empty()) {
    return absl::InvalidArgumentError(
        "Certificate chain is present in both protected and unprotected "
        "headers");
  }
  if (!protected_header.certificate_chain.empty()) {
    return protected_header.certificate_chain;
  }
  return unprotected_header.certificate_chain;
}

absl::StatusOr<absl::string_view> ExtractTimestampHeaderValue(
    const TstContainer& tst_container) {
  // The `tstTokens` array is expected to contain a single token. If this is
  // not the case, we need to return a `timeStamp.malformed` status and ignore
  // the timestamp. See
  // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_validate_the_time_stamp.
  if (tst_container.tst_tokens.size() != 1) {
    return absl::InvalidArgumentError(
        "there are zero or multiple timestamp tokens in tstTokens");
  }
  return tst_container.tst_tokens[0].val;
}

std::string ConstructSigStructure(absl::string_view body_protected,
                                  absl::string_view external_payload,
                                  absl::string_view context) {
  return EncodeSig1Structure(Sig1Structure{
      .context = std::string(context),
      .body_protected = std::string(body_protected),
      .external_aad = "",
      .payload = std::string(external_payload),
  });
}

bool CheckMessageImprintHash(const HashCheckerFactory& hash_checker_factory,
                             ValidationStatusSet* status_set,
                             const VerifiedTimestamp& oldest_trusted_timestamp,
                             absl::string_view timestamp_sig_structure) {
  absl::StatusOr<std::unique_ptr<HashChecker>> messageimprint_hash_checker =
      hash_checker_factory.Create(
          oldest_trusted_timestamp.message_imprint_hash_algorithm());
  if (!messageimprint_hash_checker.ok()) {
    RecordStatus(status_set, InformationalStatusCode::kTimestampMalformed,
                 {.url = kClaimSignatureLabel,
                  .explanation = absl::StrCat(
                      "cannot verify MessageImprint hash; failed to create "
                      "hash checker: ",
                      messageimprint_hash_checker.status())});
    return false;
  }
  (*messageimprint_hash_checker)->Update(timestamp_sig_structure);
  if (!(*messageimprint_hash_checker)
           ->Check(oldest_trusted_timestamp.message_imprint_hash())) {
    RecordStatus(status_set, InformationalStatusCode::kTimestampMismatch,
                 {.url = kClaimSignatureLabel});
    return false;
  }
  return true;
}

// The format of a timestamp.
// See v1/v2 descriptions in
// https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_storing_the_time_stamp
enum class TimestampVersion {
  // A timestamp in the "v1" format, normally found in `sigTst`.
  kV1,
  // A timestamp in the "v2" format, normally found in `sigTst2`.
  kV2,
};

struct VersionedVerifiedTimestamp {
  VerifiedTimestamp timestamp;
  TimestampVersion version;
};

bool MessageImprintMatch(
    absl::string_view& external_payload,
    const HashCheckerFactory& hash_checker_factory,
    ValidationStatusSet* status_set, absl::string_view protected_headers_bstr,
    absl::string_view signature_bstr,
    const VersionedVerifiedTimestamp& oldest_trusted_timestamp) {
  switch (oldest_trusted_timestamp.version) {
    case TimestampVersion::kV1:
      return CheckMessageImprintHash(
          hash_checker_factory, status_set, oldest_trusted_timestamp.timestamp,
          ConstructSigStructure(protected_headers_bstr, external_payload,
                                "CounterSignature"));
    case TimestampVersion::kV2:
      return CheckMessageImprintHash(
          hash_checker_factory, status_set, oldest_trusted_timestamp.timestamp,
          ConstructSigStructure(protected_headers_bstr, signature_bstr,
                                "CounterSignature"));
  }
  LOG(DFATAL) << "Fell through end of exhaustive switch statement.";
  return false;
}

[[nodiscard]] std::optional<SignatureInfo> RecordInvalidSigningCredential(
    absl::string_view explanation, ValidationStatusSet* status_set) {
  RecordStatus(status_set, FailureStatusCode::kSigningCredentialInvalid,
               {.url = kClaimSignatureLabel, .explanation = explanation});
  return std::nullopt;
}

InformationalStatusCode GetTimestampStatusCode(absl::StatusCode status_code) {
  switch (status_code) {
    case absl::StatusCode::kUnauthenticated:
      return InformationalStatusCode::kTimestampUntrusted;
    case absl::StatusCode::kOutOfRange:
      return InformationalStatusCode::kTimestampOutsideValidity;
    case absl::StatusCode::kInvalidArgument:
    default:
      return InformationalStatusCode::kTimestampMalformed;
  }
}

absl::Status RecordInformationalAndReturnStatus(
    absl::Status status, ValidationStatusSet* status_set) {
  RecordStatus(status_set, GetTimestampStatusCode(status.code()),
               {.url = kClaimSignatureLabel, .explanation = status.message()});
  return status;
}

absl::StatusOr<VersionedVerifiedTimestamp> VerifyV1Timestamp(
    absl::string_view timestamp_resp,
    const CryptoReadHandler& crypto_read_handler,
    ValidationStatusSet* status_set) {
  auto timestamp_token = ParseTimestampResp(timestamp_resp);
  if (!timestamp_token.ok()) {
    return RecordInformationalAndReturnStatus(timestamp_token.status(),
                                              status_set);
  }
  auto verified_timestamp =
      crypto_read_handler.VerifyTimestamp(*timestamp_token);
  if (!verified_timestamp.ok()) {
    return RecordInformationalAndReturnStatus(verified_timestamp.status(),
                                              status_set);
  }
  return VersionedVerifiedTimestamp{.timestamp = *std::move(verified_timestamp),
                                    .version = TimestampVersion::kV1};
}

absl::StatusOr<VersionedVerifiedTimestamp> VerifyV2Timestamp(
    absl::string_view timestamp_token,
    const CryptoReadHandler& crypto_read_handler,
    ValidationStatusSet* status_set) {
  absl::StatusOr<VerifiedTimestamp> attempt =
      crypto_read_handler.VerifyTimestamp(timestamp_token);

  if (attempt.ok()) {
    return VersionedVerifiedTimestamp{.timestamp = *std::move(attempt),
                                      .version = TimestampVersion::kV2};
  }

  return RecordInformationalAndReturnStatus(attempt.status(), status_set);
}

// Returns the oldest valid timestamp found in the `sigTst2` or `sigTst`
// header after building a trust chain from the certificate to an entry in the
// validator's trust anchors.
//
// Returns `std::nullopt` if the timestamp header is not present.
// Records a `timeStamp.untrusted` C2PA status to the tracker and returns
// an `std::nullopt` if a trust chain cannot be built from the TSA's
// certificate to one of the validator's trust anchors.
std::optional<VersionedVerifiedTimestamp> VerifyAndGetOldestTrustedTimestamp(
    const CryptoReadHandler& crypto_read_handler,
    const UnprotectedHeader& unprotected_header,
    ValidationStatusSet* status_set) {
  bool is_v2 = true;
  auto timestamp_container = unprotected_header.sig_tst2;
  if (!timestamp_container.has_value()) {
    is_v2 = false;
    timestamp_container = unprotected_header.sig_tst;
  }
  if (!timestamp_container.has_value()) {
    return std::nullopt;
  }

  auto timestamp_header_value =
      ExtractTimestampHeaderValue(*timestamp_container);
  if (!timestamp_header_value.ok()) {
    DVLOG(1) << timestamp_header_value.status();
    RecordStatus(status_set, InformationalStatusCode::kTimestampMalformed,
                 {.url = kClaimSignatureLabel,
                  .explanation = timestamp_header_value.status().ToString()});
    return std::nullopt;
  }

  absl::StatusOr<VersionedVerifiedTimestamp> verified_timestamp =
      is_v2 ? VerifyV2Timestamp(*timestamp_header_value, crypto_read_handler,
                                status_set)
            : VerifyV1Timestamp(*timestamp_header_value, crypto_read_handler,
                                status_set);

  if (!verified_timestamp.ok()) {
    DVLOG(1) << verified_timestamp.status();
    // VerifyV[12]Timestamp would have already reported any issues to `tracker`.
    return std::nullopt;
  }

  return *verified_timestamp;
}

absl::StatusOr<google::protobuf::Timestamp> EncodeGoogleApiProto(absl::Time t) {
  const int64_t s = absl::ToUnixSeconds(t);
  if (s < -62135596800 || s > 253402300799) {
    return absl::OutOfRangeError("Timestamp is out of range");
  }
  google::protobuf::Timestamp proto;
  proto.set_seconds(s);
  proto.set_nanos((t - absl::FromUnixSeconds(s)) / absl::Nanoseconds(1));
  return proto;
}

}  // namespace

std::unique_ptr<CoseSign1Verifier> CoseSign1Verifier::Create(
    const CryptoReadHandler* absl_nonnull crypto_read_handler,
    const HashCheckerFactory* absl_nonnull hash_checker_factory,
    absl::Clock* absl_nonnull clock, Options options) {
  return absl::WrapUnique(new CoseSign1Verifier(
      crypto_read_handler, hash_checker_factory, clock, options));
}

std::optional<SignatureInfo> CoseSign1Verifier::Verify(
    const CoseSign1TaggedStructure& cose_sign1,
    absl::string_view external_payload, ValidationStatusSet* status_set) const {
  // STEP 0: Get the certificate chain and parse the certificates.
  auto protected_headers = DecodeProtectedHeader(cose_sign1.protected_header);
  if (!protected_headers.ok()) {
    if (absl::IsUnimplemented(protected_headers.status())) {
      RecordStatus(status_set, FailureStatusCode::kAlgorithmUnsupported,
                   {.url = kClaimSignatureLabel,
                    .explanation = protected_headers.status().message()});
      return std::nullopt;
    }
    return RecordInvalidSigningCredential(
        absl::StrCat("cannot decode protected header: ",
                     protected_headers.status().message()),
        status_set);
  }
  auto certificate_chain =
      GetCertificateChain(*protected_headers, cose_sign1.unprotected_header);
  if (!certificate_chain.ok()) {
    return RecordInvalidSigningCredential(certificate_chain.status().message(),
                                          status_set);
  }
  if (certificate_chain->empty()) {
    return RecordInvalidSigningCredential("no claim signer certificates",
                                          status_set);
  }
  auto certs = crypto_read_handler_.ParseCertificatesDer(
      StringViewVector(*certificate_chain));
  if (!certs.ok()) {
    return RecordInvalidSigningCredential(
        absl::StrCat("malformed claim signer certificates: ",
                     certs.status().message()),
        status_set);
  }

  // STEP 1: Verify the timestamp.
  // Obtain and verify the oldest verified timestamp from sig_tst2 or sig_tst
  // in the unprotected header.
  std::optional<VersionedVerifiedTimestamp> oldest_trusted_timestamp =
      VerifyAndGetOldestTrustedTimestamp(
          crypto_read_handler_, cose_sign1.unprotected_header, status_set);
  // Check that the timestamp matches the signature.
  bool check_message_imprint = true;
  if (oldest_trusted_timestamp.has_value()) {
    if (check_message_imprint &&
        !MessageImprintMatch(external_payload, hash_checker_factory_,
                             status_set, cose_sign1.protected_header,
                             cose_sign1.signature_bstr(),
                             *oldest_trusted_timestamp)) {
      oldest_trusted_timestamp = std::nullopt;
    } else {
      RecordStatus(status_set, SuccessStatusCode::kTimestampValidated,
                   {.url = kClaimSignatureLabel});
      RecordStatus(status_set, SuccessStatusCode::kTimestampTrusted,
                   {.url = kClaimSignatureLabel});
    }
  }

  // STEP 2: Verify the signer's certificate chain.
  absl::Time content_time =
      oldest_trusted_timestamp.has_value()
          ? oldest_trusted_timestamp->timestamp.asserted_time()
          : clock_.TimeNow();
  absl::StatusOr<std::vector<std::string>> trust_chain =
      (*certs)->VerifyClaimSignerTrust(content_time);
  if (!trust_chain.ok()) {
    switch (trust_chain.status().code()) {
      case absl::StatusCode::kUnauthenticated:
        RecordStatus(status_set, FailureStatusCode::kSigningCredentialUntrusted,
                     {.url = kClaimSignatureLabel,
                      .explanation = trust_chain.status().message()});
        return std::nullopt;
      case absl::StatusCode::kOutOfRange:
        RecordStatus(status_set,
                     FailureStatusCode::kClaimSignatureOutsideValidity,
                     {.url = kClaimSignatureLabel,
                      .explanation = trust_chain.status().message()});
        return std::nullopt;
      case absl::StatusCode::kUnavailable:
        // Trust list unavailable?
        RecordStatus(status_set, FailureStatusCode::kGoogleInternalError,
                     {.url = kClaimSignatureLabel,
                      .explanation = trust_chain.status().message()});
        return std::nullopt;
      default:
        return RecordInvalidSigningCredential(trust_chain.status().message(),
                                              status_set);
    }
  }

  // STEP 3: Verify the revocation information of the signer's cert chain.
  // We first check the certificate revocation list, and then the stapled OCSP
  // response as described in
  // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_validate_the_credential_revocation_information.
  // Online OCSP checks are not supported yet.
  if (!options_.check_ocsp_responses) {
    RecordSkippedOcspCheck(status_set);
  } else if (!oldest_trusted_timestamp.has_value()) {
    // Trusted timestamp is required for verifying stapled OCSP responses
    // (https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#ocsp_stapled).
    RecordSkippedOcspCheck(status_set);
  } else {
    OcspVerifier ocsp_verifier(&crypto_read_handler_);
    if (!ocsp_verifier.VerifyOcspResponses(
            cose_sign1.unprotected_header.ocsp_responses, *trust_chain,
            oldest_trusted_timestamp->timestamp.asserted_time(), status_set)) {
      // OCSP response indicates that a certificate in the chain is revoked.
      return std::nullopt;
    }
  }

  RecordStatus(status_set, SuccessStatusCode::kSigningCredentialTrusted,
               {.url = kClaimSignatureLabel});
  RecordStatus(status_set, SuccessStatusCode::kClaimSignatureInsideValidity,
               {.url = kClaimSignatureLabel});

  // STEP 4: Verify the signature.
  if (options_.verify_signature) {
    auto signing_algorithm = protected_headers->alg;
    if (absl::Status status = (*certs)->VerifyCoseSignature(
            cose_sign1.signature,
            ConstructSigStructure(cose_sign1.protected_header, external_payload,
                                  "Signature1"),
            signing_algorithm);
        !status.ok()) {
      RecordStatus(status_set, FailureStatusCode::kClaimSignatureMismatch,
                   {.url = kClaimSignatureLabel,
                    .explanation = absl::Substitute(
                        "claim signature validation failed; alg=$0; status=$1",
                        signing_algorithm, status.ToString())});
      return std::nullopt;
    }
    RecordStatus(status_set, SuccessStatusCode::kClaimSignatureValidated,
                 {.url = kClaimSignatureLabel});
  }

  // Finally, construct and return the SignatureInfo.
  SignatureInfo signature_info;
  const ParsedCertificates& parsed_certs = **certs;
  if (oldest_trusted_timestamp.has_value()) {
    absl::StatusOr<google::protobuf::Timestamp> time_proto =
        EncodeGoogleApiProto(
            oldest_trusted_timestamp->timestamp.asserted_time());
    if (time_proto.ok()) {
      *signature_info.mutable_timestamping_time() = *std::move(time_proto);
    } else {
      RecordStatus(status_set, InformationalStatusCode::kTimestampOutOfRange,
                   {.url = kClaimSignatureLabel});
    }
  }
  absl::StatusOr<std::string> serial_number =
      parsed_certs.GetSerialNumberHex(0);
  if (serial_number.ok()) {
    signature_info.set_cert_serial_number(*serial_number);
  }
  absl::StatusOr<std::string> subject = parsed_certs.GetSubject(0);
  if (subject.ok()) {
    signature_info.set_issuer(*subject);
  }
  absl::StatusOr<std::string> issuer = parsed_certs.GetIssuer(0);
  if (issuer.ok()) {
    signature_info.set_certificate_issuer(*issuer);
  }
  absl::StatusOr<std::string> assurance_level =
      parsed_certs.GetAssuranceLevel(0);
  if (assurance_level.ok()) {
    if (*assurance_level == "1.3.6.1.4.1.62558.3.10") {
      signature_info.set_assurance_level(ASSURANCE_LEVEL1);
    } else if (*assurance_level == "1.3.6.1.4.1.62558.3.20") {
      signature_info.set_assurance_level(ASSURANCE_LEVEL2);
    }
  }
  absl::StatusOr<std::string> conforming_product_id =
      parsed_certs.GetConformingProductId(0);
  if (conforming_product_id.ok()) {
    signature_info.set_conforming_product_id(*conforming_product_id);
  }
  return signature_info;
};

}  // namespace credentio
