Skip to content

Commit 9a52ee7

Browse files
panvajuanarbol
authored andcommitted
crypto: handle invalid prepareAsymmetricKey JWK inputs
Fixes #44471 PR-URL: #44475 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Mohammed Keyvanzadeh <[email protected]>
1 parent 0e2c206 commit 9a52ee7

File tree

4 files changed

+39
-7
lines changed

4 files changed

+39
-7
lines changed

lib/internal/crypto/keygen.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ const {
3131
SecretKeyObject,
3232
parsePublicKeyEncoding,
3333
parsePrivateKeyEncoding,
34-
isJwk
3534
} = require('internal/crypto/keys');
3635

3736
const {
@@ -66,6 +65,10 @@ const { isArrayBufferView } = require('internal/util/types');
6665
const { getOptionValue } = require('internal/options');
6766
const pendingDeprecation = getOptionValue('--pending-deprecation');
6867

68+
function isJwk(obj) {
69+
return obj != null && obj.kty !== undefined;
70+
}
71+
6972
function wrapKey(key, ctor) {
7073
if (typeof key === 'string' ||
7174
isArrayBufferView(key) ||

lib/internal/crypto/keys.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -526,14 +526,18 @@ function prepareAsymmetricKey(key, ctx) {
526526
return { format: kKeyFormatPEM, data: getArrayBufferOrView(key, 'key') };
527527
} else if (typeof key === 'object') {
528528
const { key: data, encoding, format } = key;
529+
529530
// The 'key' property can be a KeyObject as well to allow specifying
530531
// additional options such as padding along with the key.
531532
if (isKeyObject(data))
532533
return { data: getKeyObjectHandle(data, ctx) };
533534
else if (isCryptoKey(data))
534535
return { data: getKeyObjectHandle(data[kKeyObject], ctx) };
535-
else if (isJwk(data) && format === 'jwk')
536+
else if (format === 'jwk') {
537+
validateObject(data, 'key.key');
536538
return { data: getKeyObjectHandleFromJwk(data, ctx), format: 'jwk' };
539+
}
540+
537541
// Either PEM or DER using PKCS#1 or SPKI.
538542
if (!isStringOrBuffer(data)) {
539543
throw new ERR_INVALID_ARG_TYPE(
@@ -723,10 +727,6 @@ function isCryptoKey(obj) {
723727
return obj != null && obj[kKeyObject] !== undefined;
724728
}
725729

726-
function isJwk(obj) {
727-
return obj != null && obj.kty !== undefined;
728-
}
729-
730730
module.exports = {
731731
// Public API.
732732
createSecretKey,
@@ -748,5 +748,4 @@ module.exports = {
748748
PrivateKeyObject,
749749
isKeyObject,
750750
isCryptoKey,
751-
isJwk,
752751
};

test/parallel/test-crypto-key-objects.js

+12
Original file line numberDiff line numberDiff line change
@@ -870,3 +870,15 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem',
870870
assert(!first.privateKey.equals(second.privateKey));
871871
assert(!first.privateKey.equals(second.publicKey));
872872
}
873+
874+
{
875+
// This should not cause a crash: https://github.com/nodejs/node/issues/44471
876+
for (const key of ['', 'foo', null, undefined, true, Boolean]) {
877+
assert.throws(() => {
878+
createPublicKey({ key, format: 'jwk' });
879+
}, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
880+
assert.throws(() => {
881+
createPrivateKey({ key, format: 'jwk' });
882+
}, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
883+
}
884+
}

test/parallel/test-crypto-sign-verify.js

+18
Original file line numberDiff line numberDiff line change
@@ -756,3 +756,21 @@ assert.throws(
756756
message: /digest too big for rsa key/
757757
});
758758
}
759+
760+
{
761+
// This should not cause a crash: https://github.com/nodejs/node/issues/44471
762+
for (const key of ['', 'foo', null, undefined, true, Boolean]) {
763+
assert.throws(() => {
764+
crypto.verify('sha256', 'foo', { key, format: 'jwk' }, Buffer.alloc(0));
765+
}, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
766+
assert.throws(() => {
767+
crypto.createVerify('sha256').verify({ key, format: 'jwk' }, Buffer.alloc(0));
768+
}, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
769+
assert.throws(() => {
770+
crypto.sign('sha256', 'foo', { key, format: 'jwk' });
771+
}, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
772+
assert.throws(() => {
773+
crypto.createSign('sha256').sign({ key, format: 'jwk' });
774+
}, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
775+
}
776+
}

0 commit comments

Comments
 (0)