mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2026-03-10 18:54:44 +00:00
Implement packet criticality check
The Packet Tag space is now partitioned into critical packets and non-critical packets. If an implementation encounters a critical packet where the packet type is unknown in a packet sequence, it MUST reject the whole packet sequence. On the other hand, an unknown non-critical packet MUST be ignored. See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#section-4.3.1 .
This commit is contained in:
@@ -308,6 +308,19 @@ export class UnsupportedError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
// unknown packet types are handled differently depending on the packet criticality
|
||||
export class UnknownPacketError extends UnsupportedError {
|
||||
constructor(...params) {
|
||||
super(...params);
|
||||
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, UnsupportedError);
|
||||
}
|
||||
|
||||
this.name = 'UnknownPacketError';
|
||||
}
|
||||
}
|
||||
|
||||
export class UnparseablePacket {
|
||||
constructor(tag, rawContent) {
|
||||
this.tag = tag;
|
||||
|
||||
@@ -4,7 +4,8 @@ import {
|
||||
writeTag, writeHeader,
|
||||
writePartialLength, writeSimpleLength,
|
||||
UnparseablePacket,
|
||||
UnsupportedError
|
||||
UnsupportedError,
|
||||
UnknownPacketError
|
||||
} from './packet';
|
||||
import util from '../util';
|
||||
import enums from '../enums';
|
||||
@@ -25,7 +26,7 @@ export function newPacketFromTag(tag, allowedPackets) {
|
||||
try {
|
||||
packetType = enums.read(enums.packet, tag);
|
||||
} catch (e) {
|
||||
throw new UnsupportedError(`Unknown packet type with tag: ${tag}`);
|
||||
throw new UnknownPacketError(`Unknown packet type with tag: ${tag}`);
|
||||
}
|
||||
throw new Error(`Packet not allowed in this context: ${packetType}`);
|
||||
}
|
||||
@@ -87,6 +88,17 @@ class PacketList extends Array {
|
||||
await packet.read(parsed.packet, config);
|
||||
await writer.write(packet);
|
||||
} catch (e) {
|
||||
// If an implementation encounters a critical packet where the packet type is unknown in a packet sequence,
|
||||
// it MUST reject the whole packet sequence. On the other hand, an unknown non-critical packet MUST be ignored.
|
||||
// Packet Tags from 0 to 39 are critical. Packet Tags from 40 to 63 are non-critical.
|
||||
if (e instanceof UnknownPacketError) {
|
||||
if (parsed.tag <= 39) {
|
||||
await writer.abort(e);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const throwUnsupportedError = !config.ignoreUnsupportedPackets && e instanceof UnsupportedError;
|
||||
const throwMalformedError = !config.ignoreMalformedPackets && !(e instanceof UnsupportedError);
|
||||
if (throwUnsupportedError || throwMalformedError || supportsStreaming(parsed.tag)) {
|
||||
|
||||
@@ -1514,6 +1514,20 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu
|
||||
).to.be.rejectedWith(/Unsupported S2K type/);
|
||||
});
|
||||
|
||||
it('Throws on critical packet even with tolerant mode enabled', async function() {
|
||||
const unknownPacketTag39 = util.hexToUint8Array('e70a750064bf943d6e756c6c'); // critical tag
|
||||
|
||||
await expect(openpgp.PacketList.fromBinary(unknownPacketTag39, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: false, ignoreMalformedPackets: false })).to.be.rejectedWith(/Unknown packet type/);
|
||||
await expect(openpgp.PacketList.fromBinary(unknownPacketTag39, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: true, ignoreMalformedPackets: true })).to.be.rejectedWith(/Unknown packet type/);
|
||||
});
|
||||
|
||||
it('Ignores non-critical packet even with tolerant mode disabled', async function() {
|
||||
const unknownPacketTag63 = util.hexToUint8Array('ff0a750064bf943d6e756c6c'); // non-critical tag
|
||||
|
||||
await expect(openpgp.PacketList.fromBinary(unknownPacketTag63, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: false, ignoreMalformedPackets: false })).to.eventually.have.length(0);
|
||||
await expect(openpgp.PacketList.fromBinary(unknownPacketTag63, allAllowedPackets, { ...openpgp.config, ignoreUnsupportedPackets: true, ignoreMalformedPackets: true })).to.eventually.have.length(0);
|
||||
});
|
||||
|
||||
it('Throws on disallowed packet even with tolerant mode enabled', async function() {
|
||||
const packets = new openpgp.PacketList();
|
||||
packets.push(new openpgp.LiteralDataPacket());
|
||||
|
||||
Reference in New Issue
Block a user