// 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, absl::string_view signature,
    const VersionedVerifiedTimestamp& oldest_trusted_timestamp) {
  switch (oldest_trusted_timestamp.version) {
    case TimestampVersion::kV1: {
      ValidationStatusSet v1_status;
      if (CheckMessageImprintHash(
              hash_checker_factory, &v1_status,
              oldest_trusted_timestamp.timestamp,
              ConstructSigStructure(protected_headers_bstr, external_payload,
                                    "CounterSignature"))) {
        status_set->MergeFrom(v1_status);
        return true;
      }

      ValidationStatusSet v2_status;
      if (CheckMessageImprintHash(
              hash_checker_factory, &v2_status,
              oldest_trusted_timestamp.timestamp,
              ConstructSigStructure(protected_headers_bstr, signature,
                                    "CounterSignature"))) {
        status_set->MergeFrom(v2_status);
        RecordStatus(
            status_set,
            InformationalStatusCode::kTimestampV2MessageImprintInV1Format,
            {.url = kClaimSignatureLabel});
        return true;
      }

      status_set->MergeFrom(v1_status);
      return false;
    }
    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> VerifyV1TimestampInternal(
    absl::string_view timestamp_resp,
    const CryptoReadHandler& crypto_read_handler) {
  ABSL_ASSIGN_OR_RETURN(auto timestamp_token,
                        ParseTimestampResp(timestamp_resp));
  ABSL_ASSIGN_OR_RETURN(auto verified_timestamp,
                        crypto_read_handler.VerifyTimestamp(timestamp_token));
  return VersionedVerifiedTimestamp{.timestamp = std::move(verified_timestamp),
                                    .version = TimestampVersion::kV1};
}

absl::StatusOr<VersionedVerifiedTimestamp> VerifyV1Timestamp(
    absl::string_view timestamp_resp,
    const CryptoReadHandler& crypto_read_handler,
    ValidationStatusSet* status_set) {
  auto result = VerifyV1TimestampInternal(timestamp_resp, crypto_read_handler);
  if (!result.ok()) {
    return RecordInformationalAndReturnStatus(result.status(), status_set);
  }
  return result;
}

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

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

  absl::StatusOr<VersionedVerifiedTimestamp> fallback_attempt =
      VerifyV1TimestampInternal(timestamp_token, crypto_read_handler);

  if (fallback_attempt.ok()) {
    RecordStatus(status_set,
                 InformationalStatusCode::kTimestampV1FormatInV2Header,
                 {.url = kClaimSignatureLabel});
    return fallback_attempt;
  }

  return RecordInformationalAndReturnStatus(default_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()) {
    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(), cose_sign1.signature,
                             *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)->VerifySignature(
            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> 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
