Skip to content

Commit

Permalink
Throw UnsupportedError on unknown algorithm in keys and signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
larabr committed May 26, 2022
1 parent 870ffde commit 3fd57a8
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 3 deletions.
5 changes: 3 additions & 2 deletions src/crypto/crypto.js
Expand Up @@ -34,6 +34,7 @@ import enums from '../enums';
import util from '../util';
import OID from '../type/oid';
import { Curve } from './public_key/elliptic/curves';
import { UnsupportedError } from '../packet/packet';

/**
* Encrypts data using specified algorithm and public key parameters.
Expand Down Expand Up @@ -156,7 +157,7 @@ export function parsePublicKeyParams(algo, bytes) {
return { read: read, publicParams: { oid, Q, kdfParams } };
}
default:
throw new Error('Invalid public key encryption algorithm.');
throw new UnsupportedError('Invalid public key encryption algorithm.');
}
}

Expand Down Expand Up @@ -197,7 +198,7 @@ export function parsePrivateKeyParams(algo, bytes, publicParams) {
return { read, privateParams: { seed } };
}
default:
throw new Error('Invalid public key encryption algorithm.');
throw new UnsupportedError('Invalid public key encryption algorithm.');
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/crypto/signature.js
Expand Up @@ -7,6 +7,7 @@
import publicKey from './public_key';
import enums from '../enums';
import util from '../util';
import { UnsupportedError } from '../packet/packet';

/**
* Parse signature in binary form to get the parameters.
Expand Down Expand Up @@ -55,7 +56,7 @@ export function parseSignatureParams(algo, signature) {
return { r, s };
}
default:
throw new Error('Invalid signature algorithm.');
throw new UnsupportedError('Invalid signature algorithm.');
}
}

Expand Down
1 change: 1 addition & 0 deletions src/packet/public_key.js
Expand Up @@ -128,6 +128,7 @@ class PublicKeyPacket {
this.publicParams = publicParams;
pos += read;
} catch (err) {
if (err instanceof UnsupportedError) throw err;
throw new Error('Error reading MPIs');
}

Expand Down
3 changes: 3 additions & 0 deletions src/packet/secret_key.js
Expand Up @@ -21,6 +21,7 @@ import crypto from '../crypto';
import enums from '../enums';
import util from '../util';
import defaultConfig from '../config';
import { UnsupportedError } from './packet';

/**
* A Secret-Key packet contains all the information that is found in a
Expand Down Expand Up @@ -155,6 +156,8 @@ class SecretKeyPacket extends PublicKeyPacket {
const { privateParams } = crypto.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
this.privateParams = privateParams;
} catch (err) {
if (err instanceof UnsupportedError) throw err;
// avoid throwing potentially sensitive errors
throw new Error('Error reading MPIs');
}
}
Expand Down
26 changes: 26 additions & 0 deletions test/general/packet.js
Expand Up @@ -996,6 +996,32 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu
).to.be.rejectedWith(/Version 1 of the signature packet is unsupported/);
});

it('Ignores unknown signature algorithm only with `config.ignoreUnsupportedPackets` enabled', async function() {
const binarySignature = util.hexToUint8Array('c2750401630a00060502628b8e2200210910f30ddfc2310b3560162104b9b0045c1930f842cb245566f30ddfc2310b35602ded0100bd69fe6a9f52499cd8b2fd2493dae91c997979890df4467cf31b197901590ff10100ead4c671487535b718a8428c8e6099e3873a41610aad9fcdaa06f6df5f404002');

const parsed = await openpgp.PacketList.fromBinary(binarySignature, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: true });
expect(parsed.length).to.equal(1);
expect(parsed[0]).instanceOf(openpgp.UnparseablePacket);
expect(parsed[0].tag).to.equal(openpgp.enums.packet.signature);

await expect(
openpgp.PacketList.fromBinary(binarySignature, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: false })
).to.be.rejectedWith(/Invalid signature algorithm/);
});

it('Ignores unknown key algorithm only with `config.ignoreUnsupportedPackets` enabled', async function() {
const binaryKey = util.hexToUint8Array('c55804628b944e63092b06010401da470f01010740d01ab8619b6dc6a36da5bff62ff416a974900f5a8c74d1bd1760d717d0aad8d50000ff516f8e3190aa5b394597655d7c32e16392e638da0e2a869fb7b1f429d9de263d1062cd0f3c7465737440746573742e636f6d3ec28c0410160a001d0502628b944e040b0907080315080a0416000201021901021b03021e01002109104803e40df201fa5b16210496dc42e91cc585e2f5e331644803e40df201fa5b340b0100812c47b60fa509e12e329fc37cc9c437cc6a6500915caa03ad8703db849846f900ff571b9a0d9e1dcc087d9fae04ec2906e60ef40ca02a387eb07ce1c37bedeecd0a');

const parsed = await openpgp.PacketList.fromBinary(binaryKey, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: true });
expect(parsed.length).to.equal(3);
expect(parsed[0]).instanceOf(openpgp.UnparseablePacket);
expect(parsed[0].tag).to.equal(openpgp.enums.packet.secretKey);

await expect(
openpgp.PacketList.fromBinary(binaryKey, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: false })
).to.be.rejectedWith(/Invalid public key encryption algorithm/);
});

it('Throws on disallowed packet even with tolerant mode enabled', async function() {
const packets = new openpgp.PacketList();
packets.push(new openpgp.LiteralDataPacket());
Expand Down

0 comments on commit 3fd57a8

Please sign in to comment.