Code Diff
diff --git a/lib/internal/crypto/aes.js b/lib/internal/crypto/aes.js
index c0765f75642189..cc443b575da46a 100644
--- a/lib/internal/crypto/aes.js
+++ b/lib/internal/crypto/aes.js
@@ -10,6 +10,8 @@ const {
AESCipherJob,
KeyObjectHandle,
kCryptoJobAsync,
+ kKeyFormatJWK,
+ kKeyTypeSecret,
kKeyVariantAES_CTR_128,
kKeyVariantAES_CBC_128,
kKeyVariantAES_GCM_128,
@@ -30,7 +32,6 @@ const {
const {
hasAnyNotIn,
jobPromise,
- validateKeyOps,
kHandle,
kKeyObject,
} = require('internal/crypto/util');
@@ -47,6 +48,10 @@ const {
kAlgorithm,
} = require('internal/crypto/keys');
+const {
+ validateJwk,
+} = require('internal/crypto/webcrypto_util');
+
const {
generateKey: _generateKey,
} = require('internal/crypto/keygen');
@@ -245,31 +250,11 @@ function aesImportKey(
break;
}
case 'jwk': {
- if (!keyData.kty)
- throw lazyDOMException('Invalid keyData', 'DataError');
-
- if (keyData.kty !== 'oct')
- throw lazyDOMException('Invalid JWK "kty" Parameter', 'DataError');
-
- if (usagesSet.size > 0 &&
- keyData.use !== undefined &&
- keyData.use !== 'enc') {
- throw lazyDOMException('Invalid JWK "use" Parameter', 'DataError');
- }
-
- validateKeyOps(keyData.key_ops, usagesSet);
-
- if (keyData.ext !== undefined &&
- keyData.ext === false &&
- extractable === true) {
- throw lazyDOMException(
- 'JWK "ext" Parameter and extractable mismatch',
- 'DataError');
- }
+ validateJwk(keyData, 'oct', extractable, usagesSet, 'enc');
const handle = new KeyObjectHandle();
try {
- handle.initJwk(keyData);
+ handle.init(kKeyTypeSecret, keyData, kKeyFormatJWK, null, null);
} catch (err) {
throw lazyDOMException(
'Invalid keyData', { name: 'DataError', cause: err });
diff --git a/lib/internal/crypto/cfrg.js b/lib/internal/crypto/cfrg.js
index b943ba020750f9..58e8fb02943b78 100644
--- a/lib/internal/crypto/cfrg.js
+++ b/lib/internal/crypto/cfrg.js
@@ -6,15 +6,11 @@ const {
TypedArrayPrototypeGetBuffer,
} = primordials;
-const { Buffer } = require('buffer');
-
const {
- KeyObjectHandle,
SignJob,
kCryptoJobAsync,
kKeyFormatDER,
- kKeyTypePrivate,
- kKeyTypePublic,
+ kKeyFormatRawPublic,
kSignJobModeSign,
kSignJobModeVerify,
kWebCryptoKeyFormatPKCS8,
@@ -22,17 +18,10 @@ const {
kWebCryptoKeyFormatSPKI,
} = internalBinding('crypto');
-const {
- codes: {
- ERR_CRYPTO_INVALID_JWK,
- },
-} = require('internal/errors');
-
const {
getUsagesUnion,
hasAnyNotIn,
jobPromise,
- validateKeyOps,
kHandle,
kKeyObject,
} = require('internal/crypto/util');
@@ -48,13 +37,16 @@ const {
const {
InternalCryptoKey,
- PrivateKeyObject,
- PublicKeyObject,
- createPrivateKey,
- createPublicKey,
kKeyType,
} = require('internal/crypto/keys');
+const {
+ importDerKey,
+ importJwkKey,
+ importRawKey,
+ validateJwk,
+} = require('internal/crypto/webcrypto_util');
+
const generateKeyPair = promisify(_generateKeyPair);
function verifyAcceptableCfrgKeyUse(name, isPublic, usages) {
@@ -81,39 +73,6 @@ function verifyAcceptableCfrgKeyUse(name, isPublic, usages) {
}
}
-function createCFRGRawKey(name, keyData, isPublic) {
- const handle = new KeyObjectHandle();
-
- switch (name) {
- case 'Ed25519':
- case 'X25519':
- if (keyData.byteLength !== 32) {
- throw lazyDOMException(
- `${name} raw keys must be exactly 32-bytes`, 'DataError');
- }
- break;
- case 'Ed448':
- if (keyData.byteLength !== 57) {
- throw lazyDOMException(
- `${name} raw keys must be exactly 57-bytes`, 'DataError');
- }
- break;
- case 'X448':
- if (keyData.byteLength !== 56) {
- throw lazyDOMException(
- `${name} raw keys must be exactly 56-bytes`, 'DataError');
- }
- break;
- }
-
- const keyType = isPublic ? kKeyTypePublic : kKeyTypePrivate;
- if (!handle.initEDRaw(name, keyData, keyType)) {
- throw lazyDOMException('Invalid keyData', 'DataError');
- }
-
- return isPublic ? new PublicKeyObject(handle) : new PrivateKeyObject(handle);
-}
-
async function cfrgGenerateKey(algorithm, extractable, keyUsages) {
const { name } = algorithm;
@@ -243,113 +202,36 @@ function cfrgImportKey(
}
case 'spki': {
verifyAcceptableCfrgKeyUse(name, true, usagesSet);
- try {
- keyObject = createPublicKey({
- key: keyData,
- format: 'der',
- type: 'spki',
- });
- } catch (err) {
- throw lazyDOMException(
- 'Invalid keyData', { name: 'DataError', cause: err });
- }
+ keyObject = importDerKey(keyData, true);
break;
}
case 'pkcs8': {
verifyAcceptableCfrgKeyUse(name, false, usagesSet);
- try {
- keyObject = createPrivateKey({
- key: keyData,
- format: 'der',
- type: 'pkcs8',
- });
- } catch (err) {
- throw lazyDOMException(
- 'Invalid keyData', { name: 'DataError', cause: err });
- }
+ keyObject = importDerKey(keyData, false);
break;
}
case 'jwk': {
- if (!keyData.kty)
- throw lazyDOMException('Invalid keyData', 'DataError');
- if (keyData.kty !== 'OKP')
- throw lazyDOMException('Invalid JWK "kty" Parameter', 'DataError');
+ const expectedUse = (name === 'X25519' || name === 'X448') ? 'enc' : 'sig';
+ validateJwk(keyData, 'OKP', extractable, usagesSet, expectedUse);
+
if (keyData.crv !== name)
throw lazyDOMException(
'JWK "crv" Parameter and algorithm name mismatch', 'DataError');
- const isPublic = keyData.d === undefined;
-
- if (usagesSet.size > 0 && keyData.use !== undefined) {
- let checkUse;
- switch (name) {
- case 'Ed25519':
- // Fall through
- case 'Ed448':
- checkUse = 'sig';
- break;
- case 'X25519':
- // Fall through
- case 'X448':
- checkUse = 'enc';
- break;
- }
- if (keyData.use !== checkUse)
- throw lazyDOMException('Invalid JWK "use" Parameter', 'DataError');
- }
-
- validateKeyOps(keyData.key_ops, usagesSet);
-
- if (keyData.ext !== undefined &&
- keyData.ext === false &&
- extractable === true) {
- throw lazyDOMException(
- 'JWK "ext" Parameter and extractable mismatch',
- 'DataError');
- }
if (keyData.alg !== undefined && (name === 'Ed25519' || name === 'Ed448')) {
- if (keyData.alg !== name && keyData.alg !== 'EdDSA') {
+ if (keyData.alg !== name && keyData.alg !== 'EdDSA')
throw lazyDOMException(
- 'JWK "alg" does not match the requested algorithm',
- 'DataError');
- }
+ 'JWK "alg" does not match the requested algorithm', 'DataError');
}
- if (!isPublic && typeof keyData.x !== 'string') {
- throw lazyDOMException('Invalid JWK', 'DataError');
- }
-
- verifyAcceptableCfrgKeyUse(
- name,
- isPublic,
- usagesSet);
-
- try {
- const publicKeyObject = createCFRGRawKey(
- name,
- Buffer.from(keyData.x, 'base64'),
- true);
-
- if (isPublic) {
- keyObject = publicKeyObject;
- } else {
- keyObject = createCFRGRawKey(
- name,
- Buffer.from(keyData.d, 'base64'),
- false);
-
- if (!createPublicKey(keyObject).equals(publicKeyObject)) {
- throw new ERR_CRYPTO_INVALID_JWK();
- }
- }
- } catch (err) {
- throw lazyDOMException('Invalid keyData', { name: 'DataError', cause: err });
- }
+ const isPublic = keyData.d === undefined;
+ verifyAcceptableCfrgKeyUse(name, isPublic, usagesSet);
+ keyObject = importJwkKey(isPublic, keyData);
break;
}
case 'raw': {
verifyAcceptableCfrgKeyUse(name, true, usagesSet);
- keyObject = createCFRGRawKey(name, keyData, true);
+ keyObject = importRawKey(true, keyData, kKeyFormatRawPublic, name);
break;
}
default:
@@ -381,6 +263,7 @@ async function eddsaSignVerify(key, data, algorithm, signature) {
undefined,
undefined,
undefined,
+ undefined,
data,
undefined,
undefined,
diff --git a/lib/internal/crypto/chacha20_poly1305.js b/lib/internal/crypto/chacha20_poly1305.js
index a2b7c1fb04fb89..2230097c4c5c9f 100644
--- a/lib/internal/crypto/chacha20_poly1305.js
+++ b/lib/internal/crypto/chacha20_poly1305.js
@@ -9,12 +9,13 @@ const {
ChaCha20Poly1305CipherJob,
KeyObjectHandle,
kCryptoJobAsync,
+ kKeyFormatJWK,
+ kKeyTypeSecret,
} = internalBinding('crypto');
const {
hasAnyNotIn,
jobPromise,
- validateKeyOps,
kHandle,
kKeyObject,
} = require('internal/crypto/util');
@@ -30,6 +31,10 @@ const {
createSecretKey,
} = require('internal/crypto/keys');
+const {
+ validateJwk,
+} = require('internal/crypto/webcrypto_util');
+
const {
randomBytes: _randomBytes,
} = require('internal/crypto/random');
@@ -107,31 +112,11 @@ function c20pImportKey(
break;
}
case 'jwk': {
- if (!keyData.kty)
- throw lazyDOMException('Invalid keyData', 'DataError');
-
- if (keyData.kty !== 'oct')
- throw lazyDOMException('Invalid JWK "kty" Parameter', 'DataError');
-
- if (usagesSet.size > 0 &&
- keyData.use !== undefined &&
- keyData.use !== 'enc') {
- throw lazyDOMException('Invalid JWK "use" Parameter', 'DataError');
- }
-
- validateKeyOps(keyData.key_ops, usagesSet);
-
- if (keyData.ext !== undefined &&
- keyData.ext === false &&
- extractable === true) {
- throw lazyDOMException(
- 'JWK "ext" Parameter and extractable mismatch',
- 'DataError');
- }
+ validateJwk(keyData, 'oct', extractable, usagesSet, 'enc');
const handle = new KeyObjectHandle();
try {
- handle.initJwk(keyData);
+ handle.init(kKeyTypeSecret, keyData, kKeyFormatJWK, null, null);
} catch (err) {
throw lazyDOMException(
'Invalid keyData', { name: 'DataError', cause: err });
diff --git a/lib/internal/crypto/cipher.js b/lib/internal/crypto/cipher.js
index 113713bc601014..c463ea41f763b3 100644
--- a/lib/internal/crypto/cipher.js
+++ b/lib/internal/crypto/cipher.js
@@ -64,7 +64,7 @@ const { StringDecoder } = require('string_decoder');
function rsaFunctionFor(method, defaultPadding, keyType) {
return (options, buffer) => {
- const { format, type, data, passphrase } =
+ const { format, type, data, passphrase, namedCurve } =
keyType === 'private' ?
preparePrivateKey(options) :
preparePublicOrPrivateKey(options);
@@ -76,8 +76,8 @@ function rsaFunctionFor(method, defaultPadding, keyType) {
if (oaepLabel !== undefined)
oaepLabel = getArrayBufferOrView(oaepLabel, 'key.oaepLabel', encoding);
buffer = getArrayBufferOrView(buffer, 'buffer', encoding);
- return method(data, format, type, passphrase, buffer, padding, oaepHash,
- oaepLabel);
+ return method(data, format, type, passphrase, namedCurve, buffer,
+ padding, oaepHash, oaepLabel);
};
}
diff --git a/lib/internal/crypto/ec.js b/lib/internal/crypto/ec.js
index a73b1c6c0bc4bf..3b0b35e8f0f822 100644
--- a/lib/internal/crypto/ec.js
+++ b/lib/internal/crypto/ec.js
@@ -11,7 +11,8 @@ const {
SignJob,
kCryptoJobAsync,
kKeyFormatDER,
- kKeyTypePrivate,
+ kKeyFormatRawPublic,
+ kKeyTypePublic,
kSignJobModeSign,
kSignJobModeVerify,
kSigEncP1363,
@@ -31,7 +32,6 @@ const {
hasAnyNotIn,
jobPromise,
normalizeHashName,
- validateKeyOps,
kHandle,
kKeyObject,
kNamedCurveAliases,
@@ -48,14 +48,17 @@ const {
const {
InternalCryptoKey,
- PrivateKeyObject,
- PublicKeyObject,
- createPrivateKey,
- createPublicKey,
kAlgorithm,
kKeyType,
} = require('internal/crypto/keys');
+const {
+ importDerKey,
+ importJwkKey,
+ importRawKey,
+ validateJwk,
+} = require('internal/crypto/webcrypto_util');
+
const generateKeyPair = promisify(_generateKeyPair);
function verifyAcceptableEcKeyUse(name, isPublic, usages) {
@@ -78,16 +81,6 @@ function verifyAcceptableEcKeyUse(name, isPublic, usages) {
}
}
-function createECPublicKeyRaw(namedCurve, keyData) {
- const handle = new KeyObjectHandle();
-
- if (!handle.initECRaw(kNamedCurveAliases[namedCurve], keyData)) {
- throw lazyDOMException('Invalid keyData', 'DataError');
- }
-
- return new PublicKeyObject(handle);
-}
-
async function ecGenerateKey(algorithm, extractable, keyUsages) {
const { name, namedCurve } = algorithm;
@@ -173,7 +166,8 @@ function ecExportKey(key, format) {
}[key[kAlgorithm].namedCurve]) {
const raw = handle.exportECPublicRaw(POINT_CONVERSION_UNCOMPRESSED);
const tmp = new KeyObjectHandle();
- tmp.initECRaw(kNamedCurveAliases[key[kAlgorithm].namedCurve], raw);
+ tmp.init(kKeyTypePublic, raw, kKeyFormatRawPublic,
+ 'ec', null, key[kAlgorithm].namedCurve);
spki = tmp.export(kKeyFormatDER, kWebCryptoKeyFormatSPKI);
}
return TypedArrayPrototypeGetBuffer(spki);
@@ -211,63 +205,23 @@ function ecImportKey(
}
case 'spki': {
verifyAcceptableEcKeyUse(name, true, usagesSet);
- try {
- keyObject = createPublicKey({
- key: keyData,
- format: 'der',
- type: 'spki',
- });
- } catch (err) {
- throw lazyDOMException(
- 'Invalid keyData', { name: 'DataError', cause: err });
- }
+ keyObject = importDerKey(keyData, true);
break;
}
case 'pkcs8': {
verifyAcceptableEcKeyUse(name, false, usagesSet);
- try {
- keyObject = createPrivateKey({
- key: keyData,
- format: 'der',
- type: 'pkcs8',
- });
- } catch (err) {
- throw lazyDOMException(
- 'Invalid keyData', { name: 'DataError', cause: err });
- }
+ keyObject = importDerKey(keyData, false);
break;
}
case 'jwk': {
- if (!keyData.kty)
- throw lazyDOMException('Invalid keyData', 'DataError');
- if (keyData.kty !== 'EC')
- throw lazyDOMException('Invalid JWK "kty" Parameter', 'DataError');
+ const expectedUse = name === 'ECDH' ? 'enc' : 'sig';
+ validateJwk(keyData, 'EC', extractable, usagesSet, expectedUse);
+
if (keyData.crv !== namedCurve)
throw lazyDOMException(
'JWK "crv" does not match the requested algorithm',
'DataError');
- verifyAcceptableEcKeyUse(
- name,
- keyData.d === undefined,
... [truncated]