Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
48 changes: 17 additions & 31 deletions lib/internal/crypto/aes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
'use strict';

const {
ArrayPrototypePush,
SafeSet,
} = primordials;

const {
AESCipherJob,
kCryptoJobWebCrypto,
Expand All @@ -28,7 +23,6 @@ const {

const {
getUsagesMask,
hasAnyNotIn,
jobPromise,
} = require('internal/crypto/util');

Expand All @@ -46,8 +40,22 @@ const {
importJwkSecretKey,
importSecretKey,
validateJwk,
validateKeyUsages,
validateUsagesNotEmpty,
} = require('internal/crypto/webcrypto_util');

const kCipherUsages = ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'];
const kWrapUsages = ['wrapKey', 'unwrapKey'];

const kUsages = {
'__proto__': null,
'AES-CBC': kCipherUsages,
'AES-CTR': kCipherUsages,
'AES-GCM': kCipherUsages,
'AES-KW': kWrapUsages,
'AES-OCB': kCipherUsages,
};

function getAlgorithmName(name, length) {
switch (name) {
case 'AES-CBC': return `A${length}CBC`;
Expand Down Expand Up @@ -176,21 +184,8 @@ function aesCipher(mode, key, data, algorithm) {
function aesGenerateKey(algorithm, extractable, usages) {
const { name, length } = algorithm;

const checkUsages = ['wrapKey', 'unwrapKey'];
if (name !== 'AES-KW')
ArrayPrototypePush(checkUsages, 'encrypt', 'decrypt');

const usagesSet = new SafeSet(usages);
if (hasAnyNotIn(usagesSet, checkUsages)) {
throw lazyDOMException(
'Unsupported key usage for an AES key',
'SyntaxError');
}
if (usagesSet.size === 0) {
throw lazyDOMException(
'Usages cannot be empty when creating a key.',
'SyntaxError');
}
const usagesSet = validateUsagesNotEmpty(
validateKeyUsages(usages, kUsages[name], name));

return jobPromise(() => new SecretKeyGenJob(
kCryptoJobWebCrypto,
Expand All @@ -207,16 +202,7 @@ function aesImportKey(
extractable,
usages) {
const { name } = algorithm;
const checkUsages = ['wrapKey', 'unwrapKey'];
if (name !== 'AES-KW')
ArrayPrototypePush(checkUsages, 'encrypt', 'decrypt');

const usagesSet = new SafeSet(usages);
if (hasAnyNotIn(usagesSet, checkUsages)) {
throw lazyDOMException(
'Unsupported key usage for an AES key',
'SyntaxError');
}
const usagesSet = validateKeyUsages(usages, kUsages[name], name);

let handle;
let length;
Expand Down
114 changes: 36 additions & 78 deletions lib/internal/crypto/cfrg.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ const {

const {
getUsagesMask,
getUsagesUnion,
hasAnyNotIn,
jobPromise,
} = require('internal/crypto/util');

Expand All @@ -42,60 +40,33 @@ const {
} = require('internal/crypto/keys');

const {
createKeyUsages,
getKeyPairUsages,
importDerKey,
importJwkKey,
importRawKey,
validateJwk,
validateKeyUsages,
validateUsagesNotEmpty,
verifyAcceptableKeyUse,
} = require('internal/crypto/webcrypto_util');

function verifyAcceptableCfrgKeyUse(name, isPublic, usages) {
let checkSet;
switch (name) {
case 'X25519':
// Fall through
case 'X448':
checkSet = isPublic ? [] : ['deriveKey', 'deriveBits'];
break;
case 'Ed25519':
// Fall through
case 'Ed448':
checkSet = isPublic ? ['verify'] : ['sign'];
break;
default:
throw lazyDOMException(
'The algorithm is not supported', 'NotSupportedError');
}
if (hasAnyNotIn(usages, checkSet)) {
throw lazyDOMException(
`Unsupported key usage for a ${name} key`,
'SyntaxError');
}
}
const kDeriveUsages = createKeyUsages([], ['deriveKey', 'deriveBits']);

const kSignVerifyUsages = createKeyUsages(['verify'], ['sign']);

const kUsages = {
'__proto__': null,
'X25519': kDeriveUsages,
'X448': kDeriveUsages,
'Ed25519': kSignVerifyUsages,
'Ed448': kSignVerifyUsages,
};

function cfrgGenerateKey(algorithm, extractable, usages) {
const { name } = algorithm;

const usageSet = new SafeSet(usages);
switch (name) {
case 'Ed25519':
// Fall through
case 'Ed448':
if (hasAnyNotIn(usageSet, ['sign', 'verify'])) {
throw lazyDOMException(
`Unsupported key usage for an ${name} key`,
'SyntaxError');
}
break;
case 'X25519':
// Fall through
case 'X448':
if (hasAnyNotIn(usageSet, ['deriveKey', 'deriveBits'])) {
throw lazyDOMException(
`Unsupported key usage for an ${name} key`,
'SyntaxError');
}
break;
}
const allowedUsages = kUsages[name];
const usagesSet = validateKeyUsages(usages, allowedUsages.keygen, name);
const nid = {
'__proto__': null,
'Ed25519': EVP_PKEY_ED25519,
Expand All @@ -104,37 +75,16 @@ function cfrgGenerateKey(algorithm, extractable, usages) {
'X448': EVP_PKEY_X448,
}[name];

let publicUsages;
let privateUsages;
switch (name) {
case 'Ed25519':
// Fall through
case 'Ed448':
publicUsages = getUsagesUnion(usageSet, 'verify');
privateUsages = getUsagesUnion(usageSet, 'sign');
break;
case 'X25519':
// Fall through
case 'X448':
publicUsages = new SafeSet();
privateUsages = getUsagesUnion(usageSet, 'deriveKey', 'deriveBits');
break;
}

const keyAlgorithm = { name };

if (privateUsages.size === 0) {
throw lazyDOMException(
'Usages cannot be empty when creating a key.',
'SyntaxError');
}
const keyUsages = getKeyPairUsages(usagesSet, allowedUsages);
validateUsagesNotEmpty(keyUsages.private);

return jobPromise(() => new NidKeyPairGenJob(
kCryptoJobWebCrypto,
nid,
keyAlgorithm,
getUsagesMask(publicUsages),
getUsagesMask(privateUsages),
getUsagesMask(keyUsages.public),
getUsagesMask(keyUsages.private),
extractable));
}

Expand Down Expand Up @@ -173,20 +123,25 @@ function cfrgImportKey(

const { name } = algorithm;
let handle;
const allowedUsages = kUsages[name];
const usagesSet = new SafeSet(usages);
switch (format) {
case 'KeyObjectHandle':
verifyAcceptableCfrgKeyUse(
name, keyData.getKeyType() === kKeyTypePublic, usagesSet);
verifyAcceptableKeyUse(
name,
usagesSet,
keyData.getKeyType() === kKeyTypePublic ?
allowedUsages.public :
allowedUsages.private);
handle = keyData;
break;
case 'spki': {
verifyAcceptableCfrgKeyUse(name, true, usagesSet);
verifyAcceptableKeyUse(name, usagesSet, allowedUsages.public);
handle = importDerKey(keyData, true);
break;
}
case 'pkcs8': {
verifyAcceptableCfrgKeyUse(name, false, usagesSet);
verifyAcceptableKeyUse(name, usagesSet, allowedUsages.private);
handle = importDerKey(keyData, false);
break;
}
Expand All @@ -205,12 +160,15 @@ function cfrgImportKey(
}

const isPublic = keyData.d === undefined;
verifyAcceptableCfrgKeyUse(name, isPublic, usagesSet);
verifyAcceptableKeyUse(
name,
usagesSet,
isPublic ? allowedUsages.public : allowedUsages.private);
handle = importJwkKey(isPublic, keyData);
break;
}
case 'raw': {
verifyAcceptableCfrgKeyUse(name, true, usagesSet);
verifyAcceptableKeyUse(name, usagesSet, allowedUsages.public);
handle = importRawKey(true, keyData, kKeyFormatRawPublic, name);
break;
}
Expand Down
33 changes: 8 additions & 25 deletions lib/internal/crypto/chacha20_poly1305.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
'use strict';

const {
SafeSet,
} = primordials;

const {
ChaCha20Poly1305CipherJob,
SecretKeyGenJob,
Expand All @@ -12,7 +8,6 @@ const {

const {
getUsagesMask,
hasAnyNotIn,
jobPromise,
} = require('internal/crypto/util');

Expand All @@ -29,8 +24,12 @@ const {
importJwkSecretKey,
importSecretKey,
validateJwk,
validateKeyUsages,
validateUsagesNotEmpty,
} = require('internal/crypto/webcrypto_util');

const kUsages = ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'];

function validateKeyLength(length) {
if (length !== 256)
throw lazyDOMException('Invalid key length', 'DataError');
Expand All @@ -49,19 +48,8 @@ function c20pCipher(mode, key, data, algorithm) {
function c20pGenerateKey(algorithm, extractable, usages) {
const { name } = algorithm;

const checkUsages = ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'];

const usagesSet = new SafeSet(usages);
if (hasAnyNotIn(usagesSet, checkUsages)) {
throw lazyDOMException(
`Unsupported key usage for a ${algorithm.name} key`,
'SyntaxError');
}
if (usagesSet.size === 0) {
throw lazyDOMException(
'Usages cannot be empty when creating a key.',
'SyntaxError');
}
const usagesSet = validateUsagesNotEmpty(
validateKeyUsages(usages, kUsages, name));

return jobPromise(() => new SecretKeyGenJob(
kCryptoJobWebCrypto,
Expand All @@ -78,14 +66,9 @@ function c20pImportKey(
extractable,
usages) {
const { name } = algorithm;
const checkUsages = ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'];

const usagesSet = new SafeSet(usages);
if (hasAnyNotIn(usagesSet, checkUsages)) {
throw lazyDOMException(
`Unsupported key usage for a ${algorithm.name} key`,
'SyntaxError');
}
const usagesSet = validateKeyUsages(
usages, kUsages, name);

let handle;
switch (format) {
Expand Down
Loading
Loading