@protontech/openpgp 6.1.1-patch.0 → 6.1.1-patch.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lightweight/argon2id.min.mjs +1 -1
- package/dist/lightweight/argon2id.mjs +1 -1
- package/dist/lightweight/legacy_ciphers.min.mjs +1 -1
- package/dist/lightweight/legacy_ciphers.mjs +1 -1
- package/dist/lightweight/noble_curves.min.mjs +1 -1
- package/dist/lightweight/noble_curves.mjs +1 -1
- package/dist/lightweight/noble_hashes.min.mjs +1 -1
- package/dist/lightweight/noble_hashes.mjs +1 -1
- package/dist/lightweight/noble_post_quantum.min.mjs +1 -1
- package/dist/lightweight/noble_post_quantum.mjs +1 -1
- package/dist/lightweight/openpgp.min.mjs +4 -4
- package/dist/lightweight/openpgp.min.mjs.map +1 -1
- package/dist/lightweight/openpgp.mjs +190 -27
- package/dist/lightweight/seek-bzip.min.mjs +1 -1
- package/dist/lightweight/seek-bzip.mjs +1 -1
- package/dist/lightweight/sha3.min.mjs +1 -1
- package/dist/lightweight/sha3.mjs +1 -1
- package/dist/lightweight/sha512.min.mjs +1 -1
- package/dist/lightweight/sha512.mjs +1 -1
- package/dist/node/openpgp.cjs +190 -26
- package/dist/node/openpgp.min.cjs +16 -16
- package/dist/node/openpgp.min.cjs.map +1 -1
- package/dist/node/openpgp.min.mjs +16 -16
- package/dist/node/openpgp.min.mjs.map +1 -1
- package/dist/node/openpgp.mjs +190 -27
- package/dist/openpgp.js +190 -26
- package/dist/openpgp.min.js +16 -16
- package/dist/openpgp.min.js.map +1 -1
- package/dist/openpgp.min.mjs +16 -16
- package/dist/openpgp.min.mjs.map +1 -1
- package/dist/openpgp.mjs +190 -27
- package/openpgp.d.ts +4 -241
- package/package.json +3 -2
- package/src/config/config.d.ts +68 -0
- package/src/config/index.d.ts +13 -0
- package/src/enums.d.ts +195 -0
package/dist/node/openpgp.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! OpenPGP.js v6.1.1-patch.
|
|
1
|
+
/*! OpenPGP.js v6.1.1-patch.2 - 2025-05-14 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
const globalThis = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -1572,6 +1572,8 @@ var config = {
|
|
|
1572
1572
|
* by v6 keys and v6 signatures, respectively.
|
|
1573
1573
|
* However, generation of v5 entities was supported behind config flag in OpenPGP.js v5, and some other libraries,
|
|
1574
1574
|
* hence parsing them might be necessary in some cases.
|
|
1575
|
+
* @memberof module:config
|
|
1576
|
+
* @property {Boolean} enableParsingV5Entities
|
|
1575
1577
|
*/
|
|
1576
1578
|
enableParsingV5Entities: false,
|
|
1577
1579
|
/**
|
|
@@ -1708,10 +1710,22 @@ var config = {
|
|
|
1708
1710
|
* @property {Boolean} ignoreMalformedPackets Ignore malformed packets on parsing instead of throwing an error
|
|
1709
1711
|
*/
|
|
1710
1712
|
ignoreMalformedPackets: false,
|
|
1713
|
+
/**
|
|
1714
|
+
* @memberof module:config
|
|
1715
|
+
* @property {Boolean} enforceGrammar whether parsed OpenPGP messages must comform to the OpenPGP grammar
|
|
1716
|
+
* defined in https://www.rfc-editor.org/rfc/rfc9580.html#name-openpgp-messages .
|
|
1717
|
+
*/
|
|
1718
|
+
enforceGrammar: true,
|
|
1719
|
+
/**
|
|
1720
|
+
* @memberof module:config
|
|
1721
|
+
* @property {function(string): any} pluggableGrammarErrorReporter callback meant to collect GrammarError reports even with `config.enforceGrammar` disabled.
|
|
1722
|
+
*/
|
|
1723
|
+
pluggableGrammarErrorReporter: null,
|
|
1711
1724
|
/**
|
|
1712
1725
|
* Parsing of packets is normally restricted to a predefined set of packets. For example a Sym. Encrypted Integrity Protected Data Packet can only
|
|
1713
1726
|
* contain a certain set of packets including LiteralDataPacket. With this setting we can allow additional packets, which is probably not advisable
|
|
1714
1727
|
* as a global config setting, but can be used for specific function calls (e.g. decrypt method of Message).
|
|
1728
|
+
* NB: `config.enforceGrammar` may need to be disabled as well.
|
|
1715
1729
|
* @memberof module:config
|
|
1716
1730
|
* @property {Array} additionalAllowedPackets Allow additional packets on parsing. Defined as array of packet classes, e.g. [PublicKeyPacket]
|
|
1717
1731
|
*/
|
|
@@ -1730,7 +1744,7 @@ var config = {
|
|
|
1730
1744
|
* @memberof module:config
|
|
1731
1745
|
* @property {String} versionString A version string to be included in armored messages
|
|
1732
1746
|
*/
|
|
1733
|
-
versionString: 'OpenPGP.js 6.1.1-patch.
|
|
1747
|
+
versionString: 'OpenPGP.js 6.1.1-patch.2',
|
|
1734
1748
|
/**
|
|
1735
1749
|
* @memberof module:config
|
|
1736
1750
|
* @property {String} commentString A comment string to be included in armored messages
|
|
@@ -2102,6 +2116,21 @@ const util = {
|
|
|
2102
2116
|
return true;
|
|
2103
2117
|
},
|
|
2104
2118
|
|
|
2119
|
+
/**
|
|
2120
|
+
* Same as Array.findLastIndex, which is not supported on Safari 14 .
|
|
2121
|
+
* @param {Array} arr
|
|
2122
|
+
* @param {function(element, index, arr): boolean} findFn
|
|
2123
|
+
* @return index of last element matching `findFn`, -1 if not found
|
|
2124
|
+
*/
|
|
2125
|
+
findLastIndex: function(arr, findFn) {
|
|
2126
|
+
for (let i = arr.length; i >= 0; i--) {
|
|
2127
|
+
if (findFn(arr[i], i, arr)) {
|
|
2128
|
+
return i;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
return -1;
|
|
2132
|
+
},
|
|
2133
|
+
|
|
2105
2134
|
/**
|
|
2106
2135
|
* Calculates a 16bit sum of a Uint8Array by adding each character
|
|
2107
2136
|
* codes modulus 65535
|
|
@@ -6928,11 +6957,7 @@ async function generate$a(algo) {
|
|
|
6928
6957
|
seed: b64ToUint8Array(privateKey.d, true)
|
|
6929
6958
|
};
|
|
6930
6959
|
} catch (err) {
|
|
6931
|
-
if (
|
|
6932
|
-
err.name !== 'NotSupportedError' &&
|
|
6933
|
-
err.name !== 'OperationError' && // Temporary (hopefully) fix for WebKit on Linux
|
|
6934
|
-
err.name !== 'SyntaxError' // Temporary fix for Palemoon throwing 'SyntaxError'
|
|
6935
|
-
) {
|
|
6960
|
+
if (err.name !== 'NotSupportedError' && err.name !== 'OperationError') { // Temporary (hopefully) fix for WebKit on Linux
|
|
6936
6961
|
throw err;
|
|
6937
6962
|
}
|
|
6938
6963
|
const seed = getRandomBytes(getPayloadSize$1(algo));
|
|
@@ -6984,7 +7009,7 @@ async function sign$9(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
6984
7009
|
|
|
6985
7010
|
return { RS: signature };
|
|
6986
7011
|
} catch (err) {
|
|
6987
|
-
if (err.name !== 'NotSupportedError'
|
|
7012
|
+
if (err.name !== 'NotSupportedError') {
|
|
6988
7013
|
throw err;
|
|
6989
7014
|
}
|
|
6990
7015
|
const secretKey = util.concatUint8Array([privateKey, publicKey]);
|
|
@@ -7030,7 +7055,7 @@ async function verify$9(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
|
|
7030
7055
|
const verified = await webCrypto.verify('Ed25519', key, RS, hashed);
|
|
7031
7056
|
return verified;
|
|
7032
7057
|
} catch (err) {
|
|
7033
|
-
if (err.name !== 'NotSupportedError'
|
|
7058
|
+
if (err.name !== 'NotSupportedError') {
|
|
7034
7059
|
throw err;
|
|
7035
7060
|
}
|
|
7036
7061
|
return verify$a(RS, hashed, publicKey);
|
|
@@ -15179,6 +15204,106 @@ OnePassSignaturePacket.prototype.hash = SignaturePacket.prototype.hash;
|
|
|
15179
15204
|
OnePassSignaturePacket.prototype.toHash = SignaturePacket.prototype.toHash;
|
|
15180
15205
|
OnePassSignaturePacket.prototype.toSign = SignaturePacket.prototype.toSign;
|
|
15181
15206
|
|
|
15207
|
+
class GrammarError extends Error {
|
|
15208
|
+
constructor(...params) {
|
|
15209
|
+
super(...params);
|
|
15210
|
+
if (Error.captureStackTrace) {
|
|
15211
|
+
Error.captureStackTrace(this, GrammarError);
|
|
15212
|
+
}
|
|
15213
|
+
this.name = 'GrammarError';
|
|
15214
|
+
}
|
|
15215
|
+
}
|
|
15216
|
+
const isValidLiteralMessage = (tagList, _acceptPartial) => tagList.length === 1 && tagList[0] === enums.packet.literalData;
|
|
15217
|
+
const isValidCompressedMessage = (tagList, _acceptPartial) => tagList.length === 1 && tagList[0] === enums.packet.compressedData;
|
|
15218
|
+
const isValidEncryptedMessage = (tagList, acceptPartial) => {
|
|
15219
|
+
// Encrypted Message: Encrypted Data | ESK Sequence, Encrypted Data.
|
|
15220
|
+
const isValidESKSequence = (tagList, _acceptPartial) => (tagList.every(packetTag => new Set([enums.packet.publicKeyEncryptedSessionKey, enums.packet.symEncryptedSessionKey]).has(packetTag)));
|
|
15221
|
+
const encryptedDataPacketIndex = tagList.findIndex(tag => new Set([enums.packet.aeadEncryptedData, enums.packet.symmetricallyEncryptedData, enums.packet.symEncryptedIntegrityProtectedData]).has(tag));
|
|
15222
|
+
if (encryptedDataPacketIndex < 0) {
|
|
15223
|
+
return isValidESKSequence(tagList);
|
|
15224
|
+
}
|
|
15225
|
+
return (encryptedDataPacketIndex === tagList.length - 1) &&
|
|
15226
|
+
isValidESKSequence(tagList.slice(0, encryptedDataPacketIndex));
|
|
15227
|
+
};
|
|
15228
|
+
const isValidSignedMessage = (tagList, acceptPartial) => {
|
|
15229
|
+
// Signature Packet, OpenPGP Message | One-Pass Signed Message.
|
|
15230
|
+
if (tagList.findIndex(tag => tag === enums.packet.signature) === 0) {
|
|
15231
|
+
return isValidOpenPGPMessage(tagList.slice(1), acceptPartial);
|
|
15232
|
+
}
|
|
15233
|
+
// One-Pass Signed Message:
|
|
15234
|
+
// One-Pass Signature Packet, OpenPGP Message, Corresponding Signature Packet.
|
|
15235
|
+
if (tagList.findIndex(tag => tag === enums.packet.onePassSignature) === 0) {
|
|
15236
|
+
const correspondingSigPacketIndex = util.findLastIndex(tagList, tag => tag === enums.packet.signature);
|
|
15237
|
+
if (correspondingSigPacketIndex !== tagList.length - 1 && !acceptPartial) {
|
|
15238
|
+
return false;
|
|
15239
|
+
}
|
|
15240
|
+
return isValidOpenPGPMessage(tagList.slice(1, correspondingSigPacketIndex < 0 ? undefined : correspondingSigPacketIndex), acceptPartial);
|
|
15241
|
+
}
|
|
15242
|
+
return false;
|
|
15243
|
+
};
|
|
15244
|
+
const isUnknownPacketTag = (tag) => {
|
|
15245
|
+
try {
|
|
15246
|
+
enums.read(enums.packet, tag);
|
|
15247
|
+
return false;
|
|
15248
|
+
}
|
|
15249
|
+
catch (e) {
|
|
15250
|
+
return true;
|
|
15251
|
+
}
|
|
15252
|
+
};
|
|
15253
|
+
/**
|
|
15254
|
+
* Implements grammar checks based on https://www.rfc-editor.org/rfc/rfc9580.html#section-10.3 .
|
|
15255
|
+
* @param notNormalizedList - list of packet tags to validate
|
|
15256
|
+
* @param acceptPartial - whether the list of tags corresponds to a partially-parsed message
|
|
15257
|
+
* @returns whether the list of tags is valid
|
|
15258
|
+
*/
|
|
15259
|
+
const isValidOpenPGPMessage = (notNormalizedList /** might have unknown tags */, acceptPartial) => {
|
|
15260
|
+
// Take care of packet tags that can appear anywhere in the sequence:
|
|
15261
|
+
// 1. A Marker packet (Section 5.8) can appear anywhere in the sequence.
|
|
15262
|
+
// 2. An implementation MUST be able to process Padding packets anywhere else in an OpenPGP stream so that future revisions of this document may specify further locations for padding.
|
|
15263
|
+
// 3. An unknown non-critical packet MUST be ignored (criticality is enforced on parsing).
|
|
15264
|
+
const normalizedList = notNormalizedList.filter(tag => (tag !== enums.packet.marker &&
|
|
15265
|
+
tag !== enums.packet.padding &&
|
|
15266
|
+
!isUnknownPacketTag(tag)));
|
|
15267
|
+
return isValidLiteralMessage(normalizedList) ||
|
|
15268
|
+
isValidCompressedMessage(normalizedList) ||
|
|
15269
|
+
isValidEncryptedMessage(normalizedList) ||
|
|
15270
|
+
isValidSignedMessage(normalizedList, acceptPartial);
|
|
15271
|
+
};
|
|
15272
|
+
/**
|
|
15273
|
+
* If `delayReporting === false`, the grammar validator throws as soon as an invalid packet sequence is detected during parsing.
|
|
15274
|
+
* This setting MUST NOT be used when parsing unauthenticated decrypted data, to avoid instantiating decryption oracles.
|
|
15275
|
+
* Passing `delayReporting === true` allows checking the grammar validity in an async manner, by
|
|
15276
|
+
* only reporting the validity status after parsing is done (i.e. and authentication is expected to
|
|
15277
|
+
* have been enstablished)
|
|
15278
|
+
*/
|
|
15279
|
+
const getMessageGrammarValidator = ({ delayReporting }) => {
|
|
15280
|
+
let logged = false;
|
|
15281
|
+
/**
|
|
15282
|
+
* @returns `true` on successful grammar validation; if `delayReporting` is set, `null` is returned
|
|
15283
|
+
* if validation is still pending (partial parsing, waiting for authentication to be confirmed).
|
|
15284
|
+
* @throws on grammar error, provided `config.enforceGrammar` is enabled.
|
|
15285
|
+
*/
|
|
15286
|
+
return (list, isPartial, config) => {
|
|
15287
|
+
if (delayReporting && isPartial)
|
|
15288
|
+
return null; // delay until the full message has been parsed (i.e. authenticated)
|
|
15289
|
+
if (!isValidOpenPGPMessage(list, isPartial)) {
|
|
15290
|
+
const error = new GrammarError(`Data does not respect OpenPGP grammar [${list}]`);
|
|
15291
|
+
if (!logged) {
|
|
15292
|
+
config.pluggableGrammarErrorReporter?.(error.message);
|
|
15293
|
+
util.printDebugError(error);
|
|
15294
|
+
logged = true;
|
|
15295
|
+
}
|
|
15296
|
+
if (config.enforceGrammar) {
|
|
15297
|
+
throw error;
|
|
15298
|
+
}
|
|
15299
|
+
else {
|
|
15300
|
+
return true;
|
|
15301
|
+
}
|
|
15302
|
+
}
|
|
15303
|
+
return true;
|
|
15304
|
+
};
|
|
15305
|
+
};
|
|
15306
|
+
|
|
15182
15307
|
/**
|
|
15183
15308
|
* Instantiate a new packet given its tag
|
|
15184
15309
|
* @function newPacketFromTag
|
|
@@ -15218,9 +15343,9 @@ class PacketList extends Array {
|
|
|
15218
15343
|
* @throws on parsing errors
|
|
15219
15344
|
* @async
|
|
15220
15345
|
*/
|
|
15221
|
-
static async fromBinary(bytes, allowedPackets, config$1 = config) {
|
|
15346
|
+
static async fromBinary(bytes, allowedPackets, config$1 = config, grammarValidator = null) {
|
|
15222
15347
|
const packets = new PacketList();
|
|
15223
|
-
await packets.read(bytes, allowedPackets, config$1);
|
|
15348
|
+
await packets.read(bytes, allowedPackets, config$1, grammarValidator);
|
|
15224
15349
|
return packets;
|
|
15225
15350
|
}
|
|
15226
15351
|
|
|
@@ -15229,15 +15354,17 @@ class PacketList extends Array {
|
|
|
15229
15354
|
* @param {Uint8Array | ReadableStream<Uint8Array>} bytes - binary data to parse
|
|
15230
15355
|
* @param {Object} allowedPackets - mapping where keys are allowed packet tags, pointing to their Packet class
|
|
15231
15356
|
* @param {Object} [config] - full configuration, defaults to openpgp.config
|
|
15357
|
+
* @param {function(enums.packet[], boolean, Object): void} [grammarValidator]
|
|
15232
15358
|
* @throws on parsing errors
|
|
15233
15359
|
* @async
|
|
15234
15360
|
*/
|
|
15235
|
-
async read(bytes, allowedPackets, config$1 = config) {
|
|
15361
|
+
async read(bytes, allowedPackets, config$1 = config, grammarValidator = null) {
|
|
15236
15362
|
if (config$1.additionalAllowedPackets.length) {
|
|
15237
15363
|
allowedPackets = { ...allowedPackets, ...util.constructAllowedPackets(config$1.additionalAllowedPackets) };
|
|
15238
15364
|
}
|
|
15239
15365
|
this.stream = transformPair(bytes, async (readable, writable) => {
|
|
15240
15366
|
const writer = getWriter(writable);
|
|
15367
|
+
const writtenTags = [];
|
|
15241
15368
|
try {
|
|
15242
15369
|
while (true) {
|
|
15243
15370
|
await writer.ready;
|
|
@@ -15255,6 +15382,12 @@ class PacketList extends Array {
|
|
|
15255
15382
|
packet.fromStream = util.isStream(parsed.packet);
|
|
15256
15383
|
await packet.read(parsed.packet, config$1);
|
|
15257
15384
|
await writer.write(packet);
|
|
15385
|
+
writtenTags.push(parsed.tag);
|
|
15386
|
+
// The `writtenTags` are only sensitive if we are parsing an _unauthenticated_ decrypted stream,
|
|
15387
|
+
// since they can enable an decryption oracle.
|
|
15388
|
+
// It's responsibility of the caller to pass a `grammarValidator` that takes care of
|
|
15389
|
+
// postponing error reporting until the data has been authenticated.
|
|
15390
|
+
grammarValidator?.(writtenTags, true, config$1);
|
|
15258
15391
|
} catch (e) {
|
|
15259
15392
|
// If an implementation encounters a critical packet where the packet type is unknown in a packet sequence,
|
|
15260
15393
|
// it MUST reject the whole packet sequence. On the other hand, an unknown non-critical packet MUST be ignored.
|
|
@@ -15269,7 +15402,8 @@ class PacketList extends Array {
|
|
|
15269
15402
|
|
|
15270
15403
|
const throwUnsupportedError = !config$1.ignoreUnsupportedPackets && e instanceof UnsupportedError;
|
|
15271
15404
|
const throwMalformedError = !config$1.ignoreMalformedPackets && !(e instanceof UnsupportedError);
|
|
15272
|
-
|
|
15405
|
+
const throwGrammarError = e instanceof GrammarError;
|
|
15406
|
+
if (throwUnsupportedError || throwMalformedError || throwGrammarError || supportsStreaming(parsed.tag)) {
|
|
15273
15407
|
// The packets that support streaming are the ones that contain message data.
|
|
15274
15408
|
// Those are also the ones we want to be more strict about and throw on parse errors
|
|
15275
15409
|
// (since we likely cannot process the message without these packets anyway).
|
|
@@ -15277,11 +15411,16 @@ class PacketList extends Array {
|
|
|
15277
15411
|
} else {
|
|
15278
15412
|
const unparsedPacket = new UnparseablePacket(parsed.tag, parsed.packet);
|
|
15279
15413
|
await writer.write(unparsedPacket);
|
|
15414
|
+
writtenTags.push(parsed.tag);
|
|
15415
|
+
grammarValidator?.(writtenTags, true, config$1);
|
|
15280
15416
|
}
|
|
15281
15417
|
util.printDebugError(e);
|
|
15282
15418
|
}
|
|
15283
15419
|
});
|
|
15284
15420
|
if (done) {
|
|
15421
|
+
// Here we are past the MDC check for SEIPDv1 data, hence
|
|
15422
|
+
// the data is always authenticated at this point.
|
|
15423
|
+
grammarValidator?.(writtenTags, false, config$1);
|
|
15285
15424
|
await writer.ready;
|
|
15286
15425
|
await writer.close();
|
|
15287
15426
|
return;
|
|
@@ -15504,7 +15643,8 @@ class CompressedDataPacket {
|
|
|
15504
15643
|
throw new Error(`${compressionName} decompression not supported`);
|
|
15505
15644
|
}
|
|
15506
15645
|
|
|
15507
|
-
|
|
15646
|
+
// Decompressing a Compressed Data packet MUST also yield a valid OpenPGP Message
|
|
15647
|
+
this.packets = await PacketList.fromBinary(await decompressionFn(this.compressed), allowedPackets$5, config$1, getMessageGrammarValidator({ enforceDelay: false }));
|
|
15508
15648
|
}
|
|
15509
15649
|
|
|
15510
15650
|
/**
|
|
@@ -15794,16 +15934,23 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
|
|
15794
15934
|
if (isArrayStream(encrypted)) encrypted = await readToEnd(encrypted);
|
|
15795
15935
|
|
|
15796
15936
|
let packetbytes;
|
|
15937
|
+
let grammarValidator;
|
|
15797
15938
|
if (this.version === 2) {
|
|
15798
15939
|
if (this.cipherAlgorithm !== sessionKeyAlgorithm) {
|
|
15799
15940
|
// sanity check
|
|
15800
15941
|
throw new Error('Unexpected session key algorithm');
|
|
15801
15942
|
}
|
|
15802
15943
|
packetbytes = await runAEAD(this, 'decrypt', key, encrypted);
|
|
15944
|
+
grammarValidator = getMessageGrammarValidator({ delayReporting: false });
|
|
15803
15945
|
} else {
|
|
15804
15946
|
const { blockSize } = getCipherParams(sessionKeyAlgorithm);
|
|
15805
15947
|
const decrypted = await decrypt$1(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize));
|
|
15806
15948
|
|
|
15949
|
+
// Grammar validation cannot be run before message integrity has been enstablished,
|
|
15950
|
+
// to avoid leaking info about the unauthenticated message structure.
|
|
15951
|
+
const releaseUnauthenticatedStream = util.isStream(encrypted) && config$1.allowUnauthenticatedStream;
|
|
15952
|
+
grammarValidator = getMessageGrammarValidator({ delayReporting: releaseUnauthenticatedStream });
|
|
15953
|
+
|
|
15807
15954
|
// there must be a modification detection code packet as the
|
|
15808
15955
|
// last packet and everything gets hashed except the hash itself
|
|
15809
15956
|
const realHash = slice(passiveClone(decrypted), -20);
|
|
@@ -15815,17 +15962,23 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
|
|
15815
15962
|
if (!util.equalsUint8Array(hash, mdc)) {
|
|
15816
15963
|
throw new Error('Modification detected.');
|
|
15817
15964
|
}
|
|
15965
|
+
// this last chunk comes at the end of the stream passed to Packetlist.read's streamTransformPair,
|
|
15966
|
+
// which can thus be 'done' only after the MDC has been checked.
|
|
15818
15967
|
return new Uint8Array();
|
|
15819
15968
|
});
|
|
15820
15969
|
const bytes = slice(tohash, blockSize + 2); // Remove random prefix
|
|
15821
15970
|
packetbytes = slice(bytes, 0, -2); // Remove MDC packet
|
|
15822
15971
|
packetbytes = concat([packetbytes, fromAsync(() => verifyHash)]);
|
|
15823
|
-
if (!
|
|
15972
|
+
if (!releaseUnauthenticatedStream) {
|
|
15824
15973
|
packetbytes = await readToEnd(packetbytes);
|
|
15825
15974
|
}
|
|
15826
15975
|
}
|
|
15827
15976
|
|
|
15828
|
-
|
|
15977
|
+
// - Decrypting a version 1 Symmetrically Encrypted and Integrity Protected Data packet
|
|
15978
|
+
// MUST yield a valid OpenPGP Message.
|
|
15979
|
+
// - Decrypting a version 2 Symmetrically Encrypted and Integrity Protected Data packet
|
|
15980
|
+
// MUST yield a valid Optionally Padded Message.
|
|
15981
|
+
this.packets = await PacketList.fromBinary(packetbytes, allowedPackets$4, config$1, grammarValidator);
|
|
15829
15982
|
return true;
|
|
15830
15983
|
}
|
|
15831
15984
|
}
|
|
@@ -16040,7 +16193,8 @@ class AEADEncryptedDataPacket {
|
|
|
16040
16193
|
this.packets = await PacketList.fromBinary(
|
|
16041
16194
|
await runAEAD(this, 'decrypt', key, clone(this.encrypted)),
|
|
16042
16195
|
allowedPackets$3,
|
|
16043
|
-
config$1
|
|
16196
|
+
config$1,
|
|
16197
|
+
getMessageGrammarValidator({ enforceDelay: false })
|
|
16044
16198
|
);
|
|
16045
16199
|
}
|
|
16046
16200
|
|
|
@@ -16967,6 +17121,10 @@ class SymmetricallyEncryptedDataPacket {
|
|
|
16967
17121
|
encrypted.subarray(2, blockSize + 2)
|
|
16968
17122
|
);
|
|
16969
17123
|
|
|
17124
|
+
// Decrypting a Symmetrically Encrypted Data packet MUST yield a valid OpenPGP Message.
|
|
17125
|
+
// But due to the lack of authentication over the decrypted data,
|
|
17126
|
+
// we do not run any grammarValidator, to avoid enabling a decryption oracle
|
|
17127
|
+
// (plus, there is probably a higher chance that these messages have an expected structure).
|
|
16970
17128
|
this.packets = await PacketList.fromBinary(decrypted, allowedPackets$2, config$1);
|
|
16971
17129
|
}
|
|
16972
17130
|
|
|
@@ -21569,7 +21727,7 @@ async function readMessage({ armoredMessage, binaryMessage, config: config$1, ..
|
|
|
21569
21727
|
}
|
|
21570
21728
|
input = data;
|
|
21571
21729
|
}
|
|
21572
|
-
const packetlist = await PacketList.fromBinary(input, allowedMessagePackets, config$1);
|
|
21730
|
+
const packetlist = await PacketList.fromBinary(input, allowedMessagePackets, config$1, getMessageGrammarValidator({ delayReporting: false }));
|
|
21573
21731
|
const message = new Message(packetlist);
|
|
21574
21732
|
message.fromStream = streamType;
|
|
21575
21733
|
return message;
|
|
@@ -22189,7 +22347,7 @@ async function decrypt({ message, decryptionKeys, passwords, sessionKeys, verifi
|
|
|
22189
22347
|
result.signatures = signature ? await decrypted.verifyDetached(signature, verificationKeys, date, config$1) : await decrypted.verify(verificationKeys, date, config$1);
|
|
22190
22348
|
result.data = format === 'binary' ? decrypted.getLiteralData() : decrypted.getText();
|
|
22191
22349
|
result.filename = decrypted.getFilename();
|
|
22192
|
-
linkStreams(result, message);
|
|
22350
|
+
linkStreams(result, message, ...new Set([decrypted, decrypted.unwrapCompressed()]));
|
|
22193
22351
|
if (expectSigned) {
|
|
22194
22352
|
if (verificationKeys.length === 0) {
|
|
22195
22353
|
throw new Error('Verification keys are required to verify message signatures');
|
|
@@ -22324,7 +22482,9 @@ async function verify({ message, verificationKeys, expectSigned = false, format
|
|
|
22324
22482
|
result.signatures = await message.verify(verificationKeys, date, config$1);
|
|
22325
22483
|
}
|
|
22326
22484
|
result.data = format === 'binary' ? message.getLiteralData() : message.getText();
|
|
22327
|
-
if (message.fromStream && !signature)
|
|
22485
|
+
if (message.fromStream && !signature) {
|
|
22486
|
+
linkStreams(result, ...new Set([message, message.unwrapCompressed()]));
|
|
22487
|
+
}
|
|
22328
22488
|
if (expectSigned) {
|
|
22329
22489
|
if (result.signatures.length === 0) {
|
|
22330
22490
|
throw new Error('Message is not signed');
|
|
@@ -22521,22 +22681,25 @@ async function convertStream(data) {
|
|
|
22521
22681
|
}
|
|
22522
22682
|
|
|
22523
22683
|
/**
|
|
22524
|
-
* Link result.data to the message stream for cancellation.
|
|
22525
|
-
* Also, forward errors in the message to result.data.
|
|
22684
|
+
* Link result.data to the input message stream for cancellation.
|
|
22685
|
+
* Also, forward errors in the input message and intermediate messages to result.data.
|
|
22526
22686
|
* @param {Object} result - the data to convert
|
|
22527
|
-
* @param {Message} message - message object
|
|
22687
|
+
* @param {Message} message - message object provided by the user
|
|
22688
|
+
* @param {Message} intermediateMessages - intermediate message object with packet streams to link
|
|
22528
22689
|
* @returns {Object}
|
|
22529
22690
|
* @private
|
|
22530
22691
|
*/
|
|
22531
|
-
function linkStreams(result,
|
|
22532
|
-
result.data = transformPair(
|
|
22692
|
+
function linkStreams(result, inputMessage, ...intermediateMessages) {
|
|
22693
|
+
result.data = transformPair(inputMessage.packets.stream, async (readable, writable) => {
|
|
22533
22694
|
await pipe(result.data, writable, {
|
|
22534
22695
|
preventClose: true
|
|
22535
22696
|
});
|
|
22536
22697
|
const writer = getWriter(writable);
|
|
22537
22698
|
try {
|
|
22538
|
-
// Forward errors in the message
|
|
22699
|
+
// Forward errors in the message streams to result.data.
|
|
22539
22700
|
await readToEnd(readable, _ => _);
|
|
22701
|
+
await Promise.all(intermediateMessages.map(intermediate => readToEnd(intermediate.packets.stream, _ => _)));
|
|
22702
|
+
// if result.data throws, the writable will be in errored state, and `close()` fails, but its ok.
|
|
22540
22703
|
await writer.close();
|
|
22541
22704
|
} catch (e) {
|
|
22542
22705
|
await writer.abort(e);
|
|
@@ -31106,6 +31269,7 @@ exports.Argon2OutOfMemoryError = Argon2OutOfMemoryError;
|
|
|
31106
31269
|
exports.Argon2S2K = Argon2S2K;
|
|
31107
31270
|
exports.CleartextMessage = CleartextMessage;
|
|
31108
31271
|
exports.CompressedDataPacket = CompressedDataPacket;
|
|
31272
|
+
exports.GrammarError = GrammarError;
|
|
31109
31273
|
exports.KDFParams = KDFParams;
|
|
31110
31274
|
exports.LiteralDataPacket = LiteralDataPacket;
|
|
31111
31275
|
exports.MarkerPacket = MarkerPacket;
|