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

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

#include "absl/base/no_destructor.h"
#include "absl/base/nullability.h"
#include "absl/log/absl_check.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/string_view.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "crypto/algorithms.h"
#include "crypto/cbs_utils.h"
#include "crypto/default/hasher.h"
#include "crypto/hash.h"
#include "openssl/base.h"
#include "openssl/bio.h"
#include "openssl/bytestring.h"
#include "openssl/digest.h"
#include "openssl/err.h"
#include "openssl/evp.h"
#include "openssl/mem.h"
#include "openssl/obj.h"
#include "openssl/pem.h"  // IWYU pragma: keep
#include "openssl/x509.h"
#include "proto/common.pb.h"
#include "testing/boringssl_utils.h"
#include "testing/cms.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/constants.h"
#include "tsp/status_codes.h"

namespace credentio {
namespace {

using ::crypto::tink::EcdsaParameters;
using ::crypto::tink::EcdsaPrivateKey;
using ::crypto::tink::KeysetHandle;
using ::crypto::tink::KeysetHandleBuilder;
using ::crypto::tink::PublicKeySign;

absl::StatusOr<KeysetHandle> LoadEcdsaPrivateKeyFromPem(
    absl::string_view pem_data) {
  ABSL_ASSIGN_OR_RETURN(
      EcdsaParameters params,
      EcdsaParameters::Builder()
          .SetCurveType(EcdsaParameters::CurveType::kNistP256)
          .SetHashType(EcdsaParameters::HashType::kSha256)
          .SetSignatureEncoding(EcdsaParameters::SignatureEncoding::kDer)
          .SetVariant(EcdsaParameters::Variant::kNoPrefix)
          .Build());
  ABSL_ASSIGN_OR_RETURN(
      EcdsaPrivateKey private_key,
      tink_pem::PemToEcdsaPrivateKey(
          pem_data, params, crypto::tink::InsecureSecretKeyAccess::Get(),
          crypto::tink::GetPartialKeyAccess()));
  KeysetHandleBuilder builder;
  builder.AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableKey(
      private_key, crypto::tink::KeyStatus::kEnabled, /*is_primary=*/true));
  return builder.Build();
}

absl::StatusOr<std::vector<uint8_t>> SignWithBoringSsl(
    const EVP_PKEY& private_key, absl::string_view data) {
  if (EVP_PKEY_id(&private_key) != EVP_PKEY_RSA) {
    return absl::UnimplementedError("Only RSA keys are supported.");
  }
  bssl::ScopedEVP_MD_CTX md_context;
  EVP_PKEY_CTX* pkey_ctx = nullptr;
  if (EVP_DigestSignInit(md_context.get(), &pkey_ctx, EVP_sha256(), nullptr,
                         const_cast<EVP_PKEY*>(&private_key)) != 1 ||
      EVP_DigestSignUpdate(md_context.get(), data.data(), data.length()) != 1) {
    return absl::InternalError("EVP_DigestSignInit/Update failed.");
  }
  size_t sig_len = 0;
  if (EVP_DigestSignFinal(md_context.get(), nullptr, &sig_len) != 1) {
    return absl::InternalError("EVP_DigestSignFinal failed.");
  }
  std::vector<uint8_t> signature(sig_len, 0);
  if (EVP_DigestSignFinal(md_context.get(), signature.data(), &sig_len) != 1) {
    return absl::InternalError("EVP_DigestSignFinal failed.");
  }
  return signature;
}

}  // namespace

std::string WrapDerSequence(absl::string_view payload) {
  CBB cbb;
  ABSL_CHECK(CBB_init(&cbb, payload.size() + 5));
  CBB seq_cbb;
  ABSL_CHECK(CBB_add_asn1(&cbb, &seq_cbb, CBS_ASN1_SEQUENCE));
  ABSL_CHECK(CBB_add_bytes(&seq_cbb,
                           reinterpret_cast<const uint8_t*>(payload.data()),
                           payload.size()));
  uint8_t* data;
  size_t len;
  ABSL_CHECK(CBB_finish(&cbb, &data, &len));
  bssl::UniquePtr<uint8_t> data_uniq(data);
  return std::string(reinterpret_cast<char*>(data), len);
}

