// 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 "testing/local_key_crypto_write_handler.h"

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

#include "absl/base/no_destructor.h"
#include "absl/base/nullability.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/absl_check.h"
#include "absl/log/die_if_null.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/synchronization/mutex.h"
#include "absl/time/clock_interface.h"
#include "absl/time/time.h"
#include "async/async_context.h"
#include "crypto/algorithms.h"
#include "crypto/crypto_write_handler.h"
#include "crypto/timestamp_write_handler.h"
#include "tink/insecure_secret_key_access.h"
#include "tink/key_status.h"
#include "tink/keyset_handle.h"
#include "tink/partial_key_access.h"
#include "tink/pem/signature_key_parser.h"
#include "tink/public_key_sign.h"
#include "tink/signature/config_v0.h"
#include "tink/signature/ecdsa_parameters.h"
#include "tink/signature/ecdsa_private_key.h"
#include "tink/signature/signature_config.h"
#include "tsp/test_helpers.h"

namespace credentio {
namespace {

using ::crypto::tink::EcdsaParameters;
using ::crypto::tink::EcdsaPrivateKey;
using ::crypto::tink::GetPartialKeyAccess;
using ::crypto::tink::InsecureSecretKeyAccess;
using ::crypto::tink::KeysetHandle;
using ::crypto::tink::KeysetHandleBuilder;
using ::crypto::tink::KeyStatus;
using ::crypto::tink::PublicKeySign;
using ::crypto::tink::SignatureConfig;

// Extra bytes reserved on top of a measured signature or timestamp size, since
// DER-encoded ECDSA signatures vary in length.
constexpr uint64_t kSizeMargin = 10;

// OCSP responses are dropped once this much time has passed since the signer
// was created.
constexpr absl::Duration kOcspResponseLifetime = absl::Hours(24 * 7);

// Returns the OID of `hash_algorithm` (see RFC 5754).
absl::StatusOr<absl::string_view> HashAlgorithmOid(
    HashAlgorithm hash_algorithm) {
  switch (hash_algorithm) {
    case HashAlgorithm::kSha256:
      return "2.16.840.1.101.3.4.2.1";
    case HashAlgorithm::kSha384:
      return "2.16.840.1.101.3.4.2.2";
    case HashAlgorithm::kSha512:
      return "2.16.840.1.101.3.4.2.3";
    default:
      return absl::InvalidArgumentError(
          absl::StrCat("Unsupported hash algorithm: ", hash_algorithm));
  }
}

// Returns an ES256 signer for the PEM-encoded EC P-256 private key `key_pem`.
absl::StatusOr<std::unique_ptr<PublicKeySign>> CreateEs256Signer(
    absl::string_view key_pem,
    EcdsaParameters::SignatureEncoding signature_encoding) {
  // Populates the global registry that the config-less
  // `KeysetHandleBuilder::Build()` below relies on.
  static const absl::NoDestructor<absl::Status> registration_status(
      SignatureConfig::Register());
  ABSL_RETURN_IF_ERROR(*registration_status);

  ABSL_ASSIGN_OR_RETURN(EcdsaParameters parameters,
                        EcdsaParameters::Builder()
                            .SetCurveType(EcdsaParameters::CurveType::kNistP256)
                            .SetHashType(EcdsaParameters::HashType::kSha256)
                            .SetSignatureEncoding(signature_encoding)
                            .SetVariant(EcdsaParameters::Variant::kNoPrefix)
                            .Build());
  ABSL_ASSIGN_OR_RETURN(EcdsaPrivateKey private_key,
                        tink_pem::PemToEcdsaPrivateKey(
                            key_pem, parameters, InsecureSecretKeyAccess::Get(),
                            GetPartialKeyAccess()));
  ABSL_ASSIGN_OR_RETURN(
      KeysetHandle keyset_handle,
      KeysetHandleBuilder()
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableKey(
              std::move(private_key), KeyStatus::kEnabled,
              /*is_primary=*/true))
          .Build());
  return keyset_handle.GetPrimitive<PublicKeySign>(
      crypto::tink::ConfigSignatureV0());
}

// Returns a DER-encoded RFC 3161 TimeStampToken over `hashed_message`, signed
// by `tsa_signer` at the current time on `clock`.
absl::StatusOr<std::string> CreateTimeStampToken(
    HashAlgorithm hash_algorithm, absl::string_view hashed_message,
    absl::Clock& clock, const PublicKeySign& tsa_signer,
    absl::string_view tsa_cert_pem) {
  ABSL_ASSIGN_OR_RETURN(absl::string_view oid,
                        HashAlgorithmOid(hash_algorithm));
  const std::string gen_time =
      absl::FormatTime("%Y%m%d%H%M%SZ", clock.TimeNow(), absl::UTCTimeZone());
  const std::string tst_info = CreateTstInfo(gen_time, hashed_message, oid);
  return CreateTimeStampTokenEcdsa({tst_info}, tsa_signer, tsa_cert_pem,
                                   /*embed_cert=*/true);
}

}  // namespace

LocalKeySigner::LocalKeySigner(
    std::unique_ptr<PublicKeySign> absl_nonnull signer,
    std::vector<std::string> certificate_chain,
    std::vector<std::string> ocsp_responses, absl::Clock* absl_nonnull clock,
    SigningAlgorithm algorithm)
    : signer_(std::move(ABSL_DIE_IF_NULL(signer))),
      certificate_chain_(std::move(certificate_chain)),
      ocsp_responses_(std::move(ocsp_responses)),
      clock_(ABSL_DIE_IF_NULL(clock)),
      create_time_(clock_->TimeNow()),
      algorithm_(algorithm) {}

