text: #ifndef SRC_CRYPTO_CRYPTO_X509_H_
  #define SRC_CRYPTO_CRYPTO_X509_H_
  
  #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
  
  #include "base_object.h"
  #include "crypto/crypto_util.h"
  #include "env.h"
  #include "memory_tracker.h"
  #include "node_worker.h"
  #include "v8.h"
  
  namespace node {
  namespace crypto {
  
  // The ManagedX509 class is essentially a smart pointer for
  // X509 objects that allows an X509Certificate instance to
  // be cloned at the JS level while pointing at the same
  // underlying X509 instance.
  class ManagedX509 : public MemoryRetainer {
   public:
    ManagedX509() = default;
    explicit ManagedX509(X509Pointer&& cert);
    ManagedX509(const ManagedX509& that);
    ManagedX509& operator=(const ManagedX509& that);
  
    operator bool() const { return !!cert_; }
    X509* get() const { return cert_.get(); }
  
    void MemoryInfo(MemoryTracker* tracker) const override;
    SET_MEMORY_INFO_NAME(ManagedX509)
    SET_SELF_SIZE(ManagedX509)
  
   private:
    X509Pointer cert_;
  };
  
  class X509Certificate : public BaseObject {
   public:
    enum class GetPeerCertificateFlag {
      NONE,
      SERVER
    };
  
    static void Initialize(Environment* env, v8::Local<v8::Object> target);
    static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
    static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
        Environment* env);
    static bool HasInstance(Environment* env, v8::Local<v8::Object> object);
  
    static v8::MaybeLocal<v8::Object> New(
        Environment* env,
        X509Pointer cert,
        STACK_OF(X509)* issuer_chain = nullptr);
  
    static v8::MaybeLocal<v8::Object> New(
        Environment* env,
        std::shared_ptr<ManagedX509> cert,
        STACK_OF(X509)* issuer_chain = nullptr);
  
    static v8::MaybeLocal<v8::Object> GetCert(
        Environment* env,
        const SSLPointer& ssl);
  
    static v8::MaybeLocal<v8::Object> GetPeerCert(
        Environment* env,
        const SSLPointer& ssl,
        GetPeerCertificateFlag flag);
  
    static v8::Local<v8::Object> Wrap(
        Environment* env,
        v8::Local<v8::Object> object,
        X509Pointer cert);
  
    static void Parse(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void Subject(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void SubjectAltName(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void Issuer(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void InfoAccess(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void ValidFrom(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void ValidTo(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void Fingerprint(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void Fingerprint256(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void KeyUsage(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void SerialNumber(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void Raw(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void PublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void Pem(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void CheckCA(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void CheckHost(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void CheckEmail(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void CheckIP(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void CheckIssued(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void CheckPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void Verify(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void ToLegacy(const v8::FunctionCallbackInfo<v8::Value>& args);
    static void GetIssuerCert(const v8::FunctionCallbackInfo<v8::Value>& args);
  
    X509* get() { return cert_->get(); }
  
    void MemoryInfo(MemoryTracker* tracker) const override;
    SET_MEMORY_INFO_NAME(X509Certificate)
    SET_SELF_SIZE(X509Certificate)
  
    class X509CertificateTransferData : public worker::TransferData {
     public:
      explicit X509CertificateTransferData(
          const std::shared_ptr<ManagedX509>& data)
          : data_(data) {}
  
      BaseObjectPtr<BaseObject> Deserialize(
          Environment* env,
          v8::Local<v8::Context> context,
          std::unique_ptr<worker::TransferData> self) override;
  
      SET_MEMORY_INFO_NAME(X509CertificateTransferData)
      SET_SELF_SIZE(X509CertificateTransferData)
      SET_NO_MEMORY_INFO()
  
     private:
      std::shared_ptr<ManagedX509> data_;
    };
  
    BaseObject::TransferMode GetTransferMode() const override;
    std::unique_ptr<worker::TransferData> CloneForMessaging() const override;
  
   private:
    X509Certificate(
        Environment* env,
        v8::Local<v8::Object> object,
        std::shared_ptr<ManagedX509> cert,
        STACK_OF(X509)* issuer_chain = nullptr);
  
    std::shared_ptr<ManagedX509> cert_;
    BaseObjectPtr<X509Certificate> issuer_cert_;
  };
  
  }  // namespace crypto
  }  // namespace node
  
  #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
  #endif  // SRC_CRYPTO_CRYPTO_X509_H_
  