Skip to content

Commit b2faeb6

Browse files
panvaaduh95
authored andcommitted
crypto: avoid throwing CryptoKey brand checks
Use the native CryptoKey FunctionTemplate brand check instead of probing slot access and catching ERR_INVALID_THIS. Keep a private-field fast path for ordinary same-realm CryptoKeys. Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: #65503 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent ae6136e commit b2faeb6

4 files changed

Lines changed: 17 additions & 12 deletions

File tree

lib/internal/crypto/keys.js

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const {
2020
createCryptoKeyClass,
2121
// eslint-disable-next-line no-restricted-syntax -- intended here
2222
getCryptoKeySlots: nativeGetCryptoKeySlots,
23+
isCryptoKey: isNativeCryptoKey,
2324
kKeyTypeSecret,
2425
kKeyTypePublic,
2526
kKeyTypePrivate,
@@ -1075,6 +1076,7 @@ function getKeyObjectAsymmetricKeyDetails(key) {
10751076
// requires repeat reads to return the same object so a consumer's
10761077
// mutation is visible next time).
10771078
let getSlots; // Populated by the createCryptoKeyClass callback below.
1079+
let isCryptoKey;
10781080

10791081
const kSlotType = 0;
10801082
const kSlotExtractable = 1;
@@ -1176,6 +1178,10 @@ const {
11761178
}
11771179

11781180
static {
1181+
isCryptoKey = (key) => {
1182+
if (key == null || typeof key !== 'object') return false;
1183+
return #slots in key || isNativeCryptoKey(key);
1184+
};
11791185
getSlots = (key) => {
11801186
if (!key || typeof key !== 'object')
11811187
throw new ERR_INVALID_THIS('CryptoKey');
@@ -1307,18 +1313,6 @@ function getCryptoKeyHandle(key) {
13071313
return getSlots(key)[kSlotHandle];
13081314
}
13091315

1310-
function isCryptoKey(obj) {
1311-
if (obj == null || typeof obj !== 'object')
1312-
return false;
1313-
1314-
try {
1315-
getSlots(obj);
1316-
return true;
1317-
} catch {
1318-
return false;
1319-
}
1320-
}
1321-
13221316
function importGenericSecretKey(
13231317
algorithm,
13241318
format,

src/crypto/crypto_keys.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,12 +1848,15 @@ void NativeCryptoKey::Initialize(Environment* env, Local<Object> target) {
18481848
NativeCryptoKey::CreateCryptoKeyClass);
18491849
SetMethod(
18501850
env->context(), target, "getCryptoKeySlots", NativeCryptoKey::GetSlots);
1851+
SetMethodNoSideEffect(
1852+
env->context(), target, "isCryptoKey", NativeCryptoKey::IsCryptoKey);
18511853
}
18521854

18531855
void NativeCryptoKey::RegisterExternalReferences(
18541856
ExternalReferenceRegistry* registry) {
18551857
registry->Register(NativeCryptoKey::CreateCryptoKeyClass);
18561858
registry->Register(NativeCryptoKey::GetSlots);
1859+
registry->Register(NativeCryptoKey::IsCryptoKey);
18571860
registry->Register(NativeCryptoKey::New);
18581861
}
18591862

@@ -1870,6 +1873,12 @@ bool NativeCryptoKey::HasInstance(Environment* env, Local<Value> value) {
18701873
return IsNativeCryptoKey(env, value);
18711874
}
18721875

1876+
void NativeCryptoKey::IsCryptoKey(const FunctionCallbackInfo<Value>& args) {
1877+
Environment* env = Environment::GetCurrent(args);
1878+
CHECK_EQ(args.Length(), 1);
1879+
args.GetReturnValue().Set(HasInstance(env, args[0]));
1880+
}
1881+
18731882
MaybeLocal<Value> NativeCryptoKey::Create(Environment* env,
18741883
const KeyObjectData& data,
18751884
Local<Value> algorithm,

src/crypto/crypto_keys.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ class NativeCryptoKey : public BaseObject {
278278
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
279279
static void CreateCryptoKeyClass(
280280
const v8::FunctionCallbackInfo<v8::Value>& args);
281+
static void IsCryptoKey(const v8::FunctionCallbackInfo<v8::Value>& args);
281282

282283
static v8::MaybeLocal<v8::Value> Create(Environment* env,
283284
const KeyObjectData& data,

typings/internalBinding/crypto.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,7 @@ export interface CryptoBinding {
949949
getFipsCrypto(): 0 | 1;
950950
getFipsCryptoGeneration(): bigint;
951951
getHashes(): string[];
952+
isCryptoKey(key: unknown): boolean;
952953
isKeyObject(key: unknown): boolean;
953954
getKeyObjectSlots(key: object): InternalCryptoBinding.KeyObjectSlots;
954955
getOpenSSLSecLevelCrypto(): number | undefined;

0 commit comments

Comments
 (0)