Skip to content

Commit 74cba08

Browse files
committed
fixup! src,crypto: add NativeCryptoKey
Signed-off-by: Filip Skokan <[email protected]>
1 parent e11737b commit 74cba08

3 files changed

Lines changed: 43 additions & 44 deletions

File tree

src/crypto/crypto_keys.cc

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,25 +1805,16 @@ void NativeCryptoKey::RegisterExternalReferences(
18051805
}
18061806

18071807
namespace {
1808-
// Brand check: every NativeCryptoKey stores this pointer in its
1809-
// kClassTagField slot. Nothing else in the binary can produce the
1810-
// same pointer, so HasInstance() can use it to recognize a real
1811-
// NativeCryptoKey.
1812-
constexpr int kNativeCryptoKeyClassTag = 0;
1813-
const void* class_tag() {
1814-
return &kNativeCryptoKeyClassTag;
1808+
// Verifies that `value` is a `NativeCryptoKey` by checking whether it
1809+
// was constructed from the Environment's `NativeCryptoKey` template.
1810+
bool IsNativeCryptoKey(Environment* env, Local<Value> value) {
1811+
auto t = env->crypto_cryptokey_constructor_template();
1812+
return !t.IsEmpty() && t->HasInstance(value);
18151813
}
18161814
} // namespace
18171815

1818-
bool NativeCryptoKey::HasInstance(Local<Value> value) {
1819-
if (!value->IsObject()) return false;
1820-
Local<Object> obj = value.As<Object>();
1821-
if (obj->InternalFieldCount() < NativeCryptoKey::kInternalFieldCount) {
1822-
return false;
1823-
}
1824-
return obj->GetAlignedPointerFromInternalField(
1825-
NativeCryptoKey::kClassTagField, EmbedderDataTag::kDefault) ==
1826-
class_tag();
1816+
bool NativeCryptoKey::HasInstance(Environment* env, Local<Value> value) {
1817+
return IsNativeCryptoKey(env, value);
18271818
}
18281819

18291820
void NativeCryptoKey::New(const FunctionCallbackInfo<Value>& args) {
@@ -1848,17 +1839,12 @@ void NativeCryptoKey::New(const FunctionCallbackInfo<Value>& args) {
18481839

18491840
auto* native = new NativeCryptoKey(env, args.This(), handle->Data());
18501841

1851-
// Brand-check tag for HasInstance().
1852-
args.This()->SetAlignedPointerInInternalField(kClassTagField,
1853-
const_cast<void*>(class_tag()),
1854-
EmbedderDataTag::kDefault);
1855-
18561842
if (!args[1]->IsUndefined()) {
18571843
CHECK(args[1]->IsObject());
18581844
CHECK(args[2]->IsArray());
18591845
CHECK(args[3]->IsBoolean());
1860-
native->algorithm_.Reset(env->isolate(), args[1].As<Object>());
1861-
native->usages_.Reset(env->isolate(), args[2].As<Array>());
1846+
args.This()->SetInternalField(kAlgorithmField, args[1]);
1847+
args.This()->SetInternalField(kUsagesField, args[2]);
18621848
native->extractable_ = args[3]->IsTrue();
18631849
}
18641850
}
@@ -1876,6 +1862,8 @@ void NativeCryptoKey::CreateCryptoKeyClass(
18761862
NewFunctionTemplate(isolate, NativeCryptoKey::New);
18771863
t->InstanceTemplate()->SetInternalFieldCount(
18781864
NativeCryptoKey::kInternalFieldCount);
1865+
CHECK(env->crypto_cryptokey_constructor_template().IsEmpty());
1866+
env->set_crypto_cryptokey_constructor_template(t);
18791867

18801868
Local<Value> ctor;
18811869
if (!t->GetFunction(env->context()).ToLocal(&ctor)) return;
@@ -1890,6 +1878,7 @@ void NativeCryptoKey::CreateCryptoKeyClass(
18901878
Local<Array> ret = ret_v.As<Array>();
18911879
Local<Value> internal_ctor_v;
18921880
if (!ret->Get(env->context(), 1).ToLocal(&internal_ctor_v)) return;
1881+
CHECK(env->crypto_internal_cryptokey_constructor().IsEmpty());
18931882
env->set_crypto_internal_cryptokey_constructor(
18941883
internal_ctor_v.As<Function>());
18951884
args.GetReturnValue().Set(ret);
@@ -1902,12 +1891,13 @@ void NativeCryptoKey::CreateCryptoKeyClass(
19021891
void NativeCryptoKey::GetSlots(const FunctionCallbackInfo<Value>& args) {
19031892
Environment* env = Environment::GetCurrent(args);
19041893
CHECK_EQ(args.Length(), 1);
1905-
if (!HasInstance(args[0])) {
1894+
if (!HasInstance(env, args[0])) {
19061895
THROW_ERR_INVALID_THIS(env, "Value of \"this\" must be of type CryptoKey");
19071896
return;
19081897
}
19091898
Isolate* isolate = env->isolate();
1910-
NativeCryptoKey* native = Unwrap<NativeCryptoKey>(args[0].As<Object>());
1899+
Local<Object> obj = args[0].As<Object>();
1900+
NativeCryptoKey* native = Unwrap<NativeCryptoKey>(obj);
19111901

19121902
const char* type_str;
19131903
switch (native->handle_data_.GetKeyType()) {
@@ -1929,13 +1919,15 @@ void NativeCryptoKey::GetSlots(const FunctionCallbackInfo<Value>& args) {
19291919
return;
19301920
}
19311921

1932-
CHECK(!native->algorithm_.IsEmpty());
1933-
CHECK(!native->usages_.IsEmpty());
1922+
Local<Value> algorithm = obj->GetInternalField(kAlgorithmField).As<Value>();
1923+
Local<Value> usages = obj->GetInternalField(kUsagesField).As<Value>();
1924+
CHECK(algorithm->IsObject());
1925+
CHECK(usages->IsArray());
19341926
Local<Value> slots[] = {
19351927
OneByteString(isolate, type_str),
19361928
v8::Boolean::New(isolate, native->extractable_),
1937-
PersistentToLocal::Strong(native->algorithm_),
1938-
PersistentToLocal::Strong(native->usages_),
1929+
algorithm,
1930+
usages,
19391931
handle,
19401932
};
19411933
args.GetReturnValue().Set(Array::New(isolate, slots, arraysize(slots)));
@@ -1948,11 +1940,13 @@ BaseObject::TransferMode NativeCryptoKey::GetTransferMode() const {
19481940
std::unique_ptr<worker::TransferData> NativeCryptoKey::CloneForMessaging()
19491941
const {
19501942
Isolate* isolate = env()->isolate();
1951-
CHECK(!algorithm_.IsEmpty());
1952-
CHECK(!usages_.IsEmpty());
1953-
v8::Global<Object> algorithm_copy(isolate,
1954-
PersistentToLocal::Strong(algorithm_));
1955-
v8::Global<Array> usages_copy(isolate, PersistentToLocal::Strong(usages_));
1943+
Local<Object> obj = object();
1944+
Local<Value> algorithm_v = obj->GetInternalField(kAlgorithmField).As<Value>();
1945+
Local<Value> usages_v = obj->GetInternalField(kUsagesField).As<Value>();
1946+
CHECK(algorithm_v->IsObject());
1947+
CHECK(usages_v->IsArray());
1948+
v8::Global<Object> algorithm_copy(isolate, algorithm_v.As<Object>());
1949+
v8::Global<Array> usages_copy(isolate, usages_v.As<Array>());
19561950
return std::make_unique<CryptoKeyTransferData>(handle_data_,
19571951
std::move(algorithm_copy),
19581952
std::move(usages_copy),
@@ -1968,22 +1962,29 @@ Maybe<void> NativeCryptoKey::FinalizeTransferRead(
19681962
CHECK(bundle_v->IsObject());
19691963
Local<Object> bundle = bundle_v.As<Object>();
19701964
Isolate* isolate = env()->isolate();
1965+
Local<Object> obj = object();
1966+
1967+
// The partially-initialized object produced by
1968+
// CryptoKeyTransferData::Deserialize should not have algorithm/usages
1969+
// set yet.
1970+
CHECK(obj->GetInternalField(kAlgorithmField).As<Value>()->IsUndefined());
1971+
CHECK(obj->GetInternalField(kUsagesField).As<Value>()->IsUndefined());
19711972

19721973
Local<Value> algorithm_v;
19731974
if (!bundle->Get(context, FIXED_ONE_BYTE_STRING(isolate, "algorithm"))
19741975
.ToLocal(&algorithm_v)) {
19751976
return Nothing<void>();
19761977
}
19771978
CHECK(algorithm_v->IsObject());
1978-
algorithm_.Reset(isolate, algorithm_v.As<Object>());
1979+
obj->SetInternalField(kAlgorithmField, algorithm_v);
19791980

19801981
Local<Value> usages_v;
19811982
if (!bundle->Get(context, FIXED_ONE_BYTE_STRING(isolate, "usages"))
19821983
.ToLocal(&usages_v)) {
19831984
return Nothing<void>();
19841985
}
19851986
CHECK(usages_v->IsArray());
1986-
usages_.Reset(isolate, usages_v.As<Array>());
1987+
obj->SetInternalField(kUsagesField, usages_v);
19871988

19881989
Local<Value> extractable_v;
19891990
if (!bundle->Get(context, FIXED_ONE_BYTE_STRING(isolate, "extractable"))
@@ -2067,8 +2068,6 @@ BaseObjectPtr<BaseObject> NativeCryptoKey::CryptoKeyTransferData::Deserialize(
20672068

20682069
void NativeCryptoKey::MemoryInfo(MemoryTracker* tracker) const {
20692070
tracker->TrackField("handle_data", handle_data_);
2070-
tracker->TrackField("algorithm", algorithm_);
2071-
tracker->TrackField("usages", usages_);
20722071
}
20732072

20742073
void NativeCryptoKey::CryptoKeyTransferData::MemoryInfo(

src/crypto/crypto_keys.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ class NativeKeyObject : public BaseObject {
245245
class NativeCryptoKey : public BaseObject {
246246
public:
247247
enum InternalFields {
248-
kClassTagField = BaseObject::kInternalFieldCount,
248+
kAlgorithmField = BaseObject::kInternalFieldCount,
249+
kUsagesField,
249250
kInternalFieldCount,
250251
};
251252

@@ -256,10 +257,10 @@ class NativeCryptoKey : public BaseObject {
256257
static void CreateCryptoKeyClass(
257258
const v8::FunctionCallbackInfo<v8::Value>& args);
258259

259-
// True if `value` is a real NativeCryptoKey instance. Checks the
260-
// kClassTagField internal field.
260+
// True if `value` is a real NativeCryptoKey instance. Uses the
261+
// FunctionTemplate stored on the Environment as a brand check.
261262
// Used by `GetSlots` to validate its receiver.
262-
static bool HasInstance(v8::Local<v8::Value> value);
263+
static bool HasInstance(Environment* env, v8::Local<v8::Value> value);
263264

264265
// Returns [type, extractable, algorithm, usages, handle] in one call
265266
// so JS can prime a per-instance cache on first access.
@@ -317,8 +318,6 @@ class NativeCryptoKey : public BaseObject {
317318
}
318319

319320
KeyObjectData handle_data_;
320-
v8::Global<v8::Object> algorithm_;
321-
v8::Global<v8::Array> usages_;
322321
bool extractable_ = false;
323322
};
324323

src/env_properties.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@
403403
V(contextify_global_template, v8::ObjectTemplate) \
404404
V(contextify_wrapper_template, v8::ObjectTemplate) \
405405
V(cpu_usage_template, v8::DictionaryTemplate) \
406+
V(crypto_cryptokey_constructor_template, v8::FunctionTemplate) \
406407
V(crypto_key_object_handle_constructor, v8::FunctionTemplate) \
407408
V(env_proxy_template, v8::ObjectTemplate) \
408409
V(env_proxy_ctor_template, v8::FunctionTemplate) \

0 commit comments

Comments
 (0)