@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.
Files changed (36) hide show
  1. package/dist/lightweight/argon2id.min.mjs +1 -1
  2. package/dist/lightweight/argon2id.mjs +1 -1
  3. package/dist/lightweight/legacy_ciphers.min.mjs +1 -1
  4. package/dist/lightweight/legacy_ciphers.mjs +1 -1
  5. package/dist/lightweight/noble_curves.min.mjs +1 -1
  6. package/dist/lightweight/noble_curves.mjs +1 -1
  7. package/dist/lightweight/noble_hashes.min.mjs +1 -1
  8. package/dist/lightweight/noble_hashes.mjs +1 -1
  9. package/dist/lightweight/noble_post_quantum.min.mjs +1 -1
  10. package/dist/lightweight/noble_post_quantum.mjs +1 -1
  11. package/dist/lightweight/openpgp.min.mjs +4 -4
  12. package/dist/lightweight/openpgp.min.mjs.map +1 -1
  13. package/dist/lightweight/openpgp.mjs +190 -27
  14. package/dist/lightweight/seek-bzip.min.mjs +1 -1
  15. package/dist/lightweight/seek-bzip.mjs +1 -1
  16. package/dist/lightweight/sha3.min.mjs +1 -1
  17. package/dist/lightweight/sha3.mjs +1 -1
  18. package/dist/lightweight/sha512.min.mjs +1 -1
  19. package/dist/lightweight/sha512.mjs +1 -1
  20. package/dist/node/openpgp.cjs +190 -26
  21. package/dist/node/openpgp.min.cjs +16 -16
  22. package/dist/node/openpgp.min.cjs.map +1 -1
  23. package/dist/node/openpgp.min.mjs +16 -16
  24. package/dist/node/openpgp.min.mjs.map +1 -1
  25. package/dist/node/openpgp.mjs +190 -27
  26. package/dist/openpgp.js +190 -26
  27. package/dist/openpgp.min.js +16 -16
  28. package/dist/openpgp.min.js.map +1 -1
  29. package/dist/openpgp.min.mjs +16 -16
  30. package/dist/openpgp.min.mjs.map +1 -1
  31. package/dist/openpgp.mjs +190 -27
  32. package/openpgp.d.ts +4 -241
  33. package/package.json +3 -2
  34. package/src/config/config.d.ts +68 -0
  35. package/src/config/index.d.ts +13 -0
  36. package/src/enums.d.ts +195 -0
