Skip to content

Commit 91a9434

Browse files
committed
crypto: reject raw-public private imports
Reject raw-public object input in createPrivateKey() before it reaches native raw key import. Cover matching-length raw public keys across the supported raw-public key types. Signed-off-by: Filip Skokan <panva.ip@gmail.com>
1 parent d482318 commit 91a9434

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

lib/internal/crypto/keys.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,10 @@ function prepareAsymmetricKey(key, ctx, name = 'key') {
666666
return { data, format: kKeyFormatJWK };
667667
} else if (format === 'raw-public' || format === 'raw-private' ||
668668
format === 'raw-seed') {
669+
if ((ctx === kConsumePrivate || ctx === kCreatePrivate) &&
670+
format === 'raw-public') {
671+
throw new ERR_INVALID_ARG_VALUE(`${name}.format`, format);
672+
}
669673
if (!isArrayBufferView(data) && !isAnyArrayBuffer(data)) {
670674
throw new ERR_INVALID_ARG_TYPE(
671675
`${name}.key`,

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

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,47 @@ const { hasOpenSSL } = require('../common/crypto');
5959
}
6060
}
6161

62+
// Raw public keys cannot be imported as private keys.
63+
{
64+
const rawPublicKeys = [
65+
['ec', 'ec_p256_public.pem', { namedCurve: 'P-256' }],
66+
['ed25519', 'ed25519_public.pem'],
67+
['x25519', 'x25519_public.pem'],
68+
];
69+
70+
if (!process.features.openssl_is_boringssl) {
71+
rawPublicKeys.push(
72+
['ed448', 'ed448_public.pem'],
73+
['x448', 'x448_public.pem'],
74+
);
75+
} else {
76+
common.printSkipMessage('Skipping unsupported ed448/x448 test cases');
77+
}
78+
79+
if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) {
80+
rawPublicKeys.push(
81+
['ml-dsa-44', 'ml_dsa_44_public.pem'],
82+
['ml-kem-768', 'ml_kem_768_public.pem'],
83+
);
84+
}
85+
86+
if (hasOpenSSL(3, 5)) {
87+
rawPublicKeys.push(
88+
['slh-dsa-sha2-128f', 'slh_dsa_sha2_128f_public.pem'],
89+
);
90+
}
91+
92+
for (const [asymmetricKeyType, fixture, options = {}] of rawPublicKeys) {
93+
const publicKey = crypto.createPublicKey(fixtures.readKey(fixture, 'ascii'));
94+
assert.throws(() => crypto.createPrivateKey({
95+
key: publicKey.export({ format: 'raw-public' }),
96+
format: 'raw-public',
97+
asymmetricKeyType,
98+
...options,
99+
}), { code: 'ERR_INVALID_ARG_VALUE' });
100+
}
101+
}
102+
62103
// Raw seed imports do not support strings.
63104
if (hasOpenSSL(3, 5)) {
64105
const privKeyObj = crypto.createPrivateKey(
@@ -113,7 +154,11 @@ if (hasOpenSSL(3, 5)) {
113154
assert.throws(() => privKeyObj.export({ format: 'raw-private' }),
114155
{ code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS' });
115156

116-
for (const format of ['raw-public', 'raw-private', 'raw-seed']) {
157+
assert.throws(() => crypto.createPrivateKey({
158+
key: Buffer.alloc(32), format: 'raw-public', asymmetricKeyType: 'dh',
159+
}), { code: 'ERR_INVALID_ARG_VALUE' });
160+
161+
for (const format of ['raw-private', 'raw-seed']) {
117162
assert.throws(() => crypto.createPrivateKey({
118163
key: Buffer.alloc(32), format, asymmetricKeyType: 'dh',
119164
}), { code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS' });

0 commit comments

Comments
 (0)