mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 21:19:50 +01:00
90e3e5e173
PR-URL: https://github.com/nodejs/node/pull/55262 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
279 lines
7.1 KiB
JavaScript
279 lines
7.1 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
|
|
if (!common.hasCrypto)
|
|
common.skip('missing crypto');
|
|
|
|
const assert = require('assert');
|
|
const { subtle } = globalThis.crypto;
|
|
|
|
{
|
|
async function test() {
|
|
const keyData = globalThis.crypto.getRandomValues(new Uint8Array(32));
|
|
await Promise.all([1, null, undefined, {}, []].map((format) =>
|
|
assert.rejects(
|
|
subtle.importKey(format, keyData, {}, false, ['wrapKey']), {
|
|
code: 'ERR_INVALID_ARG_VALUE'
|
|
})
|
|
));
|
|
await assert.rejects(
|
|
subtle.importKey('not valid', keyData, {}, false, ['wrapKey']), {
|
|
code: 'ERR_INVALID_ARG_VALUE'
|
|
});
|
|
await assert.rejects(
|
|
subtle.importKey('KeyObject', keyData, {}, false, ['wrapKey']), {
|
|
message: /'KeyObject' is not a valid enum value of type KeyFormat/,
|
|
code: 'ERR_INVALID_ARG_VALUE'
|
|
});
|
|
await assert.rejects(
|
|
subtle.importKey('raw', 1, {}, false, ['deriveBits']), {
|
|
code: 'ERR_INVALID_ARG_TYPE'
|
|
});
|
|
await assert.rejects(
|
|
subtle.importKey('raw', keyData, {
|
|
name: 'HMAC'
|
|
}, false, ['sign', 'verify']), {
|
|
code: 'ERR_MISSING_OPTION'
|
|
});
|
|
await assert.rejects(
|
|
subtle.importKey('raw', keyData, {
|
|
name: 'HMAC',
|
|
hash: 'SHA-256'
|
|
}, false, ['deriveBits']), {
|
|
name: 'SyntaxError',
|
|
message: 'Unsupported key usage for an HMAC key'
|
|
});
|
|
await assert.rejects(
|
|
subtle.importKey('raw', keyData, {
|
|
name: 'HMAC',
|
|
hash: 'SHA-256',
|
|
length: 0
|
|
}, false, ['sign', 'verify']), {
|
|
name: 'DataError',
|
|
message: 'Zero-length key is not supported'
|
|
});
|
|
await assert.rejects(
|
|
subtle.importKey('raw', keyData, {
|
|
name: 'HMAC',
|
|
hash: 'SHA-256',
|
|
length: 1
|
|
}, false, ['sign', 'verify']), {
|
|
name: 'DataError',
|
|
message: 'Invalid key length'
|
|
});
|
|
await assert.rejects(
|
|
subtle.importKey('jwk', null, {
|
|
name: 'HMAC',
|
|
hash: 'SHA-256',
|
|
}, false, ['sign', 'verify']), {
|
|
name: 'DataError',
|
|
message: 'Invalid keyData'
|
|
});
|
|
}
|
|
|
|
test().then(common.mustCall());
|
|
}
|
|
|
|
// Import/Export HMAC Secret Key
|
|
{
|
|
async function test() {
|
|
const keyData = globalThis.crypto.getRandomValues(new Uint8Array(32));
|
|
const key = await subtle.importKey(
|
|
'raw',
|
|
keyData, {
|
|
name: 'HMAC',
|
|
hash: 'SHA-256'
|
|
}, true, ['sign', 'verify']);
|
|
|
|
const raw = await subtle.exportKey('raw', key);
|
|
|
|
assert.deepStrictEqual(
|
|
Buffer.from(keyData).toString('hex'),
|
|
Buffer.from(raw).toString('hex'));
|
|
|
|
const jwk = await subtle.exportKey('jwk', key);
|
|
assert.deepStrictEqual(jwk.key_ops, ['sign', 'verify']);
|
|
assert(jwk.ext);
|
|
assert.strictEqual(jwk.kty, 'oct');
|
|
|
|
assert.deepStrictEqual(
|
|
Buffer.from(jwk.k, 'base64').toString('hex'),
|
|
Buffer.from(raw).toString('hex'));
|
|
|
|
await assert.rejects(
|
|
subtle.importKey(
|
|
'raw',
|
|
keyData,
|
|
{
|
|
name: 'HMAC',
|
|
hash: 'SHA-256'
|
|
},
|
|
true,
|
|
[/* empty usages */]),
|
|
{ name: 'SyntaxError', message: 'Usages cannot be empty when importing a secret key.' });
|
|
}
|
|
|
|
test().then(common.mustCall());
|
|
}
|
|
|
|
// Import/Export AES Secret Key
|
|
{
|
|
async function test() {
|
|
const keyData = globalThis.crypto.getRandomValues(new Uint8Array(32));
|
|
const key = await subtle.importKey(
|
|
'raw',
|
|
keyData, {
|
|
name: 'AES-CTR',
|
|
length: 256,
|
|
}, true, ['encrypt', 'decrypt']);
|
|
|
|
const raw = await subtle.exportKey('raw', key);
|
|
|
|
assert.deepStrictEqual(
|
|
Buffer.from(keyData).toString('hex'),
|
|
Buffer.from(raw).toString('hex'));
|
|
|
|
const jwk = await subtle.exportKey('jwk', key);
|
|
assert.deepStrictEqual(jwk.key_ops, ['encrypt', 'decrypt']);
|
|
assert(jwk.ext);
|
|
assert.strictEqual(jwk.kty, 'oct');
|
|
|
|
assert.deepStrictEqual(
|
|
Buffer.from(jwk.k, 'base64').toString('hex'),
|
|
Buffer.from(raw).toString('hex'));
|
|
|
|
await assert.rejects(
|
|
subtle.importKey(
|
|
'raw',
|
|
keyData,
|
|
{
|
|
name: 'AES-CTR',
|
|
length: 256,
|
|
},
|
|
true,
|
|
[/* empty usages */]),
|
|
{ name: 'SyntaxError', message: 'Usages cannot be empty when importing a secret key.' });
|
|
}
|
|
|
|
test().then(common.mustCall());
|
|
}
|
|
|
|
// Import/Export RSA Key Pairs
|
|
{
|
|
async function test() {
|
|
const { publicKey, privateKey } = await subtle.generateKey({
|
|
name: 'RSA-PSS',
|
|
modulusLength: 1024,
|
|
publicExponent: new Uint8Array([1, 0, 1]),
|
|
hash: 'SHA-384'
|
|
}, true, ['sign', 'verify']);
|
|
|
|
const [
|
|
spki,
|
|
pkcs8,
|
|
publicJwk,
|
|
privateJwk,
|
|
] = await Promise.all([
|
|
subtle.exportKey('spki', publicKey),
|
|
subtle.exportKey('pkcs8', privateKey),
|
|
subtle.exportKey('jwk', publicKey),
|
|
subtle.exportKey('jwk', privateKey),
|
|
]);
|
|
|
|
assert(spki);
|
|
assert(pkcs8);
|
|
assert(publicJwk);
|
|
assert(privateJwk);
|
|
|
|
const [
|
|
importedSpkiPublicKey,
|
|
importedPkcs8PrivateKey,
|
|
importedJwkPublicKey,
|
|
importedJwkPrivateKey,
|
|
] = await Promise.all([
|
|
subtle.importKey('spki', spki, {
|
|
name: 'RSA-PSS',
|
|
hash: 'SHA-384',
|
|
}, true, ['verify']),
|
|
subtle.importKey('pkcs8', pkcs8, {
|
|
name: 'RSA-PSS',
|
|
hash: 'SHA-384',
|
|
}, true, ['sign']),
|
|
subtle.importKey('jwk', publicJwk, {
|
|
name: 'RSA-PSS',
|
|
hash: 'SHA-384',
|
|
}, true, ['verify']),
|
|
subtle.importKey('jwk', privateJwk, {
|
|
name: 'RSA-PSS',
|
|
hash: 'SHA-384',
|
|
}, true, ['sign']),
|
|
]);
|
|
|
|
assert(importedSpkiPublicKey);
|
|
assert(importedPkcs8PrivateKey);
|
|
assert(importedJwkPublicKey);
|
|
assert(importedJwkPrivateKey);
|
|
}
|
|
|
|
test().then(common.mustCall());
|
|
}
|
|
|
|
// Import/Export EC Key Pairs
|
|
{
|
|
async function test() {
|
|
const { publicKey, privateKey } = await subtle.generateKey({
|
|
name: 'ECDSA',
|
|
namedCurve: 'P-384'
|
|
}, true, ['sign', 'verify']);
|
|
|
|
const [
|
|
spki,
|
|
pkcs8,
|
|
publicJwk,
|
|
privateJwk,
|
|
] = await Promise.all([
|
|
subtle.exportKey('spki', publicKey),
|
|
subtle.exportKey('pkcs8', privateKey),
|
|
subtle.exportKey('jwk', publicKey),
|
|
subtle.exportKey('jwk', privateKey),
|
|
]);
|
|
|
|
assert(spki);
|
|
assert(pkcs8);
|
|
assert(publicJwk);
|
|
assert(privateJwk);
|
|
|
|
const [
|
|
importedSpkiPublicKey,
|
|
importedPkcs8PrivateKey,
|
|
importedJwkPublicKey,
|
|
importedJwkPrivateKey,
|
|
] = await Promise.all([
|
|
subtle.importKey('spki', spki, {
|
|
name: 'ECDSA',
|
|
namedCurve: 'P-384'
|
|
}, true, ['verify']),
|
|
subtle.importKey('pkcs8', pkcs8, {
|
|
name: 'ECDSA',
|
|
namedCurve: 'P-384'
|
|
}, true, ['sign']),
|
|
subtle.importKey('jwk', publicJwk, {
|
|
name: 'ECDSA',
|
|
namedCurve: 'P-384'
|
|
}, true, ['verify']),
|
|
subtle.importKey('jwk', privateJwk, {
|
|
name: 'ECDSA',
|
|
namedCurve: 'P-384'
|
|
}, true, ['sign']),
|
|
]);
|
|
|
|
assert(importedSpkiPublicKey);
|
|
assert(importedPkcs8PrivateKey);
|
|
assert(importedJwkPublicKey);
|
|
assert(importedJwkPrivateKey);
|
|
}
|
|
|
|
test().then(common.mustCall());
|
|
}
|