std::string EncodeDerInteger(uint64_t n) {
  CBB cbb;
  ABSL_CHECK(CBB_init(&cbb, 10));
  ABSL_CHECK(CBB_add_asn1_int64(&cbb, n));
  uint8_t* cbb_data;
  size_t cbb_len;
  ABSL_CHECK(CBB_finish(&cbb, &cbb_data, &cbb_len));
  bssl::UniquePtr<uint8_t> cbb_data_uniq(cbb_data);
  return std::string(reinterpret_cast<char*>(cbb_data), cbb_len);
}

std::string CreateTimeStampResp(absl::string_view ts_token) {
  CBB cbb;
  ABSL_CHECK(CBB_init(&cbb, 40));
  CBB ts_resp_cbb;
  ABSL_CHECK(CBB_add_asn1(&cbb, &ts_resp_cbb, CBS_ASN1_SEQUENCE));

  CBB pki_status_cbb;
  ABSL_CHECK(CBB_add_asn1(&ts_resp_cbb, &pki_status_cbb, CBS_ASN1_SEQUENCE));
  ABSL_CHECK(CBB_add_asn1_int64(&pki_status_cbb,
                                static_cast<int64_t>(TspPkiStatus::kGranted)));

  ABSL_CHECK(CBB_add_bytes(&ts_resp_cbb,
                           reinterpret_cast<const uint8_t*>(ts_token.data()),
                           ts_token.size()));

  uint8_t* cbb_data_ptr;
  size_t cbb_len;
  ABSL_CHECK(CBB_finish(&cbb, &cbb_data_ptr, &cbb_len));
  bssl::UniquePtr<uint8_t> cbb_uniq(cbb_data_ptr);

  std::string cbb_str(cbb_data_ptr, cbb_data_ptr + cbb_len);
  return cbb_str;
}

std::string CreateFailedTimeStampResp(
    TspPkiStatus status, absl::Span<const absl::string_view> status_string,
    absl::Span<const int32_t> failure_info) {
  CBB cbb;
  ABSL_CHECK(CBB_init(&cbb, 512));
  CBB resp;
  ABSL_CHECK(CBB_add_asn1(&cbb, &resp, CBS_ASN1_SEQUENCE));
  CBB pki_status_info;
  ABSL_CHECK(CBB_add_asn1(&resp, &pki_status_info, CBS_ASN1_SEQUENCE));
  ABSL_CHECK(
      CBB_add_asn1_int64(&pki_status_info, static_cast<int64_t>(status)));
  if (!status_string.empty()) {
    CBB status_string_cbb;
    ABSL_CHECK(
        CBB_add_asn1(&pki_status_info, &status_string_cbb, CBS_ASN1_SEQUENCE));
    for (absl::string_view entry : status_string) {
      CBB utf8_string;
      ABSL_CHECK(
          CBB_add_asn1(&status_string_cbb, &utf8_string, CBS_ASN1_UTF8STRING));
      ABSL_CHECK(CBB_add_bytes(&utf8_string,
                               reinterpret_cast<const uint8_t*>(entry.data()),
                               entry.length()));
      ABSL_CHECK(CBB_flush(&status_string_cbb));
    }
    ABSL_CHECK(CBB_flush(&pki_status_info));
  }
  if (!failure_info.empty()) {
    CBB failure_info_cbb;
    ABSL_CHECK(
        CBB_add_asn1(&pki_status_info, &failure_info_cbb, CBS_ASN1_BITSTRING));
    ABSL_CHECK(CBB_add_u8(&failure_info_cbb, 0 /* no padding bits */));
    int32_t max_bit = 0;
    for (int32_t entry : failure_info) {
      if (entry > max_bit) {
        max_bit = entry;
      }
    }
    int32_t bytes = (max_bit / 8) + 1;
    std::string data(bytes, 0);
    for (int32_t entry : failure_info) {
      data[entry >> 3] |= 1 << (7 - (entry & 7));
    }
    ABSL_CHECK(CBB_add_bytes(&failure_info_cbb,
                             reinterpret_cast<const uint8_t*>(data.data()),
                             data.size()));
    ABSL_CHECK(CBB_flush(&pki_status_info));
  }

  uint8_t* cbb_data;
  size_t cbb_len;
  ABSL_CHECK(CBB_finish(&cbb, &cbb_data, &cbb_len));
  bssl::UniquePtr<uint8_t> cbb_data_uniq(cbb_data);

  return std::string(reinterpret_cast<char*>(cbb_data), cbb_len);
}

