mirror of
https://github.com/nodejs/node.git
synced 2025-05-11 05:03:38 +00:00

WebCryptoAPI functions' arguments are now coersed and validated as per their WebIDL definitions like in other Web Crypto API implementations. This further improves interoperability with other implementations of Web Crypto API. PR-URL: https://github.com/nodejs/node/pull/46067 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
182 lines
4.3 KiB
JavaScript
182 lines
4.3 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
|
|
if (!common.hasCrypto)
|
|
common.skip('missing crypto');
|
|
|
|
const assert = require('assert');
|
|
const { subtle } = globalThis.crypto;
|
|
|
|
const vectors = require('../fixtures/crypto/hmac')();
|
|
|
|
async function testVerify({ hash,
|
|
keyBuffer,
|
|
signature,
|
|
plaintext }) {
|
|
const name = 'HMAC';
|
|
const [
|
|
key,
|
|
noVerifyKey,
|
|
rsaKeys,
|
|
] = await Promise.all([
|
|
subtle.importKey(
|
|
'raw',
|
|
keyBuffer,
|
|
{ name, hash },
|
|
false,
|
|
['verify']),
|
|
subtle.importKey(
|
|
'raw',
|
|
keyBuffer,
|
|
{ name, hash },
|
|
false,
|
|
[ /* No usages */ ]),
|
|
subtle.generateKey(
|
|
{
|
|
name: 'RSA-PSS',
|
|
modulusLength: 1024,
|
|
publicExponent: new Uint8Array([1, 0, 1]),
|
|
hash: 'SHA-256',
|
|
},
|
|
false,
|
|
['sign']),
|
|
]);
|
|
|
|
assert(await subtle.verify({ name, hash }, key, signature, plaintext));
|
|
|
|
// Test verification with altered buffers
|
|
const copy = Buffer.from(plaintext);
|
|
const sigcopy = Buffer.from(signature);
|
|
const p = subtle.verify({ name, hash }, key, sigcopy, copy);
|
|
copy[0] = 255 - copy[0];
|
|
sigcopy[0] = 255 - sigcopy[0];
|
|
assert(await p);
|
|
|
|
// Test failure when using wrong key
|
|
await assert.rejects(
|
|
subtle.verify({ name, hash }, noVerifyKey, signature, plaintext), {
|
|
message: /Unable to use this key to verify/
|
|
});
|
|
|
|
// Test failure when using the wrong algorithms
|
|
await assert.rejects(
|
|
subtle.verify({ name, hash }, rsaKeys.publicKey, signature, plaintext), {
|
|
message: /Unable to use this key to verify/
|
|
});
|
|
|
|
// Test failure when signature is altered
|
|
{
|
|
const copy = Buffer.from(signature);
|
|
copy[0] = 255 - copy[0];
|
|
assert(!(await subtle.verify(
|
|
{ name, hash },
|
|
key,
|
|
copy,
|
|
plaintext)));
|
|
assert(!(await subtle.verify(
|
|
{ name, hash },
|
|
key,
|
|
copy.slice(1),
|
|
plaintext)));
|
|
}
|
|
|
|
// Test failure when data is altered
|
|
{
|
|
const copy = Buffer.from(plaintext);
|
|
copy[0] = 255 - copy[0];
|
|
assert(!(await subtle.verify({ name, hash }, key, signature, copy)));
|
|
}
|
|
|
|
// Test failure when wrong hash is used
|
|
{
|
|
const otherhash = hash === 'SHA-1' ? 'SHA-256' : 'SHA-1';
|
|
const keyWithOtherHash = await subtle.importKey(
|
|
'raw',
|
|
keyBuffer,
|
|
{ name, hash: otherhash },
|
|
false,
|
|
['verify']);
|
|
assert(!(await subtle.verify({ name }, keyWithOtherHash, signature, plaintext)));
|
|
}
|
|
}
|
|
|
|
async function testSign({ hash,
|
|
keyBuffer,
|
|
signature,
|
|
plaintext }) {
|
|
const name = 'HMAC';
|
|
const [
|
|
key,
|
|
noSignKey,
|
|
rsaKeys,
|
|
] = await Promise.all([
|
|
subtle.importKey(
|
|
'raw',
|
|
keyBuffer,
|
|
{ name, hash },
|
|
false,
|
|
['verify', 'sign']),
|
|
subtle.importKey(
|
|
'raw',
|
|
keyBuffer,
|
|
{ name, hash },
|
|
false,
|
|
[ 'verify' ]),
|
|
subtle.generateKey(
|
|
{
|
|
name: 'RSA-PSS',
|
|
modulusLength: 1024,
|
|
publicExponent: new Uint8Array([1, 0, 1]),
|
|
hash: 'SHA-256',
|
|
},
|
|
false,
|
|
['sign']),
|
|
]);
|
|
|
|
{
|
|
const sig = await subtle.sign({ name, hash }, key, plaintext);
|
|
assert.strictEqual(
|
|
Buffer.from(sig).toString('hex'),
|
|
signature.toString('hex'));
|
|
assert(await subtle.verify({ name, hash }, key, sig, plaintext));
|
|
}
|
|
|
|
{
|
|
const copy = Buffer.from(plaintext);
|
|
const p = subtle.sign({ name, hash }, key, copy);
|
|
copy[0] = 255 - copy[0];
|
|
const sig = await p;
|
|
assert(await subtle.verify({ name, hash }, key, sig, plaintext));
|
|
}
|
|
|
|
await assert.rejects(
|
|
subtle.generateKey({ name }, false, ['sign', 'verify']), {
|
|
name: 'TypeError',
|
|
code: 'ERR_MISSING_OPTION',
|
|
});
|
|
|
|
// Test failure when no sign usage
|
|
await assert.rejects(
|
|
subtle.sign({ name, hash }, noSignKey, plaintext), {
|
|
message: /Unable to use this key to sign/
|
|
});
|
|
|
|
// Test failure when using the wrong algorithms
|
|
await assert.rejects(
|
|
subtle.sign({ name, hash }, rsaKeys.privateKey, plaintext), {
|
|
message: /Unable to use this key to sign/
|
|
});
|
|
}
|
|
|
|
(async function() {
|
|
const variations = [];
|
|
|
|
vectors.forEach((vector) => {
|
|
variations.push(testVerify(vector));
|
|
variations.push(testSign(vector));
|
|
});
|
|
|
|
await Promise.all(variations);
|
|
})().then(common.mustCall());
|