package/dist/openpgp.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! OpenPGP.js v6.1.1-patch.0 - 2025-02-12 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
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
  var openpgp = (function (exports) {
3
3
  'use strict';
4
4
 
@@ -1548,6 +1548,8 @@ var openpgp = (function (exports) {
1548
1548
  * by v6 keys and v6 signatures, respectively.
1549
1549
  * However, generation of v5 entities was supported behind config flag in OpenPGP.js v5, and some other libraries,
1550
1550
  * hence parsing them might be necessary in some cases.
1551
+ * @memberof module:config
1552
+ * @property {Boolean} enableParsingV5Entities
1551
1553
  */
1552
1554
  enableParsingV5Entities: false,
1553
1555
  /**
@@ -1684,10 +1686,22 @@ var openpgp = (function (exports) {
1684
1686
  * @property {Boolean} ignoreMalformedPackets Ignore malformed packets on parsing instead of throwing an error
1685
1687
  */
1686
1688
  ignoreMalformedPackets: false,
1689
+ /**
1690
+ * @memberof module:config
1691
+ * @property {Boolean} enforceGrammar whether parsed OpenPGP messages must comform to the OpenPGP grammar
1692
+ * defined in https://www.rfc-editor.org/rfc/rfc9580.html#name-openpgp-messages .
1693
+ */
1694
+ enforceGrammar: true,
1695
+ /**
1696
+ * @memberof module:config
1697
+ * @property {function(string): any} pluggableGrammarErrorReporter callback meant to collect GrammarError reports even with `config.enforceGrammar` disabled.
1698
+ */
1699
+ pluggableGrammarErrorReporter: null,
1687
1700
  /**
1688
1701
  * Parsing of packets is normally restricted to a predefined set of packets. For example a Sym. Encrypted Integrity Protected Data Packet can only
1689
1702
  * contain a certain set of packets including LiteralDataPacket. With this setting we can allow additional packets, which is probably not advisable
1690
1703
  * as a global config setting, but can be used for specific function calls (e.g. decrypt method of Message).
1704
+ * NB: `config.enforceGrammar` may need to be disabled as well.
1691
1705
  * @memberof module:config
1692
1706
  * @property {Array} additionalAllowedPackets Allow additional packets on parsing. Defined as array of packet classes, e.g. [PublicKeyPacket]
1693
1707
  */
@@ -1706,7 +1720,7 @@ var openpgp = (function (exports) {
1706
1720
  * @memberof module:config
1707
1721
  * @property {String} versionString A version string to be included in armored messages
1708
1722
  */
1709
- versionString: 'OpenPGP.js 6.1.1-patch.0',
1723
+ versionString: 'OpenPGP.js 6.1.1-patch.2',
1710
1724
  /**
1711
1725
  * @memberof module:config
1712
1726
  * @property {String} commentString A comment string to be included in armored messages
@@ -2079,6 +2093,21 @@ var openpgp = (function (exports) {
2079
2093
  return true;
2080
2094
  },
2081
2095
 
2096
+ /**
2097
+ * Same as Array.findLastIndex, which is not supported on Safari 14 .
2098
+ * @param {Array} arr
2099
+ * @param {function(element, index, arr): boolean} findFn
2100
+ * @return index of last element matching `findFn`, -1 if not found
2101
+ */
2102
+ findLastIndex: function(arr, findFn) {
2103
+ for (let i = arr.length; i >= 0; i--) {
2104
+ if (findFn(arr[i], i, arr)) {
2105
+ return i;
2106
+ }
2107
+ }
2108
+ return -1;
2109
+ },
2110
+
2082
2111
  /**
2083
2112
  * Calculates a 16bit sum of a Uint8Array by adding each character
2084
2113
  * codes modulus 65535
@@ -6898,11 +6927,7 @@ var openpgp = (function (exports) {
6898
6927
  seed: b64ToUint8Array(privateKey.d, true)
6899
6928
  };
6900
6929
  } catch (err) {
6901
- if (
6902
- err.name !== 'NotSupportedError' &&
6903
- err.name !== 'OperationError' && // Temporary (hopefully) fix for WebKit on Linux
6904
- err.name !== 'SyntaxError' // Temporary fix for Palemoon throwing 'SyntaxError'
6905
- ) {
6930
+ if (err.name !== 'NotSupportedError' && err.name !== 'OperationError') { // Temporary (hopefully) fix for WebKit on Linux
6906
6931
  throw err;
6907
6932
  }
6908
6933
  const seed = getRandomBytes(getPayloadSize$1(algo));
@@ -6954,7 +6979,7 @@ var openpgp = (function (exports) {
6954
6979
 
6955
6980
  return { RS: signature };
6956
6981
  } catch (err) {
6957
- if (err.name !== 'NotSupportedError' && err.name !== 'SyntaxError') { // Temporary fix for Palemoon throwing 'SyntaxError'
6982
+ if (err.name !== 'NotSupportedError') {
6958
6983
  throw err;
6959
6984
  }
6960
6985
  const secretKey = util.concatUint8Array([privateKey, publicKey]);
@@ -7000,7 +7025,7 @@ var openpgp = (function (exports) {
7000
7025
  const verified = await webCrypto.verify('Ed25519', key, RS, hashed);
7001
7026
  return verified;
7002
7027
  } catch (err) {
7003
- if (err.name !== 'NotSupportedError' && err.name !== 'SyntaxError') { // Temporary fix for Palemoon throwing 'SyntaxError'
7028
+ if (err.name !== 'NotSupportedError') {
7004
7029
  throw err;
7005
7030
  }
7006
7031
  return verify$a(RS, hashed, publicKey);
@@ -15141,6 +15166,106 @@ var openpgp = (function (exports) {
15141
15166
  OnePassSignaturePacket.prototype.toHash = SignaturePacket.prototype.toHash;
15142
15167
  OnePassSignaturePacket.prototype.toSign = SignaturePacket.prototype.toSign;
15143
15168
 
15169
+ class GrammarError extends Error {
15170
+ constructor(...params) {
15171
+ super(...params);
15172
+ if (Error.captureStackTrace) {
15173
+ Error.captureStackTrace(this, GrammarError);
15174
+ }
15175
+ this.name = 'GrammarError';
15176
+ }
15177
+ }
15178
+ const isValidLiteralMessage = (tagList, _acceptPartial) => tagList.length === 1 && tagList[0] === enums.packet.literalData;
15179
+ const isValidCompressedMessage = (tagList, _acceptPartial) => tagList.length === 1 && tagList[0] === enums.packet.compressedData;
15180
+ const isValidEncryptedMessage = (tagList, acceptPartial) => {
15181
+ // Encrypted Message: Encrypted Data | ESK Sequence, Encrypted Data.
15182
+ const isValidESKSequence = (tagList, _acceptPartial) => (tagList.every(packetTag => new Set([enums.packet.publicKeyEncryptedSessionKey, enums.packet.symEncryptedSessionKey]).has(packetTag)));
15183
+ const encryptedDataPacketIndex = tagList.findIndex(tag => new Set([enums.packet.aeadEncryptedData, enums.packet.symmetricallyEncryptedData, enums.packet.symEncryptedIntegrityProtectedData]).has(tag));
15184
+ if (encryptedDataPacketIndex < 0) {
15185
+ return isValidESKSequence(tagList);
15186
+ }
15187
+ return (encryptedDataPacketIndex === tagList.length - 1) &&
15188
+ isValidESKSequence(tagList.slice(0, encryptedDataPacketIndex));
15189
+ };
15190
+ const isValidSignedMessage = (tagList, acceptPartial) => {
15191
+ // Signature Packet, OpenPGP Message | One-Pass Signed Message.
15192
+ if (tagList.findIndex(tag => tag === enums.packet.signature) === 0) {
15193
+ return isValidOpenPGPMessage(tagList.slice(1), acceptPartial);
15194
+ }
15195
+ // One-Pass Signed Message:
15196
+ // One-Pass Signature Packet, OpenPGP Message, Corresponding Signature Packet.
15197
+ if (tagList.findIndex(tag => tag === enums.packet.onePassSignature) === 0) {
15198
+ const correspondingSigPacketIndex = util.findLastIndex(tagList, tag => tag === enums.packet.signature);
15199
+ if (correspondingSigPacketIndex !== tagList.length - 1 && !acceptPartial) {
15200
+ return false;
15201
+ }
15202
+ return isValidOpenPGPMessage(tagList.slice(1, correspondingSigPacketIndex < 0 ? undefined : correspondingSigPacketIndex), acceptPartial);
15203
+ }
15204
+ return false;
15205
+ };
15206
+ const isUnknownPacketTag = (tag) => {
15207
+ try {
15208
+ enums.read(enums.packet, tag);
15209
+ return false;
15210
+ }
15211
+ catch (e) {
15212
+ return true;
15213
+ }
15214
+ };
15215
+ /**
15216
+ * Implements grammar checks based on https://www.rfc-editor.org/rfc/rfc9580.html#section-10.3 .
15217
+ * @param notNormalizedList - list of packet tags to validate
15218
+ * @param acceptPartial - whether the list of tags corresponds to a partially-parsed message
15219
+ * @returns whether the list of tags is valid
15220
+ */
15221
+ const isValidOpenPGPMessage = (notNormalizedList /** might have unknown tags */, acceptPartial) => {
15222
+ // Take care of packet tags that can appear anywhere in the sequence:
15223
+ // 1. A Marker packet (Section 5.8) can appear anywhere in the sequence.
15224
+ // 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.
15225
+ // 3. An unknown non-critical packet MUST be ignored (criticality is enforced on parsing).
15226
+ const normalizedList = notNormalizedList.filter(tag => (tag !== enums.packet.marker &&
15227
+ tag !== enums.packet.padding &&
15228
+ !isUnknownPacketTag(tag)));
15229
+ return isValidLiteralMessage(normalizedList) ||
15230
+ isValidCompressedMessage(normalizedList) ||
15231
+ isValidEncryptedMessage(normalizedList) ||
15232
+ isValidSignedMessage(normalizedList, acceptPartial);
15233
+ };
15234
+ /**
15235
+ * If `delayReporting === false`, the grammar validator throws as soon as an invalid packet sequence is detected during parsing.
15236
+ * This setting MUST NOT be used when parsing unauthenticated decrypted data, to avoid instantiating decryption oracles.
15237
+ * Passing `delayReporting === true` allows checking the grammar validity in an async manner, by
15238
+ * only reporting the validity status after parsing is done (i.e. and authentication is expected to
15239
+ * have been enstablished)
15240
+ */
15241
+ const getMessageGrammarValidator = ({ delayReporting }) => {
15242
+ let logged = false;
15243
+ /**
15244
+ * @returns `true` on successful grammar validation; if `delayReporting` is set, `null` is returned
15245
+ * if validation is still pending (partial parsing, waiting for authentication to be confirmed).
15246
+ * @throws on grammar error, provided `config.enforceGrammar` is enabled.
15247
+ */
15248
+ return (list, isPartial, config) => {
15249
+ if (delayReporting && isPartial)
15250
+ return null; // delay until the full message has been parsed (i.e. authenticated)
15251
+ if (!isValidOpenPGPMessage(list, isPartial)) {
15252
+ const error = new GrammarError(`Data does not respect OpenPGP grammar [${list}]`);
15253
+ if (!logged) {
15254
+ config.pluggableGrammarErrorReporter?.(error.message);
15255
+ util.printDebugError(error);
15256
+ logged = true;
15257
+ }
15258
+ if (config.enforceGrammar) {
15259
+ throw error;
15260
+ }
15261
+ else {
15262
+ return true;
15263
+ }
15264
+ }
15265
+ return true;
15266
+ };
15267
+ };
15268
+
15144
15269
  /**
15145
15270
  * Instantiate a new packet given its tag
15146
15271
  * @function newPacketFromTag
@@ -15180,9 +15305,9 @@ var openpgp = (function (exports) {
15180
15305
  * @throws on parsing errors
15181
15306
  * @async
15182
15307
  */
15183
- static async fromBinary(bytes, allowedPackets, config$1 = config) {
15308
+ static async fromBinary(bytes, allowedPackets, config$1 = config, grammarValidator = null) {
15184
15309
  const packets = new PacketList();
15185
- await packets.read(bytes, allowedPackets, config$1);
15310
+ await packets.read(bytes, allowedPackets, config$1, grammarValidator);
15186
15311
  return packets;
15187
15312
  }
15188
15313
 
@@ -15191,15 +15316,17 @@ var openpgp = (function (exports) {
15191
15316
  * @param {Uint8Array | ReadableStream<Uint8Array>} bytes - binary data to parse
15192
15317
  * @param {Object} allowedPackets - mapping where keys are allowed packet tags, pointing to their Packet class
15193
15318
  * @param {Object} [config] - full configuration, defaults to openpgp.config
15319
+ * @param {function(enums.packet[], boolean, Object): void} [grammarValidator]
15194
15320
  * @throws on parsing errors
15195
15321
  * @async
15196
15322
  */
15197
- async read(bytes, allowedPackets, config$1 = config) {
15323
+ async read(bytes, allowedPackets, config$1 = config, grammarValidator = null) {
15198
15324
  if (config$1.additionalAllowedPackets.length) {
15199
15325
  allowedPackets = { ...allowedPackets, ...util.constructAllowedPackets(config$1.additionalAllowedPackets) };
15200
15326
  }
15201
15327
  this.stream = transformPair(bytes, async (readable, writable) => {
15202
15328
  const writer = getWriter(writable);
15329
+ const writtenTags = [];
15203
15330
  try {
15204
15331
  while (true) {
15205
15332
  await writer.ready;
@@ -15217,6 +15344,12 @@ var openpgp = (function (exports) {
15217
15344
  packet.fromStream = util.isStream(parsed.packet);
15218
15345
  await packet.read(parsed.packet, config$1);
15219
15346
  await writer.write(packet);
15347
+ writtenTags.push(parsed.tag);
15348
+ // The `writtenTags` are only sensitive if we are parsing an _unauthenticated_ decrypted stream,
15349
+ // since they can enable an decryption oracle.
15350
+ // It's responsibility of the caller to pass a `grammarValidator` that takes care of
15351
+ // postponing error reporting until the data has been authenticated.
15352
+ grammarValidator?.(writtenTags, true, config$1);
15220
15353
  } catch (e) {
15221
15354
  // If an implementation encounters a critical packet where the packet type is unknown in a packet sequence,
15222
15355
  // it MUST reject the whole packet sequence. On the other hand, an unknown non-critical packet MUST be ignored.
@@ -15231,7 +15364,8 @@ var openpgp = (function (exports) {
15231
15364
 
15232
15365
  const throwUnsupportedError = !config$1.ignoreUnsupportedPackets && e instanceof UnsupportedError;
15233
15366
  const throwMalformedError = !config$1.ignoreMalformedPackets && !(e instanceof UnsupportedError);
15234
- if (throwUnsupportedError || throwMalformedError || supportsStreaming(parsed.tag)) {
15367
+ const throwGrammarError = e instanceof GrammarError;
15368
+ if (throwUnsupportedError || throwMalformedError || throwGrammarError || supportsStreaming(parsed.tag)) {
15235
15369
  // The packets that support streaming are the ones that contain message data.
15236
15370
  // Those are also the ones we want to be more strict about and throw on parse errors
15237
15371
  // (since we likely cannot process the message without these packets anyway).
@@ -15239,11 +15373,16 @@ var openpgp = (function (exports) {
15239
15373
  } else {
15240
15374
  const unparsedPacket = new UnparseablePacket(parsed.tag, parsed.packet);
15241
15375
  await writer.write(unparsedPacket);
15376
+ writtenTags.push(parsed.tag);
15377
+ grammarValidator?.(writtenTags, true, config$1);
15242
15378
  }
15243
15379
  util.printDebugError(e);
15244
15380
  }
15245
15381
  });
15246
15382
  if (done) {
15383
+ // Here we are past the MDC check for SEIPDv1 data, hence
15384
+ // the data is always authenticated at this point.
15385
+ grammarValidator?.(writtenTags, false, config$1);
15247
15386
  await writer.ready;
15248
15387
  await writer.close();
15249
15388
  return;
@@ -15466,7 +15605,8 @@ var openpgp = (function (exports) {
15466
15605
  throw new Error(`${compressionName} decompression not supported`);
15467
15606
  }
15468
15607
 
15469
- this.packets = await PacketList.fromBinary(await decompressionFn(this.compressed), allowedPackets$5, config$1);
15608
+ // Decompressing a Compressed Data packet MUST also yield a valid OpenPGP Message
15609
+ this.packets = await PacketList.fromBinary(await decompressionFn(this.compressed), allowedPackets$5, config$1, getMessageGrammarValidator({ enforceDelay: false }));
15470
15610
  }
15471
15611
 
15472
15612
  /**
@@ -15756,16 +15896,23 @@ var openpgp = (function (exports) {
15756
15896
  if (isArrayStream(encrypted)) encrypted = await readToEnd(encrypted);
15757
15897
 
15758
15898
  let packetbytes;
15899
+ let grammarValidator;
15759
15900
  if (this.version === 2) {
15760
15901
  if (this.cipherAlgorithm !== sessionKeyAlgorithm) {
15761
15902
  // sanity check
15762
15903
  throw new Error('Unexpected session key algorithm');
15763
15904
  }
15764
15905
  packetbytes = await runAEAD(this, 'decrypt', key, encrypted);
15906
+ grammarValidator = getMessageGrammarValidator({ delayReporting: false });
15765
15907
  } else {
15766
15908
  const { blockSize } = getCipherParams(sessionKeyAlgorithm);
15767
15909
  const decrypted = await decrypt$1(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize));
15768
15910
 
15911
+ // Grammar validation cannot be run before message integrity has been enstablished,
15912
+ // to avoid leaking info about the unauthenticated message structure.
15913
+ const releaseUnauthenticatedStream = util.isStream(encrypted) && config$1.allowUnauthenticatedStream;
15914
+ grammarValidator = getMessageGrammarValidator({ delayReporting: releaseUnauthenticatedStream });
15915
+
15769
15916
  // there must be a modification detection code packet as the
15770
15917
  // last packet and everything gets hashed except the hash itself
15771
15918
  const realHash = slice(passiveClone(decrypted), -20);
@@ -15777,17 +15924,23 @@ var openpgp = (function (exports) {
15777
15924
  if (!util.equalsUint8Array(hash, mdc)) {
15778
15925
  throw new Error('Modification detected.');
15779
15926
  }
15927
+ // this last chunk comes at the end of the stream passed to Packetlist.read's streamTransformPair,
15928
+ // which can thus be 'done' only after the MDC has been checked.
15780
15929
  return new Uint8Array();
15781
15930
  });
15782
15931
  const bytes = slice(tohash, blockSize + 2); // Remove random prefix
15783
15932
  packetbytes = slice(bytes, 0, -2); // Remove MDC packet
15784
15933
  packetbytes = concat([packetbytes, fromAsync(() => verifyHash)]);
15785
- if (!util.isStream(encrypted) || !config$1.allowUnauthenticatedStream) {
15934
+ if (!releaseUnauthenticatedStream) {
15786
15935
  packetbytes = await readToEnd(packetbytes);
15787
15936
  }
15788
15937
  }
15789
15938
 
15790
- this.packets = await PacketList.fromBinary(packetbytes, allowedPackets$4, config$1);
15939
+ // - Decrypting a version 1 Symmetrically Encrypted and Integrity Protected Data packet
15940
+ // MUST yield a valid OpenPGP Message.
15941
+ // - Decrypting a version 2 Symmetrically Encrypted and Integrity Protected Data packet
15942
+ // MUST yield a valid Optionally Padded Message.
15943
+ this.packets = await PacketList.fromBinary(packetbytes, allowedPackets$4, config$1, grammarValidator);
15791
15944
  return true;
15792
15945
  }
15793
15946
  }
@@ -16002,7 +16155,8 @@ var openpgp = (function (exports) {
16002
16155
  this.packets = await PacketList.fromBinary(
16003
16156
  await runAEAD(this, 'decrypt', key, clone(this.encrypted)),
16004
16157
  allowedPackets$3,
16005
- config$1
16158
+ config$1,
16159
+ getMessageGrammarValidator({ enforceDelay: false })
16006
16160
  );
16007
16161
  }
16008
16162
 
@@ -16929,6 +17083,10 @@ var openpgp = (function (exports) {
16929
17083
  encrypted.subarray(2, blockSize + 2)
16930
17084
  );
16931
17085
 
17086
+ // Decrypting a Symmetrically Encrypted Data packet MUST yield a valid OpenPGP Message.
17087
+ // But due to the lack of authentication over the decrypted data,
17088
+ // we do not run any grammarValidator, to avoid enabling a decryption oracle
17089
+ // (plus, there is probably a higher chance that these messages have an expected structure).
16932
17090
  this.packets = await PacketList.fromBinary(decrypted, allowedPackets$2, config$1);
16933
17091
  }
16934
17092
 
@@ -21531,7 +21689,7 @@ var openpgp = (function (exports) {
21531
21689
  }
21532
21690
  input = data;
21533
21691
  }
21534
- const packetlist = await PacketList.fromBinary(input, allowedMessagePackets, config$1);
21692
+ const packetlist = await PacketList.fromBinary(input, allowedMessagePackets, config$1, getMessageGrammarValidator({ delayReporting: false }));
21535
21693
  const message = new Message(packetlist);
21536
21694
  message.fromStream = streamType;
21537
21695
  return message;
@@ -22151,7 +22309,7 @@ var openpgp = (function (exports) {
22151
22309
  result.signatures = signature ? await decrypted.verifyDetached(signature, verificationKeys, date, config$1) : await decrypted.verify(verificationKeys, date, config$1);
22152
22310
  result.data = format === 'binary' ? decrypted.getLiteralData() : decrypted.getText();
22153
22311
  result.filename = decrypted.getFilename();
22154
- linkStreams(result, message);
22312
+ linkStreams(result, message, ...new Set([decrypted, decrypted.unwrapCompressed()]));
22155
22313
  if (expectSigned) {
22156
22314
  if (verificationKeys.length === 0) {
22157
22315
  throw new Error('Verification keys are required to verify message signatures');
@@ -22286,7 +22444,9 @@ var openpgp = (function (exports) {
22286
22444
  result.signatures = await message.verify(verificationKeys, date, config$1);
22287
22445
  }
22288
22446
  result.data = format === 'binary' ? message.getLiteralData() : message.getText();
22289
- if (message.fromStream && !signature) linkStreams(result, message);
22447
+ if (message.fromStream && !signature) {
22448
+ linkStreams(result, ...new Set([message, message.unwrapCompressed()]));
22449
+ }
22290
22450
  if (expectSigned) {
22291
22451
  if (result.signatures.length === 0) {
22292
22452
  throw new Error('Message is not signed');
@@ -22483,22 +22643,25 @@ var openpgp = (function (exports) {
22483
22643
  }
22484
22644
 
22485
22645
  /**
22486
- * Link result.data to the message stream for cancellation.
22487
- * Also, forward errors in the message to result.data.
22646
+ * Link result.data to the input message stream for cancellation.
22647
+ * Also, forward errors in the input message and intermediate messages to result.data.
22488
22648
  * @param {Object} result - the data to convert
22489
- * @param {Message} message - message object
22649
+ * @param {Message} message - message object provided by the user
22650
+ * @param {Message} intermediateMessages - intermediate message object with packet streams to link
22490
22651
  * @returns {Object}
22491
22652
  * @private
22492
22653
  */
22493
- function linkStreams(result, message) {
22494
- result.data = transformPair(message.packets.stream, async (readable, writable) => {
22654
+ function linkStreams(result, inputMessage, ...intermediateMessages) {
22655
+ result.data = transformPair(inputMessage.packets.stream, async (readable, writable) => {
22495
22656
  await pipe(result.data, writable, {
22496
22657
  preventClose: true
22497
22658
  });
22498
22659
  const writer = getWriter(writable);
22499
22660
  try {
22500
- // Forward errors in the message stream to result.data.
22661
+ // Forward errors in the message streams to result.data.
22501
22662
  await readToEnd(readable, _ => _);
22663
+ await Promise.all(intermediateMessages.map(intermediate => readToEnd(intermediate.packets.stream, _ => _)));
22664
+ // if result.data throws, the writable will be in errored state, and `close()` fails, but its ok.
22502
22665
  await writer.close();
22503
22666
  } catch (e) {
22504
22667
  await writer.abort(e);
@@ -31065,6 +31228,7 @@ var openpgp = (function (exports) {
31065
31228
  exports.Argon2S2K = Argon2S2K;
31066
31229
  exports.CleartextMessage = CleartextMessage;
31067
31230
  exports.CompressedDataPacket = CompressedDataPacket;
31231
+ exports.GrammarError = GrammarError;
31068
31232
  exports.KDFParams = KDFParams;
31069
31233
  exports.LiteralDataPacket = LiteralDataPacket;
31070
31234
  exports.MarkerPacket = MarkerPacket;