From fd3a8bfe8bbe26d4b8b5ef2803845bb73d0b30e9 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 3 Apr 2022 12:11:21 +0200 Subject: [PATCH] crypto: do not add undefined hash in webcrypto normalizeAlgorithm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/42559 Reviewed-By: Rich Trott Reviewed-By: Tobias Nießen --- lib/internal/crypto/util.js | 15 +++++++++------ lib/internal/crypto/webcrypto.js | 4 ++-- test/parallel/test-webcrypto-util.js | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 test/parallel/test-webcrypto-util.js 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 e9380ed53bf4d2..cf440ebf8ff39d 100644 --- a/lib/internal/crypto/webcrypto.js +++ b/lib/internal/crypto/webcrypto.js @@ -587,10 +587,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' }); +}