std::string CreateTimeStampTokenRsa(
    absl::Span<const absl::string_view> der_data, absl::string_view key_pem,
    absl::string_view cert_pem, bool embed_cert,
    std::variant<absl::string_view, bool> signing_certificate_attribute) {
  bssl::UniquePtr<EVP_PKEY> key(PemToKey(key_pem));
  ABSL_CHECK(key != nullptr);
  bssl::UniquePtr<X509> cert(PemToCertificate(cert_pem));
  ABSL_CHECK(cert != nullptr);
  std::string extra_attrs;
  if (std::holds_alternative<absl::string_view>(
          signing_certificate_attribute)) {
    extra_attrs = std::get<absl::string_view>(signing_certificate_attribute);
  } else {
    if (std::get<bool>(signing_certificate_attribute)) {
      X509* certs[] = {cert.get()};
      extra_attrs =
          CreateSigningCertificateV2Attribute(certs, HashAlgorithm::kSha256);
    }
  }

  auto cms_or = credentio_testing::CreateSignedCms(
      der_data, *cert,
      [&key](absl::string_view data) { return SignWithBoringSsl(*key, data); },
      {.include_user_certificate = embed_cert,
       .extra_signed_attributes = extra_attrs,
       .is_time_stamp_token = true});
  ABSL_CHECK_OK(cms_or.status());
  return *cms_or;
}

std::string CreateTimeStampTokenEcdsa(
    absl::Span<const absl::string_view> der_data,
    const crypto::tink::PublicKeySign& signer, absl::string_view cert_pem,
    bool embed_cert,
    std::variant<absl::string_view, bool> signing_certificate_attribute,
    std::optional<absl::Time> signing_time) {
  bssl::UniquePtr<X509> cert(PemToCertificate(cert_pem));
  ABSL_CHECK(cert != nullptr);
  std::string extra_attrs;
  if (std::holds_alternative<absl::string_view>(
          signing_certificate_attribute)) {
    extra_attrs = std::get<absl::string_view>(signing_certificate_attribute);
  } else {
    if (std::get<bool>(signing_certificate_attribute)) {
      X509* certs[] = {cert.get()};
      extra_attrs =
          CreateSigningCertificateV2Attribute(certs, HashAlgorithm::kSha256);
    }
  }

  auto cms_or = credentio_testing::CreateSignedCms(
      der_data, *cert,
      [&signer](
          absl::string_view data) -> absl::StatusOr<std::vector<uint8_t>> {
        ABSL_ASSIGN_OR_RETURN(auto signature, signer.Sign(data));
        return std::vector<uint8_t>(signature.begin(), signature.end());
      },
      {.signing_time = signing_time,
       .include_user_certificate = embed_cert,
       .extra_signed_attributes = extra_attrs,
       .is_time_stamp_token = true});
  ABSL_CHECK_OK(cms_or.status());
  return *cms_or;
}

