Skip to content

Commit cc7f6b4

Browse files
committed
fixup! crypto: discover hashes from OpenSSL providers
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
1 parent 1023414 commit cc7f6b4

2 files changed

Lines changed: 45 additions & 6 deletions

File tree

‎src/crypto/crypto_hash.cc‎

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,13 @@ void ResetHashCache(Environment* env,
8989
Isolate* isolate = env->isolate();
9090
Local<Context> context = isolate->GetCurrentContext();
9191
for (const auto& entry : cache->aliases()) {
92-
algorithm_cache
93-
->Set(context,
94-
OneByteString(isolate, entry.first),
95-
Int32::New(isolate, -1))
96-
.Check();
92+
if (algorithm_cache
93+
->Set(context,
94+
OneByteString(isolate, entry.first),
95+
Int32::New(isolate, -1))
96+
.IsNothing()) {
97+
return;
98+
}
9799
}
98100
}
99101
cache->reset(generation);
@@ -135,6 +137,7 @@ MaybeCachedMD FetchAndMaybeCacheMD(
135137
Local<Object> algorithm_cache = Local<Object>(),
136138
const char* fetch_name = nullptr) {
137139
SynchronizeHashCache(env, algorithm_cache);
140+
if (env->isolate()->HasPendingException()) return {};
138141
ncrypto::DigestCache* cache = env->provider_digest_cache.get();
139142
CHECK_NOT_NULL(cache);
140143
const uint64_t generation = env->hash_cache_generation;
@@ -320,6 +323,7 @@ const EVP_MD* GetDigestImplementation(
320323
if (cache_id != -1) {
321324
// Alias already cached, return the cached EVP_MD*.
322325
if (const EVP_MD* md = GetCachedMDByID(env, cache_id, cache)) return md;
326+
if (env->isolate()->HasPendingException()) return nullptr;
323327
}
324328

325329
// Only decode the algorithm when we don't have it cached to avoid
@@ -328,6 +332,7 @@ const EVP_MD* GetDigestImplementation(
328332
Utf8Value utf8(isolate, algorithm);
329333

330334
auto result = FetchAndMaybeCacheMD(env, *utf8, cache);
335+
if (env->isolate()->HasPendingException()) return nullptr;
331336
if (result.cache_id != -1) {
332337
// Add the alias to the JavaScript side to speed up the next lookup. The
333338
// native cache added it while inserting the implementation.
@@ -539,6 +544,7 @@ void Hash::OneShotDigest(const FunctionCallbackInfo<Value>& args) {
539544
GetCachedMDByID(env, cache_id, args[2].As<Object>())) {
540545
return OneShotDigestWithMD(env, args, md, nullptr);
541546
}
547+
if (env->isolate()->HasPendingException()) return;
542548
}
543549
#else
544550
Utf8Value utf8(env->isolate(), args[0]);
@@ -554,12 +560,14 @@ void Hash::OneShotDigest(const FunctionCallbackInfo<Value>& args) {
554560
std::optional<ncrypto::Digest> digest_owner;
555561
const EVP_MD* md =
556562
GetDigestImplementation(env, args[0], args[1], args[2], digest_owner);
563+
if (env->isolate()->HasPendingException()) return;
557564
return OneShotDigestWithMD(env, args, md, &options);
558565
}
559566

560567
std::optional<ncrypto::Digest> digest_owner;
561568
const EVP_MD* md =
562569
GetDigestImplementation(env, args[0], args[1], args[2], digest_owner);
570+
if (env->isolate()->HasPendingException()) return;
563571
OneShotDigestWithMD(env, args, md, nullptr);
564572
}
565573

@@ -627,6 +635,7 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
627635
}
628636
return;
629637
}
638+
if (env->isolate()->HasPendingException()) return;
630639
}
631640
}
632641
#endif
@@ -640,6 +649,7 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
640649
md = orig->mdctx_.getDigest();
641650
} else {
642651
md = GetDigestImplementation(env, args[0], args[2], args[3], digest_owner);
652+
if (env->isolate()->HasPendingException()) return;
643653
}
644654

645655
Hash* hash = new Hash(env, args.This());

‎test/addons/openssl-providers/test-default-properties-config.js‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Flags: --expose-internals
12
'use strict';
23

34
const common = require('../../common');
@@ -13,13 +14,14 @@ const {
1314
setFips,
1415
} = require('node:crypto');
1516
const { Worker } = require('node:worker_threads');
17+
const { getHashCache } = require('internal/crypto/util');
1618
const option = `--openssl-config=${fixtures.path(
1719
'openssl3-conf',
1820
'default_properties.cnf',
1921
)}`;
2022

2123
if (!process.execArgv.includes(option)) {
22-
const cp = fork(__filename, { execArgv: [option] });
24+
const cp = fork(__filename, { execArgv: [...process.execArgv, option] });
2325
cp.on('exit', common.mustCall((code, signal) => {
2426
assert.strictEqual(code, 0);
2527
assert.strictEqual(signal, null);
@@ -37,7 +39,34 @@ const md5 = 'd41d8cd98f00b204e9800998ecf8427e';
3739
assert.strictEqual(createHash('md5').update(input).digest('hex'), md5);
3840
assert.strictEqual(oneShotHash('md5', input), md5);
3941

42+
const hashName = 'SHA256';
43+
const hashCache = getHashCache();
44+
const descriptor = Object.getOwnPropertyDescriptor(hashCache, hashName);
45+
assert(descriptor);
46+
const cacheId = descriptor.value;
47+
const sentinel = new Error('hash cache setter');
48+
const throwsSentinel = (err) => err === sentinel;
49+
50+
function installThrowingHashCacheEntry(id) {
51+
Object.defineProperty(hashCache, hashName, {
52+
__proto__: null,
53+
configurable: true,
54+
enumerable: descriptor.enumerable,
55+
get() { return id; },
56+
set() { throw sentinel; },
57+
});
58+
}
59+
60+
installThrowingHashCacheEntry(-1);
61+
assert.throws(() => createHash(hashName), throwsSentinel);
62+
assert.throws(() => oneShotHash(hashName, input), throwsSentinel);
63+
Object.defineProperty(hashCache, hashName, descriptor);
64+
65+
installThrowingHashCacheEntry(cacheId);
4066
setFips(true);
67+
assert.throws(() => createHash(hashName), throwsSentinel);
68+
assert.throws(() => oneShotHash(hashName, input), throwsSentinel);
69+
Object.defineProperty(hashCache, hashName, descriptor);
4170
assert.deepStrictEqual(getHashes(), []);
4271
assert.throws(
4372
() => createHash('md5'),

0 commit comments

Comments
 (0)