diff --git a/lib/internal/crypto/aes.js b/lib/internal/crypto/aes.js index 1d5d0bdb2380d8..041118fe3263fe 100644 --- a/lib/internal/crypto/aes.js +++ b/lib/internal/crypto/aes.js @@ -58,7 +58,6 @@ const { generateKey: _generateKey, } = require('internal/crypto/keygen'); -const kMaxCounterLength = 128; const kTagLengths = [32, 64, 96, 104, 112, 120, 128]; const generateKey = promisify(_generateKey); @@ -109,15 +108,19 @@ function getVariant(name, length) { } } -function asyncAesCtrCipher(mode, key, data, { counter, length }) { - validateByteLength(counter, 'algorithm.counter', 16); +function validateAesCtrAlgorithm(algorithm) { + validateByteLength(algorithm.counter, 'algorithm.counter', 16); // The length must specify an integer between 1 and 128. While // there is no default, this should typically be 64. - if (length === 0 || length > kMaxCounterLength) { + if (algorithm.length === 0 || algorithm.length > 128) { throw lazyDOMException( 'AES-CTR algorithm.length must be between 1 and 128', 'OperationError'); } +} + +function asyncAesCtrCipher(mode, key, data, algorithm) { + validateAesCtrAlgorithm(algorithm); return jobPromise(() => new AESCipherJob( kCryptoJobAsync, @@ -125,19 +128,23 @@ function asyncAesCtrCipher(mode, key, data, { counter, length }) { key[kKeyObject][kHandle], data, getVariant('AES-CTR', key.algorithm.length), - counter, - length)); + algorithm.counter, + algorithm.length)); +} + +function validateAesCbcAlgorithm(algorithm) { + validateByteLength(algorithm.iv, 'algorithm.iv', 16); } -function asyncAesCbcCipher(mode, key, data, { iv }) { - validateByteLength(iv, 'algorithm.iv', 16); +function asyncAesCbcCipher(mode, key, data, algorithm) { + validateAesCbcAlgorithm(algorithm); return jobPromise(() => new AESCipherJob( kCryptoJobAsync, mode, key[kKeyObject][kHandle], data, getVariant('AES-CBC', key.algorithm.length), - iv)); + algorithm.iv)); } function asyncAesKwCipher(mode, key, data) { @@ -149,24 +156,25 @@ function asyncAesKwCipher(mode, key, data) { getVariant('AES-KW', key.algorithm.length))); } -function asyncAesGcmCipher( - mode, - key, - data, - { iv, additionalData, tagLength = 128 }) { - if (!ArrayPrototypeIncludes(kTagLengths, tagLength)) { - return PromiseReject(lazyDOMException( - `${tagLength} is not a valid AES-GCM tag length`, - 'OperationError')); +function validateAesGcmAlgorithm(algorithm) { + if (!ArrayPrototypeIncludes(kTagLengths, algorithm.tagLength)) { + throw lazyDOMException( + `${algorithm.tagLength} is not a valid AES-GCM tag length`, + 'OperationError'); } - validateMaxBufferLength(iv, 'algorithm.iv'); + validateMaxBufferLength(algorithm.iv, 'algorithm.iv'); - if (additionalData !== undefined) { - validateMaxBufferLength(additionalData, 'algorithm.additionalData'); + if (algorithm.additionalData !== undefined) { + validateMaxBufferLength(algorithm.additionalData, 'algorithm.additionalData'); } +} - const tagByteLength = MathFloor(tagLength / 8); +function asyncAesGcmCipher(mode, key, data, algorithm) { + algorithm.tagLength ??= 128; + validateAesGcmAlgorithm(algorithm); + + const tagByteLength = MathFloor(algorithm.tagLength / 8); let tag; switch (mode) { case kWebCryptoCipherDecrypt: { @@ -198,9 +206,9 @@ function asyncAesGcmCipher( key[kKeyObject][kHandle], data, getVariant('AES-GCM', key.algorithm.length), - iv, + algorithm.iv, tag, - additionalData)); + algorithm.additionalData)); } function aesCipher(mode, key, data, algorithm) { @@ -212,13 +220,17 @@ function aesCipher(mode, key, data, algorithm) { } } -async function aesGenerateKey(algorithm, extractable, keyUsages) { - const { name, length } = algorithm; - if (!ArrayPrototypeIncludes(kAesKeyLengths, length)) { +function validateAesGenerateKeyAlgorithm(algorithm) { + if (!ArrayPrototypeIncludes(kAesKeyLengths, algorithm.length)) { throw lazyDOMException( 'AES key length must be 128, 192, or 256 bits', 'OperationError'); } +} + +async function aesGenerateKey(algorithm, extractable, keyUsages) { + validateAesGenerateKeyAlgorithm(algorithm); + const { name, length } = algorithm; const checkUsages = ['wrapKey', 'unwrapKey']; if (name !== 'AES-KW') diff --git a/lib/internal/crypto/cfrg.js b/lib/internal/crypto/cfrg.js index 7bea4ed3544f87..80cab657068985 100644 --- a/lib/internal/crypto/cfrg.js +++ b/lib/internal/crypto/cfrg.js @@ -329,18 +329,21 @@ function cfrgImportKey( extractable); } -function eddsaSignVerify(key, data, { name, context }, signature) { +function validateEdDSASignVerifyAlgorithm(algorithm) { + if (algorithm.name === 'Ed448' && algorithm.context?.byteLength) { + throw lazyDOMException( + 'Non zero-length context is not yet supported.', 'NotSupportedError'); + } +} + +function eddsaSignVerify(key, data, algorithm, signature) { + validateEdDSASignVerifyAlgorithm(algorithm); const mode = signature === undefined ? kSignJobModeSign : kSignJobModeVerify; const type = mode === kSignJobModeSign ? 'private' : 'public'; if (key.type !== type) throw lazyDOMException(`Key must be a ${type} key`, 'InvalidAccessError'); - if (name === 'Ed448' && context?.byteLength) { - throw lazyDOMException( - 'Non zero-length context is not yet supported.', 'NotSupportedError'); - } - return jobPromise(() => new SignJob( kCryptoJobAsync, mode, diff --git a/lib/internal/crypto/diffiehellman.js b/lib/internal/crypto/diffiehellman.js index 9ebd9766f6bc8c..71a023e9ea4513 100644 --- a/lib/internal/crypto/diffiehellman.js +++ b/lib/internal/crypto/diffiehellman.js @@ -298,28 +298,28 @@ function diffieHellman(options) { let masks; +function validateEcdhDeriveBitsAlgorithmAndLength(algorithm, length) { + if (algorithm.public.type !== 'public') { + throw lazyDOMException( + 'algorithm.public must be a public key', 'InvalidAccessError'); + } + + if (algorithm.name !== algorithm.public.algorithm.name) { + throw lazyDOMException(`algorithm.public must be an ${algorithm.name} key`, 'InvalidAccessError'); + } +} + // The ecdhDeriveBits function is part of the Web Crypto API and serves both // deriveKeys and deriveBits functions. async function ecdhDeriveBits(algorithm, baseKey, length) { + validateEcdhDeriveBitsAlgorithmAndLength(algorithm, length); const { 'public': key } = algorithm; - if (key.type !== 'public') { - throw lazyDOMException( - 'algorithm.public must be a public key', 'InvalidAccessError'); - } if (baseKey.type !== 'private') { throw lazyDOMException( 'baseKey must be a private key', 'InvalidAccessError'); } - if ( - key.algorithm.name !== 'ECDH' && - key.algorithm.name !== 'X25519' && - key.algorithm.name !== 'X448' - ) { - throw lazyDOMException('Keys must be ECDH, X25519, or X448 keys', 'InvalidAccessError'); - } - if (key.algorithm.name !== baseKey.algorithm.name) { throw lazyDOMException( 'The public and private keys must be of the same type', diff --git a/lib/internal/crypto/ec.js b/lib/internal/crypto/ec.js index 3cd5d12cdb2bc2..fe43fe3eb23814 100644 --- a/lib/internal/crypto/ec.js +++ b/lib/internal/crypto/ec.js @@ -1,8 +1,7 @@ 'use strict'; const { - ArrayPrototypeIncludes, - ObjectKeys, + ObjectPrototypeHasOwnProperty, SafeSet, } = primordials; @@ -77,14 +76,17 @@ function createECPublicKeyRaw(namedCurve, keyData) { return new PublicKeyObject(handle); } -async function ecGenerateKey(algorithm, extractable, keyUsages) { - const { name, namedCurve } = algorithm; - - if (!ArrayPrototypeIncludes(ObjectKeys(kNamedCurveAliases), namedCurve)) { +function validateEcKeyAlgorithm(algorithm) { + if (!ObjectPrototypeHasOwnProperty(kNamedCurveAliases, algorithm.namedCurve)) { throw lazyDOMException( 'Unrecognized namedCurve', 'NotSupportedError'); } +} + +async function ecGenerateKey(algorithm, extractable, keyUsages) { + validateEcKeyAlgorithm(algorithm); + const { name, namedCurve } = algorithm; const usageSet = new SafeSet(keyUsages); switch (name) { @@ -154,16 +156,11 @@ function ecImportKey( keyData, algorithm, extractable, - keyUsages) { - + keyUsages, +) { + validateEcKeyAlgorithm(algorithm); const { name, namedCurve } = algorithm; - if (!ArrayPrototypeIncludes(ObjectKeys(kNamedCurveAliases), namedCurve)) { - throw lazyDOMException( - 'Unrecognized namedCurve', - 'NotSupportedError'); - } - let keyObject; const usagesSet = new SafeSet(keyUsages); switch (format) { diff --git a/lib/internal/crypto/hkdf.js b/lib/internal/crypto/hkdf.js index 849e593e440a04..953ebacd91c437 100644 --- a/lib/internal/crypto/hkdf.js +++ b/lib/internal/crypto/hkdf.js @@ -138,11 +138,7 @@ function hkdfSync(hash, key, salt, info, length) { } const hkdfPromise = promisify(hkdf); -async function hkdfDeriveBits(algorithm, baseKey, length) { - const { hash, salt, info } = algorithm; - - if (length === 0) - return new ArrayBuffer(0); +function validateHkdfDeriveBitsAlgorithmAndLength(algorithm, length) { if (length === null) throw lazyDOMException('length cannot be null', 'OperationError'); if (length % 8) { @@ -150,6 +146,14 @@ async function hkdfDeriveBits(algorithm, baseKey, length) { 'length must be a multiple of 8', 'OperationError'); } +} + +async function hkdfDeriveBits(algorithm, baseKey, length) { + validateHkdfDeriveBitsAlgorithmAndLength(algorithm, length); + const { hash, salt, info } = algorithm; + + if (length === 0) + return new ArrayBuffer(0); try { return await hkdfPromise( diff --git a/lib/internal/crypto/keys.js b/lib/internal/crypto/keys.js index 96771f09c8c941..7529254685fb17 100644 --- a/lib/internal/crypto/keys.js +++ b/lib/internal/crypto/keys.js @@ -895,12 +895,14 @@ function isCryptoKey(obj) { } function importGenericSecretKey( - { name, length }, + algorithm, format, keyData, extractable, - keyUsages) { + keyUsages, +) { const usagesSet = new SafeSet(keyUsages); + const { name } = algorithm; if (extractable) throw lazyDOMException(`${name} keys are not extractable`, 'SyntaxError'); @@ -910,47 +912,22 @@ function importGenericSecretKey( 'SyntaxError'); } + let keyObject; switch (format) { case 'KeyObject': { - if (hasAnyNotIn(usagesSet, ['deriveKey', 'deriveBits'])) { - throw lazyDOMException( - `Unsupported key usage for a ${name} key`, - 'SyntaxError'); - } - - const checkLength = keyData.symmetricKeySize * 8; - - // The Web Crypto spec allows for key lengths that are not multiples of - // 8. We don't. Our check here is stricter than that defined by the spec - // in that we require that algorithm.length match keyData.length * 8 if - // algorithm.length is specified. - if (length !== undefined && length !== checkLength) { - throw lazyDOMException('Invalid key length', 'DataError'); - } - return new InternalCryptoKey(keyData, { name }, keyUsages, false); + keyObject = keyData; + break; } case 'raw': { - if (hasAnyNotIn(usagesSet, ['deriveKey', 'deriveBits'])) { - throw lazyDOMException( - `Unsupported key usage for a ${name} key`, - 'SyntaxError'); - } - - const checkLength = keyData.byteLength * 8; - - // The Web Crypto spec allows for key lengths that are not multiples of - // 8. We don't. Our check here is stricter than that defined by the spec - // in that we require that algorithm.length match keyData.length * 8 if - // algorithm.length is specified. - if (length !== undefined && length !== checkLength) { - throw lazyDOMException('Invalid key length', 'DataError'); - } - - const keyObject = createSecretKey(keyData); - return new InternalCryptoKey(keyObject, { name }, keyUsages, false); + keyObject = createSecretKey(keyData); + break; } } + if (keyObject) { + return new InternalCryptoKey(keyObject, { name }, keyUsages, false); + } + throw lazyDOMException( `Unable to import ${name} key with format ${format}`, 'NotSupportedError'); diff --git a/lib/internal/crypto/mac.js b/lib/internal/crypto/mac.js index 356ce5a8d79a31..bb3bb2d27ba81e 100644 --- a/lib/internal/crypto/mac.js +++ b/lib/internal/crypto/mac.js @@ -18,7 +18,6 @@ const { hasAnyNotIn, jobPromise, normalizeHashName, - validateBitLength, validateKeyOps, kHandle, kKeyObject, @@ -41,15 +40,30 @@ const { const generateKey = promisify(_generateKey); +function validateHmacGenerateKeyAlgorithm(algorithm) { + if (algorithm.length !== undefined) { + if (algorithm.length === 0) + throw lazyDOMException( + 'Zero-length key is not supported', + 'OperationError'); + + // The Web Crypto spec allows for key lengths that are not multiples of 8. We don't. + if (algorithm.length % 8) { + throw lazyDOMException( + 'Unsupported algorithm.length', + 'NotSupportedError'); + } + } +} + async function hmacGenerateKey(algorithm, extractable, keyUsages) { + validateHmacGenerateKeyAlgorithm(algorithm); const { hash, name } = algorithm; let { length } = algorithm; if (length === undefined) length = getBlockSize(hash.name); - validateBitLength(length, 'algorithm.length', true); - const usageSet = new SafeSet(keyUsages); if (hasAnyNotIn(usageSet, ['sign', 'verify'])) { throw lazyDOMException( @@ -82,12 +96,27 @@ function getAlgorithmName(hash) { } } +function validateHmacImportKeyAlgorithm(algorithm) { + if (algorithm.length !== undefined) { + if (algorithm.length === 0) { + throw lazyDOMException('Zero-length key is not supported', 'DataError'); + } + + // The Web Crypto spec allows for key lengths that are not multiples of 8. We don't. + if (algorithm.length % 8) { + throw lazyDOMException('Unsupported algorithm.length', 'NotSupportedError'); + } + } +} + function hmacImportKey( format, keyData, algorithm, extractable, - keyUsages) { + keyUsages, +) { + validateHmacImportKeyAlgorithm(algorithm); const usagesSet = new SafeSet(keyUsages); if (hasAnyNotIn(usagesSet, ['sign', 'verify'])) { throw lazyDOMException( @@ -97,38 +126,10 @@ function hmacImportKey( let keyObject; switch (format) { case 'KeyObject': { - const checkLength = keyData.symmetricKeySize * 8; - - if (checkLength === 0 || algorithm.length === 0) - throw lazyDOMException('Zero-length key is not supported', 'DataError'); - - // The Web Crypto spec allows for key lengths that are not multiples of - // 8. We don't. Our check here is stricter than that defined by the spec - // in that we require that algorithm.length match keyData.length * 8 if - // algorithm.length is specified. - if (algorithm.length !== undefined && - algorithm.length !== checkLength) { - throw lazyDOMException('Invalid key length', 'DataError'); - } - keyObject = keyData; break; } case 'raw': { - const checkLength = keyData.byteLength * 8; - - if (checkLength === 0 || algorithm.length === 0) - throw lazyDOMException('Zero-length key is not supported', 'DataError'); - - // The Web Crypto spec allows for key lengths that are not multiples of - // 8. We don't. Our check here is stricter than that defined by the spec - // in that we require that algorithm.length match keyData.length * 8 if - // algorithm.length is specified. - if (algorithm.length !== undefined && - algorithm.length !== checkLength) { - throw lazyDOMException('Invalid key length', 'DataError'); - } - keyObject = createSecretKey(keyData); break; } @@ -178,6 +179,14 @@ function hmacImportKey( const { length } = keyObject[kHandle].keyDetail({}); + if (length === 0) + throw lazyDOMException('Zero-length key is not supported', 'DataError'); + + if (algorithm.length !== undefined && + algorithm.length !== length) { + throw lazyDOMException('Invalid key length', 'DataError'); + } + return new InternalCryptoKey( keyObject, { name: 'HMAC', diff --git a/lib/internal/crypto/pbkdf2.js b/lib/internal/crypto/pbkdf2.js index 4148725d0340db..f17816464a36a4 100644 --- a/lib/internal/crypto/pbkdf2.js +++ b/lib/internal/crypto/pbkdf2.js @@ -92,22 +92,28 @@ function check(password, salt, iterations, keylen, digest) { } const pbkdf2Promise = promisify(pbkdf2); -async function pbkdf2DeriveBits(algorithm, baseKey, length) { - const { iterations, hash, salt } = algorithm; - if (iterations === 0) +function validatePbkdf2DeriveBitsAlgorithmAndLength(algorithm, length) { + if (algorithm.iterations === 0) throw lazyDOMException( 'iterations cannot be zero', 'OperationError'); - if (length === 0) - return new ArrayBuffer(0); if (length === null) throw lazyDOMException('length cannot be null', 'OperationError'); + if (length % 8) { throw lazyDOMException( 'length must be a multiple of 8', 'OperationError'); } +} + +async function pbkdf2DeriveBits(algorithm, baseKey, length) { + validatePbkdf2DeriveBitsAlgorithmAndLength(algorithm, length); + const { iterations, hash, salt } = algorithm; + + if (length === 0) + return new ArrayBuffer(0); let result; try { diff --git a/lib/internal/crypto/rsa.js b/lib/internal/crypto/rsa.js index 99c12ebbe3b83f..1dc83f4f6a52a8 100644 --- a/lib/internal/crypto/rsa.js +++ b/lib/internal/crypto/rsa.js @@ -85,16 +85,21 @@ function verifyAcceptableRsaKeyUse(name, isPublic, usages) { } } -function rsaOaepCipher(mode, key, data, { label }) { +function validateRsaOaepAlgorithm(algorithm) { + if (algorithm.label !== undefined) { + validateMaxBufferLength(algorithm.label, 'algorithm.label'); + } +} + +function rsaOaepCipher(mode, key, data, algorithm) { + validateRsaOaepAlgorithm(algorithm); + const type = mode === kWebCryptoCipherEncrypt ? 'public' : 'private'; if (key.type !== type) { throw lazyDOMException( 'The requested operation is not valid for the provided key', 'InvalidAccessError'); } - if (label !== undefined) { - validateMaxBufferLength(label, 'algorithm.label'); - } return jobPromise(() => new RSACipherJob( kCryptoJobAsync, @@ -103,14 +108,26 @@ function rsaOaepCipher(mode, key, data, { label }) { data, kKeyVariantRSA_OAEP, normalizeHashName(key.algorithm.hash.name), - label)); + algorithm.label)); +} + +function validateRsaKeyGenerateAlgorithm(algorithm) { + const publicExponentConverted = bigIntArrayToUnsignedInt(algorithm.publicExponent); + if (publicExponentConverted === undefined) { + throw lazyDOMException( + 'The publicExponent must be equivalent to an unsigned 32-bit value', + 'OperationError'); + } + + return publicExponentConverted; } async function rsaKeyGenerate( algorithm, extractable, - keyUsages) { - + keyUsages, +) { + const publicExponentConverted = validateRsaKeyGenerateAlgorithm(algorithm); const { name, modulusLength, @@ -120,13 +137,6 @@ async function rsaKeyGenerate( const usageSet = new SafeSet(keyUsages); - const publicExponentConverted = bigIntArrayToUnsignedInt(publicExponent); - if (publicExponentConverted === undefined) { - throw lazyDOMException( - 'The publicExponent must be equivalent to an unsigned 32-bit value', - 'OperationError'); - } - switch (name) { case 'RSA-OAEP': if (hasAnyNotIn(usageSet, @@ -319,7 +329,7 @@ function rsaImportKey( }, keyUsages, extractable); } -async function rsaSignVerify(key, data, { saltLength }, signature) { +function rsaSignVerify(key, data, { saltLength }, signature) { const mode = signature === undefined ? kSignJobModeSign : kSignJobModeVerify; const type = mode === kSignJobModeSign ? 'private' : 'public'; diff --git a/lib/internal/crypto/util.js b/lib/internal/crypto/util.js index b2fa04c6691539..e6a8fbdb7743e6 100644 --- a/lib/internal/crypto/util.js +++ b/lib/internal/crypto/util.js @@ -50,8 +50,6 @@ const { ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED, ERR_CRYPTO_ENGINE_UNKNOWN, ERR_INVALID_ARG_TYPE, - ERR_INVALID_ARG_VALUE, - ERR_OUT_OF_RANGE, }, hideStackFrames, } = require('internal/errors'); @@ -418,20 +416,6 @@ function hasAnyNotIn(set, checks) { return false; } -function validateBitLength(length, name, required = false) { - if (length !== undefined || required) { - validateNumber(length, name); - if (length < 0) - throw new ERR_OUT_OF_RANGE(name, '> 0'); - if (length % 8) { - throw new ERR_INVALID_ARG_VALUE( - name, - length, - 'must be a multiple of 8'); - } - } -} - function validateByteLength(buf, name, target) { if (buf.byteLength !== target) { throw lazyDOMException( @@ -617,7 +601,6 @@ module.exports = { normalizeAlgorithm, normalizeHashName, hasAnyNotIn, - validateBitLength, validateByteLength, validateByteSource, validateKeyOps, diff --git a/test/parallel/test-webcrypto-derivebits-cfrg.js b/test/parallel/test-webcrypto-derivebits-cfrg.js index f5c602b6deb630..d45e59fd5087b9 100644 --- a/test/parallel/test-webcrypto-derivebits-cfrg.js +++ b/test/parallel/test-webcrypto-derivebits-cfrg.js @@ -182,7 +182,7 @@ async function prepareKeys() { }, keys.X448.privateKey, 8 * keys.X448.size), - { message: 'The public and private keys must be of the same type' }); + { message: 'algorithm.public must be an X448 key' }); } { diff --git a/test/parallel/test-webcrypto-derivebits-ecdh.js b/test/parallel/test-webcrypto-derivebits-ecdh.js index 6c99946752b4b6..7a7fa09d2b3754 100644 --- a/test/parallel/test-webcrypto-derivebits-ecdh.js +++ b/test/parallel/test-webcrypto-derivebits-ecdh.js @@ -202,7 +202,7 @@ async function prepareKeys() { public: keys['P-384'].publicKey }, keys['P-521'].privateKey, - 8 * keys['P-521'].size), + 8 * keys['P-384'].size), { message: /Named curve mismatch/ }); } @@ -218,7 +218,7 @@ async function prepareKeys() { name: 'ECDH', public: publicKey }, keys['P-521'].privateKey, null), { - message: /Keys must be ECDH, X25519, or X448 keys/ + message: 'algorithm.public must be an ECDH key' }); } diff --git a/test/parallel/test-webcrypto-derivekey-cfrg.js b/test/parallel/test-webcrypto-derivekey-cfrg.js index 213463355ff758..7d8467b4a37cde 100644 --- a/test/parallel/test-webcrypto-derivekey-cfrg.js +++ b/test/parallel/test-webcrypto-derivekey-cfrg.js @@ -136,7 +136,7 @@ async function prepareKeys() { }, keys.X448.privateKey, ...otherArgs), - { message: 'The public and private keys must be of the same type' }); + { message: 'algorithm.public must be an X448 key' }); } { diff --git a/test/parallel/test-webcrypto-derivekey-ecdh.js b/test/parallel/test-webcrypto-derivekey-ecdh.js index 4f801da75afdf0..3b4f86cc02d5ba 100644 --- a/test/parallel/test-webcrypto-derivekey-ecdh.js +++ b/test/parallel/test-webcrypto-derivekey-ecdh.js @@ -174,7 +174,7 @@ async function prepareKeys() { }, keys['P-521'].privateKey, ...otherArgs), - { message: /Keys must be ECDH, X25519, or X448 keys/ }); + { message: 'algorithm.public must be an ECDH key' }); } { diff --git a/test/parallel/test-webcrypto-encrypt-decrypt.js b/test/parallel/test-webcrypto-encrypt-decrypt.js index cba193b8c76594..5d4ecc02c74a31 100644 --- a/test/parallel/test-webcrypto-encrypt-decrypt.js +++ b/test/parallel/test-webcrypto-encrypt-decrypt.js @@ -37,6 +37,20 @@ const { subtle } = globalThis.crypto; assert.strictEqual( Buffer.from(plaintext).toString('hex'), Buffer.from(buf).toString('hex')); + + await assert.rejects(() => subtle.encrypt({ + name: 'RSA-OAEP', + }, privateKey, buf), { + name: 'InvalidAccessError', + message: 'The requested operation is not valid for the provided key' + }); + + await assert.rejects(() => subtle.decrypt({ + name: 'RSA-OAEP', + }, publicKey, ciphertext), { + name: 'InvalidAccessError', + message: 'The requested operation is not valid for the provided key' + }); } test().then(common.mustCall()); diff --git a/test/parallel/test-webcrypto-export-import.js b/test/parallel/test-webcrypto-export-import.js index 02eb33dfa4cdf7..bd0cd056d46741 100644 --- a/test/parallel/test-webcrypto-export-import.js +++ b/test/parallel/test-webcrypto-export-import.js @@ -36,6 +36,15 @@ const { subtle } = globalThis.crypto; }, false, ['sign', 'verify']), { code: 'ERR_MISSING_OPTION' }); + await assert.rejects( + subtle.importKey('raw', keyData, { + name: 'HMAC', + hash: 'SHA-256', + length: 384, + }, false, ['sign', 'verify']), { + name: 'DataError', + message: 'Invalid key length' + }); await assert.rejects( subtle.importKey('raw', keyData, { name: 'HMAC', @@ -59,8 +68,8 @@ const { subtle } = globalThis.crypto; hash: 'SHA-256', length: 1 }, false, ['sign', 'verify']), { - name: 'DataError', - message: 'Invalid key length' + name: 'NotSupportedError', + message: 'Unsupported algorithm.length' }); await assert.rejects( subtle.importKey('jwk', null, { diff --git a/test/parallel/test-webcrypto-keygen.js b/test/parallel/test-webcrypto-keygen.js index 5d36aa3e16a6ca..a60463bdb5f139 100644 --- a/test/parallel/test-webcrypto-keygen.js +++ b/test/parallel/test-webcrypto-keygen.js @@ -345,6 +345,14 @@ const vectors = { { code: 'ERR_INVALID_ARG_TYPE' }); })); + await assert.rejects( + subtle.generateKey( + { name, modulusLength, publicExponent: new Uint8Array([1, 1, 1, 1, 1]), hash }, true, usages), + { + message: /The publicExponent must be equivalent to an unsigned 32-bit value/, + name: 'OperationError', + }); + await Promise.all([true, 1].map((hash) => { return assert.rejects(subtle.generateKey({ name, @@ -494,8 +502,6 @@ const vectors = { const tests = kTests.map((args) => test(...args)); - // Test bad parameters - Promise.all(tests).then(common.mustCall()); } @@ -675,7 +681,5 @@ assert.throws(() => new CryptoKey(), { code: 'ERR_ILLEGAL_CONSTRUCTOR' }); const tests = kTests.map((args) => test(...args)); - // Test bad parameters - Promise.all(tests).then(common.mustCall()); }