node/test/parallel/test-webcrypto-export-import.js
Filip Skokan 3ef38c4bd7
crypto: use WebIDL converters in WebCryptoAPI
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>
2023-01-17 08:57:58 +00:00

250 lines
6.3 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('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'));
}
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'));
}
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());
}