Skip to content

Commit 0c090a2

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 a13cc3f commit 0c090a2

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
@@ -1875,12 +1875,15 @@ void NativeCryptoKey::Initialize(Environment* env, Local<Object> target) {
18751875
NativeCryptoKey::CreateCryptoKeyClass);
18761876
SetMethod(
18771877
env->context(), target, "getCryptoKeySlots", NativeCryptoKey::GetSlots);
1878+
SetMethodNoSideEffect(
1879+
env->context(), target, "isCryptoKey", NativeCryptoKey::IsCryptoKey);
18781880
}
18791881

18801882
void NativeCryptoKey::RegisterExternalReferences(
18811883
ExternalReferenceRegistry* registry) {
18821884
registry->Register(NativeCryptoKey::CreateCryptoKeyClass);
18831885
registry->Register(NativeCryptoKey::GetSlots);
1886+
registry->Register(NativeCryptoKey::IsCryptoKey);
18841887
registry->Register(NativeCryptoKey::New);
18851888
}
18861889

@@ -1897,6 +1900,12 @@ bool NativeCryptoKey::HasInstance(Environment* env, Local<Value> value) {
18971900
return IsNativeCryptoKey(env, value);
18981901
}
18991902

1903+
void NativeCryptoKey::IsCryptoKey(const FunctionCallbackInfo<Value>& args) {
1904+
Environment* env = Environment::GetCurrent(args);
1905+
CHECK_EQ(args.Length(), 1);
1906+
args.GetReturnValue().Set(HasInstance(env, args[0]));
1907+
}
1908+
19001909
MaybeLocal<Value> NativeCryptoKey::Create(Environment* env,
19011910
const KeyObjectData& data,
19021911
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
@@ -939,6 +939,7 @@ export interface CryptoBinding {
939939
getExtraCACertificates(): string[];
940940
getFipsCrypto(): 0 | 1;
941941
getHashes(): string[];
942+
isCryptoKey(key: unknown): boolean;
942943
isKeyObject(key: unknown): boolean;
943944
getKeyObjectSlots(key: object): InternalCryptoBinding.KeyObjectSlots;
944945
getOpenSSLSecLevelCrypto(): number | undefined;

0 commit comments

Comments
 (0)