Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fixup! lib: improve Web Cryptography key validation ordering
  • Loading branch information
panva committed Apr 15, 2026
commit ad8217c6abfc720acbf51fcf9560bc08203e5cc1
40 changes: 20 additions & 20 deletions lib/internal/crypto/webcrypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -920,12 +920,12 @@ async function wrapKey(format, key, wrappingKey, algorithm) {
algorithm = normalizeAlgorithm(algorithm, 'encrypt');
}

if (algorithm.name !== wrappingKey[kAlgorithm].name ||
!ArrayPrototypeIncludes(wrappingKey[kKeyUsages], 'wrapKey')) {
if (algorithm.name !== wrappingKey[kAlgorithm].name)
throw lazyDOMException('Key algorithm mismatch', 'InvalidAccessError');

if (!ArrayPrototypeIncludes(wrappingKey[kKeyUsages], 'wrapKey'))
throw lazyDOMException(
'The requested operation is not valid for the provided key',
'InvalidAccessError');
}
'Unable to use this key to wrapKey', 'InvalidAccessError');

let keyData = await FunctionPrototypeCall(exportKey, this, format, key);

Expand Down Expand Up @@ -1005,12 +1005,12 @@ async function unwrapKey(

unwrappedKeyAlgo = normalizeAlgorithm(unwrappedKeyAlgo, 'importKey');

if (unwrapAlgo.name !== unwrappingKey[kAlgorithm].name ||
!ArrayPrototypeIncludes(unwrappingKey[kKeyUsages], 'unwrapKey')) {
if (unwrapAlgo.name !== unwrappingKey[kAlgorithm].name)
throw lazyDOMException('Key algorithm mismatch', 'InvalidAccessError');

if (!ArrayPrototypeIncludes(unwrappingKey[kKeyUsages], 'unwrapKey'))
throw lazyDOMException(
'The requested operation is not valid for the provided key',
'InvalidAccessError');
}
'Unable to use this key to unwrapKey', 'InvalidAccessError');

let keyData = await cipherOrWrap(
kWebCryptoCipherDecrypt,
Expand Down Expand Up @@ -1186,12 +1186,12 @@ async function encrypt(algorithm, key, data) {

algorithm = normalizeAlgorithm(algorithm, 'encrypt');

if (algorithm.name !== key[kAlgorithm].name ||
!ArrayPrototypeIncludes(key[kKeyUsages], 'encrypt')) {
if (algorithm.name !== key[kAlgorithm].name)
throw lazyDOMException('Key algorithm mismatch', 'InvalidAccessError');

if (!ArrayPrototypeIncludes(key[kKeyUsages], 'encrypt'))
throw lazyDOMException(
'The requested operation is not valid for the provided key',
'InvalidAccessError');
}
'Unable to use this key to encrypt', 'InvalidAccessError');

return await cipherOrWrap(
kWebCryptoCipherEncrypt,
Expand Down Expand Up @@ -1223,12 +1223,12 @@ async function decrypt(algorithm, key, data) {

algorithm = normalizeAlgorithm(algorithm, 'decrypt');

if (algorithm.name !== key[kAlgorithm].name ||
!ArrayPrototypeIncludes(key[kKeyUsages], 'decrypt')) {
if (algorithm.name !== key[kAlgorithm].name)
throw lazyDOMException('Key algorithm mismatch', 'InvalidAccessError');

if (!ArrayPrototypeIncludes(key[kKeyUsages], 'decrypt'))
throw lazyDOMException(
'The requested operation is not valid for the provided key',
'InvalidAccessError');
}
'Unable to use this key to decrypt', 'InvalidAccessError');

return await cipherOrWrap(
kWebCryptoCipherDecrypt,
Expand Down
6 changes: 3 additions & 3 deletions test/parallel/test-webcrypto-encrypt-decrypt-aes.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ async function testEncryptNoEncrypt({ keyBuffer, algorithm, plaintext }) {
['decrypt']);

return assert.rejects(subtle.encrypt(algorithm, key, plaintext), {
message: /The requested operation is not valid for the provided key/
message: /Unable to use this key to encrypt/
});
}

Expand All @@ -65,7 +65,7 @@ async function testEncryptNoDecrypt({ keyBuffer, algorithm, plaintext }) {
const output = await subtle.encrypt(algorithm, key, plaintext);

return assert.rejects(subtle.decrypt(algorithm, key, output), {
message: /The requested operation is not valid for the provided key/
message: /Unable to use this key to decrypt/
});
}

Expand All @@ -80,7 +80,7 @@ async function testEncryptWrongAlg({ keyBuffer, algorithm, plaintext }, alg) {
['encrypt']);

return assert.rejects(subtle.encrypt(algorithm, key, plaintext), {
message: /The requested operation is not valid for the provided key/
message: /Key algorithm mismatch/
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async function testEncryptNoEncrypt({ keyBuffer, algorithm, plaintext }) {
['decrypt']);

return assert.rejects(subtle.encrypt(algorithm, key, plaintext), {
message: /The requested operation is not valid for the provided key/
message: /Unable to use this key to encrypt/
});
}

Expand All @@ -63,7 +63,7 @@ async function testEncryptNoDecrypt({ keyBuffer, algorithm, plaintext }) {
const output = await subtle.encrypt(algorithm, key, plaintext);

return assert.rejects(subtle.decrypt(algorithm, key, output), {
message: /The requested operation is not valid for the provided key/
message: /Unable to use this key to decrypt/
});
}

Expand All @@ -77,7 +77,7 @@ async function testEncryptWrongAlg({ keyBuffer, algorithm, plaintext }, alg) {
['encrypt']);

return assert.rejects(subtle.encrypt(algorithm, key, plaintext), {
message: /The requested operation is not valid for the provided key/
message: /Key algorithm mismatch/
});
}

Expand Down
8 changes: 4 additions & 4 deletions test/parallel/test-webcrypto-encrypt-decrypt-rsa.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ async function testEncryptionWrongKey({ algorithm,
['decrypt']);
return assert.rejects(
subtle.encrypt(algorithm, privateKey, plaintext), {
message: /The requested operation is not valid/
message: /Unable to use this key to encrypt/
});
}

Expand All @@ -167,7 +167,7 @@ async function testEncryptionBadUsage({ algorithm,
['decrypt']);
return assert.rejects(
subtle.encrypt(algorithm, publicKey, plaintext), {
message: /The requested operation is not valid/
message: /Unable to use this key to encrypt/
});
}

Expand All @@ -191,7 +191,7 @@ async function testDecryptionWrongKey({ ciphertext,

return assert.rejects(
subtle.decrypt(algorithm, publicKey, ciphertext), {
message: /The requested operation is not valid/
message: /Unable to use this key to decrypt/
});
}

Expand All @@ -215,7 +215,7 @@ async function testDecryptionBadUsage({ ciphertext,

return assert.rejects(
subtle.decrypt(algorithm, publicKey, ciphertext), {
message: /The requested operation is not valid/
message: /Unable to use this key to decrypt/
});
}

Expand Down
8 changes: 4 additions & 4 deletions test/parallel/test-webcrypto-encrypt-decrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ const { subtle } = globalThis.crypto;
name: 'RSA-OAEP',
}, privateKey, buf), {
name: 'InvalidAccessError',
message: 'The requested operation is not valid for the provided key'
message: 'Unable to use this key to encrypt'
});

await assert.rejects(() => subtle.decrypt({
name: 'RSA-OAEP',
}, publicKey, ciphertext), {
name: 'InvalidAccessError',
message: 'The requested operation is not valid for the provided key'
message: 'Unable to use this key to decrypt'
});
}

