Skip to content

Commit 7aaf9b4

Browse files
panvanodejs-github-bot
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 ebd88be commit 7aaf9b4

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,
@@ -1049,6 +1050,7 @@ function getKeyObjectAsymmetricKeyDetails(key) {
10491050
// requires repeat reads to return the same object so a consumer's
10501051
// mutation is visible next time).
10511052
let getSlots; // Populated by the createCryptoKeyClass callback below.
1053+
let isCryptoKey;
10521054

10531055
const kSlotType = 0;
10541056
const kSlotExtractable = 1;
@@ -1150,6 +1152,10 @@ const {
11501152
}
11511153

11521154
static {
1155+
isCryptoKey = (key) => {
1156+
if (key == null || typeof key !== 'object') return false;
1157+
return #slots in key || isNativeCryptoKey(key);
1158+
};
11531159
getSlots = (key) => {
11541160
if (!key || typeof key !== 'object')
11551161
throw new ERR_INVALID_THIS('CryptoKey');
@@ -1281,18 +1287,6 @@ function getCryptoKeyHandle(key) {
12811287
return getSlots(key)[kSlotHandle];
12821288
}
12831289

1284-
function isCryptoKey(obj) {
1285-
if (obj == null || typeof obj !== 'object')
1286-
return false;
1287-
1288-
try {
1289-
getSlots(obj);
1290-
return true;
1291-
} catch {
1292-
return false;
1293-
}
1294-
}
1295-
12961290
function importGenericSecretKey(
12971291
algorithm,
12981292
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
@@ -940,6 +940,7 @@ export interface CryptoBinding {
940940
getExtraCACertificates(): string[];
941941
getFipsCrypto(): 0 | 1;
942942
getHashes(): string[];
943+
isCryptoKey(key: unknown): boolean;
943944
isKeyObject(key: unknown): boolean;
944945
getKeyObjectSlots(key: object): InternalCryptoBinding.KeyObjectSlots;
945946
getOpenSSLSecLevelCrypto(): number | undefined;

0 commit comments

Comments
 (0)