Skip to content

Commit 5a84bc9

Browse files
committed
fixup! crypto: add raw key formats support to the KeyObject APIs
1 parent 0dd56b5 commit 5a84bc9

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

doc/api/crypto.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3785,7 +3785,7 @@ changes:
37853785

37863786
* `key` {Object|string|ArrayBuffer|Buffer|TypedArray|DataView}
37873787
* `key` {string|ArrayBuffer|Buffer|TypedArray|DataView|Object} The key
3788-
material, either in PEM, DER, or JWK format.
3788+
material, either in PEM, DER, JWK, or raw format.
37893789
* `format` {string} Must be `'pem'`, `'der'`, `'jwk'`, `'raw-private'`,
37903790
or `'raw-seed'`. **Default:** `'pem'`.
37913791
* `type` {string} Must be `'pkcs1'`, `'pkcs8'` or `'sec1'`. This option is
@@ -3839,7 +3839,7 @@ changes:
38393839

38403840
* `key` {Object|string|ArrayBuffer|Buffer|TypedArray|DataView}
38413841
* `key` {string|ArrayBuffer|Buffer|TypedArray|DataView|Object} The key
3842-
material, either in PEM, DER, or JWK format.
3842+
material, either in PEM, DER, JWK, or raw format.
38433843
* `format` {string} Must be `'pem'`, `'der'`, `'jwk'`, or `'raw-public'`.
38443844
**Default:** `'pem'`.
38453845
* `type` {string} Must be `'pkcs1'` or `'spki'`. This option is

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,11 @@ if (hasOpenSSL(3, 5)) {
318318
});
319319
const derivedPub = crypto.createPublicKey(importedPriv);
320320
assert.strictEqual(derivedPub.equals(edPub), true);
321+
// Private key must not be extractable from the derived public key.
322+
assert.throws(() => derivedPub.export({ format: 'pem', type: 'pkcs8' }),
323+
{ code: 'ERR_INVALID_ARG_VALUE' });
324+
assert.throws(() => derivedPub.export({ format: 'der', type: 'pkcs8' }),
325+
{ code: 'ERR_INVALID_ARG_VALUE' });
321326

322327
// EC raw-private -> createPublicKey
323328
const ecPriv = crypto.createPrivateKey(
@@ -331,6 +336,11 @@ if (hasOpenSSL(3, 5)) {
331336
});
332337
const ecDerivedPub = crypto.createPublicKey(ecImportedPriv);
333338
assert.strictEqual(ecDerivedPub.equals(ecPub), true);
339+
// Private key must not be extractable from the derived public key.
340+
assert.throws(() => ecDerivedPub.export({ format: 'pem', type: 'pkcs8' }),
341+
{ code: 'ERR_INVALID_ARG_VALUE' });
342+
assert.throws(() => ecDerivedPub.export({ format: 'pem', type: 'sec1' }),
343+
{ code: 'ERR_INVALID_ARG_VALUE' });
334344

335345
// PQC raw-seed -> createPublicKey
336346
if (hasOpenSSL(3, 5)) {
@@ -344,6 +354,9 @@ if (hasOpenSSL(3, 5)) {
344354
});
345355
const mlDsaDerivedPub = crypto.createPublicKey(mlDsaImportedPriv);
346356
assert.strictEqual(mlDsaDerivedPub.equals(mlDsaPub), true);
357+
// Private key must not be extractable from the derived public key.
358+
assert.throws(() => mlDsaDerivedPub.export({ format: 'pem', type: 'pkcs8' }),
359+
{ code: 'ERR_INVALID_ARG_VALUE' });
347360
}
348361
}
349362

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,23 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem',
170170
assert.strictEqual(derivedPublicKey.asymmetricKeyType, 'rsa');
171171
assert.strictEqual(derivedPublicKey.symmetricKeySize, undefined);
172172

173+
// The private key should not be extractable from the derived public key.
174+
assert.throws(() => derivedPublicKey.export({ format: 'pem', type: 'pkcs8' }),
175+
{ code: 'ERR_INVALID_ARG_VALUE' });
176+
assert.throws(() => derivedPublicKey.export({ format: 'der', type: 'pkcs8' }),
177+
{ code: 'ERR_INVALID_ARG_VALUE' });
178+
// JWK export should only contain public components, no 'd'.
179+
{
180+
const jwkExport = derivedPublicKey.export({ format: 'jwk' });
181+
assert.strictEqual(jwkExport.kty, 'RSA');
182+
assert.strictEqual(jwkExport.d, undefined);
183+
assert.strictEqual(jwkExport.dp, undefined);
184+
assert.strictEqual(jwkExport.dq, undefined);
185+
assert.strictEqual(jwkExport.qi, undefined);
186+
assert.strictEqual(jwkExport.p, undefined);
187+
assert.strictEqual(jwkExport.q, undefined);
188+
}
189+
173190
const publicKeyFromJwk = createPublicKey({ key: publicJwk, format: 'jwk' });
174191
assert.strictEqual(publicKeyFromJwk.type, 'public');
175192
assert.strictEqual(publicKeyFromJwk.toString(), '[object KeyObject]');
@@ -533,6 +550,16 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem',
533550
delete jwk.d;
534551
assert.deepStrictEqual(
535552
key.export({ format: 'jwk' }), jwk);
553+
554+
// Private key material must not be extractable from a derived public key.
555+
assert.throws(() => key.export({ format: 'pem', type: 'pkcs8' }),
556+
{ code: 'ERR_INVALID_ARG_VALUE' });
557+
assert.throws(() => key.export({ format: 'pem', type: 'sec1' }),
558+
{ code: 'ERR_INVALID_ARG_VALUE' });
559+
assert.throws(() => key.export({ format: 'der', type: 'pkcs8' }),
560+
{ code: 'ERR_INVALID_ARG_VALUE' });
561+
assert.throws(() => key.export({ format: 'der', type: 'sec1' }),
562+
{ code: 'ERR_INVALID_ARG_VALUE' });
536563
}
537564
}
538565

0 commit comments

Comments
 (0)