Expand Down Expand Up @@ -88,14 +88,14 @@ if (!process.features.openssl_is_boringssl) {
name: 'RSA-OAEP',
}, privateKey, buf), {
name: 'InvalidAccessError',
message: 'The requested operation is not valid for the provided key'
message: 'Unable to use this key to encrypt'
});

await assert.rejects(() => subtle.decrypt({
name: 'RSA-OAEP',
}, publicKey, ciphertext), {
name: 'InvalidAccessError',
message: 'The requested operation is not valid for the provided key'
message: 'Unable to use this key to decrypt'
});
}

Expand Down
8 changes: 4 additions & 4 deletions test/parallel/test-webcrypto-wrap-unwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ function testWrapping(name, keys) {
iv: new Uint8Array(12),
}), {
name: 'InvalidAccessError',
message: 'The requested operation is not valid for the provided key',
message: 'Key algorithm mismatch',
});

// Missing wrapKey usage: aesKey only has encrypt/decrypt, not wrapKey.
Expand All @@ -423,7 +423,7 @@ function testWrapping(name, keys) {
iv: new Uint8Array(12),
}), {
name: 'InvalidAccessError',
message: 'The requested operation is not valid for the provided key',
message: 'Unable to use this key to wrapKey',
});

// Correct wrapping key algorithm and usage results in the expected
Expand Down Expand Up @@ -454,7 +454,7 @@ function testWrapping(name, keys) {
iv: new Uint8Array(12),
}, { name: 'AES-GCM', length: 128 }, true, ['encrypt']), {
name: 'InvalidAccessError',
message: 'The requested operation is not valid for the provided key',
message: 'Key algorithm mismatch',
});

// Missing unwrapKey usage: aesKey only has encrypt/decrypt, not unwrapKey.
Expand All @@ -464,6 +464,6 @@ function testWrapping(name, keys) {
iv: new Uint8Array(12),
}, { name: 'AES-GCM', length: 128 }, true, ['encrypt']), {
name: 'InvalidAccessError',
message: 'The requested operation is not valid for the provided key',
message: 'Unable to use this key to unwrapKey',
});
})().then(common.mustCall());
Loading