Make PacketList
a valid subtype of Array
and update Packet.tag
types (#1289)
Changes: - Implementation: - Remove `PacketList.prototype.concat` and `push` (we solely rely on `Array.push` instead) - Fix https://github.com/openpgpjs/openpgpjs/issues/907 by correctly handling result of `filterByTag` - Implement `write()` method for `Trust` and `Marker` packets, to make them compatible with the `BasePacket` interface - Types: - Simplify and updated `PacketList` type definitions - Fix types for `Packet.tag`, which is `static` since https://github.com/openpgpjs/openpgpjs/pull/1268 - Prevent passing SubkeyPackets where KeyPackets are expected, and vice versa
This commit is contained in:
parent
2d07c43030
commit
aeddac438e
83
openpgp.d.ts
vendored
83
openpgp.d.ts
vendored
|
@ -292,7 +292,7 @@ interface PartialConfig extends Partial<Config> {}
|
||||||
/* ############## v5 PACKET #################### */
|
/* ############## v5 PACKET #################### */
|
||||||
|
|
||||||
declare abstract class BasePacket {
|
declare abstract class BasePacket {
|
||||||
public tag: enums.packet;
|
static readonly tag: enums.packet;
|
||||||
public read(bytes: Uint8Array): void;
|
public read(bytes: Uint8Array): void;
|
||||||
public write(): Uint8Array;
|
public write(): Uint8Array;
|
||||||
}
|
}
|
||||||
|
@ -314,14 +314,20 @@ declare abstract class BasePublicKeyPacket extends BasePacket {
|
||||||
public getKeyID(): KeyID;
|
public getKeyID(): KeyID;
|
||||||
public isDecrypted(): boolean;
|
public isDecrypted(): boolean;
|
||||||
public publicParams: object;
|
public publicParams: object;
|
||||||
|
// `isSubkey` is a dummy method to ensure that Subkey packets are not accepted as Key one, and vice versa.
|
||||||
|
// The key class hierarchy is already modelled to cover this, but the concrete key packet classes
|
||||||
|
// have compatible structure and TS can't detect the difference.
|
||||||
|
protected isSubkey(): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PublicKeyPacket extends BasePublicKeyPacket {
|
export class PublicKeyPacket extends BasePublicKeyPacket {
|
||||||
public tag: enums.packet.publicKey;
|
static readonly tag: enums.packet.publicKey;
|
||||||
|
protected isSubkey(): false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PublicSubkeyPacket extends BasePublicKeyPacket {
|
export class PublicSubkeyPacket extends BasePublicKeyPacket {
|
||||||
public tag: enums.packet.publicSubkey;
|
static readonly tag: enums.packet.publicSubkey;
|
||||||
|
protected isSubkey(): true;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare abstract class BaseSecretKeyPacket extends BasePublicKeyPacket {
|
declare abstract class BaseSecretKeyPacket extends BasePublicKeyPacket {
|
||||||
|
@ -334,56 +340,78 @@ declare abstract class BaseSecretKeyPacket extends BasePublicKeyPacket {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SecretKeyPacket extends BaseSecretKeyPacket {
|
export class SecretKeyPacket extends BaseSecretKeyPacket {
|
||||||
public tag: enums.packet.secretKey;
|
static readonly tag: enums.packet.secretKey;
|
||||||
|
protected isSubkey(): false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SecretSubkeyPacket extends BaseSecretKeyPacket {
|
export class SecretSubkeyPacket extends BaseSecretKeyPacket {
|
||||||
public tag: enums.packet.secretSubkey;
|
static readonly tag: enums.packet.secretSubkey;
|
||||||
|
protected isSubkey(): true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompressedDataPacket extends BasePacket {
|
export class CompressedDataPacket extends BasePacket {
|
||||||
public tag: enums.packet.compressedData;
|
static readonly tag: enums.packet.compressedData;
|
||||||
|
private compress(): void;
|
||||||
|
private decompress(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SymEncryptedIntegrityProtectedDataPacket extends BasePacket {
|
export class SymEncryptedIntegrityProtectedDataPacket extends BasePacket {
|
||||||
public tag: enums.packet.symEncryptedIntegrityProtectedData;
|
static readonly tag: enums.packet.symEncryptedIntegrityProtectedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AEADEncryptedDataPacket extends BasePacket {
|
export class AEADEncryptedDataPacket extends BasePacket {
|
||||||
public tag: enums.packet.aeadEncryptedData;
|
static readonly tag: enums.packet.aeadEncryptedData;
|
||||||
|
private decrypt(sessionKeyAlgorithm: string, sessionKey: Uint8Array): void;
|
||||||
|
private encrypt(sessionKeyAlgorithm: string, sessionKey: Uint8Array, config?: Config): void;
|
||||||
|
private crypt(fn: Function, sessionKey: Uint8Array, data: MaybeStream<Uint8Array>): MaybeStream<Uint8Array>
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PublicKeyEncryptedSessionKeyPaclet extends BasePacket {
|
export class PublicKeyEncryptedSessionKeyPaclet extends BasePacket {
|
||||||
public tag: enums.packet.publicKeyEncryptedSessionKey;
|
static readonly tag: enums.packet.publicKeyEncryptedSessionKey;
|
||||||
|
private decrypt(keyPacket: SecretKeyPacket): Promise<true>; // throws on error
|
||||||
|
private encrypt(keyPacket: PublicKeyPacket): Promise<true>; // throws on error
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SymEncryptedSessionKey extends BasePacket {
|
export class SymEncryptedSessionKey extends BasePacket {
|
||||||
public tag: enums.packet.symEncryptedSessionKey;
|
static readonly tag: enums.packet.symEncryptedSessionKey;
|
||||||
|
private decrypt(passphrase: string): Promise<void>;
|
||||||
|
private encrypt(passphrase: string, config?: Config): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LiteralDataPacket extends BasePacket {
|
export class LiteralDataPacket extends BasePacket {
|
||||||
public tag: enums.packet.literalData;
|
static readonly tag: enums.packet.literalData;
|
||||||
|
private getText(clone?: boolean): MaybeStream<string>;
|
||||||
|
private getBytes(clone?: boolean): MaybeStream<Uint8Array>;
|
||||||
|
private setText(text: MaybeStream<string>, format?: DataPacketType);
|
||||||
|
private setBytes(bytes: MaybeStream<Uint8Array>, format?: DataPacketType);
|
||||||
|
private setFilename(filename: string);
|
||||||
|
private getFilename(): string;
|
||||||
|
private writeHeader(): Uint8Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SymmetricallyEncryptedDataPacket extends BasePacket {
|
export class SymmetricallyEncryptedDataPacket extends BasePacket {
|
||||||
public tag: enums.packet.symmetricallyEncryptedData;
|
static readonly tag: enums.packet.symmetricallyEncryptedData;
|
||||||
|
private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void;
|
||||||
|
private encrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MarkerPacket extends BasePacket {
|
export class MarkerPacket extends BasePacket {
|
||||||
public tag: enums.packet.marker;
|
static readonly tag: enums.packet.marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UserAttributePacket extends BasePacket {
|
export class UserAttributePacket extends BasePacket {
|
||||||
public tag: enums.packet.userAttribute;
|
static readonly tag: enums.packet.userAttribute;
|
||||||
|
private equals(packet: UserAttributePacket): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OnePassSignaturePacket extends BasePacket {
|
export class OnePassSignaturePacket extends BasePacket {
|
||||||
public tag: enums.packet.onePassSignature;
|
static readonly tag: enums.packet.onePassSignature;
|
||||||
public correspondingSig?: Promise<SignaturePacket>;
|
public correspondingSig?: Promise<SignaturePacket>;
|
||||||
|
private verify: SignaturePacket['verify'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UserIDPacket extends BasePacket {
|
export class UserIDPacket extends BasePacket {
|
||||||
public readonly tag: enums.packet.userID;
|
static readonly tag: enums.packet.userID;
|
||||||
public readonly name: string;
|
public readonly name: string;
|
||||||
public readonly comment: string;
|
public readonly comment: string;
|
||||||
public readonly email: string;
|
public readonly email: string;
|
||||||
|
@ -392,7 +420,7 @@ export class UserIDPacket extends BasePacket {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SignaturePacket extends BasePacket {
|
export class SignaturePacket extends BasePacket {
|
||||||
public tag: enums.packet.signature;
|
static readonly tag: enums.packet.signature;
|
||||||
public version: number;
|
public version: number;
|
||||||
public signatureType: enums.signature | null;
|
public signatureType: enums.signature | null;
|
||||||
public hashAlgorithm: enums.hash | null;
|
public hashAlgorithm: enums.hash | null;
|
||||||
|
@ -443,7 +471,7 @@ export class SignaturePacket extends BasePacket {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TrustPacket extends BasePacket {
|
export class TrustPacket extends BasePacket {
|
||||||
public tag: enums.packet.trust;
|
static readonly tag: enums.packet.trust;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AnyPacket = BasePacket;
|
export type AnyPacket = BasePacket;
|
||||||
|
@ -453,24 +481,13 @@ export type AnyKeyPacket = BasePublicKeyPacket;
|
||||||
type DataPacketType = 'utf8' | 'binary' | 'text' | 'mime';
|
type DataPacketType = 'utf8' | 'binary' | 'text' | 'mime';
|
||||||
|
|
||||||
|
|
||||||
export class PacketList<PACKET_TYPE> extends Array<PACKET_TYPE> {
|
export class PacketList<T extends AnyPacket> extends Array<T> {
|
||||||
[index: number]: PACKET_TYPE;
|
|
||||||
public length: number;
|
public length: number;
|
||||||
public read(bytes: Uint8Array, allowedPackets?: object, config?: Config): void;
|
public read(bytes: Uint8Array, allowedPackets?: object, config?: Config): void;
|
||||||
public write(): Uint8Array;
|
public write(): Uint8Array;
|
||||||
public push(...packet: PACKET_TYPE[]): number;
|
public filterByTag(...args: enums.packet[]): PacketList<T>;
|
||||||
public pop(): PACKET_TYPE;
|
public indexOfTag(...tags: enums.packet[]): number[];
|
||||||
public filter(callback: (packet: PACKET_TYPE, i: number, self: PacketList<PACKET_TYPE>) => void): PacketList<PACKET_TYPE>;
|
public findPacket(tag: enums.packet): T | undefined;
|
||||||
public filterByTag(...args: enums.packet[]): PacketList<PACKET_TYPE>;
|
|
||||||
public forEach(callback: (packet: PACKET_TYPE, i: number, self: PacketList<PACKET_TYPE>) => void): void;
|
|
||||||
public map<RETURN_TYPE>(callback: (packet: PACKET_TYPE, i: number, self: PacketList<PACKET_TYPE>) => RETURN_TYPE): PacketList<RETURN_TYPE>;
|
|
||||||
// some()
|
|
||||||
// every()
|
|
||||||
// findPacket()
|
|
||||||
// indexOfTag()
|
|
||||||
// slice()
|
|
||||||
// concat()
|
|
||||||
// fromStructuredClone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ############## v5 STREAM #################### */
|
/* ############## v5 STREAM #################### */
|
||||||
|
|
|
@ -150,10 +150,10 @@ class Key {
|
||||||
toPacketlist() {
|
toPacketlist() {
|
||||||
const packetlist = new PacketList();
|
const packetlist = new PacketList();
|
||||||
packetlist.push(this.keyPacket);
|
packetlist.push(this.keyPacket);
|
||||||
packetlist.concat(this.revocationSignatures);
|
packetlist.push(...this.revocationSignatures);
|
||||||
packetlist.concat(this.directSignatures);
|
packetlist.push(...this.directSignatures);
|
||||||
this.users.map(user => packetlist.concat(user.toPacketlist()));
|
this.users.map(user => packetlist.push(...user.toPacketlist()));
|
||||||
this.subKeys.map(subKey => packetlist.concat(subKey.toPacketlist()));
|
this.subKeys.map(subKey => packetlist.push(...subKey.toPacketlist()));
|
||||||
return packetlist;
|
return packetlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ class SubKey {
|
||||||
toPacketlist() {
|
toPacketlist() {
|
||||||
const packetlist = new PacketList();
|
const packetlist = new PacketList();
|
||||||
packetlist.push(this.keyPacket);
|
packetlist.push(this.keyPacket);
|
||||||
packetlist.concat(this.revocationSignatures);
|
packetlist.push(...this.revocationSignatures);
|
||||||
packetlist.concat(this.bindingSignatures);
|
packetlist.push(...this.bindingSignatures);
|
||||||
return packetlist;
|
return packetlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@ class User {
|
||||||
toPacketlist() {
|
toPacketlist() {
|
||||||
const packetlist = new PacketList();
|
const packetlist = new PacketList();
|
||||||
packetlist.push(this.userID || this.userAttribute);
|
packetlist.push(this.userID || this.userAttribute);
|
||||||
packetlist.concat(this.revocationSignatures);
|
packetlist.push(...this.revocationSignatures);
|
||||||
packetlist.concat(this.selfCertifications);
|
packetlist.push(...this.selfCertifications);
|
||||||
packetlist.concat(this.otherCertifications);
|
packetlist.push(...this.otherCertifications);
|
||||||
return packetlist;
|
return packetlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ export class Message {
|
||||||
let exception;
|
let exception;
|
||||||
if (passwords) {
|
if (passwords) {
|
||||||
const symESKeyPacketlist = this.packets.filterByTag(enums.packet.symEncryptedSessionKey);
|
const symESKeyPacketlist = this.packets.filterByTag(enums.packet.symEncryptedSessionKey);
|
||||||
if (!symESKeyPacketlist) {
|
if (symESKeyPacketlist.length === 0) {
|
||||||
throw new Error('No symmetrically encrypted session key packet found.');
|
throw new Error('No symmetrically encrypted session key packet found.');
|
||||||
}
|
}
|
||||||
await Promise.all(passwords.map(async function(password, i) {
|
await Promise.all(passwords.map(async function(password, i) {
|
||||||
|
@ -192,7 +192,7 @@ export class Message {
|
||||||
}));
|
}));
|
||||||
} else if (privateKeys) {
|
} else if (privateKeys) {
|
||||||
const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
|
const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
|
||||||
if (!pkESKeyPacketlist) {
|
if (pkESKeyPacketlist.length === 0) {
|
||||||
throw new Error('No public key encrypted session key packet found.');
|
throw new Error('No public key encrypted session key packet found.');
|
||||||
}
|
}
|
||||||
await Promise.all(pkESKeyPacketlist.map(async function(keyPacket) {
|
await Promise.all(pkESKeyPacketlist.map(async function(keyPacket) {
|
||||||
|
@ -385,7 +385,7 @@ export class Message {
|
||||||
delete pkESKeyPacket.sessionKey; // delete plaintext session key after encryption
|
delete pkESKeyPacket.sessionKey; // delete plaintext session key after encryption
|
||||||
return pkESKeyPacket;
|
return pkESKeyPacket;
|
||||||
}));
|
}));
|
||||||
packetlist.concat(results);
|
packetlist.push(...results);
|
||||||
}
|
}
|
||||||
if (passwords) {
|
if (passwords) {
|
||||||
const testDecrypt = async function(keyPacket, password) {
|
const testDecrypt = async function(keyPacket, password) {
|
||||||
|
@ -420,7 +420,7 @@ export class Message {
|
||||||
};
|
};
|
||||||
|
|
||||||
const results = await Promise.all(passwords.map(pwd => encryptPassword(sessionKey, algorithm, aeadAlgorithm, pwd)));
|
const results = await Promise.all(passwords.map(pwd => encryptPassword(sessionKey, algorithm, aeadAlgorithm, pwd)));
|
||||||
packetlist.concat(results);
|
packetlist.push(...results);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Message(packetlist);
|
return new Message(packetlist);
|
||||||
|
@ -487,7 +487,7 @@ export class Message {
|
||||||
});
|
});
|
||||||
|
|
||||||
packetlist.push(literalDataPacket);
|
packetlist.push(literalDataPacket);
|
||||||
packetlist.concat(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, false, config));
|
packetlist.push(...(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, false, config)));
|
||||||
|
|
||||||
return new Message(packetlist);
|
return new Message(packetlist);
|
||||||
}
|
}
|
||||||
|
@ -551,7 +551,7 @@ export class Message {
|
||||||
throw new Error('Can only verify message with one literal data packet.');
|
throw new Error('Can only verify message with one literal data packet.');
|
||||||
}
|
}
|
||||||
if (stream.isArrayStream(msg.packets.stream)) {
|
if (stream.isArrayStream(msg.packets.stream)) {
|
||||||
msg.packets.concat(await stream.readToEnd(msg.packets.stream, _ => _));
|
msg.packets.push(...await stream.readToEnd(msg.packets.stream, _ => _ || []));
|
||||||
}
|
}
|
||||||
const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature).reverse();
|
const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature).reverse();
|
||||||
const signatureList = msg.packets.filterByTag(enums.packet.signature);
|
const signatureList = msg.packets.filterByTag(enums.packet.signature);
|
||||||
|
@ -686,7 +686,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
|
||||||
|
|
||||||
if (signature) {
|
if (signature) {
|
||||||
const existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
|
const existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
|
||||||
packetlist.concat(existingSigPacketlist);
|
packetlist.push(...existingSigPacketlist);
|
||||||
}
|
}
|
||||||
return packetlist;
|
return packetlist;
|
||||||
}
|
}
|
||||||
|
@ -752,7 +752,7 @@ async function createVerificationObject(signature, literalDataList, keys, date =
|
||||||
signature: (async () => {
|
signature: (async () => {
|
||||||
const sig = await signaturePacket;
|
const sig = await signaturePacket;
|
||||||
const packetlist = new PacketList();
|
const packetlist = new PacketList();
|
||||||
packetlist.push(sig);
|
sig && packetlist.push(sig);
|
||||||
return new Signature(packetlist);
|
return new Signature(packetlist);
|
||||||
})()
|
})()
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,6 +25,7 @@ import LiteralDataPacket from './literal_data';
|
||||||
import CompressedDataPacket from './compressed_data';
|
import CompressedDataPacket from './compressed_data';
|
||||||
import OnePassSignaturePacket from './one_pass_signature';
|
import OnePassSignaturePacket from './one_pass_signature';
|
||||||
import SignaturePacket from './signature';
|
import SignaturePacket from './signature';
|
||||||
|
import PacketList from './packetlist';
|
||||||
|
|
||||||
// An AEAD-encrypted Data packet can contain the following packet types
|
// An AEAD-encrypted Data packet can contain the following packet types
|
||||||
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
|
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
|
||||||
|
@ -93,6 +94,7 @@ class AEADEncryptedDataPacket {
|
||||||
* @async
|
* @async
|
||||||
*/
|
*/
|
||||||
async decrypt(sessionKeyAlgorithm, key) {
|
async decrypt(sessionKeyAlgorithm, key) {
|
||||||
|
this.packets = new PacketList();
|
||||||
await this.packets.read(await this.crypt('decrypt', key, stream.clone(this.encrypted)), allowedPackets);
|
await this.packets.read(await this.crypt('decrypt', key, stream.clone(this.encrypted)), allowedPackets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import defaultConfig from '../config';
|
||||||
import LiteralDataPacket from './literal_data';
|
import LiteralDataPacket from './literal_data';
|
||||||
import OnePassSignaturePacket from './one_pass_signature';
|
import OnePassSignaturePacket from './one_pass_signature';
|
||||||
import SignaturePacket from './signature';
|
import SignaturePacket from './signature';
|
||||||
|
import PacketList from './packetlist';
|
||||||
|
|
||||||
// A Compressed Data packet can contain the following packet types
|
// A Compressed Data packet can contain the following packet types
|
||||||
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
|
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
|
||||||
|
@ -116,6 +117,7 @@ class CompressedDataPacket {
|
||||||
throw new Error(this.algorithm + ' decompression not supported');
|
throw new Error(this.algorithm + ' decompression not supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.packets = new PacketList();
|
||||||
await this.packets.read(decompress_fns[this.algorithm](this.compressed), allowedPackets);
|
await this.packets.read(decompress_fns[this.algorithm](this.compressed), allowedPackets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,13 @@ import enums from '../enums';
|
||||||
* tag. With PGP 5.x, this packet has been reassigned and is reserved for use as
|
* tag. With PGP 5.x, this packet has been reassigned and is reserved for use as
|
||||||
* the Marker packet.
|
* the Marker packet.
|
||||||
*
|
*
|
||||||
* Such a packet MUST be ignored when received.
|
* The body of this packet consists of:
|
||||||
|
* The three octets 0x50, 0x47, 0x50 (which spell "PGP" in UTF-8).
|
||||||
|
*
|
||||||
|
* Such a packet MUST be ignored when received. It may be placed at the
|
||||||
|
* beginning of a message that uses features not available in PGP
|
||||||
|
* version 2.6 in order to cause that version to report that newer
|
||||||
|
* software is necessary to process the message.
|
||||||
*/
|
*/
|
||||||
class MarkerPacket {
|
class MarkerPacket {
|
||||||
static get tag() {
|
static get tag() {
|
||||||
|
@ -36,15 +42,9 @@ class MarkerPacket {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parsing function for a literal data packet (tag 10).
|
* Parsing function for a marker data packet (tag 10).
|
||||||
*
|
* @param {Uint8Array} bytes - Payload of a tag 10 packet
|
||||||
* @param {String} input - Payload of a tag 10 packet
|
* @returns {Boolean} whether the packet payload contains "PGP"
|
||||||
* @param {Integer} position
|
|
||||||
* Position to start reading from the input string
|
|
||||||
* @param {Integer} len
|
|
||||||
* Length of the packet or the remaining length of
|
|
||||||
* input at position
|
|
||||||
* @returns {MarkerPacket} Object representation.
|
|
||||||
*/
|
*/
|
||||||
read(bytes) {
|
read(bytes) {
|
||||||
if (bytes[0] === 0x50 && // P
|
if (bytes[0] === 0x50 && // P
|
||||||
|
@ -52,9 +52,13 @@ class MarkerPacket {
|
||||||
bytes[2] === 0x50) { // P
|
bytes[2] === 0x50) { // P
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// marker packet does not contain "PGP"
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
write() {
|
||||||
|
return new Uint8Array([0x50, 0x47, 0x50]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MarkerPacket;
|
export default MarkerPacket;
|
||||||
|
|
|
@ -127,30 +127,17 @@ class PacketList extends Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a packet to the list. This is the only supported method of doing so;
|
* Creates a new PacketList with all packets matching the given tag(s)
|
||||||
* writing to packetlist[i] directly will result in an error.
|
* @param {...module:enums.packet} tags - packet tags to look for
|
||||||
* @param {Object} packet - Packet to push
|
* @returns {PacketList}
|
||||||
*/
|
*/
|
||||||
push(packet) {
|
filterByTag(...tags) {
|
||||||
if (!packet) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
packet.packets = packet.packets || new PacketList();
|
|
||||||
|
|
||||||
super.push(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new PacketList with all packets from the given types
|
|
||||||
*/
|
|
||||||
filterByTag(...args) {
|
|
||||||
const filtered = new PacketList();
|
const filtered = new PacketList();
|
||||||
|
|
||||||
const handle = tag => packetType => tag === packetType;
|
const handle = tag => packetType => tag === packetType;
|
||||||
|
|
||||||
for (let i = 0; i < this.length; i++) {
|
for (let i = 0; i < this.length; i++) {
|
||||||
if (args.some(handle(this[i].constructor.tag))) {
|
if (tags.some(handle(this[i].constructor.tag))) {
|
||||||
filtered.push(this[i]);
|
filtered.push(this[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,42 +146,32 @@ class PacketList extends Array {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traverses packet tree and returns first matching packet
|
* Traverses packet list and returns first packet with matching tag
|
||||||
* @param {module:enums.packet} type - The packet type
|
* @param {module:enums.packet} tag - The packet tag
|
||||||
* @returns {Packet|undefined}
|
* @returns {Packet|undefined}
|
||||||
*/
|
*/
|
||||||
findPacket(type) {
|
findPacket(tag) {
|
||||||
return this.find(packet => packet.constructor.tag === type);
|
return this.find(packet => packet.constructor.tag === tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns array of found indices by tag
|
* Find indices of packets with the given tag(s)
|
||||||
|
* @param {...module:enums.packet} tags - packet tags to look for
|
||||||
|
* @returns {Integer[]} packet indices
|
||||||
*/
|
*/
|
||||||
indexOfTag(...args) {
|
indexOfTag(...tags) {
|
||||||
const tagIndex = [];
|
const tagIndex = [];
|
||||||
const that = this;
|
const that = this;
|
||||||
|
|
||||||
const handle = tag => packetType => tag === packetType;
|
const handle = tag => packetType => tag === packetType;
|
||||||
|
|
||||||
for (let i = 0; i < this.length; i++) {
|
for (let i = 0; i < this.length; i++) {
|
||||||
if (args.some(handle(that[i].constructor.tag))) {
|
if (tags.some(handle(that[i].constructor.tag))) {
|
||||||
tagIndex.push(i);
|
tagIndex.push(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tagIndex;
|
return tagIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Concatenates packetlist or array of packets
|
|
||||||
*/
|
|
||||||
concat(packetlist) {
|
|
||||||
if (packetlist) {
|
|
||||||
for (let i = 0; i < packetlist.length; i++) {
|
|
||||||
this.push(packetlist[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PacketList;
|
export default PacketList;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import LiteralDataPacket from './literal_data';
|
||||||
import CompressedDataPacket from './compressed_data';
|
import CompressedDataPacket from './compressed_data';
|
||||||
import OnePassSignaturePacket from './one_pass_signature';
|
import OnePassSignaturePacket from './one_pass_signature';
|
||||||
import SignaturePacket from './signature';
|
import SignaturePacket from './signature';
|
||||||
|
import PacketList from './packetlist';
|
||||||
|
|
||||||
// A SEIP packet can contain the following packet types
|
// A SEIP packet can contain the following packet types
|
||||||
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
|
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
|
||||||
|
@ -53,15 +54,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.version = VERSION;
|
this.version = VERSION;
|
||||||
/** The encrypted payload. */
|
this.encrypted = null;
|
||||||
this.encrypted = null; // string
|
|
||||||
/**
|
|
||||||
* If after decrypting the packet this is set to true,
|
|
||||||
* a modification has been detected and thus the contents
|
|
||||||
* should be discarded.
|
|
||||||
* @type {Boolean}
|
|
||||||
*/
|
|
||||||
this.modification = false;
|
|
||||||
this.packets = null;
|
this.packets = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +131,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
||||||
if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) {
|
if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) {
|
||||||
packetbytes = await stream.readToEnd(packetbytes);
|
packetbytes = await stream.readToEnd(packetbytes);
|
||||||
}
|
}
|
||||||
|
this.packets = new PacketList();
|
||||||
await this.packets.read(packetbytes, allowedPackets);
|
await this.packets.read(packetbytes, allowedPackets);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import LiteralDataPacket from './literal_data';
|
||||||
import CompressedDataPacket from './compressed_data';
|
import CompressedDataPacket from './compressed_data';
|
||||||
import OnePassSignaturePacket from './one_pass_signature';
|
import OnePassSignaturePacket from './one_pass_signature';
|
||||||
import SignaturePacket from './signature';
|
import SignaturePacket from './signature';
|
||||||
|
import PacketList from './packetlist';
|
||||||
|
|
||||||
// A SE packet can contain the following packet types
|
// A SE packet can contain the following packet types
|
||||||
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
|
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
|
||||||
|
@ -91,6 +92,7 @@ class SymmetricallyEncryptedDataPacket {
|
||||||
encrypted.subarray(2, crypto.cipher[sessionKeyAlgorithm].blockSize + 2)
|
encrypted.subarray(2, crypto.cipher[sessionKeyAlgorithm].blockSize + 2)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.packets = new PacketList();
|
||||||
await this.packets.read(decrypted, allowedPackets);
|
await this.packets.read(decrypted, allowedPackets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ class TrustPacket {
|
||||||
* @param {String} byptes - Payload of a tag 12 packet
|
* @param {String} byptes - Payload of a tag 12 packet
|
||||||
*/
|
*/
|
||||||
read() {} // TODO
|
read() {} // TODO
|
||||||
|
|
||||||
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
write() {
|
||||||
|
throw new Error('Trust packets are not supported');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TrustPacket;
|
export default TrustPacket;
|
||||||
|
|
|
@ -2722,7 +2722,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
|
||||||
};
|
};
|
||||||
return openpgp.sign(signOpt).then(async function (signed) {
|
return openpgp.sign(signOpt).then(async function (signed) {
|
||||||
const message = await openpgp.readMessage({ binaryMessage: signed });
|
const message = await openpgp.readMessage({ binaryMessage: signed });
|
||||||
message.packets.concat(await openpgp.stream.readToEnd(message.packets.stream, _ => _));
|
message.packets.push(...await openpgp.stream.readToEnd(message.packets.stream, _ => _));
|
||||||
const packets = new openpgp.PacketList();
|
const packets = new openpgp.PacketList();
|
||||||
packets.push(message.packets.findPacket(openpgp.enums.packet.signature));
|
packets.push(message.packets.findPacket(openpgp.enums.packet.signature));
|
||||||
packets.push(message.packets.findPacket(openpgp.enums.packet.literalData));
|
packets.push(message.packets.findPacket(openpgp.enums.packet.literalData));
|
||||||
|
@ -2762,7 +2762,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
|
||||||
return openpgp.sign(signOpt).then(async function (signed) {
|
return openpgp.sign(signOpt).then(async function (signed) {
|
||||||
expect(openpgp.stream.isStream(signed)).to.equal(global.ReadableStream ? 'web' : 'node');
|
expect(openpgp.stream.isStream(signed)).to.equal(global.ReadableStream ? 'web' : 'node');
|
||||||
const message = await openpgp.readMessage({ binaryMessage: signed });
|
const message = await openpgp.readMessage({ binaryMessage: signed });
|
||||||
message.packets.concat(await openpgp.stream.readToEnd(message.packets.stream, _ => _));
|
message.packets.push(...await openpgp.stream.readToEnd(message.packets.stream, _ => _));
|
||||||
const packets = new openpgp.PacketList();
|
const packets = new openpgp.PacketList();
|
||||||
packets.push(message.packets.findPacket(openpgp.enums.packet.signature));
|
packets.push(message.packets.findPacket(openpgp.enums.packet.signature));
|
||||||
packets.push(message.packets.findPacket(openpgp.enums.packet.literalData));
|
packets.push(message.packets.findPacket(openpgp.enums.packet.literalData));
|
||||||
|
|
|
@ -81,8 +81,9 @@ module.exports = () => describe("Packet", function() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const enc = new openpgp.SymmetricallyEncryptedDataPacket();
|
const enc = new openpgp.SymmetricallyEncryptedDataPacket();
|
||||||
message.push(enc);
|
enc.packets = new openpgp.PacketList();
|
||||||
enc.packets.push(literal);
|
enc.packets.push(literal);
|
||||||
|
message.push(enc);
|
||||||
|
|
||||||
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
|
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
|
||||||
const algo = 'aes256';
|
const algo = 'aes256';
|
||||||
|
@ -112,8 +113,9 @@ module.exports = () => describe("Packet", function() {
|
||||||
literal.setText(testText);
|
literal.setText(testText);
|
||||||
|
|
||||||
const enc = new openpgp.SymmetricallyEncryptedDataPacket();
|
const enc = new openpgp.SymmetricallyEncryptedDataPacket();
|
||||||
|
enc.packets = new openpgp.PacketList();
|
||||||
|
enc.packets.push(literal);
|
||||||
message.push(enc);
|
message.push(enc);
|
||||||
await enc.packets.push(literal);
|
|
||||||
|
|
||||||
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
|
const key = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
|
||||||
const algo = 'aes256';
|
const algo = 'aes256';
|
||||||
|
@ -135,11 +137,12 @@ module.exports = () => describe("Packet", function() {
|
||||||
|
|
||||||
const literal = new openpgp.LiteralDataPacket();
|
const literal = new openpgp.LiteralDataPacket();
|
||||||
const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket();
|
const enc = new openpgp.SymEncryptedIntegrityProtectedDataPacket();
|
||||||
const msg = new openpgp.PacketList();
|
enc.packets = new openpgp.PacketList();
|
||||||
|
|
||||||
msg.push(enc);
|
|
||||||
literal.setText(testText);
|
|
||||||
enc.packets.push(literal);
|
enc.packets.push(literal);
|
||||||
|
const msg = new openpgp.PacketList();
|
||||||
|
msg.push(enc);
|
||||||
|
|
||||||
|
literal.setText(testText);
|
||||||
await enc.encrypt(algo, key, undefined, openpgp.config);
|
await enc.encrypt(algo, key, undefined, openpgp.config);
|
||||||
|
|
||||||
const msg2 = new openpgp.PacketList();
|
const msg2 = new openpgp.PacketList();
|
||||||
|
@ -158,12 +161,12 @@ module.exports = () => describe("Packet", function() {
|
||||||
const algo = 'aes256';
|
const algo = 'aes256';
|
||||||
const testText = input.createSomeMessage();
|
const testText = input.createSomeMessage();
|
||||||
const literal = new openpgp.LiteralDataPacket();
|
const literal = new openpgp.LiteralDataPacket();
|
||||||
const enc = new openpgp.AEADEncryptedDataPacket();
|
|
||||||
const msg = new openpgp.PacketList();
|
|
||||||
|
|
||||||
msg.push(enc);
|
|
||||||
literal.setText(testText);
|
literal.setText(testText);
|
||||||
|
const enc = new openpgp.AEADEncryptedDataPacket();
|
||||||
|
enc.packets = new openpgp.PacketList();
|
||||||
enc.packets.push(literal);
|
enc.packets.push(literal);
|
||||||
|
const msg = new openpgp.PacketList();
|
||||||
|
msg.push(enc);
|
||||||
|
|
||||||
const msg2 = new openpgp.PacketList();
|
const msg2 = new openpgp.PacketList();
|
||||||
|
|
||||||
|
@ -210,13 +213,13 @@ module.exports = () => describe("Packet", function() {
|
||||||
const algo = 'aes256';
|
const algo = 'aes256';
|
||||||
|
|
||||||
const literal = new openpgp.LiteralDataPacket();
|
const literal = new openpgp.LiteralDataPacket();
|
||||||
const enc = new openpgp.AEADEncryptedDataPacket();
|
|
||||||
const msg = new openpgp.PacketList();
|
|
||||||
enc.aeadAlgorithm = 'experimentalGCM';
|
|
||||||
|
|
||||||
msg.push(enc);
|
|
||||||
literal.setText(testText);
|
literal.setText(testText);
|
||||||
|
const enc = new openpgp.AEADEncryptedDataPacket();
|
||||||
|
enc.aeadAlgorithm = 'experimentalGCM';
|
||||||
|
enc.packets = new openpgp.PacketList();
|
||||||
enc.packets.push(literal);
|
enc.packets.push(literal);
|
||||||
|
const msg = new openpgp.PacketList();
|
||||||
|
msg.push(enc);
|
||||||
|
|
||||||
const msg2 = new openpgp.PacketList();
|
const msg2 = new openpgp.PacketList();
|
||||||
|
|
||||||
|
@ -252,13 +255,13 @@ module.exports = () => describe("Packet", function() {
|
||||||
const algo = 'aes128';
|
const algo = 'aes128';
|
||||||
|
|
||||||
const literal = new openpgp.LiteralDataPacket(0);
|
const literal = new openpgp.LiteralDataPacket(0);
|
||||||
const enc = new openpgp.AEADEncryptedDataPacket();
|
|
||||||
const msg = new openpgp.PacketList();
|
|
||||||
|
|
||||||
msg.push(enc);
|
|
||||||
literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
|
literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
|
||||||
literal.filename = '';
|
literal.filename = '';
|
||||||
|
const enc = new openpgp.AEADEncryptedDataPacket();
|
||||||
|
enc.packets = new openpgp.PacketList();
|
||||||
enc.packets.push(literal);
|
enc.packets.push(literal);
|
||||||
|
const msg = new openpgp.PacketList();
|
||||||
|
msg.push(enc);
|
||||||
|
|
||||||
const msg2 = new openpgp.PacketList();
|
const msg2 = new openpgp.PacketList();
|
||||||
|
|
||||||
|
@ -446,8 +449,11 @@ module.exports = () => describe("Packet", function() {
|
||||||
const testText = input.createSomeMessage();
|
const testText = input.createSomeMessage();
|
||||||
|
|
||||||
const literal = new openpgp.LiteralDataPacket();
|
const literal = new openpgp.LiteralDataPacket();
|
||||||
|
literal.setText(testText);
|
||||||
const skesk = new openpgp.SymEncryptedSessionKeyPacket();
|
const skesk = new openpgp.SymEncryptedSessionKeyPacket();
|
||||||
const seip = new openpgp.SymEncryptedIntegrityProtectedDataPacket();
|
const seip = new openpgp.SymEncryptedIntegrityProtectedDataPacket();
|
||||||
|
seip.packets = new openpgp.PacketList();
|
||||||
|
seip.packets.push(literal);
|
||||||
const msg = new openpgp.PacketList();
|
const msg = new openpgp.PacketList();
|
||||||
|
|
||||||
msg.push(skesk);
|
msg.push(skesk);
|
||||||
|
@ -457,9 +463,6 @@ module.exports = () => describe("Packet", function() {
|
||||||
await skesk.encrypt(passphrase, openpgp.config);
|
await skesk.encrypt(passphrase, openpgp.config);
|
||||||
|
|
||||||
const key = skesk.sessionKey;
|
const key = skesk.sessionKey;
|
||||||
|
|
||||||
literal.setText(testText);
|
|
||||||
seip.packets.push(literal);
|
|
||||||
await seip.encrypt(algo, key, undefined, openpgp.config);
|
await seip.encrypt(algo, key, undefined, openpgp.config);
|
||||||
|
|
||||||
const msg2 = new openpgp.PacketList();
|
const msg2 = new openpgp.PacketList();
|
||||||
|
@ -485,10 +488,12 @@ module.exports = () => describe("Packet", function() {
|
||||||
const testText = input.createSomeMessage();
|
const testText = input.createSomeMessage();
|
||||||
|
|
||||||
const literal = new openpgp.LiteralDataPacket();
|
const literal = new openpgp.LiteralDataPacket();
|
||||||
|
literal.setText(testText);
|
||||||
const skesk = new openpgp.SymEncryptedSessionKeyPacket();
|
const skesk = new openpgp.SymEncryptedSessionKeyPacket();
|
||||||
const aeadEnc = new openpgp.AEADEncryptedDataPacket();
|
const aeadEnc = new openpgp.AEADEncryptedDataPacket();
|
||||||
|
aeadEnc.packets = new openpgp.PacketList();
|
||||||
|
aeadEnc.packets.push(literal);
|
||||||
const msg = new openpgp.PacketList();
|
const msg = new openpgp.PacketList();
|
||||||
|
|
||||||
msg.push(skesk);
|
msg.push(skesk);
|
||||||
msg.push(aeadEnc);
|
msg.push(aeadEnc);
|
||||||
|
|
||||||
|
@ -496,9 +501,6 @@ module.exports = () => describe("Packet", function() {
|
||||||
await skesk.encrypt(passphrase, openpgp.config);
|
await skesk.encrypt(passphrase, openpgp.config);
|
||||||
|
|
||||||
const key = skesk.sessionKey;
|
const key = skesk.sessionKey;
|
||||||
|
|
||||||
literal.setText(testText);
|
|
||||||
aeadEnc.packets.push(literal);
|
|
||||||
await aeadEnc.encrypt(algo, key, undefined, openpgp.config);
|
await aeadEnc.encrypt(algo, key, undefined, openpgp.config);
|
||||||
|
|
||||||
const msg2 = new openpgp.PacketList();
|
const msg2 = new openpgp.PacketList();
|
||||||
|
@ -556,21 +558,20 @@ module.exports = () => describe("Packet", function() {
|
||||||
const algo = 'aes128';
|
const algo = 'aes128';
|
||||||
|
|
||||||
const literal = new openpgp.LiteralDataPacket(0);
|
const literal = new openpgp.LiteralDataPacket(0);
|
||||||
|
literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
|
||||||
|
literal.filename = '';
|
||||||
const skesk = new openpgp.SymEncryptedSessionKeyPacket();
|
const skesk = new openpgp.SymEncryptedSessionKeyPacket();
|
||||||
|
skesk.sessionKeyAlgorithm = algo;
|
||||||
const encData = new openpgp.AEADEncryptedDataPacket();
|
const encData = new openpgp.AEADEncryptedDataPacket();
|
||||||
|
encData.packets = new openpgp.PacketList();
|
||||||
|
encData.packets.push(literal);
|
||||||
const msg = new openpgp.PacketList();
|
const msg = new openpgp.PacketList();
|
||||||
|
|
||||||
msg.push(skesk);
|
msg.push(skesk);
|
||||||
msg.push(encData);
|
msg.push(encData);
|
||||||
|
|
||||||
skesk.sessionKeyAlgorithm = algo;
|
|
||||||
await skesk.encrypt(passphrase, openpgp.config);
|
await skesk.encrypt(passphrase, openpgp.config);
|
||||||
|
|
||||||
const key = skesk.sessionKey;
|
const key = skesk.sessionKey;
|
||||||
|
|
||||||
literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
|
|
||||||
literal.filename = '';
|
|
||||||
encData.packets.push(literal);
|
|
||||||
await encData.encrypt(algo, key, undefined, openpgp.config);
|
await encData.encrypt(algo, key, undefined, openpgp.config);
|
||||||
|
|
||||||
const data = msg.write();
|
const data = msg.write();
|
||||||
|
@ -634,22 +635,21 @@ module.exports = () => describe("Packet", function() {
|
||||||
const algo = 'aes128';
|
const algo = 'aes128';
|
||||||
|
|
||||||
const literal = new openpgp.LiteralDataPacket(0);
|
const literal = new openpgp.LiteralDataPacket(0);
|
||||||
|
literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
|
||||||
|
literal.filename = '';
|
||||||
const key_enc = new openpgp.SymEncryptedSessionKeyPacket();
|
const key_enc = new openpgp.SymEncryptedSessionKeyPacket();
|
||||||
|
key_enc.sessionKeyAlgorithm = algo;
|
||||||
const enc = new openpgp.AEADEncryptedDataPacket();
|
const enc = new openpgp.AEADEncryptedDataPacket();
|
||||||
const msg = new openpgp.PacketList();
|
enc.packets = new openpgp.PacketList();
|
||||||
|
enc.packets.push(literal);
|
||||||
enc.aeadAlgorithm = key_enc.aeadAlgorithm = 'ocb';
|
enc.aeadAlgorithm = key_enc.aeadAlgorithm = 'ocb';
|
||||||
|
const msg = new openpgp.PacketList();
|
||||||
msg.push(key_enc);
|
msg.push(key_enc);
|
||||||
msg.push(enc);
|
msg.push(enc);
|
||||||
|
|
||||||
key_enc.sessionKeyAlgorithm = algo;
|
|
||||||
await key_enc.encrypt(passphrase, openpgp.config);
|
await key_enc.encrypt(passphrase, openpgp.config);
|
||||||
|
|
||||||
const key = key_enc.sessionKey;
|
const key = key_enc.sessionKey;
|
||||||
|
|
||||||
literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
|
|
||||||
literal.filename = '';
|
|
||||||
enc.packets.push(literal);
|
|
||||||
await enc.encrypt(algo, key, undefined, openpgp.config);
|
await enc.encrypt(algo, key, undefined, openpgp.config);
|
||||||
|
|
||||||
const data = msg.write();
|
const data = msg.write();
|
||||||
|
@ -747,7 +747,7 @@ module.exports = () => describe("Packet", function() {
|
||||||
await encData.decrypt(pkesk.sessionKeyAlgorithm, pkesk.sessionKey);
|
await encData.decrypt(pkesk.sessionKeyAlgorithm, pkesk.sessionKey);
|
||||||
|
|
||||||
const payload = encData.packets[0].packets;
|
const payload = encData.packets[0].packets;
|
||||||
payload.concat(await openpgp.stream.readToEnd(payload.stream, arr => arr));
|
payload.push(...await openpgp.stream.readToEnd(payload.stream, arr => arr));
|
||||||
const literal = payload[1];
|
const literal = payload[1];
|
||||||
const signature = payload[2];
|
const signature = payload[2];
|
||||||
|
|
||||||
|
@ -942,7 +942,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
|
||||||
|
|
||||||
const signed2 = new openpgp.PacketList();
|
const signed2 = new openpgp.PacketList();
|
||||||
await signed2.read(raw, allAllowedPackets);
|
await signed2.read(raw, allAllowedPackets);
|
||||||
signed2.concat(await openpgp.stream.readToEnd(signed2.stream, arr => arr));
|
signed2.push(...await openpgp.stream.readToEnd(signed2.stream, arr => arr));
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
signed2[1].verify(key, openpgp.enums.signature.text, signed2[0]),
|
signed2[1].verify(key, openpgp.enums.signature.text, signed2[0]),
|
||||||
|
|
|
@ -56,7 +56,7 @@ async function testSubkeyTrust() {
|
||||||
fakeBindingSignature.keyFlags = [enums.keyFlags.signData];
|
fakeBindingSignature.keyFlags = [enums.keyFlags.signData];
|
||||||
await fakeBindingSignature.sign(attackerPrivKey.keyPacket, dataToSign);
|
await fakeBindingSignature.sign(attackerPrivKey.keyPacket, dataToSign);
|
||||||
const newList = new PacketList();
|
const newList = new PacketList();
|
||||||
newList.concat([
|
newList.push(...[
|
||||||
pktPrivAttacker[0], // attacker private key
|
pktPrivAttacker[0], // attacker private key
|
||||||
pktPrivAttacker[1], // attacker user
|
pktPrivAttacker[1], // attacker user
|
||||||
pktPrivAttacker[2], // attacker self signature
|
pktPrivAttacker[2], // attacker self signature
|
||||||
|
|
|
@ -81,7 +81,7 @@ async function makeKeyValid() {
|
||||||
pusersig.readSubPackets(fake.writeHashedSubPackets(), false);
|
pusersig.readSubPackets(fake.writeHashedSubPackets(), false);
|
||||||
// reconstruct the modified key
|
// reconstruct the modified key
|
||||||
const newlist = new PacketList();
|
const newlist = new PacketList();
|
||||||
newlist.concat([pubkey, puser, pusersig]);
|
newlist.push(...[pubkey, puser, pusersig]);
|
||||||
let modifiedkey = new Key(newlist);
|
let modifiedkey = new Key(newlist);
|
||||||
// re-read the message to eliminate any
|
// re-read the message to eliminate any
|
||||||
// behaviour due to cached values.
|
// behaviour due to cached values.
|
||||||
|
|
|
@ -6,9 +6,13 @@
|
||||||
* - if it fails to run, edit this file to match the actual library API, then edit the definitions file (openpgp.d.ts) accordingly.
|
* - if it fails to run, edit this file to match the actual library API, then edit the definitions file (openpgp.d.ts) accordingly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { generateKey, readKey, readKeys, Key, readMessage, createMessage, Message, createCleartextMessage, encrypt, decrypt, sign, verify, config } from '../..';
|
|
||||||
|
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
|
import {
|
||||||
|
generateKey, readKey, readKeys, Key,
|
||||||
|
readMessage, createMessage, Message, createCleartextMessage,
|
||||||
|
encrypt, decrypt, sign, verify, config, enums,
|
||||||
|
LiteralDataPacket, PacketList, CompressedDataPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket
|
||||||
|
} from '../..';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
||||||
|
@ -78,6 +82,34 @@ import { expect } from 'chai';
|
||||||
const verifiedBinaryData: Uint8Array = verifiedBinary.data;
|
const verifiedBinaryData: Uint8Array = verifiedBinary.data;
|
||||||
expect(verifiedBinaryData).to.deep.equal(binary);
|
expect(verifiedBinaryData).to.deep.equal(binary);
|
||||||
|
|
||||||
|
// Generic packetlist
|
||||||
|
const packets = new PacketList();
|
||||||
|
expect(packets.push()).to.equal(0);
|
||||||
|
expect(packets.push(new LiteralDataPacket())).to.equal(1);
|
||||||
|
packets.map(packet => packet.write);
|
||||||
|
// @ts-expect-error for unsafe downcasting
|
||||||
|
packets.map((packet: LiteralDataPacket) => packet.getText());
|
||||||
|
// @ts-expect-error for non-packet element
|
||||||
|
try { new PacketList().push(1); } catch (e) {}
|
||||||
|
|
||||||
|
|
||||||
|
// Packetlist of specific type
|
||||||
|
const literalPackets = new PacketList<LiteralDataPacket>();
|
||||||
|
literalPackets.push(new LiteralDataPacket());
|
||||||
|
literalPackets[0].write();
|
||||||
|
literalPackets.map((packet: LiteralDataPacket) => packet);
|
||||||
|
packets.push(...literalPackets);
|
||||||
|
// @ts-expect-error for incompatible packetlist type
|
||||||
|
literalPackets.push(...packets);
|
||||||
|
// @ts-expect-error for incompatible packet type
|
||||||
|
new PacketList<LiteralDataPacket>().push(new CompressedDataPacket());
|
||||||
|
// @ts-expect-error for incompatible packet type
|
||||||
|
new PacketList<PublicKeyPacket>().push(new PublicSubkeyPacket());
|
||||||
|
// @ts-expect-error for incompatible packet type
|
||||||
|
new PacketList<SecretKeyPacket>().push(new SecretSubkeyPacket());
|
||||||
|
|
||||||
|
expect(LiteralDataPacket.tag).to.equal(enums.packet.literalData);
|
||||||
|
|
||||||
// // Detached - sign cleartext message (armored)
|
// // Detached - sign cleartext message (armored)
|
||||||
// import { Message, sign } from 'openpgp';
|
// import { Message, sign } from 'openpgp';
|
||||||
// const message = await createMessage({ text: util.removeTrailingSpaces(text) });
|
// const message = await createMessage({ text: util.removeTrailingSpaces(text) });
|
||||||
|
|
Loading…
Reference in New Issue
Block a user