std::string CreateTimeStampTokenEcdsa(
    absl::Span<const absl::string_view> der_data, absl::string_view key_pem,
    absl::string_view cert_pem, bool embed_cert,
    std::optional<std::vector<const X509*>> extra_certs,
    std::variant<absl::string_view, bool> signing_certificate_attribute,
    bool use_wrong_e_content_type) {
  static const absl::NoDestructor<absl::Status> registration_status(
      []() { return crypto::tink::SignatureConfig::Register(); }());
  ABSL_CHECK_OK(*registration_status);
  absl::StatusOr<KeysetHandle> keyset_handle =
      LoadEcdsaPrivateKeyFromPem(key_pem);
  ABSL_CHECK_OK(keyset_handle);
  auto signer = keyset_handle->GetPrimitive<crypto::tink::PublicKeySign>(
      crypto::tink::ConfigSignatureV0());
  ABSL_CHECK_OK(signer);
  std::unique_ptr<crypto::tink::PublicKeySign> signer_ptr = *std::move(signer);

  bssl::UniquePtr<EVP_PKEY> key(PemToKey(key_pem));
  ABSL_CHECK(key != nullptr);
  bssl::UniquePtr<X509> cert(PemToCertificate(cert_pem));
  ABSL_CHECK(cert != nullptr);
  std::string extra_attrs;
  if (std::holds_alternative<absl::string_view>(
          signing_certificate_attribute)) {
    extra_attrs = std::get<absl::string_view>(signing_certificate_attribute);
  } else {
    if (std::get<bool>(signing_certificate_attribute)) {
      std::vector<X509*> certs;
      certs.push_back(cert.get());
      if (extra_certs.has_value()) {
        for (const X509* extra_cert : *extra_certs) {
          certs.push_back(const_cast<X509*>(extra_cert));
        }
      }
      extra_attrs = CreateSigningCertificateV2Attribute(absl::MakeSpan(certs),
                                                        HashAlgorithm::kSha256);
    }
  }

  std::vector<const X509*> ca_certs;
  if (extra_certs.has_value()) {
    ca_certs = *extra_certs;
  }

  auto cms_or = credentio_testing::CreateSignedCms(
      der_data, *cert,
      [&signer_ptr](
          absl::string_view data) -> absl::StatusOr<std::vector<uint8_t>> {
        ABSL_ASSIGN_OR_RETURN(auto signature, signer_ptr->Sign(data));
        return std::vector<uint8_t>(signature.begin(), signature.end());
      },
      {.include_user_certificate = embed_cert,
       .ca_certificates = ca_certs,
       .extra_signed_attributes = extra_attrs,
       .is_time_stamp_token = !use_wrong_e_content_type});
  ABSL_CHECK_OK(cms_or.status());
  return *cms_or;
}

std::string CreateTstInfo(absl::string_view gen_time,
                          absl::string_view message_imprint_hash,
                          absl::string_view message_imprint_algorithm_txt,
                          std::optional<absl::string_view> nonce) {
  CBB cbb;
  ABSL_CHECK(CBB_init(&cbb, 30));

  CBB sequence_cbb;
  ABSL_CHECK(CBB_add_asn1(&cbb, &sequence_cbb, CBS_ASN1_SEQUENCE));
  // version
  ABSL_CHECK(CBB_add_asn1_int64(&sequence_cbb, 1));

  // policy
  CBB policy_cbb;
  ABSL_CHECK(CBB_add_asn1(&sequence_cbb, &policy_cbb, CBS_ASN1_OBJECT));
  ABSL_CHECK(
      CBB_add_asn1_oid_from_text(&policy_cbb, "1.2.840.113554.4.1.72585", 24));
  ABSL_CHECK(CBB_flush(&sequence_cbb));

  // messageImprint
  CBB mi_cbb;
  ABSL_CHECK(CBB_add_asn1(&sequence_cbb, &mi_cbb, CBS_ASN1_SEQUENCE));
  // messageImprint.hashAlgorithm
  CBB algorithm_identifier_cbb;
  ABSL_CHECK(
      CBB_add_asn1(&mi_cbb, &algorithm_identifier_cbb, CBS_ASN1_SEQUENCE));
  // messageImprint.hashAlgorithm.algorithm
  CBB algorithm_cbb;
  ABSL_CHECK(
      CBB_add_asn1(&algorithm_identifier_cbb, &algorithm_cbb, CBS_ASN1_OBJECT));
  ABSL_CHECK(CBB_add_asn1_oid_from_text(
      &algorithm_cbb, message_imprint_algorithm_txt.data(),
      message_imprint_algorithm_txt.length()));
  ABSL_CHECK(CBB_flush(&mi_cbb));

  // messageImprint.hashedMessage
  ABSL_CHECK(CBB_add_asn1_octet_string(
      &mi_cbb, reinterpret_cast<const uint8_t*>(message_imprint_hash.data()),
      message_imprint_hash.length()));
  ABSL_CHECK(CBB_flush(&sequence_cbb));

  // serial_number
  ABSL_CHECK(CBB_add_asn1_int64(&sequence_cbb, 1));

  // genTime
  CBB gen_time_cbb;
  ABSL_CHECK(
      CBB_add_asn1(&sequence_cbb, &gen_time_cbb, CBS_ASN1_GENERALIZEDTIME));
  ABSL_CHECK(CBB_add_bytes(&gen_time_cbb,
                           reinterpret_cast<const uint8_t*>(gen_time.data()),
                           gen_time.length()));
  ABSL_CHECK(CBB_flush(&sequence_cbb));

  // accuracy (this is an empty SEQUENCE because currently code under test will
  // never actually read it)
  CBB accuracy_cbb;
  ABSL_CHECK(CBB_add_asn1(&sequence_cbb, &accuracy_cbb, CBS_ASN1_SEQUENCE));

  // ordering
  ABSL_CHECK(CBB_add_asn1_bool(&sequence_cbb, true));

  // nonce
  if (nonce.has_value()) {
    ABSL_CHECK(CBB_add_bytes(&sequence_cbb,
                             reinterpret_cast<const uint8_t*>(nonce->data()),
                             nonce->length()));
  }

  uint8_t* der_data;
  size_t der_len;
  ABSL_CHECK(CBB_finish(&cbb, &der_data, &der_len));

  std::string der(der_data, der_data + der_len);

  OPENSSL_free(der_data);
  return der;
}

