Skip to content

Commit

Permalink
crypto: use cppgc to manage Hash
Browse files Browse the repository at this point in the history
  • Loading branch information
joyeecheung committed Aug 18, 2024
1 parent 8284613 commit 0067a0b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 17 deletions.
20 changes: 14 additions & 6 deletions src/crypto/crypto_hash.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "crypto/crypto_hash.h"
#include "async_wrap-inl.h"
#include "base_object-inl.h"
#include "cppgc/allocation.h"
#include "env-inl.h"
#include "memory_tracker-inl.h"
#include "string_bytes.h"
Expand All @@ -26,14 +27,20 @@ using v8::Object;
using v8::Uint32;
using v8::Value;

#ifdef ASSIGN_OR_RETURN_UNWRAP
#undef ASSIGN_OR_RETURN_UNWRAP
#endif

#define ASSIGN_OR_RETURN_UNWRAP ASSIGN_OR_RETURN_UNWRAP_CPPGC
namespace crypto {
Hash::Hash(Environment* env, Local<Object> wrap) : BaseObject(env, wrap) {
MakeWeak();
Hash::Hash(Environment* env, Local<Object> wrap) {
InitializeCppgc(this, env, wrap);
}

void Hash::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackFieldWithSize("mdctx", mdctx_ ? kSizeOf_EVP_MD_CTX : 0);
tracker->TrackFieldWithSize("md", digest_ ? md_len_ : 0);
void Hash::Trace(cppgc::Visitor* visitor) const {
CppgcMixin::Trace(visitor);
visitor->TraceExternal(&mdctx_);
visitor->TraceExternal(&digest_);
}

#if OPENSSL_VERSION_MAJOR >= 3
Expand Down Expand Up @@ -321,7 +328,8 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
xof_md_len = Just<unsigned int>(args[1].As<Uint32>()->Value());
}

Hash* hash = new Hash(env, args.This());
Hash* hash = cppgc::MakeGarbageCollected<Hash>(
env->isolate()->GetCppHeap()->GetAllocationHandle(), env, args.This());
if (md == nullptr || !hash->HashInit(md, xof_md_len)) {
return ThrowCryptoError(env, ERR_get_error(),
"Digest method not supported");
Expand Down
36 changes: 27 additions & 9 deletions src/crypto/crypto_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,41 @@

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include "base_object.h"
#include "cppgc_helpers.h"
#include "crypto/crypto_keys.h"
#include "crypto/crypto_util.h"
#include "env.h"
#include "memory_tracker.h"
#include "v8.h"
#include "cppgc/external.h"

namespace node {
namespace crypto {
class Hash final : public BaseObject {

class ExternalEVPCtx final : public cppgc::External {
public:
virtual size_t GetSize() const override {
return ptr_ ? kSizeOf_EVP_MD_CTX : 0;
}
virtual const char* GetHumanReadableName() const override { return "EVP_MD_CTX"; }
virtual void Trace(cppgc::Visitor* v) const override {}

EVP_MD_CTX* get() const { return ptr_.get(); }
void reset(EVP_MD_CTX* ptr = nullptr) { ptr_.reset(ptr); }
explicit operator bool() const { return !!ptr_; }

private:
EVPMDCtxPointer ptr_{};
};

class Hash final : public cppgc::GarbageCollected<Hash>,
public cppgc::NameProvider,
public CppgcMixin {
public:
static void Initialize(Environment* env, v8::Local<v8::Object> target);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);

void MemoryInfo(MemoryTracker* tracker) const override;
SET_MEMORY_INFO_NAME(Hash)
SET_SELF_SIZE(Hash)
const char* GetHumanReadableName() const final { return "Node / Hash"; }
void Trace(cppgc::Visitor* visitor) const final;

bool HashInit(const EVP_MD* md, v8::Maybe<unsigned int> xof_md_len);
bool HashUpdate(const char* data, size_t len);
Expand All @@ -28,15 +46,15 @@ class Hash final : public BaseObject {
static void GetCachedAliases(const v8::FunctionCallbackInfo<v8::Value>& args);
static void OneShotDigest(const v8::FunctionCallbackInfo<v8::Value>& args);

Hash(Environment* env, v8::Local<v8::Object> wrap);

protected:
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args);
static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args);

Hash(Environment* env, v8::Local<v8::Object> wrap);

private:
EVPMDCtxPointer mdctx_{};
ExternalEVPCtx mdctx_{};
unsigned int md_len_ = 0;
ByteSource digest_;
};
Expand Down
17 changes: 15 additions & 2 deletions src/crypto/crypto_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include "async_wrap.h"
#include "cppgc_helpers.h"
#include "env.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_internals.h"
#include "string_bytes.h"
#include "util.h"
#include "v8.h"
#include "cppgc/external.h"

#include "ncrypto.h"

Expand Down Expand Up @@ -101,7 +103,12 @@ void Decode(const v8::FunctionCallbackInfo<v8::Value>& args,
void (*callback)(T*, const v8::FunctionCallbackInfo<v8::Value>&,
const char*, size_t)) {
T* ctx;
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.This());
if constexpr (std::is_base_of_v<BaseObject, T>) {
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.This());
} else {
ctx = CppgcMixin::Unwrap<T>(args.This());
if (ctx == nullptr) return;
}

if (args[0]->IsString()) {
StringBytes::InlineDecoder decoder;
Expand Down Expand Up @@ -192,7 +199,7 @@ T* MallocOpenSSL(size_t count) {

// A helper class representing a read-only byte array. When deallocated, its
// contents are zeroed.
class ByteSource {
class ByteSource : public cppgc::External {
public:
class Builder {
public:
Expand Down Expand Up @@ -307,6 +314,12 @@ class ByteSource {
static ByteSource FromSecretKeyBytes(
Environment* env, v8::Local<v8::Value> value);

virtual size_t GetSize() const {
return size_;
}
virtual const char* GetHumanReadableName() const { return "Node / ByteSource"; }
virtual void Trace(cppgc::Visitor* v) const {}

private:
const void* data_ = nullptr;
void* allocated_data_ = nullptr;
Expand Down

0 comments on commit 0067a0b

Please sign in to comment.