Skip to content

Commit

Permalink
crypto: fix webcrypto operation errors to be OperationError
Browse files Browse the repository at this point in the history
PR-URL: nodejs/node#44171
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Tobias Nießen <[email protected]>
Backport-PR-URL: nodejs/node#44872
  • Loading branch information
panva authored and guangwong committed Jan 3, 2023
1 parent 0ea9df3 commit 99c78d6
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 205 deletions.
32 changes: 15 additions & 17 deletions lib/internal/crypto/aes.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const {
ArrayPrototypeIncludes,
ArrayPrototypePush,
MathFloor,
Promise,
SafeSet,
TypedArrayPrototypeSlice,
} = primordials;
Expand Down Expand Up @@ -46,6 +45,7 @@ const {

const {
lazyDOMException,
promisify,
} = require('internal/util');

const { PromiseReject } = primordials;
Expand All @@ -57,11 +57,12 @@ const {
} = require('internal/crypto/keys');

const {
generateKey,
generateKey: _generateKey,
} = require('internal/crypto/keygen');

const kMaxCounterLength = 128;
const kTagLengths = [32, 64, 96, 104, 112, 120, 128];
const generateKey = promisify(_generateKey);

function getAlgorithmName(name, length) {
switch (name) {
Expand Down Expand Up @@ -239,22 +240,19 @@ async function aesGenerateKey(algorithm, extractable, keyUsages) {
'SyntaxError');
}

return new Promise((resolve, reject) => {
generateKey('aes', { length }, (err, key) => {
if (err) {
return reject(lazyDOMException(
'The operation failed for an operation-specific reason ' +
`[${err.message}]`,
'OperationError'));
}

resolve(new InternalCryptoKey(
key,
{ name, length },
ArrayFrom(usagesSet),
extractable));
});
const key = await generateKey('aes', { length }).catch((err) => {
// TODO(@panva): add err as cause to DOMException
throw lazyDOMException(
'The operation failed for an operation-specific reason' +
`[${err.message}]`,
'OperationError');
});

return new InternalCryptoKey(
key,
{ name, length },
ArrayFrom(usagesSet),
extractable);
}

async function aesImportKey(
Expand Down
116 changes: 58 additions & 58 deletions lib/internal/crypto/cfrg.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

const {
Promise,
SafeSet,
} = primordials;

Expand Down Expand Up @@ -31,10 +30,11 @@ const {
const {
emitExperimentalWarning,
lazyDOMException,
promisify,
} = require('internal/util');

const {
generateKeyPair,
generateKeyPair: _generateKeyPair,
} = require('internal/crypto/keygen');

const {
Expand All @@ -45,6 +45,8 @@ const {
createPublicKey,
} = require('internal/crypto/keys');

const generateKeyPair = promisify(_generateKeyPair);

function verifyAcceptableCfrgKeyUse(name, type, usages) {
let checkSet;
switch (name) {
Expand Down Expand Up @@ -131,65 +133,63 @@ async function cfrgGenerateKey(algorithm, extractable, keyUsages) {
}
break;
}
return new Promise((resolve, reject) => {
let genKeyType;
switch (name) {
case 'Ed25519':
genKeyType = 'ed25519';
break;
case 'Ed448':
genKeyType = 'ed448';
break;
case 'X25519':
genKeyType = 'x25519';
break;
case 'X448':
genKeyType = 'x448';
break;
}
generateKeyPair(genKeyType, undefined, (err, pubKey, privKey) => {
if (err) {
return reject(lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError'));
}
let genKeyType;
switch (name) {
case 'Ed25519':
genKeyType = 'ed25519';
break;
case 'Ed448':
genKeyType = 'ed448';
break;
case 'X25519':
genKeyType = 'x25519';
break;
case 'X448':
genKeyType = 'x448';
break;
}

const algorithm = { name };
const keyPair = await generateKeyPair(genKeyType).catch((err) => {
// TODO(@panva): add err as cause to DOMException
throw lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError');
});

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 = [];
privateUsages = getUsagesUnion(usageSet, 'deriveKey', 'deriveBits');
break;
}
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 = [];
privateUsages = getUsagesUnion(usageSet, 'deriveKey', 'deriveBits');
break;
}

const publicKey =
new InternalCryptoKey(
pubKey,
algorithm,
publicUsages,
true);

const privateKey =
new InternalCryptoKey(
privKey,
algorithm,
privateUsages,
extractable);

resolve({ publicKey, privateKey });
});
});
const keyAlgorithm = { name };

const publicKey =
new InternalCryptoKey(
keyPair.publicKey,
keyAlgorithm,
publicUsages,
true);

const privateKey =
new InternalCryptoKey(
keyPair.privateKey,
keyAlgorithm,
privateUsages,
extractable);

return { privateKey, publicKey };
}

function cfrgExportKey(key, format) {
Expand Down
78 changes: 39 additions & 39 deletions lib/internal/crypto/ec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

const {
ObjectKeys,
Promise,
SafeSet,
} = primordials;

Expand Down Expand Up @@ -42,10 +41,11 @@ const {

const {
lazyDOMException,
promisify,
} = require('internal/util');

const {
generateKeyPair,
generateKeyPair: _generateKeyPair,
} = require('internal/crypto/keygen');

const {
Expand All @@ -56,6 +56,8 @@ const {
createPublicKey,
} = require('internal/crypto/keys');

const generateKeyPair = promisify(_generateKeyPair);

function verifyAcceptableEcKeyUse(name, type, usages) {
let checkSet;
switch (name) {
Expand Down Expand Up @@ -111,46 +113,44 @@ async function ecGenerateKey(algorithm, extractable, keyUsages) {
}
// Fall through
}
return new Promise((resolve, reject) => {
generateKeyPair('ec', { namedCurve }, (err, pubKey, privKey) => {
if (err) {
return reject(lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError'));
}

const algorithm = { name, namedCurve };
const keypair = await generateKeyPair('ec', { namedCurve }).catch((err) => {
// TODO(@panva): add err as cause to DOMException
throw lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError');
});

let publicUsages;
let privateUsages;
switch (name) {
case 'ECDSA':
publicUsages = getUsagesUnion(usageSet, 'verify');
privateUsages = getUsagesUnion(usageSet, 'sign');
break;
case 'ECDH':
publicUsages = [];
privateUsages = getUsagesUnion(usageSet, 'deriveKey', 'deriveBits');
break;
}
let publicUsages;
let privateUsages;
switch (name) {
case 'ECDSA':
publicUsages = getUsagesUnion(usageSet, 'verify');
privateUsages = getUsagesUnion(usageSet, 'sign');
break;
case 'ECDH':
publicUsages = [];
privateUsages = getUsagesUnion(usageSet, 'deriveKey', 'deriveBits');
break;
}

const publicKey =
new InternalCryptoKey(
pubKey,
algorithm,
publicUsages,
true);

const privateKey =
new InternalCryptoKey(
privKey,
algorithm,
privateUsages,
extractable);

resolve({ publicKey, privateKey });
});
});
const keyAlgorithm = { name, namedCurve };

const publicKey =
new InternalCryptoKey(
keypair.publicKey,
keyAlgorithm,
publicUsages,
true);

const privateKey =
new InternalCryptoKey(
keypair.privateKey,
keyAlgorithm,
privateUsages,
extractable);

return { publicKey, privateKey };
}

function ecExportKey(key, format) {
Expand Down
30 changes: 15 additions & 15 deletions lib/internal/crypto/mac.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

const {
ArrayFrom,
Promise,
SafeSet,
} = primordials;

Expand All @@ -27,6 +26,7 @@ const {

const {
lazyDOMException,
promisify,
} = require('internal/util');

const {
Expand All @@ -36,7 +36,7 @@ const {
} = require('internal/errors');

const {
generateKey,
generateKey: _generateKey,
} = require('internal/crypto/keygen');

const {
Expand All @@ -45,6 +45,8 @@ const {
createSecretKey,
} = require('internal/crypto/keys');

const generateKey = promisify(_generateKey);

async function hmacGenerateKey(algorithm, extractable, keyUsages) {
const { hash, name } = algorithm;
let { length } = algorithm;
Expand All @@ -62,21 +64,19 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) {
'Unsupported key usage for an HMAC key',
'SyntaxError');
}
return new Promise((resolve, reject) => {
generateKey('hmac', { length }, (err, key) => {
if (err) {
return reject(lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError'));
}

resolve(new InternalCryptoKey(
key,
{ name, length, hash: { name: hash.name } },
ArrayFrom(usageSet),
extractable));
});
const key = await generateKey('hmac', { length }).catch((err) => {
// TODO(@panva): add err as cause to DOMException
throw lazyDOMException(
'The operation failed for an operation-specific reason',
'OperationError');
});

return new InternalCryptoKey(
key,
{ name, length, hash: { name: hash.name } },
ArrayFrom(usageSet),
extractable);
}

async function hmacImportKey(
Expand Down
Loading

0 comments on commit 99c78d6

Please sign in to comment.