std::string CreateSigningCertificateV2Attribute(
    absl::Span<X509* absl_nonnull> certs, HashAlgorithm hash_algorithm) {
  CBB cbb;
  ABSL_CHECK(CBB_init(&cbb, 1000));
  CBB attr_seq_cbb;
  ABSL_CHECK(CBB_add_asn1(&cbb, &attr_seq_cbb, CBS_ASN1_SEQUENCE));
  CBB oid_cbb;
  ABSL_CHECK(CBB_add_asn1(&attr_seq_cbb, &oid_cbb, CBS_ASN1_OBJECT));
  ABSL_CHECK(CBB_add_bytes(&oid_cbb, OBJ_get0_data(IdAaSigningCertificateV2()),
                           OBJ_length(IdAaSigningCertificateV2())));
  ABSL_CHECK(CBB_flush(&attr_seq_cbb));

  CBB value_set_cbb;
  ABSL_CHECK(CBB_add_asn1(&attr_seq_cbb, &value_set_cbb, CBS_ASN1_SET));
  CBB value_seq_cbb;
  ABSL_CHECK(CBB_add_asn1(&value_set_cbb, &value_seq_cbb, CBS_ASN1_SEQUENCE));
  CBB certs_cbb;
  ABSL_CHECK(CBB_add_asn1(&value_seq_cbb, &certs_cbb, CBS_ASN1_SEQUENCE));
  for (X509* x509 : certs) {
    uint8_t* der_ptr = nullptr;
    size_t der_len = i2d_X509(x509, &der_ptr);
    bssl::UniquePtr<uint8_t> der(der_ptr);

    CBS der_cbs;
    CBS_init(&der_cbs, der_ptr, der_len);
    auto hasher = CreateHasher(hash_algorithm);
    ABSL_CHECK_OK(hasher);
    (*hasher)->Update(ToStringView(der_cbs));
    std::string hash = (*hasher)->Digest();
    CBS hash_cbs = FromStringView(hash);

    CBB certs_entry_cbb;
    ABSL_CHECK(CBB_add_asn1(&certs_cbb, &certs_entry_cbb, CBS_ASN1_SEQUENCE));
    if (hash_algorithm != HashAlgorithm::kSha256) {
      ABSL_CHECK(
          OBJ_nid2cbb(&certs_entry_cbb, static_cast<int>(hash_algorithm)));
    }
    ABSL_CHECK(CBB_add_asn1_octet_string(&certs_entry_cbb, CBS_data(&hash_cbs),
                                         CBS_len(&hash_cbs)));
    ABSL_CHECK(CBB_flush(&certs_cbb));
  }

  auto result = FinishToString(&cbb);
  ABSL_CHECK_OK(result);
  return *result;
}

}  // namespace credentio
