11cb0ef41Sopenharmony_ci#include "base_object-inl.h"
21cb0ef41Sopenharmony_ci#include "crypto_x509.h"
31cb0ef41Sopenharmony_ci#include "crypto_common.h"
41cb0ef41Sopenharmony_ci#include "crypto_context.h"
51cb0ef41Sopenharmony_ci#include "crypto_keys.h"
61cb0ef41Sopenharmony_ci#include "crypto_bio.h"
71cb0ef41Sopenharmony_ci#include "env-inl.h"
81cb0ef41Sopenharmony_ci#include "memory_tracker-inl.h"
91cb0ef41Sopenharmony_ci#include "node_errors.h"
101cb0ef41Sopenharmony_ci#include "util-inl.h"
111cb0ef41Sopenharmony_ci#include "v8.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci#include <string>
141cb0ef41Sopenharmony_ci#include <vector>
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cinamespace node {
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciusing v8::ArrayBufferView;
191cb0ef41Sopenharmony_ciusing v8::Context;
201cb0ef41Sopenharmony_ciusing v8::EscapableHandleScope;
211cb0ef41Sopenharmony_ciusing v8::Function;
221cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo;
231cb0ef41Sopenharmony_ciusing v8::FunctionTemplate;
241cb0ef41Sopenharmony_ciusing v8::Isolate;
251cb0ef41Sopenharmony_ciusing v8::Local;
261cb0ef41Sopenharmony_ciusing v8::MaybeLocal;
271cb0ef41Sopenharmony_ciusing v8::Object;
281cb0ef41Sopenharmony_ciusing v8::Uint32;
291cb0ef41Sopenharmony_ciusing v8::Value;
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_cinamespace crypto {
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ciManagedX509::ManagedX509(X509Pointer&& cert) : cert_(std::move(cert)) {}
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ciManagedX509::ManagedX509(const ManagedX509& that) {
361cb0ef41Sopenharmony_ci  *this = that;
371cb0ef41Sopenharmony_ci}
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ciManagedX509& ManagedX509::operator=(const ManagedX509& that) {
401cb0ef41Sopenharmony_ci  cert_.reset(that.get());
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  if (cert_)
431cb0ef41Sopenharmony_ci    X509_up_ref(cert_.get());
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  return *this;
461cb0ef41Sopenharmony_ci}
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_civoid ManagedX509::MemoryInfo(MemoryTracker* tracker) const {
491cb0ef41Sopenharmony_ci  // This is an approximation based on the der encoding size.
501cb0ef41Sopenharmony_ci  int size = i2d_X509(cert_.get(), nullptr);
511cb0ef41Sopenharmony_ci  tracker->TrackFieldWithSize("cert", size);
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_cinamespace {
551cb0ef41Sopenharmony_citemplate <const EVP_MD* (*algo)()>
561cb0ef41Sopenharmony_civoid Fingerprint(const FunctionCallbackInfo<Value>& args) {
571cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
581cb0ef41Sopenharmony_ci  X509Certificate* cert;
591cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
601cb0ef41Sopenharmony_ci  Local<Value> ret;
611cb0ef41Sopenharmony_ci  if (GetFingerprintDigest(env, algo(), cert->get()).ToLocal(&ret))
621cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(ret);
631cb0ef41Sopenharmony_ci}
641cb0ef41Sopenharmony_ci}  // namespace
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ciLocal<FunctionTemplate> X509Certificate::GetConstructorTemplate(
671cb0ef41Sopenharmony_ci    Environment* env) {
681cb0ef41Sopenharmony_ci  Local<FunctionTemplate> tmpl = env->x509_constructor_template();
691cb0ef41Sopenharmony_ci  if (tmpl.IsEmpty()) {
701cb0ef41Sopenharmony_ci    Isolate* isolate = env->isolate();
711cb0ef41Sopenharmony_ci    tmpl = NewFunctionTemplate(isolate, nullptr);
721cb0ef41Sopenharmony_ci    tmpl->InstanceTemplate()->SetInternalFieldCount(
731cb0ef41Sopenharmony_ci        BaseObject::kInternalFieldCount);
741cb0ef41Sopenharmony_ci    tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
751cb0ef41Sopenharmony_ci    tmpl->SetClassName(
761cb0ef41Sopenharmony_ci        FIXED_ONE_BYTE_STRING(env->isolate(), "X509Certificate"));
771cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "subject", Subject);
781cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "subjectAltName", SubjectAltName);
791cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "infoAccess", InfoAccess);
801cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "issuer", Issuer);
811cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "validTo", ValidTo);
821cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "validFrom", ValidFrom);
831cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "fingerprint", Fingerprint<EVP_sha1>);
841cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "fingerprint256", Fingerprint<EVP_sha256>);
851cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "fingerprint512", Fingerprint<EVP_sha512>);
861cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "keyUsage", KeyUsage);
871cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "serialNumber", SerialNumber);
881cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "pem", Pem);
891cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "raw", Raw);
901cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "publicKey", PublicKey);
911cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "checkCA", CheckCA);
921cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "checkHost", CheckHost);
931cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "checkEmail", CheckEmail);
941cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "checkIP", CheckIP);
951cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "checkIssued", CheckIssued);
961cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "checkPrivateKey", CheckPrivateKey);
971cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "verify", Verify);
981cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "toLegacy", ToLegacy);
991cb0ef41Sopenharmony_ci    SetProtoMethod(isolate, tmpl, "getIssuerCert", GetIssuerCert);
1001cb0ef41Sopenharmony_ci    env->set_x509_constructor_template(tmpl);
1011cb0ef41Sopenharmony_ci  }
1021cb0ef41Sopenharmony_ci  return tmpl;
1031cb0ef41Sopenharmony_ci}
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_cibool X509Certificate::HasInstance(Environment* env, Local<Object> object) {
1061cb0ef41Sopenharmony_ci  return GetConstructorTemplate(env)->HasInstance(object);
1071cb0ef41Sopenharmony_ci}
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ciMaybeLocal<Object> X509Certificate::New(
1101cb0ef41Sopenharmony_ci    Environment* env,
1111cb0ef41Sopenharmony_ci    X509Pointer cert,
1121cb0ef41Sopenharmony_ci    STACK_OF(X509)* issuer_chain) {
1131cb0ef41Sopenharmony_ci  std::shared_ptr<ManagedX509> mcert(new ManagedX509(std::move(cert)));
1141cb0ef41Sopenharmony_ci  return New(env, std::move(mcert), issuer_chain);
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ciMaybeLocal<Object> X509Certificate::New(
1181cb0ef41Sopenharmony_ci    Environment* env,
1191cb0ef41Sopenharmony_ci    std::shared_ptr<ManagedX509> cert,
1201cb0ef41Sopenharmony_ci    STACK_OF(X509)* issuer_chain) {
1211cb0ef41Sopenharmony_ci  EscapableHandleScope scope(env->isolate());
1221cb0ef41Sopenharmony_ci  Local<Function> ctor;
1231cb0ef41Sopenharmony_ci  if (!GetConstructorTemplate(env)->GetFunction(env->context()).ToLocal(&ctor))
1241cb0ef41Sopenharmony_ci    return MaybeLocal<Object>();
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  Local<Object> obj;
1271cb0ef41Sopenharmony_ci  if (!ctor->NewInstance(env->context()).ToLocal(&obj))
1281cb0ef41Sopenharmony_ci    return MaybeLocal<Object>();
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  new X509Certificate(env, obj, std::move(cert), issuer_chain);
1311cb0ef41Sopenharmony_ci  return scope.Escape(obj);
1321cb0ef41Sopenharmony_ci}
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ciMaybeLocal<Object> X509Certificate::GetCert(
1351cb0ef41Sopenharmony_ci    Environment* env,
1361cb0ef41Sopenharmony_ci    const SSLPointer& ssl) {
1371cb0ef41Sopenharmony_ci  ClearErrorOnReturn clear_error_on_return;
1381cb0ef41Sopenharmony_ci  X509* cert = SSL_get_certificate(ssl.get());
1391cb0ef41Sopenharmony_ci  if (cert == nullptr)
1401cb0ef41Sopenharmony_ci    return MaybeLocal<Object>();
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  X509Pointer ptr(X509_dup(cert));
1431cb0ef41Sopenharmony_ci  return New(env, std::move(ptr));
1441cb0ef41Sopenharmony_ci}
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ciMaybeLocal<Object> X509Certificate::GetPeerCert(
1471cb0ef41Sopenharmony_ci    Environment* env,
1481cb0ef41Sopenharmony_ci    const SSLPointer& ssl,
1491cb0ef41Sopenharmony_ci    GetPeerCertificateFlag flag) {
1501cb0ef41Sopenharmony_ci  ClearErrorOnReturn clear_error_on_return;
1511cb0ef41Sopenharmony_ci  MaybeLocal<Object> maybe_cert;
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  bool is_server =
1541cb0ef41Sopenharmony_ci      static_cast<int>(flag) & static_cast<int>(GetPeerCertificateFlag::SERVER);
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci  X509Pointer cert(is_server ? SSL_get_peer_certificate(ssl.get()) : nullptr);
1571cb0ef41Sopenharmony_ci  STACK_OF(X509)* ssl_certs = SSL_get_peer_cert_chain(ssl.get());
1581cb0ef41Sopenharmony_ci  if (!cert && (ssl_certs == nullptr || sk_X509_num(ssl_certs) == 0))
1591cb0ef41Sopenharmony_ci    return MaybeLocal<Object>();
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci  std::vector<Local<Value>> certs;
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci  if (!cert) {
1641cb0ef41Sopenharmony_ci    cert.reset(sk_X509_value(ssl_certs, 0));
1651cb0ef41Sopenharmony_ci    sk_X509_delete(ssl_certs, 0);
1661cb0ef41Sopenharmony_ci  }
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  return sk_X509_num(ssl_certs)
1691cb0ef41Sopenharmony_ci      ? New(env, std::move(cert), ssl_certs)
1701cb0ef41Sopenharmony_ci      : New(env, std::move(cert));
1711cb0ef41Sopenharmony_ci}
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_civoid X509Certificate::Parse(const FunctionCallbackInfo<Value>& args) {
1741cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci  CHECK(args[0]->IsArrayBufferView());
1771cb0ef41Sopenharmony_ci  ArrayBufferViewContents<unsigned char> buf(args[0].As<ArrayBufferView>());
1781cb0ef41Sopenharmony_ci  const unsigned char* data = buf.data();
1791cb0ef41Sopenharmony_ci  unsigned data_len = buf.length();
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci  ClearErrorOnReturn clear_error_on_return;
1821cb0ef41Sopenharmony_ci  BIOPointer bio(LoadBIO(env, args[0]));
1831cb0ef41Sopenharmony_ci  if (!bio)
1841cb0ef41Sopenharmony_ci    return ThrowCryptoError(env, ERR_get_error());
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ci  Local<Object> cert;
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci  X509Pointer pem(PEM_read_bio_X509_AUX(
1891cb0ef41Sopenharmony_ci      bio.get(), nullptr, NoPasswordCallback, nullptr));
1901cb0ef41Sopenharmony_ci  if (!pem) {
1911cb0ef41Sopenharmony_ci    // Try as DER, but return the original PEM failure if it isn't DER.
1921cb0ef41Sopenharmony_ci    MarkPopErrorOnReturn mark_here;
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ci    X509Pointer der(d2i_X509(nullptr, &data, data_len));
1951cb0ef41Sopenharmony_ci    if (!der)
1961cb0ef41Sopenharmony_ci      return ThrowCryptoError(env, ERR_get_error());
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci    if (!X509Certificate::New(env, std::move(der)).ToLocal(&cert))
1991cb0ef41Sopenharmony_ci      return;
2001cb0ef41Sopenharmony_ci  } else if (!X509Certificate::New(env, std::move(pem)).ToLocal(&cert)) {
2011cb0ef41Sopenharmony_ci    return;
2021cb0ef41Sopenharmony_ci  }
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(cert);
2051cb0ef41Sopenharmony_ci}
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_citemplate <MaybeLocal<Value> Property(
2081cb0ef41Sopenharmony_ci    Environment* env, X509* cert, const BIOPointer& bio)>
2091cb0ef41Sopenharmony_cistatic void ReturnPropertyThroughBIO(const FunctionCallbackInfo<Value>& args) {
2101cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2111cb0ef41Sopenharmony_ci  X509Certificate* cert;
2121cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
2131cb0ef41Sopenharmony_ci  BIOPointer bio(BIO_new(BIO_s_mem()));
2141cb0ef41Sopenharmony_ci  CHECK(bio);
2151cb0ef41Sopenharmony_ci  Local<Value> ret;
2161cb0ef41Sopenharmony_ci  if (Property(env, cert->get(), bio).ToLocal(&ret))
2171cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(ret);
2181cb0ef41Sopenharmony_ci}
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_civoid X509Certificate::Subject(const FunctionCallbackInfo<Value>& args) {
2211cb0ef41Sopenharmony_ci  ReturnPropertyThroughBIO<GetSubject>(args);
2221cb0ef41Sopenharmony_ci}
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_civoid X509Certificate::Issuer(const FunctionCallbackInfo<Value>& args) {
2251cb0ef41Sopenharmony_ci  ReturnPropertyThroughBIO<GetIssuerString>(args);
2261cb0ef41Sopenharmony_ci}
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_civoid X509Certificate::SubjectAltName(const FunctionCallbackInfo<Value>& args) {
2291cb0ef41Sopenharmony_ci  ReturnPropertyThroughBIO<GetSubjectAltNameString>(args);
2301cb0ef41Sopenharmony_ci}
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_civoid X509Certificate::InfoAccess(const FunctionCallbackInfo<Value>& args) {
2331cb0ef41Sopenharmony_ci  ReturnPropertyThroughBIO<GetInfoAccessString>(args);
2341cb0ef41Sopenharmony_ci}
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_civoid X509Certificate::ValidFrom(const FunctionCallbackInfo<Value>& args) {
2371cb0ef41Sopenharmony_ci  ReturnPropertyThroughBIO<GetValidFrom>(args);
2381cb0ef41Sopenharmony_ci}
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_civoid X509Certificate::ValidTo(const FunctionCallbackInfo<Value>& args) {
2411cb0ef41Sopenharmony_ci  ReturnPropertyThroughBIO<GetValidTo>(args);
2421cb0ef41Sopenharmony_ci}
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_citemplate <MaybeLocal<Value> Property(Environment* env, X509* cert)>
2451cb0ef41Sopenharmony_cistatic void ReturnProperty(const FunctionCallbackInfo<Value>& args) {
2461cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2471cb0ef41Sopenharmony_ci  X509Certificate* cert;
2481cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
2491cb0ef41Sopenharmony_ci  Local<Value> ret;
2501cb0ef41Sopenharmony_ci  if (Property(env, cert->get()).ToLocal(&ret)) args.GetReturnValue().Set(ret);
2511cb0ef41Sopenharmony_ci}
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_civoid X509Certificate::KeyUsage(const FunctionCallbackInfo<Value>& args) {
2541cb0ef41Sopenharmony_ci  ReturnProperty<GetKeyUsage>(args);
2551cb0ef41Sopenharmony_ci}
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_civoid X509Certificate::SerialNumber(const FunctionCallbackInfo<Value>& args) {
2581cb0ef41Sopenharmony_ci  ReturnProperty<GetSerialNumber>(args);
2591cb0ef41Sopenharmony_ci}
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_civoid X509Certificate::Raw(const FunctionCallbackInfo<Value>& args) {
2621cb0ef41Sopenharmony_ci  ReturnProperty<GetRawDERCertificate>(args);
2631cb0ef41Sopenharmony_ci}
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_civoid X509Certificate::PublicKey(const FunctionCallbackInfo<Value>& args) {
2661cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2671cb0ef41Sopenharmony_ci  X509Certificate* cert;
2681cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  // TODO(tniessen): consider checking X509_get_pubkey() when the
2711cb0ef41Sopenharmony_ci  // X509Certificate object is being created.
2721cb0ef41Sopenharmony_ci  ClearErrorOnReturn clear_error_on_return;
2731cb0ef41Sopenharmony_ci  EVPKeyPointer pkey(X509_get_pubkey(cert->get()));
2741cb0ef41Sopenharmony_ci  if (!pkey) return ThrowCryptoError(env, ERR_get_error());
2751cb0ef41Sopenharmony_ci  ManagedEVPPKey epkey(std::move(pkey));
2761cb0ef41Sopenharmony_ci  std::shared_ptr<KeyObjectData> key_data =
2771cb0ef41Sopenharmony_ci      KeyObjectData::CreateAsymmetric(kKeyTypePublic, epkey);
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  Local<Value> ret;
2801cb0ef41Sopenharmony_ci  if (KeyObjectHandle::Create(env, key_data).ToLocal(&ret))
2811cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(ret);
2821cb0ef41Sopenharmony_ci}
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_civoid X509Certificate::Pem(const FunctionCallbackInfo<Value>& args) {
2851cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2861cb0ef41Sopenharmony_ci  X509Certificate* cert;
2871cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
2881cb0ef41Sopenharmony_ci  BIOPointer bio(BIO_new(BIO_s_mem()));
2891cb0ef41Sopenharmony_ci  CHECK(bio);
2901cb0ef41Sopenharmony_ci  if (PEM_write_bio_X509(bio.get(), cert->get()))
2911cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(ToV8Value(env, bio));
2921cb0ef41Sopenharmony_ci}
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_civoid X509Certificate::CheckCA(const FunctionCallbackInfo<Value>& args) {
2951cb0ef41Sopenharmony_ci  X509Certificate* cert;
2961cb0ef41Sopenharmony_ci  ClearErrorOnReturn clear_error_on_return;
2971cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
2981cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(X509_check_ca(cert->get()) == 1);
2991cb0ef41Sopenharmony_ci}
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_civoid X509Certificate::CheckHost(const FunctionCallbackInfo<Value>& args) {
3021cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
3031cb0ef41Sopenharmony_ci  X509Certificate* cert;
3041cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci  CHECK(args[0]->IsString());  // name
3071cb0ef41Sopenharmony_ci  CHECK(args[1]->IsUint32());  // flags
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ci  Utf8Value name(env->isolate(), args[0]);
3101cb0ef41Sopenharmony_ci  uint32_t flags = args[1].As<Uint32>()->Value();
3111cb0ef41Sopenharmony_ci  char* peername;
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci  switch (X509_check_host(
3141cb0ef41Sopenharmony_ci              cert->get(),
3151cb0ef41Sopenharmony_ci              *name,
3161cb0ef41Sopenharmony_ci              name.length(),
3171cb0ef41Sopenharmony_ci              flags,
3181cb0ef41Sopenharmony_ci              &peername)) {
3191cb0ef41Sopenharmony_ci    case 1:  {  // Match!
3201cb0ef41Sopenharmony_ci      Local<Value> ret = args[0];
3211cb0ef41Sopenharmony_ci      if (peername != nullptr) {
3221cb0ef41Sopenharmony_ci        ret = OneByteString(env->isolate(), peername);
3231cb0ef41Sopenharmony_ci        OPENSSL_free(peername);
3241cb0ef41Sopenharmony_ci      }
3251cb0ef41Sopenharmony_ci      return args.GetReturnValue().Set(ret);
3261cb0ef41Sopenharmony_ci    }
3271cb0ef41Sopenharmony_ci    case 0:  // No Match!
3281cb0ef41Sopenharmony_ci      return;  // No return value is set
3291cb0ef41Sopenharmony_ci    case -2:  // Error!
3301cb0ef41Sopenharmony_ci      return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name");
3311cb0ef41Sopenharmony_ci    default:  // Error!
3321cb0ef41Sopenharmony_ci      return THROW_ERR_CRYPTO_OPERATION_FAILED(env);
3331cb0ef41Sopenharmony_ci  }
3341cb0ef41Sopenharmony_ci}
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_civoid X509Certificate::CheckEmail(const FunctionCallbackInfo<Value>& args) {
3371cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
3381cb0ef41Sopenharmony_ci  X509Certificate* cert;
3391cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
3401cb0ef41Sopenharmony_ci
3411cb0ef41Sopenharmony_ci  CHECK(args[0]->IsString());  // name
3421cb0ef41Sopenharmony_ci  CHECK(args[1]->IsUint32());  // flags
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ci  Utf8Value name(env->isolate(), args[0]);
3451cb0ef41Sopenharmony_ci  uint32_t flags = args[1].As<Uint32>()->Value();
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci  switch (X509_check_email(
3481cb0ef41Sopenharmony_ci              cert->get(),
3491cb0ef41Sopenharmony_ci              *name,
3501cb0ef41Sopenharmony_ci              name.length(),
3511cb0ef41Sopenharmony_ci              flags)) {
3521cb0ef41Sopenharmony_ci    case 1:  // Match!
3531cb0ef41Sopenharmony_ci      return args.GetReturnValue().Set(args[0]);
3541cb0ef41Sopenharmony_ci    case 0:  // No Match!
3551cb0ef41Sopenharmony_ci      return;  // No return value is set
3561cb0ef41Sopenharmony_ci    case -2:  // Error!
3571cb0ef41Sopenharmony_ci      return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid name");
3581cb0ef41Sopenharmony_ci    default:  // Error!
3591cb0ef41Sopenharmony_ci      return THROW_ERR_CRYPTO_OPERATION_FAILED(env);
3601cb0ef41Sopenharmony_ci  }
3611cb0ef41Sopenharmony_ci}
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_civoid X509Certificate::CheckIP(const FunctionCallbackInfo<Value>& args) {
3641cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
3651cb0ef41Sopenharmony_ci  X509Certificate* cert;
3661cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci  CHECK(args[0]->IsString());  // IP
3691cb0ef41Sopenharmony_ci  CHECK(args[1]->IsUint32());  // flags
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  Utf8Value name(env->isolate(), args[0]);
3721cb0ef41Sopenharmony_ci  uint32_t flags = args[1].As<Uint32>()->Value();
3731cb0ef41Sopenharmony_ci
3741cb0ef41Sopenharmony_ci  switch (X509_check_ip_asc(cert->get(), *name, flags)) {
3751cb0ef41Sopenharmony_ci    case 1:  // Match!
3761cb0ef41Sopenharmony_ci      return args.GetReturnValue().Set(args[0]);
3771cb0ef41Sopenharmony_ci    case 0:  // No Match!
3781cb0ef41Sopenharmony_ci      return;  // No return value is set
3791cb0ef41Sopenharmony_ci    case -2:  // Error!
3801cb0ef41Sopenharmony_ci      return THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP");
3811cb0ef41Sopenharmony_ci    default:  // Error!
3821cb0ef41Sopenharmony_ci      return THROW_ERR_CRYPTO_OPERATION_FAILED(env);
3831cb0ef41Sopenharmony_ci  }
3841cb0ef41Sopenharmony_ci}
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_civoid X509Certificate::CheckIssued(const FunctionCallbackInfo<Value>& args) {
3871cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
3881cb0ef41Sopenharmony_ci  X509Certificate* cert;
3891cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci  CHECK(args[0]->IsObject());
3921cb0ef41Sopenharmony_ci  CHECK(X509Certificate::HasInstance(env, args[0].As<Object>()));
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ci  X509Certificate* issuer;
3951cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&issuer, args[0]);
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_ci  ClearErrorOnReturn clear_error_on_return;
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(
4001cb0ef41Sopenharmony_ci    X509_check_issued(issuer->get(), cert->get()) == X509_V_OK);
4011cb0ef41Sopenharmony_ci}
4021cb0ef41Sopenharmony_ci
4031cb0ef41Sopenharmony_civoid X509Certificate::CheckPrivateKey(const FunctionCallbackInfo<Value>& args) {
4041cb0ef41Sopenharmony_ci  X509Certificate* cert;
4051cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
4061cb0ef41Sopenharmony_ci
4071cb0ef41Sopenharmony_ci  CHECK(args[0]->IsObject());
4081cb0ef41Sopenharmony_ci  KeyObjectHandle* key;
4091cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&key, args[0]);
4101cb0ef41Sopenharmony_ci  CHECK_EQ(key->Data()->GetKeyType(), kKeyTypePrivate);
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci  ClearErrorOnReturn clear_error_on_return;
4131cb0ef41Sopenharmony_ci
4141cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(
4151cb0ef41Sopenharmony_ci      X509_check_private_key(
4161cb0ef41Sopenharmony_ci          cert->get(),
4171cb0ef41Sopenharmony_ci          key->Data()->GetAsymmetricKey().get()) == 1);
4181cb0ef41Sopenharmony_ci}
4191cb0ef41Sopenharmony_ci
4201cb0ef41Sopenharmony_civoid X509Certificate::Verify(const FunctionCallbackInfo<Value>& args) {
4211cb0ef41Sopenharmony_ci  X509Certificate* cert;
4221cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci  CHECK(args[0]->IsObject());
4251cb0ef41Sopenharmony_ci  KeyObjectHandle* key;
4261cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&key, args[0]);
4271cb0ef41Sopenharmony_ci  CHECK_EQ(key->Data()->GetKeyType(), kKeyTypePublic);
4281cb0ef41Sopenharmony_ci
4291cb0ef41Sopenharmony_ci  ClearErrorOnReturn clear_error_on_return;
4301cb0ef41Sopenharmony_ci
4311cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(
4321cb0ef41Sopenharmony_ci      X509_verify(
4331cb0ef41Sopenharmony_ci          cert->get(),
4341cb0ef41Sopenharmony_ci          key->Data()->GetAsymmetricKey().get()) > 0);
4351cb0ef41Sopenharmony_ci}
4361cb0ef41Sopenharmony_ci
4371cb0ef41Sopenharmony_civoid X509Certificate::ToLegacy(const FunctionCallbackInfo<Value>& args) {
4381cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
4391cb0ef41Sopenharmony_ci  X509Certificate* cert;
4401cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
4411cb0ef41Sopenharmony_ci  ClearErrorOnReturn clear_error_on_return;
4421cb0ef41Sopenharmony_ci  Local<Value> ret;
4431cb0ef41Sopenharmony_ci  if (X509ToObject(env, cert->get()).ToLocal(&ret))
4441cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(ret);
4451cb0ef41Sopenharmony_ci}
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_civoid X509Certificate::GetIssuerCert(const FunctionCallbackInfo<Value>& args) {
4481cb0ef41Sopenharmony_ci  X509Certificate* cert;
4491cb0ef41Sopenharmony_ci  ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder());
4501cb0ef41Sopenharmony_ci  if (cert->issuer_cert_)
4511cb0ef41Sopenharmony_ci    args.GetReturnValue().Set(cert->issuer_cert_->object());
4521cb0ef41Sopenharmony_ci}
4531cb0ef41Sopenharmony_ci
4541cb0ef41Sopenharmony_ciX509Certificate::X509Certificate(
4551cb0ef41Sopenharmony_ci    Environment* env,
4561cb0ef41Sopenharmony_ci    Local<Object> object,
4571cb0ef41Sopenharmony_ci    std::shared_ptr<ManagedX509> cert,
4581cb0ef41Sopenharmony_ci    STACK_OF(X509)* issuer_chain)
4591cb0ef41Sopenharmony_ci    : BaseObject(env, object),
4601cb0ef41Sopenharmony_ci      cert_(std::move(cert)) {
4611cb0ef41Sopenharmony_ci  MakeWeak();
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_ci  if (issuer_chain != nullptr && sk_X509_num(issuer_chain)) {
4641cb0ef41Sopenharmony_ci    X509Pointer cert(X509_dup(sk_X509_value(issuer_chain, 0)));
4651cb0ef41Sopenharmony_ci    sk_X509_delete(issuer_chain, 0);
4661cb0ef41Sopenharmony_ci    Local<Object> obj = sk_X509_num(issuer_chain)
4671cb0ef41Sopenharmony_ci        ? X509Certificate::New(env, std::move(cert), issuer_chain)
4681cb0ef41Sopenharmony_ci            .ToLocalChecked()
4691cb0ef41Sopenharmony_ci        : X509Certificate::New(env, std::move(cert))
4701cb0ef41Sopenharmony_ci            .ToLocalChecked();
4711cb0ef41Sopenharmony_ci    issuer_cert_.reset(Unwrap<X509Certificate>(obj));
4721cb0ef41Sopenharmony_ci  }
4731cb0ef41Sopenharmony_ci}
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_civoid X509Certificate::MemoryInfo(MemoryTracker* tracker) const {
4761cb0ef41Sopenharmony_ci  tracker->TrackField("cert", cert_);
4771cb0ef41Sopenharmony_ci}
4781cb0ef41Sopenharmony_ci
4791cb0ef41Sopenharmony_ciBaseObjectPtr<BaseObject>
4801cb0ef41Sopenharmony_ciX509Certificate::X509CertificateTransferData::Deserialize(
4811cb0ef41Sopenharmony_ci    Environment* env,
4821cb0ef41Sopenharmony_ci    Local<Context> context,
4831cb0ef41Sopenharmony_ci    std::unique_ptr<worker::TransferData> self) {
4841cb0ef41Sopenharmony_ci  if (context != env->context()) {
4851cb0ef41Sopenharmony_ci    THROW_ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE(env);
4861cb0ef41Sopenharmony_ci    return {};
4871cb0ef41Sopenharmony_ci  }
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  Local<Value> handle;
4901cb0ef41Sopenharmony_ci  if (!X509Certificate::New(env, data_).ToLocal(&handle))
4911cb0ef41Sopenharmony_ci    return {};
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci  return BaseObjectPtr<BaseObject>(
4941cb0ef41Sopenharmony_ci      Unwrap<X509Certificate>(handle.As<Object>()));
4951cb0ef41Sopenharmony_ci}
4961cb0ef41Sopenharmony_ci
4971cb0ef41Sopenharmony_ci
4981cb0ef41Sopenharmony_ciBaseObject::TransferMode X509Certificate::GetTransferMode() const {
4991cb0ef41Sopenharmony_ci  return BaseObject::TransferMode::kCloneable;
5001cb0ef41Sopenharmony_ci}
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_cistd::unique_ptr<worker::TransferData> X509Certificate::CloneForMessaging()
5031cb0ef41Sopenharmony_ci    const {
5041cb0ef41Sopenharmony_ci  return std::make_unique<X509CertificateTransferData>(cert_);
5051cb0ef41Sopenharmony_ci}
5061cb0ef41Sopenharmony_ci
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_civoid X509Certificate::Initialize(Environment* env, Local<Object> target) {
5091cb0ef41Sopenharmony_ci  SetMethod(env->context(), target, "parseX509", X509Certificate::Parse);
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT);
5121cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NEVER_CHECK_SUBJECT);
5131cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NO_WILDCARDS);
5141cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
5151cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS);
5161cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(target, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS);
5171cb0ef41Sopenharmony_ci}
5181cb0ef41Sopenharmony_ci
5191cb0ef41Sopenharmony_civoid X509Certificate::RegisterExternalReferences(
5201cb0ef41Sopenharmony_ci    ExternalReferenceRegistry* registry) {
5211cb0ef41Sopenharmony_ci  registry->Register(X509Certificate::Parse);
5221cb0ef41Sopenharmony_ci  registry->Register(Subject);
5231cb0ef41Sopenharmony_ci  registry->Register(SubjectAltName);
5241cb0ef41Sopenharmony_ci  registry->Register(InfoAccess);
5251cb0ef41Sopenharmony_ci  registry->Register(Issuer);
5261cb0ef41Sopenharmony_ci  registry->Register(ValidTo);
5271cb0ef41Sopenharmony_ci  registry->Register(ValidFrom);
5281cb0ef41Sopenharmony_ci  registry->Register(Fingerprint<EVP_sha1>);
5291cb0ef41Sopenharmony_ci  registry->Register(Fingerprint<EVP_sha256>);
5301cb0ef41Sopenharmony_ci  registry->Register(Fingerprint<EVP_sha512>);
5311cb0ef41Sopenharmony_ci  registry->Register(KeyUsage);
5321cb0ef41Sopenharmony_ci  registry->Register(SerialNumber);
5331cb0ef41Sopenharmony_ci  registry->Register(Pem);
5341cb0ef41Sopenharmony_ci  registry->Register(Raw);
5351cb0ef41Sopenharmony_ci  registry->Register(PublicKey);
5361cb0ef41Sopenharmony_ci  registry->Register(CheckCA);
5371cb0ef41Sopenharmony_ci  registry->Register(CheckHost);
5381cb0ef41Sopenharmony_ci  registry->Register(CheckEmail);
5391cb0ef41Sopenharmony_ci  registry->Register(CheckIP);
5401cb0ef41Sopenharmony_ci  registry->Register(CheckIssued);
5411cb0ef41Sopenharmony_ci  registry->Register(CheckPrivateKey);
5421cb0ef41Sopenharmony_ci  registry->Register(Verify);
5431cb0ef41Sopenharmony_ci  registry->Register(ToLegacy);
5441cb0ef41Sopenharmony_ci  registry->Register(GetIssuerCert);
5451cb0ef41Sopenharmony_ci}
5461cb0ef41Sopenharmony_ci}  // namespace crypto
5471cb0ef41Sopenharmony_ci}  // namespace node
548