Skip to content

Commit

Permalink
Disallow generating and parsing v4 keys of type ML-DSA
Browse files Browse the repository at this point in the history
  • Loading branch information
larabr committed Sep 13, 2024
1 parent fb00782 commit 2654b58
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-DSA + EdDSA schemes MUST be used only with v6 keys
if (this.version !== 6 && this.algorithm === enums.publicKey.pqc_mldsa_ed25519) {
throw new Error('Unexpected key version for ML-DSA + EdDSA key');
}
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_mldsa_ed25519) {
throw new Error(`Cannot generate v${this.version} signing 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 @@ -318,7 +318,7 @@ export default () => {
let pqcSigningKey;
let pqcEncryptionSubkey;
before(async () => {
pqcSigningKey = await generatePrivateKeyObject({ type: 'pqc' });
pqcSigningKey = await generatePrivateKeyObject({ type: 'pqc', config: { v6Keys: true } });
pqcEncryptionSubkey = pqcSigningKey.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-DSA 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: true })).to.be.rejectedWith(/Cannot generate v4 signing 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 2654b58

Please sign in to comment.