// 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 "crypto/default/eku_verifier.h"

#include "absl/strings/string_view.h"
#include "openssl/asn1.h"
#include "openssl/base.h"
#include "openssl/bio.h"
#include "openssl/nid.h"
#include "openssl/obj.h"
#include "openssl/x509.h"

namespace credentio {
namespace {

constexpr absl::string_view kAnyEkuOid = "2.5.29.37.0";
// See
// https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_trust_lists.
constexpr absl::string_view kC2paClaimSigningEkuOid = "1.3.6.1.4.1.62558.2.1";
// The maximum number of EKU values that can be present in a certificate.
// We have this upper limit to prevent malicious certificates with arbitrarily
// large EKU lists to be processed by the check.
constexpr size_t kMaxEkuCount = 100;
// The bit index of the `digitalSignature` KU bit in the keyUsage bit string.
constexpr int kDigitalSignatureKeyUsageBit = 0;

}  // namespace

bool EkuVerifier::CheckLeafCertEku(absl::string_view leaf_cert_der) {
  const unsigned char* leaf_cert_der_bytes =
      reinterpret_cast<const unsigned char*>(leaf_cert_der.data());
  bssl::UniquePtr<BIO> bio(
      BIO_new_mem_buf(leaf_cert_der_bytes, leaf_cert_der.size()));
  if (bio == nullptr) {
    return false;
  }
  bssl::UniquePtr<X509> leaf_cert(d2i_X509_bio(bio.get(), /*x509=*/nullptr));
  if (leaf_cert == nullptr) {
    return false;
  }

  // Check that the certificate asserts the `digitalSignature` KU bit per
  // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_general_requirements.
  bssl::UniquePtr<ASN1_BIT_STRING> key_usage(static_cast<ASN1_BIT_STRING*>(
      X509_get_ext_d2i(leaf_cert.get(), NID_key_usage, /*out_critical=*/nullptr,
                       /*out_idx=*/nullptr)));
  if (key_usage == nullptr) {
    return false;
  }
  if (ASN1_BIT_STRING_get_bit(key_usage.get(), kDigitalSignatureKeyUsageBit) ==
      0) {
    return false;
  }

  int loc_eku =
      X509_get_ext_by_NID(leaf_cert.get(), NID_ext_key_usage, /*lastpos=*/-1);
  if (loc_eku < 0) {
    return false;
  }
  X509_EXTENSION* ext = X509_get_ext(leaf_cert.get(), loc_eku);
  if (!ext) {
    return false;
  }
  bssl::UniquePtr<EXTENDED_KEY_USAGE> eku(
      (EXTENDED_KEY_USAGE*)X509V3_EXT_d2i(ext));
  if (!eku) {
    return false;
  }
  bssl::UniquePtr<ASN1_OBJECT> target_oid(
      OBJ_txt2obj(kC2paClaimSigningEkuOid.data(), 0));
  if (!target_oid) {
    return false;
  }
  bssl::UniquePtr<ASN1_OBJECT> any_eku_oid(OBJ_txt2obj(kAnyEkuOid.data(), 0));
  if (!any_eku_oid) {
    return false;
  }
  bool found = false;
  bool any_eku_found = false;
  int num_usages = sk_ASN1_OBJECT_num(eku.get());
  if (num_usages > kMaxEkuCount) {
    return false;
  }
  for (int i = 0; i < num_usages; ++i) {
    ASN1_OBJECT* obj = sk_ASN1_OBJECT_value(eku.get(), i);
    if (!obj) {
      continue;
    }
    if (OBJ_cmp(obj, target_oid.get()) == 0) {
      // The C2PA claim signing EKU is present
      found = true;
    }
    if (OBJ_cmp(obj, any_eku_oid.get()) == 0) {
      // The `anyExtendedKeyUsage` EKU is present
      any_eku_found = true;
    }
  }
  return found && !any_eku_found;
}

}  // namespace credentio
