diff --git a/lib/internal/crypto/util.js b/lib/internal/crypto/util.js index eafcc3d9669288..9492409e3a6437 100644 --- a/lib/internal/crypto/util.js +++ b/lib/internal/crypto/util.js @@ -206,30 +206,33 @@ function validateMaxBufferLength(data, name) { } } -function normalizeAlgorithm(algorithm, label = 'algorithm') { +function normalizeAlgorithm(algorithm) { if (algorithm != null) { if (typeof algorithm === 'string') algorithm = { name: algorithm }; if (typeof algorithm === 'object') { const { name } = algorithm; - let hash; if (typeof name !== 'string' || !ArrayPrototypeIncludes( kAlgorithmsKeys, StringPrototypeToLowerCase(name))) { throw lazyDOMException('Unrecognized name.', 'NotSupportedError'); } - if (algorithm.hash !== undefined) { - hash = normalizeAlgorithm(algorithm.hash, 'algorithm.hash'); + let { hash } = algorithm; + if (hash !== undefined) { + hash = normalizeAlgorithm(hash); if (!ArrayPrototypeIncludes(kHashTypes, hash.name)) throw lazyDOMException('Unrecognized name.', 'NotSupportedError'); } - return { + const normalized = { ...algorithm, name: kAlgorithms[StringPrototypeToLowerCase(name)], - hash, }; + if (hash) { + normalized.hash = hash; + } + return normalized; } } throw lazyDOMException('Unrecognized name.', 'NotSupportedError'); diff --git a/lib/internal/crypto/webcrypto.js b/lib/internal/crypto/webcrypto.js index 63dd03bd00e0f0..e5801ea52f0bc3 100644 --- a/lib/internal/crypto/webcrypto.js +++ b/lib/internal/crypto/webcrypto.js @@ -557,10 +557,10 @@ async function unwrapKey( extractable, keyUsages) { wrappedKey = getArrayBufferOrView(wrappedKey, 'wrappedKey'); - + unwrapAlgo = normalizeAlgorithm(unwrapAlgo); let keyData = await cipherOrWrap( kWebCryptoCipherDecrypt, - normalizeAlgorithm(unwrapAlgo), + unwrapAlgo, unwrappingKey, wrappedKey, 'unwrapKey'); diff --git a/test/parallel/test-webcrypto-util.js b/test/parallel/test-webcrypto-util.js new file mode 100644 index 00000000000000..4bb14a7f91494f --- /dev/null +++ b/test/parallel/test-webcrypto-util.js @@ -0,0 +1,25 @@ +// Flags: --expose-internals +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); + +const { + normalizeAlgorithm, +} = require('internal/crypto/util'); + +{ + // Check that normalizeAlgorithm does not add an undefined hash property. + assert.strictEqual('hash' in normalizeAlgorithm({ name: 'ECDH' }), false); + assert.strictEqual('hash' in normalizeAlgorithm('ECDH'), false); +} + +{ + // Check that normalizeAlgorithm does not mutate object inputs. + const algorithm = { name: 'ECDH', hash: 'SHA-256' }; + assert.strictEqual(normalizeAlgorithm(algorithm) !== algorithm, true); + assert.deepStrictEqual(algorithm, { name: 'ECDH', hash: 'SHA-256' }); +}