mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-11-26 15:35:52 +00:00
Reuse additionalAllowedPackets object
This commit is contained in:
parent
5d8d7b5175
commit
1aedcbe5b6
@ -1,5 +1,4 @@
|
||||
import enums from '../enums';
|
||||
import type { Config } from '../config';
|
||||
|
||||
export class GrammarError extends Error {
|
||||
constructor(...params: any[]) {
|
||||
@ -39,11 +38,10 @@ export class MessageGrammarValidator {
|
||||
* NB: padding, marker and unknown packets are expected to already be filtered out on parsing,
|
||||
* and are not accepted by `recordPacket`.
|
||||
* @param packet - packet to validate
|
||||
* @param config - needed to determine the `additionalAllowedPackets`: these are allowed anywhere in the sequence, except they cannot precede a OPS packet
|
||||
* @param additionalAllowedPackets - object containing packets which are allowed anywhere in the sequence, except they cannot precede a OPS packet
|
||||
* @throws {GrammarError} on invalid `packet` input
|
||||
*/
|
||||
recordPacket(packet: enums.packet, config: Config) {
|
||||
const additionalAllowedPacketsTags = new Set(config.additionalAllowedPackets.map(c => c.tag));
|
||||
recordPacket(packet: enums.packet, additionalAllowedPackets?: { [key in enums.packet]: any }) {
|
||||
switch (this.state) {
|
||||
case MessageType.EmptyMessage:
|
||||
case MessageType.StandaloneAdditionalAllowedData:
|
||||
@ -79,7 +77,7 @@ export class MessageGrammarValidator {
|
||||
this.state = MessageType.EncryptedSessionKeys;
|
||||
return;
|
||||
default:
|
||||
if (!additionalAllowedPacketsTags.has(packet)) {
|
||||
if (!additionalAllowedPackets?.[packet]) {
|
||||
throw new GrammarError(`Unexpected packet ${packet} in state ${this.state}`);
|
||||
}
|
||||
this.state = MessageType.StandaloneAdditionalAllowedData;
|
||||
@ -94,7 +92,7 @@ export class MessageGrammarValidator {
|
||||
this.state = MessageType.PlaintextOrEncryptedData;
|
||||
return;
|
||||
default:
|
||||
if (!additionalAllowedPacketsTags.has(packet)) {
|
||||
if (!additionalAllowedPackets?.[packet]) {
|
||||
throw new GrammarError(`Unexpected packet ${packet} in state ${this.state}`);
|
||||
}
|
||||
this.state = MessageType.PlaintextOrEncryptedData;
|
||||
@ -118,7 +116,7 @@ export class MessageGrammarValidator {
|
||||
this.state = MessageType.PlaintextOrEncryptedData;
|
||||
return;
|
||||
default:
|
||||
if (!additionalAllowedPacketsTags.has(packet)) {
|
||||
if (!additionalAllowedPackets?.[packet]) {
|
||||
throw new GrammarError(`Unexpected packet ${packet} in state ${this.state}`);
|
||||
}
|
||||
this.state = MessageType.EncryptedSessionKeys;
|
||||
|
||||
@ -70,8 +70,10 @@ class PacketList extends Array {
|
||||
* @async
|
||||
*/
|
||||
async read(bytes, allowedPackets, config = defaultConfig, grammarValidator = null, delayErrors = false) {
|
||||
let additionalAllowedPackets;
|
||||
if (config.additionalAllowedPackets.length) {
|
||||
allowedPackets = { ...allowedPackets, ...util.constructAllowedPackets(config.additionalAllowedPackets) };
|
||||
additionalAllowedPackets = util.constructAllowedPackets(config.additionalAllowedPackets);
|
||||
allowedPackets = { ...allowedPackets, ...additionalAllowedPackets };
|
||||
}
|
||||
this.stream = streamTransformPair(bytes, async (readable, writable) => {
|
||||
const reader = streamGetReader(readable);
|
||||
@ -95,7 +97,7 @@ class PacketList extends Array {
|
||||
// Unknown packets throw in the call above, we ignore them
|
||||
// in the grammar checker.
|
||||
try {
|
||||
grammarValidator?.recordPacket(parsed.tag, config);
|
||||
grammarValidator?.recordPacket(parsed.tag, additionalAllowedPackets);
|
||||
} catch (e) {
|
||||
if (config.enforceGrammar) {
|
||||
throw e;
|
||||
|
||||
@ -1379,85 +1379,85 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu
|
||||
it('valid nested signed messages should be valid', () => {
|
||||
// Sig | OPS | Literal | Sig
|
||||
const m1 = new MessageGrammarValidator();
|
||||
m1.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets: [] });
|
||||
m1.recordPacket(openpgp.enums.packet.onePassSignature, { additionalAllowedPackets: [] });
|
||||
m1.recordPacket(openpgp.enums.packet.literalData, { additionalAllowedPackets: [] });
|
||||
m1.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets: [] });
|
||||
m1.recordPacket(openpgp.enums.packet.signature);
|
||||
m1.recordPacket(openpgp.enums.packet.onePassSignature);
|
||||
m1.recordPacket(openpgp.enums.packet.literalData);
|
||||
m1.recordPacket(openpgp.enums.packet.signature);
|
||||
expect(() => m1.recordEnd()).to.not.throw();
|
||||
|
||||
// OPS | Sig | Literal | Sig
|
||||
const m2 = new MessageGrammarValidator();
|
||||
m2.recordPacket(openpgp.enums.packet.onePassSignature, { additionalAllowedPackets: [] });
|
||||
m2.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets: [] });
|
||||
m2.recordPacket(openpgp.enums.packet.literalData, { additionalAllowedPackets: [] });
|
||||
m2.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets: [] });
|
||||
m2.recordPacket(openpgp.enums.packet.onePassSignature);
|
||||
m2.recordPacket(openpgp.enums.packet.signature);
|
||||
m2.recordPacket(openpgp.enums.packet.literalData);
|
||||
m2.recordPacket(openpgp.enums.packet.signature);
|
||||
expect(() => m2.recordEnd()).to.not.throw();
|
||||
|
||||
// OPS | Sig | Literal - should throw due to missing trailing signature
|
||||
const m3 = new MessageGrammarValidator();
|
||||
m3.recordPacket(openpgp.enums.packet.onePassSignature, { additionalAllowedPackets: [] });
|
||||
m3.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets: [] });
|
||||
m3.recordPacket(openpgp.enums.packet.literalData, { additionalAllowedPackets: [] });
|
||||
m3.recordPacket(openpgp.enums.packet.onePassSignature);
|
||||
m3.recordPacket(openpgp.enums.packet.signature);
|
||||
m3.recordPacket(openpgp.enums.packet.literalData);
|
||||
expect(() => m3.recordEnd()).to.throw();
|
||||
|
||||
// Sig - should throw due to standalone signature packet
|
||||
const m4 = new MessageGrammarValidator();
|
||||
m4.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets: [] });
|
||||
m4.recordPacket(openpgp.enums.packet.signature);
|
||||
expect(() => m3.recordEnd()).to.throw();
|
||||
|
||||
// ESK | Sig | SEIPD - should throw
|
||||
const m5 = new MessageGrammarValidator();
|
||||
m5.recordPacket(openpgp.enums.packet.publicKeyEncryptedSessionKey, { additionalAllowedPackets: [] });
|
||||
expect(() => m5.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets: [] })).to.throw();
|
||||
m5.recordPacket(openpgp.enums.packet.publicKeyEncryptedSessionKey);
|
||||
expect(() => m5.recordPacket(openpgp.enums.packet.signature)).to.throw();
|
||||
});
|
||||
|
||||
it('standalone additional allowed packets should be valid', () => {
|
||||
const additionalAllowedPackets = [openpgp.PublicKeyPacket];
|
||||
const additionalAllowedPackets = { [openpgp.PublicKeyPacket.tag]: openpgp.PublicKeyPacket };
|
||||
// Sig | OPS | PublicKeyPacket | Sig
|
||||
const m1 = new MessageGrammarValidator();
|
||||
m1.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets });
|
||||
m1.recordPacket(openpgp.enums.packet.onePassSignature, { additionalAllowedPackets });
|
||||
m1.recordPacket(openpgp.enums.packet.publicKey, { additionalAllowedPackets });
|
||||
m1.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets });
|
||||
m1.recordPacket(openpgp.enums.packet.signature, additionalAllowedPackets);
|
||||
m1.recordPacket(openpgp.enums.packet.onePassSignature, additionalAllowedPackets);
|
||||
m1.recordPacket(openpgp.enums.packet.publicKey, additionalAllowedPackets);
|
||||
m1.recordPacket(openpgp.enums.packet.signature, additionalAllowedPackets);
|
||||
expect(() => m1.recordEnd()).to.not.throw();
|
||||
|
||||
// OPS | Sig | PublicKeyPacket | Sig
|
||||
const m2 = new MessageGrammarValidator();
|
||||
m2.recordPacket(openpgp.enums.packet.onePassSignature, { additionalAllowedPackets });
|
||||
m2.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets });
|
||||
m2.recordPacket(openpgp.enums.packet.publicKey, { additionalAllowedPackets });
|
||||
m2.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets });
|
||||
m2.recordPacket(openpgp.enums.packet.onePassSignature, additionalAllowedPackets);
|
||||
m2.recordPacket(openpgp.enums.packet.signature, additionalAllowedPackets);
|
||||
m2.recordPacket(openpgp.enums.packet.publicKey, additionalAllowedPackets);
|
||||
m2.recordPacket(openpgp.enums.packet.signature, additionalAllowedPackets);
|
||||
expect(() => m2.recordEnd()).to.not.throw();
|
||||
|
||||
// standalone PublicKeyPacket
|
||||
const m3 = new MessageGrammarValidator();
|
||||
m3.recordPacket(openpgp.enums.packet.publicKey, { additionalAllowedPackets });
|
||||
m3.recordPacket(openpgp.enums.packet.publicKey, additionalAllowedPackets);
|
||||
expect(() => m3.recordEnd()).to.not.throw();
|
||||
|
||||
// OPS | Sig | PublicKey - should throw due to missing trailing signature
|
||||
const m4 = new MessageGrammarValidator();
|
||||
m4.recordPacket(openpgp.enums.packet.onePassSignature, { additionalAllowedPackets });
|
||||
m4.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets });
|
||||
m4.recordPacket(openpgp.enums.packet.publicKey, { additionalAllowedPackets });
|
||||
m4.recordPacket(openpgp.enums.packet.onePassSignature, additionalAllowedPackets);
|
||||
m4.recordPacket(openpgp.enums.packet.signature, additionalAllowedPackets);
|
||||
m4.recordPacket(openpgp.enums.packet.publicKey, additionalAllowedPackets);
|
||||
expect(() => m4.recordEnd()).to.throw();
|
||||
|
||||
// Sig | PublicKey | Sig | PublicKey - should throw
|
||||
const m5 = new MessageGrammarValidator();
|
||||
m5.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets });
|
||||
m5.recordPacket(openpgp.enums.packet.publicKey, { additionalAllowedPackets });
|
||||
expect(() => m5.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets })).to.throw();
|
||||
m5.recordPacket(openpgp.enums.packet.signature, additionalAllowedPackets);
|
||||
m5.recordPacket(openpgp.enums.packet.publicKey, additionalAllowedPackets);
|
||||
expect(() => m5.recordPacket(openpgp.enums.packet.signature, additionalAllowedPackets)).to.throw();
|
||||
|
||||
// Sig | PublicKey | OPS | PublicKey | Sig - should throw
|
||||
const m6 = new MessageGrammarValidator();
|
||||
m6.recordPacket(openpgp.enums.packet.signature, { additionalAllowedPackets });
|
||||
m6.recordPacket(openpgp.enums.packet.publicKey, { additionalAllowedPackets });
|
||||
expect(() => m6.recordPacket(openpgp.enums.packet.onePassSignature, { additionalAllowedPackets })).to.throw();
|
||||
m6.recordPacket(openpgp.enums.packet.signature, additionalAllowedPackets);
|
||||
m6.recordPacket(openpgp.enums.packet.publicKey, additionalAllowedPackets);
|
||||
expect(() => m6.recordPacket(openpgp.enums.packet.onePassSignature, additionalAllowedPackets)).to.throw();
|
||||
});
|
||||
|
||||
it('standalone disallowed packets should not be valid', () => {
|
||||
// standalone PublicKeyPacket
|
||||
const m1 = new MessageGrammarValidator();
|
||||
expect(() => m1.recordPacket(openpgp.enums.packet.publicKey, { additionalAllowedPackets: [] })).to.throw();
|
||||
expect(() => m1.recordPacket(openpgp.enums.packet.publicKey)).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user