Skip to content

Commit

Permalink
Disallow generating and parsing v4 keys of type ML-KEM
Browse files Browse the repository at this point in the history
  • Loading branch information
larabr committed Oct 21, 2024
1 parent 32f246d commit b2d2d56
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/packet/public_key.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ class PublicKeyPacket {
) {
throw new Error('Legacy curve25519 cannot be used with v6 keys');
}
// The composite ML-KEM + ECDH schemes MUST be used only with v6 keys.
if (this.version !== 6 && this.algorithm === enums.publicKey.pqc_mlkem_x25519) {
throw new Error('Unexpected key version: ML-KEM algorithms can only be used with v6 keys');
}
this.publicParams = publicParams;
pos += read;

Expand Down
3 changes: 3 additions & 0 deletions src/packet/secret_key.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,9 @@ class SecretKeyPacket extends PublicKeyPacket {
)) {
throw new Error(`Cannot generate v6 keys of type 'ecc' with curve ${curve}. Generate a key of type 'curve25519' instead`);
}
if (this.version !== 6 && this.algorithm === enums.publicKey.pqc_mlkem_x25519) {
throw new Error(`Cannot generate v${this.version} keys of type 'pqc'. Generate a v6 key instead`);
}
const { privateParams, publicParams } = await crypto.generateParams(this.algorithm, bits, curve, symmetric);
this.privateParams = privateParams;
this.publicParams = publicParams;
Expand Down
4 changes: 2 additions & 2 deletions test/crypto/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ async function cloneKeyPacket(key) {
}

async function generatePrivateKeyObject(options) {
const config = { rejectCurves: new Set() };
const config = { rejectCurves: new Set(), ...options.config };
const { privateKey } = await openpgp.generateKey({ ...options, userIDs: [{ name: 'Test', email: '[email protected]' }], format: 'object', config });
return privateKey;
}
Expand Down Expand Up @@ -317,7 +317,7 @@ export default () => {
describe('PQC parameter validation', function() {
let pqcEncryptionSubkey;
before(async () => {
const key = await generatePrivateKeyObject({ type: 'symmetric', subkeys: [{ type: 'pqc' }] });
const key = await generatePrivateKeyObject({ type: 'symmetric', subkeys: [{ type: 'pqc', config: { v6Keys: true } }] });
pqcEncryptionSubkey = key.subkeys[0];
});

Expand Down
11 changes: 11 additions & 0 deletions test/general/key.js
Original file line number Diff line number Diff line change
Expand Up @@ -4525,6 +4525,17 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg==
expect(v6Key.subkeys).to.have.length(1);
});

it('should throw when trying to add a ML-KEM PQC key to a v4 key', async function() {
const v4Key = await openpgp.decryptKey({
privateKey: await openpgp.readKey({ armoredKey: priv_key_rsa }),
passphrase: 'hello world'
});
expect(v4Key.keyPacket.version).to.equal(4);
expect(v4Key.subkeys).to.have.length(1);
await expect(v4Key.addSubkey({ type: 'pqc', sign: false })).to.be.rejectedWith(/Cannot generate v4 keys of type 'pqc'/);
expect(v4Key.subkeys).to.have.length(1);
});

it('should throw when trying to encrypt a subkey separately from key', async function() {
const privateKey = await openpgp.decryptKey({
privateKey: await openpgp.readKey({ armoredKey: priv_key_rsa }),
Expand Down

0 comments on commit b2d2d56

Please sign in to comment.