const std::vector<std::string>& LocalKeySigner::ocsp_responses() const {
  if (clock_->TimeNow() > create_time_ + kOcspResponseLifetime) {
    static const absl::NoDestructor<std::vector<std::string>> kNoResponses;
    return *kNoResponses;
  }
  return ocsp_responses_;
}

uint64_t LocalKeySigner::max_signature_byte_size() const {
  absl::MutexLock lock(mutex_);
  if (!max_signature_byte_size_.has_value()) {
    // The interface cannot report errors, and a signer that cannot sign is
    // unusable, so crash.
    absl::StatusOr<SignResponse> response = Sign("measure signature size");
    ABSL_CHECK_OK(response);
    max_signature_byte_size_ = response->signature.size() + kSizeMargin;
  }
  return *max_signature_byte_size_;
}

absl::StatusOr<SignResponse> LocalKeySigner::Sign(
    absl::string_view to_be_signed) const {
  ABSL_ASSIGN_OR_RETURN(std::string signature, signer_->Sign(to_be_signed));
  return SignResponse{.signature = std::move(signature)};
}

LocalKeyCryptoWriteHandler::LocalKeyCryptoWriteHandler(
    absl::Clock* absl_nonnull clock,
    std::unique_ptr<PublicKeySign> absl_nonnull signer,
    std::unique_ptr<PublicKeySign> absl_nullable tsa_signer,
    bool is_timestamping_disabled, std::vector<std::string> certificate_chain,
    std::vector<std::string> ocsp_responses, SigningAlgorithm algorithm,
    std::string tsa_cert_pem)
    : clock_(ABSL_DIE_IF_NULL(clock)),
      signer_(std::move(signer), std::move(certificate_chain),
              std::move(ocsp_responses), clock, algorithm),
      tsa_signer_(std::move(tsa_signer)),
      is_timestamping_disabled_(is_timestamping_disabled),
      tsa_cert_pem_(std::move(tsa_cert_pem)) {}

void LocalKeyCryptoWriteHandler::CreateTimestamp(
    HashAlgorithm hash_algorithm, std::string hashed_message,
    TimestampWriteHandler::Options options,
    absl::AnyInvocable<void(absl::StatusOr<std::string>) &&> cb) const {
  AsyncResolver<std::string> resolver(options.async_context, std::move(cb));
  if (is_timestamping_disabled_ || tsa_signer_ == nullptr) {
    resolver.Return(absl::UnavailableError("TSA is disabled."));
    return;
  }
  resolver.Return(CreateTimeStampToken(hash_algorithm, hashed_message, *clock_,
                                       *tsa_signer_, tsa_cert_pem_));
}

uint64_t LocalKeyCryptoWriteHandler::max_timestamp_byte_size(
    HashAlgorithm hash_algorithm) const {
  if (tsa_signer_ == nullptr) {
    return 0;
  }
  absl::MutexLock lock(mutex_);
  auto [it, inserted] =
      max_timestamp_byte_size_map_.try_emplace(hash_algorithm);
  if (inserted) {
    // The interface cannot report errors, and a TSA that cannot sign is
    // unusable, so crash.
    absl::StatusOr<std::string> token = CreateTimeStampToken(
        hash_algorithm, std::string(HashSizeBytes(hash_algorithm), '\0'),
        *clock_, *tsa_signer_, tsa_cert_pem_);
    ABSL_CHECK_OK(token);
    it->second = token->size() + kSizeMargin;
  }
  return it->second;
}

absl::StatusOr<std::unique_ptr<CryptoWriteHandler>>
CreateLocalKeyCryptoWriteHandler(LocalKeyCryptoWriteHandlerOptions options) {
  if (options.claim_signer.key_pem.empty()) {
    return absl::InvalidArgumentError("Claim signer key is missing.");
  }
  if (options.claim_signer.certificate_chain.empty()) {
    return absl::InvalidArgumentError(
        "Claim signer certificate chain is missing.");
  }
  if (!options.disable_timestamping) {
    if (options.tsa.key_pem.empty()) {
      return absl::InvalidArgumentError("TSA key is missing.");
    }
    if (options.tsa.cert_pem.empty()) {
      return absl::InvalidArgumentError("TSA certificate is missing.");
    }
  } else if (options.tsa.key_pem.empty() != options.tsa.cert_pem.empty()) {
    return absl::InvalidArgumentError(
        "TSA key and certificate must either both be provided or both be "
        "omitted.");
  }

  // COSE requires raw (IEEE P1363) ECDSA signatures, while CMS in RFC 3161
  // timestamps requires DER.
  ABSL_ASSIGN_OR_RETURN(
      std::unique_ptr<PublicKeySign> signer,
      CreateEs256Signer(options.claim_signer.key_pem,
                        EcdsaParameters::SignatureEncoding::kIeeeP1363));
  std::unique_ptr<PublicKeySign> tsa_signer;
  if (!options.tsa.key_pem.empty()) {
    ABSL_ASSIGN_OR_RETURN(
        tsa_signer,
        CreateEs256Signer(options.tsa.key_pem,
                          EcdsaParameters::SignatureEncoding::kDer));
  }
  absl::Clock* clock =
      options.clock != nullptr ? options.clock : &absl::Clock::GetRealClock();
  return std::make_unique<LocalKeyCryptoWriteHandler>(
      clock, std::move(signer), std::move(tsa_signer),
      options.disable_timestamping,
      std::move(options.claim_signer.certificate_chain),
      std::move(options.claim_signer.ocsp_responses), SigningAlgorithm::kEs256,
      std::move(options.tsa.cert_pem));
}

}  // namespace credentio
