@protontech/openpgp 5.7.0 → 5.9.0

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.
@@ -1,4 +1,4 @@
1
- /*! OpenPGP.js v5.7.0 - 2023-03-06 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
1
+ /*! OpenPGP.js v5.9.0 - 2023-05-15 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
2
2
  const globalThis = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
3
3
 
4
4
  const doneWritingPromise = Symbol('doneWritingPromise');
@@ -1907,7 +1907,7 @@ const util = {
1907
1907
  if (!util.isString(data)) {
1908
1908
  return false;
1909
1909
  }
1910
- const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+([a-zA-Z]{2,}|xn--[a-zA-Z\-0-9]+)))$/;
1910
+ const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+([a-zA-Z]{2,}[0-9]*|xn--[a-zA-Z\-0-9]+)))$/;
1911
1911
  return re.test(data);
1912
1912
  },
1913
1913
 
@@ -2303,6 +2303,7 @@ var enums = {
2303
2303
  simple: 0,
2304
2304
  salted: 1,
2305
2305
  iterated: 3,
2306
+ argon2: 4,
2306
2307
  gnu: 101
2307
2308
  },
2308
2309
 
@@ -2617,6 +2618,8 @@ var enums = {
2617
2618
  splitPrivateKey: 16,
2618
2619
  /** 0x20 - This key may be used for authentication. */
2619
2620
  authentication: 32,
2621
+ /** This key may be used for forwarded communications */
2622
+ forwardedCommunication: 64,
2620
2623
  /** 0x80 - The private component of this key may be in the
2621
2624
  * possession of more than one person. */
2622
2625
  sharedPrivateKey: 128
@@ -2767,12 +2770,41 @@ var config = {
2767
2770
  */
2768
2771
  v5Keys: false,
2769
2772
  /**
2770
- * {@link https://tools.ietf.org/html/rfc4880#section-3.7.1.3|RFC4880 3.7.1.3}:
2771
- * Iteration Count Byte for S2K (String to Key)
2773
+ * S2K (String to Key) type, used for key derivation in the context of secret key encryption
2774
+ * and password-encrypted data. Weaker s2k options are not allowed.
2775
+ * Note: Argon2 is the strongest option but not all OpenPGP implementations are compatible with it
2776
+ * (pending standardisation).
2777
+ * @memberof module:config
2778
+ * @property {enums.s2k.argon2|enums.s2k.iterated} s2kType {@link module:enums.s2k}
2779
+ */
2780
+ s2kType: enums.s2k.iterated,
2781
+ /**
2782
+ * {@link https://tools.ietf.org/html/rfc4880#section-3.7.1.3| RFC4880 3.7.1.3}:
2783
+ * Iteration Count Byte for Iterated and Salted S2K (String to Key).
2784
+ * Only relevant if `config.s2kType` is set to `enums.s2k.iterated`.
2785
+ * Note: this is the exponent value, not the final number of iterations (refer to specs for more details).
2772
2786
  * @memberof module:config
2773
2787
  * @property {Integer} s2kIterationCountByte
2774
2788
  */
2775
2789
  s2kIterationCountByte: 224,
2790
+ /**
2791
+ * {@link https://tools.ietf.org/html/draft-ietf-openpgp-crypto-refresh-07.html#section-3.7.1.4| draft-crypto-refresh 3.7.1.4}:
2792
+ * Argon2 parameters for S2K (String to Key).
2793
+ * Only relevant if `config.s2kType` is set to `enums.s2k.argon2`.
2794
+ * Default settings correspond to the second recommendation from RFC9106 ("uniformly safe option"),
2795
+ * to ensure compatibility with memory-constrained environments.
2796
+ * For more details on the choice of parameters, see https://tools.ietf.org/html/rfc9106#section-4.
2797
+ * @memberof module:config
2798
+ * @property {Object} params
2799
+ * @property {Integer} params.passes - number of iterations t
2800
+ * @property {Integer} params.parallelism - degree of parallelism p
2801
+ * @property {Integer} params.memoryExponent - one-octet exponent indicating the memory size, which will be: 2**memoryExponent kibibytes.
2802
+ */
2803
+ s2kArgon2Params: {
2804
+ passes: 3,
2805
+ parallelism: 4, // lanes
2806
+ memoryExponent: 16 // 64 MiB of RAM
2807
+ },
2776
2808
  /**
2777
2809
  * Allow decryption of messages without integrity protection.
2778
2810
  * This is an **insecure** setting:
@@ -2792,6 +2824,13 @@ var config = {
2792
2824
  * @property {Boolean} allowUnauthenticatedStream
2793
2825
  */
2794
2826
  allowUnauthenticatedStream: false,
2827
+ /**
2828
+ * Allow decrypting forwarded messages, using keys with 0x40 ('forwarded communication') flag.
2829
+ * Note: this is related to a **non-standard feature**.
2830
+ * @memberof module:config
2831
+ * @property {Boolean} allowForwardedMessages
2832
+ */
2833
+ allowForwardedMessages: false,
2795
2834
  /**
2796
2835
  * @memberof module:config
2797
2836
  * @property {Boolean} checksumRequired Do not throw error when armor is missing a checksum
@@ -2868,6 +2907,14 @@ var config = {
2868
2907
  * @property {Boolean} ignoreMalformedPackets Ignore malformed packets on parsing instead of throwing an error
2869
2908
  */
2870
2909
  ignoreMalformedPackets: false,
2910
+ /**
2911
+ * Parsing of packets is normally restricted to a predefined set of packets. For example a Sym. Encrypted Integrity Protected Data Packet can only
2912
+ * contain a certain set of packets including LiteralDataPacket. With this setting we can allow additional packets, which is probably not advisable
2913
+ * as a global config setting, but can be used for specific function calls (e.g. decrypt method of Message).
2914
+ * @memberof module:config
2915
+ * @property {Array} additionalAllowedPackets Allow additional packets on parsing. Defined as array of packet classes, e.g. [PublicKeyPacket]
2916
+ */
2917
+ additionalAllowedPackets: [],
2871
2918
  /**
2872
2919
  * @memberof module:config
2873
2920
  * @property {Boolean} showVersion Whether to include {@link module:config/config.versionString} in armored messages
@@ -2882,7 +2929,7 @@ var config = {
2882
2929
  * @memberof module:config
2883
2930
  * @property {String} versionString A version string to be included in armored messages
2884
2931
  */
2885
- versionString: 'OpenPGP.js 5.7.0',
2932
+ versionString: 'OpenPGP.js 5.9.0',
2886
2933
  /**
2887
2934
  * @memberof module:config
2888
2935
  * @property {String} commentString A comment string to be included in armored messages
@@ -14366,7 +14413,7 @@ function buildEcdhParam(public_algo, oid, kdfParams, fingerprint) {
14366
14413
  return util.concatUint8Array([
14367
14414
  oid.write(),
14368
14415
  new Uint8Array([public_algo]),
14369
- kdfParams.replacementKDFParams || kdfParams.write(),
14416
+ kdfParams.write(true),
14370
14417
  util.stringToUint8Array('Anonymous Sender '),
14371
14418
  kdfParams.replacementFingerprint || fingerprint.subarray(0, 20)
14372
14419
  ]);
@@ -15208,32 +15255,28 @@ class ECDHSymmetricKey {
15208
15255
 
15209
15256
  // OpenPGP.js - An OpenPGP implementation in javascript
15210
15257
 
15258
+ const VERSION_FORWARDING = 0xFF;
15259
+
15211
15260
  class KDFParams {
15212
15261
  /**
15213
15262
  * @param {Integer} version Version, defaults to 1
15214
15263
  * @param {enums.hash} hash Hash algorithm
15215
15264
  * @param {enums.symmetric} cipher Symmetric algorithm
15216
- * @param {enums.kdfFlags} flags (v2 only) flags
15217
- * @param {Uint8Array} replacementFingerprint (v2 only) fingerprint to use instead of recipient one (v5 keys, the 20 leftmost bytes of the fingerprint)
15218
- * @param {Uint8Array} replacementKDFParams (v2 only) serialized KDF params to use in KDF digest computation
15265
+ * @param {Uint8Array} replacementFingerprint (forwarding only) fingerprint to use instead of recipient one (v5 keys, the 20 leftmost bytes of the fingerprint)
15219
15266
  */
15220
15267
  constructor(data) {
15221
15268
  if (data) {
15222
- const { version, hash, cipher, flags, replacementFingerprint, replacementKDFParams } = data;
15269
+ const { version, hash, cipher, replacementFingerprint } = data;
15223
15270
  this.version = version || 1;
15224
15271
  this.hash = hash;
15225
15272
  this.cipher = cipher;
15226
15273
 
15227
- this.flags = flags;
15228
15274
  this.replacementFingerprint = replacementFingerprint;
15229
- this.replacementKDFParams = replacementKDFParams;
15230
15275
  } else {
15231
15276
  this.version = null;
15232
15277
  this.hash = null;
15233
15278
  this.cipher = null;
15234
- this.flags = null;
15235
15279
  this.replacementFingerprint = null;
15236
- this.replacementKDFParams = null;
15237
15280
  }
15238
15281
  }
15239
15282
 
@@ -15243,44 +15286,41 @@ class KDFParams {
15243
15286
  * @returns {Number} Number of read bytes.
15244
15287
  */
15245
15288
  read(input) {
15289
+ const totalBytes = input[0];
15246
15290
  this.version = input[1];
15247
15291
  this.hash = input[2];
15248
15292
  this.cipher = input[3];
15249
15293
  let readBytes = 4;
15250
15294
 
15251
- if (this.version === 2) {
15252
- this.flags = input[readBytes++];
15253
- if (this.flags & enums.kdfFlags.replace_fingerprint) {
15254
- this.replacementFingerprint = input.slice(readBytes, readBytes + 20);
15255
- readBytes += 20;
15256
- }
15257
- if (this.flags & enums.kdfFlags.replace_kdf_params) {
15258
- const fieldLength = input[readBytes] + 1; // account for length
15259
- this.replacementKDFParams = input.slice(readBytes, readBytes + fieldLength);
15260
- readBytes += fieldLength;
15261
- }
15295
+ if (this.version === VERSION_FORWARDING) {
15296
+ const fingerprintLength = totalBytes - readBytes + 1; // acount for length byte
15297
+ this.replacementFingerprint = input.slice(readBytes, readBytes + fingerprintLength);
15298
+ readBytes += fingerprintLength;
15262
15299
  }
15263
15300
  return readBytes;
15264
15301
  }
15265
15302
 
15266
15303
  /**
15267
15304
  * Write KDFParams to an Uint8Array
15305
+ * @param {Boolean} [forReplacementParams] - forwarding only: whether to serialize data to use for replacement params
15268
15306
  * @returns {Uint8Array} Array with the KDFParams value
15269
15307
  */
15270
- write() {
15271
- if (!this.version || this.version === 1) {
15308
+ write(forReplacementParams) {
15309
+ if (!this.version || this.version === 1 || forReplacementParams) {
15272
15310
  return new Uint8Array([3, 1, this.hash, this.cipher]);
15273
15311
  }
15274
15312
 
15275
- const v2Fields = util.concatUint8Array([
15276
- new Uint8Array([4, 2, this.hash, this.cipher, this.flags]),
15277
- this.replacementFingerprint || new Uint8Array(),
15278
- this.replacementKDFParams || new Uint8Array()
15313
+ const forwardingFields = util.concatUint8Array([
15314
+ new Uint8Array([
15315
+ 3 + this.replacementFingerprint.length,
15316
+ this.version,
15317
+ this.hash,
15318
+ this.cipher
15319
+ ]),
15320
+ this.replacementFingerprint
15279
15321
  ]);
15280
15322
 
15281
- // update length field
15282
- v2Fields[0] = v2Fields.length - 1;
15283
- return new Uint8Array(v2Fields);
15323
+ return forwardingFields;
15284
15324
  }
15285
15325
  }
15286
15326
 
@@ -15863,6 +15903,339 @@ const mod = {
15863
15903
 
15864
15904
  Object.assign(mod, crypto$1);
15865
15905
 
15906
+ const ARGON2_TYPE = 0x02; // id
15907
+ const ARGON2_VERSION = 0x13;
15908
+ const ARGON2_SALT_SIZE = 16;
15909
+
15910
+ class Argon2OutOfMemoryError extends Error {
15911
+ constructor(...params) {
15912
+ super(...params);
15913
+
15914
+ if (Error.captureStackTrace) {
15915
+ Error.captureStackTrace(this, Argon2OutOfMemoryError);
15916
+ }
15917
+
15918
+ this.name = 'Argon2OutOfMemoryError';
15919
+ }
15920
+ }
15921
+
15922
+ // cache argon wasm module
15923
+ let loadArgonWasmModule;
15924
+ let argon2Promise;
15925
+ // reload wasm module above this treshold, to deallocated used memory
15926
+ const ARGON2_WASM_MEMORY_THRESHOLD_RELOAD = 2 << 19;
15927
+
15928
+ class Argon2S2K {
15929
+ /**
15930
+ * @param {Object} [config] - Full configuration, defaults to openpgp.config
15931
+ */
15932
+ constructor(config$1 = config) {
15933
+ const { passes, parallelism, memoryExponent } = config$1.s2kArgon2Params;
15934
+
15935
+ this.type = 'argon2';
15936
+ /** @type {Uint8Array} 16 bytes of salt */
15937
+ this.salt = null;
15938
+ /** @type {Integer} number of passes */
15939
+ this.t = passes;
15940
+ /** @type {Integer} degree of parallelism (lanes) */
15941
+ this.p = parallelism;
15942
+ /** @type {Integer} exponent indicating memory size */
15943
+ this.encodedM = memoryExponent;
15944
+ }
15945
+
15946
+ generateSalt() {
15947
+ this.salt = mod.random.getRandomBytes(ARGON2_SALT_SIZE);
15948
+ }
15949
+
15950
+ /**
15951
+ * Parsing function for argon2 string-to-key specifier.
15952
+ * @param {Uint8Array} bytes - Payload of argon2 string-to-key specifier
15953
+ * @returns {Integer} Actual length of the object.
15954
+ */
15955
+ read(bytes) {
15956
+ let i = 0;
15957
+
15958
+ this.salt = bytes.subarray(i, i + 16);
15959
+ i += 16;
15960
+
15961
+ this.t = bytes[i++];
15962
+ this.p = bytes[i++];
15963
+ this.encodedM = bytes[i++]; // memory size exponent, one-octect
15964
+
15965
+ return i;
15966
+ }
15967
+
15968
+ /**
15969
+ * Serializes s2k information
15970
+ * @returns {Uint8Array} Binary representation of s2k.
15971
+ */
15972
+ write() {
15973
+ const arr = [
15974
+ new Uint8Array([enums.write(enums.s2k, this.type)]),
15975
+ this.salt,
15976
+ new Uint8Array([this.t, this.p, this.encodedM])
15977
+ ];
15978
+
15979
+ return util.concatUint8Array(arr);
15980
+ }
15981
+
15982
+ /**
15983
+ * Produces a key using the specified passphrase and the defined
15984
+ * hashAlgorithm
15985
+ * @param {String} passphrase - Passphrase containing user input
15986
+ * @returns {Promise<Uint8Array>} Produced key with a length corresponding to `keySize`
15987
+ * @throws {Argon2OutOfMemoryError|Errors}
15988
+ * @async
15989
+ */
15990
+ async produceKey(passphrase, keySize) {
15991
+ const decodedM = 2 << (this.encodedM - 1);
15992
+
15993
+ try {
15994
+ if (!argon2Promise) { // first load
15995
+ loadArgonWasmModule = loadArgonWasmModule || (await import('./argon2id.mjs')).default;
15996
+ argon2Promise = loadArgonWasmModule();
15997
+ }
15998
+ // important to keep local ref to argon2 in case the module is reloaded by another instance
15999
+ const argon2 = await argon2Promise;
16000
+
16001
+ const passwordBytes = util.encodeUTF8(passphrase);
16002
+ const hash = argon2({
16003
+ version: ARGON2_VERSION,
16004
+ type: ARGON2_TYPE,
16005
+ password: passwordBytes,
16006
+ salt: this.salt,
16007
+ tagLength: keySize,
16008
+ memorySize: decodedM,
16009
+ parallelism: this.p,
16010
+ passes: this.t
16011
+ });
16012
+
16013
+ // a lot of memory was used, reload to deallocate
16014
+ if (decodedM > ARGON2_WASM_MEMORY_THRESHOLD_RELOAD) {
16015
+ // it will be awaited if needed at the next `produceKey` invocation
16016
+ argon2Promise = loadArgonWasmModule();
16017
+ }
16018
+ return hash;
16019
+ } catch (e) {
16020
+ if (e.message && (
16021
+ e.message.includes('Unable to grow instance memory') || // Chrome
16022
+ e.message.includes('failed to grow memory') || // Firefox
16023
+ e.message.includes('WebAssembly.Memory.grow') || // Safari
16024
+ e.message.includes('Out of memory') // Safari iOS
16025
+ )) {
16026
+ throw new Argon2OutOfMemoryError('Could not allocate required memory for Argon2');
16027
+ } else {
16028
+ throw e;
16029
+ }
16030
+ }
16031
+ }
16032
+ }
16033
+
16034
+ // GPG4Browsers - An OpenPGP implementation in javascript
16035
+
16036
+ class GenericS2K {
16037
+ /**
16038
+ * @param {Object} [config] - Full configuration, defaults to openpgp.config
16039
+ */
16040
+ constructor(s2kType, config$1 = config) {
16041
+ /**
16042
+ * Hash function identifier, or 0 for gnu-dummy keys
16043
+ * @type {module:enums.hash | 0}
16044
+ */
16045
+ this.algorithm = enums.hash.sha256;
16046
+ /**
16047
+ * enums.s2k identifier or 'gnu-dummy'
16048
+ * @type {String}
16049
+ */
16050
+ this.type = enums.read(enums.s2k, s2kType);
16051
+ /** @type {Integer} */
16052
+ this.c = config$1.s2kIterationCountByte;
16053
+ /** Eight bytes of salt in a binary string.
16054
+ * @type {Uint8Array}
16055
+ */
16056
+ this.salt = null;
16057
+ }
16058
+
16059
+ generateSalt() {
16060
+ switch (this.type) {
16061
+ case 'salted':
16062
+ case 'iterated':
16063
+ this.salt = mod.random.getRandomBytes(8);
16064
+ }
16065
+ }
16066
+
16067
+ getCount() {
16068
+ // Exponent bias, defined in RFC4880
16069
+ const expbias = 6;
16070
+
16071
+ return (16 + (this.c & 15)) << ((this.c >> 4) + expbias);
16072
+ }
16073
+
16074
+ /**
16075
+ * Parsing function for a string-to-key specifier ({@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC 4880 3.7}).
16076
+ * @param {Uint8Array} bytes - Payload of string-to-key specifier
16077
+ * @returns {Integer} Actual length of the object.
16078
+ */
16079
+ read(bytes) {
16080
+ let i = 0;
16081
+ this.algorithm = bytes[i++];
16082
+
16083
+ switch (this.type) {
16084
+ case 'simple':
16085
+ break;
16086
+
16087
+ case 'salted':
16088
+ this.salt = bytes.subarray(i, i + 8);
16089
+ i += 8;
16090
+ break;
16091
+
16092
+ case 'iterated':
16093
+ this.salt = bytes.subarray(i, i + 8);
16094
+ i += 8;
16095
+
16096
+ // Octet 10: count, a one-octet, coded value
16097
+ this.c = bytes[i++];
16098
+ break;
16099
+ case 'gnu':
16100
+ if (util.uint8ArrayToString(bytes.subarray(i, i + 3)) === 'GNU') {
16101
+ i += 3; // GNU
16102
+ const gnuExtType = 1000 + bytes[i++];
16103
+ if (gnuExtType === 1001) {
16104
+ this.type = 'gnu-dummy';
16105
+ // GnuPG extension mode 1001 -- don't write secret key at all
16106
+ } else {
16107
+ throw new Error('Unknown s2k gnu protection mode.');
16108
+ }
16109
+ } else {
16110
+ throw new Error('Unknown s2k type.');
16111
+ }
16112
+ break;
16113
+
16114
+ default:
16115
+ throw new Error('Unknown s2k type.');
16116
+ }
16117
+
16118
+ return i;
16119
+ }
16120
+
16121
+ /**
16122
+ * Serializes s2k information
16123
+ * @returns {Uint8Array} Binary representation of s2k.
16124
+ */
16125
+ write() {
16126
+ if (this.type === 'gnu-dummy') {
16127
+ return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]);
16128
+ }
16129
+ const arr = [new Uint8Array([enums.write(enums.s2k, this.type), this.algorithm])];
16130
+
16131
+ switch (this.type) {
16132
+ case 'simple':
16133
+ break;
16134
+ case 'salted':
16135
+ arr.push(this.salt);
16136
+ break;
16137
+ case 'iterated':
16138
+ arr.push(this.salt);
16139
+ arr.push(new Uint8Array([this.c]));
16140
+ break;
16141
+ case 'gnu':
16142
+ throw new Error('GNU s2k type not supported.');
16143
+ default:
16144
+ throw new Error('Unknown s2k type.');
16145
+ }
16146
+
16147
+ return util.concatUint8Array(arr);
16148
+ }
16149
+
16150
+ /**
16151
+ * Produces a key using the specified passphrase and the defined
16152
+ * hashAlgorithm
16153
+ * @param {String} passphrase - Passphrase containing user input
16154
+ * @returns {Promise<Uint8Array>} Produced key with a length corresponding to.
16155
+ * hashAlgorithm hash length
16156
+ * @async
16157
+ */
16158
+ async produceKey(passphrase, numBytes) {
16159
+ passphrase = util.encodeUTF8(passphrase);
16160
+
16161
+ const arr = [];
16162
+ let rlength = 0;
16163
+
16164
+ let prefixlen = 0;
16165
+ while (rlength < numBytes) {
16166
+ let toHash;
16167
+ switch (this.type) {
16168
+ case 'simple':
16169
+ toHash = util.concatUint8Array([new Uint8Array(prefixlen), passphrase]);
16170
+ break;
16171
+ case 'salted':
16172
+ toHash = util.concatUint8Array([new Uint8Array(prefixlen), this.salt, passphrase]);
16173
+ break;
16174
+ case 'iterated': {
16175
+ const data = util.concatUint8Array([this.salt, passphrase]);
16176
+ let datalen = data.length;
16177
+ const count = Math.max(this.getCount(), datalen);
16178
+ toHash = new Uint8Array(prefixlen + count);
16179
+ toHash.set(data, prefixlen);
16180
+ for (let pos = prefixlen + datalen; pos < count; pos += datalen, datalen *= 2) {
16181
+ toHash.copyWithin(pos, prefixlen, pos);
16182
+ }
16183
+ break;
16184
+ }
16185
+ case 'gnu':
16186
+ throw new Error('GNU s2k type not supported.');
16187
+ default:
16188
+ throw new Error('Unknown s2k type.');
16189
+ }
16190
+ const result = await mod.hash.digest(this.algorithm, toHash);
16191
+ arr.push(result);
16192
+ rlength += result.length;
16193
+ prefixlen++;
16194
+ }
16195
+
16196
+ return util.concatUint8Array(arr).subarray(0, numBytes);
16197
+ }
16198
+ }
16199
+
16200
+ const allowedS2KTypesForEncryption = new Set([enums.s2k.argon2, enums.s2k.iterated]);
16201
+
16202
+ /**
16203
+ * Instantiate a new S2K instance of the given type
16204
+ * @param {module:enums.s2k} type
16205
+ * @oaram {Object} [config]
16206
+ * @returns {Object} New s2k object
16207
+ * @throws {Error} for unknown or unsupported types
16208
+ */
16209
+ function newS2KFromType(type, config$1 = config) {
16210
+ switch (type) {
16211
+ case enums.s2k.argon2:
16212
+ return new Argon2S2K(config$1);
16213
+ case enums.s2k.iterated:
16214
+ case enums.s2k.gnu:
16215
+ case enums.s2k.salted:
16216
+ case enums.s2k.simple:
16217
+ return new GenericS2K(type, config$1);
16218
+ default:
16219
+ throw new Error(`Unsupported S2K type ${type}`);
16220
+ }
16221
+ }
16222
+
16223
+ /**
16224
+ * Instantiate a new S2K instance based on the config settings
16225
+ * @oaram {Object} config
16226
+ * @returns {Object} New s2k object
16227
+ * @throws {Error} for unknown or unsupported types
16228
+ */
16229
+ function newS2KFromConfig(config) {
16230
+ const { s2kType } = config;
16231
+
16232
+ if (!allowedS2KTypesForEncryption.has(s2kType)) {
16233
+ throw new Error('The provided `config.s2kType` value is not allowed');
16234
+ }
16235
+
16236
+ return newS2KFromType(s2kType, config);
16237
+ }
16238
+
15866
16239
  var TYPED_OK = typeof Uint8Array !== "undefined" &&
15867
16240
  typeof Uint16Array !== "undefined" &&
15868
16241
  typeof Int32Array !== "undefined";
@@ -23917,6 +24290,9 @@ class PacketList extends Array {
23917
24290
  * @async
23918
24291
  */
23919
24292
  async read(bytes, allowedPackets, config$1 = config) {
24293
+ if (config$1.additionalAllowedPackets.length) {
24294
+ allowedPackets = { ...allowedPackets, ...util.constructAllowedPackets(config$1.additionalAllowedPackets) };
24295
+ }
23920
24296
  this.stream = transformPair(bytes, async (readable, writable) => {
23921
24297
  const writer = getWriter(writable);
23922
24298
  try {
@@ -24684,166 +25060,6 @@ class PublicKeyEncryptedSessionKeyPacket {
24684
25060
 
24685
25061
  // GPG4Browsers - An OpenPGP implementation in javascript
24686
25062
 
24687
- class S2K {
24688
- /**
24689
- * @param {Object} [config] - Full configuration, defaults to openpgp.config
24690
- */
24691
- constructor(config$1 = config) {
24692
- /**
24693
- * Hash function identifier, or 0 for gnu-dummy keys
24694
- * @type {module:enums.hash | 0}
24695
- */
24696
- this.algorithm = enums.hash.sha256;
24697
- /**
24698
- * enums.s2k identifier or 'gnu-dummy'
24699
- * @type {String}
24700
- */
24701
- this.type = 'iterated';
24702
- /** @type {Integer} */
24703
- this.c = config$1.s2kIterationCountByte;
24704
- /** Eight bytes of salt in a binary string.
24705
- * @type {Uint8Array}
24706
- */
24707
- this.salt = null;
24708
- }
24709
-
24710
- getCount() {
24711
- // Exponent bias, defined in RFC4880
24712
- const expbias = 6;
24713
-
24714
- return (16 + (this.c & 15)) << ((this.c >> 4) + expbias);
24715
- }
24716
-
24717
- /**
24718
- * Parsing function for a string-to-key specifier ({@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC 4880 3.7}).
24719
- * @param {Uint8Array} bytes - Payload of string-to-key specifier
24720
- * @returns {Integer} Actual length of the object.
24721
- */
24722
- read(bytes) {
24723
- let i = 0;
24724
- this.type = enums.read(enums.s2k, bytes[i++]);
24725
- this.algorithm = bytes[i++];
24726
-
24727
- switch (this.type) {
24728
- case 'simple':
24729
- break;
24730
-
24731
- case 'salted':
24732
- this.salt = bytes.subarray(i, i + 8);
24733
- i += 8;
24734
- break;
24735
-
24736
- case 'iterated':
24737
- this.salt = bytes.subarray(i, i + 8);
24738
- i += 8;
24739
-
24740
- // Octet 10: count, a one-octet, coded value
24741
- this.c = bytes[i++];
24742
- break;
24743
-
24744
- case 'gnu':
24745
- if (util.uint8ArrayToString(bytes.subarray(i, i + 3)) === 'GNU') {
24746
- i += 3; // GNU
24747
- const gnuExtType = 1000 + bytes[i++];
24748
- if (gnuExtType === 1001) {
24749
- this.type = 'gnu-dummy';
24750
- // GnuPG extension mode 1001 -- don't write secret key at all
24751
- } else {
24752
- throw new Error('Unknown s2k gnu protection mode.');
24753
- }
24754
- } else {
24755
- throw new Error('Unknown s2k type.');
24756
- }
24757
- break;
24758
-
24759
- default:
24760
- throw new Error('Unknown s2k type.');
24761
- }
24762
-
24763
- return i;
24764
- }
24765
-
24766
- /**
24767
- * Serializes s2k information
24768
- * @returns {Uint8Array} Binary representation of s2k.
24769
- */
24770
- write() {
24771
- if (this.type === 'gnu-dummy') {
24772
- return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]);
24773
- }
24774
- const arr = [new Uint8Array([enums.write(enums.s2k, this.type), this.algorithm])];
24775
-
24776
- switch (this.type) {
24777
- case 'simple':
24778
- break;
24779
- case 'salted':
24780
- arr.push(this.salt);
24781
- break;
24782
- case 'iterated':
24783
- arr.push(this.salt);
24784
- arr.push(new Uint8Array([this.c]));
24785
- break;
24786
- case 'gnu':
24787
- throw new Error('GNU s2k type not supported.');
24788
- default:
24789
- throw new Error('Unknown s2k type.');
24790
- }
24791
-
24792
- return util.concatUint8Array(arr);
24793
- }
24794
-
24795
- /**
24796
- * Produces a key using the specified passphrase and the defined
24797
- * hashAlgorithm
24798
- * @param {String} passphrase - Passphrase containing user input
24799
- * @returns {Promise<Uint8Array>} Produced key with a length corresponding to.
24800
- * hashAlgorithm hash length
24801
- * @async
24802
- */
24803
- async produceKey(passphrase, numBytes) {
24804
- passphrase = util.encodeUTF8(passphrase);
24805
-
24806
- const arr = [];
24807
- let rlength = 0;
24808
-
24809
- let prefixlen = 0;
24810
- while (rlength < numBytes) {
24811
- let toHash;
24812
- switch (this.type) {
24813
- case 'simple':
24814
- toHash = util.concatUint8Array([new Uint8Array(prefixlen), passphrase]);
24815
- break;
24816
- case 'salted':
24817
- toHash = util.concatUint8Array([new Uint8Array(prefixlen), this.salt, passphrase]);
24818
- break;
24819
- case 'iterated': {
24820
- const data = util.concatUint8Array([this.salt, passphrase]);
24821
- let datalen = data.length;
24822
- const count = Math.max(this.getCount(), datalen);
24823
- toHash = new Uint8Array(prefixlen + count);
24824
- toHash.set(data, prefixlen);
24825
- for (let pos = prefixlen + datalen; pos < count; pos += datalen, datalen *= 2) {
24826
- toHash.copyWithin(pos, prefixlen, pos);
24827
- }
24828
- break;
24829
- }
24830
- case 'gnu':
24831
- throw new Error('GNU s2k type not supported.');
24832
- default:
24833
- throw new Error('Unknown s2k type.');
24834
- }
24835
- const result = await mod.hash.digest(this.algorithm, toHash);
24836
- arr.push(result);
24837
- rlength += result.length;
24838
- prefixlen++;
24839
- }
24840
-
24841
- return util.concatUint8Array(arr).subarray(0, numBytes);
24842
- }
24843
- }
24844
-
24845
- // GPG4Browsers - An OpenPGP implementation in javascript
24846
-
24847
25063
  /**
24848
25064
  * Symmetric-Key Encrypted Session Key Packets (Tag 3)
24849
25065
  *
@@ -24911,7 +25127,8 @@ class SymEncryptedSessionKeyPacket {
24911
25127
  }
24912
25128
 
24913
25129
  // A string-to-key (S2K) specifier, length as defined above.
24914
- this.s2k = new S2K();
25130
+ const s2kType = bytes[offset++];
25131
+ this.s2k = newS2KFromType(s2kType);
24915
25132
  offset += this.s2k.read(bytes.subarray(offset, bytes.length));
24916
25133
 
24917
25134
  if (this.version === 5) {
@@ -25000,8 +25217,8 @@ class SymEncryptedSessionKeyPacket {
25000
25217
 
25001
25218
  this.sessionKeyEncryptionAlgorithm = algo;
25002
25219
 
25003
- this.s2k = new S2K(config$1);
25004
- this.s2k.salt = mod.random.getRandomBytes(8);
25220
+ this.s2k = newS2KFromConfig(config$1);
25221
+ this.s2k.generateSalt();
25005
25222
 
25006
25223
  const { blockSize, keySize } = mod.getCipher(algo);
25007
25224
  const encryptionKey = await this.s2k.produceKey(passphrase, keySize);
@@ -25627,7 +25844,8 @@ class SecretKeyPacket extends PublicKeyPacket {
25627
25844
  // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
25628
25845
  // string-to-key specifier. The length of the string-to-key
25629
25846
  // specifier is implied by its type, as described above.
25630
- this.s2k = new S2K();
25847
+ const s2kType = bytes[i++];
25848
+ this.s2k = newS2KFromType(s2kType);
25631
25849
  i += this.s2k.read(bytes.subarray(i, bytes.length));
25632
25850
 
25633
25851
  if (this.s2k.type === 'gnu-dummy') {
@@ -25765,7 +25983,7 @@ class SecretKeyPacket extends PublicKeyPacket {
25765
25983
  }
25766
25984
  this.isEncrypted = null;
25767
25985
  this.keyMaterial = null;
25768
- this.s2k = new S2K(config$1);
25986
+ this.s2k = newS2KFromType(enums.s2k.gnu, config$1);
25769
25987
  this.s2k.algorithm = 0;
25770
25988
  this.s2k.c = 0;
25771
25989
  this.s2k.type = 'gnu-dummy';
@@ -25796,8 +26014,8 @@ class SecretKeyPacket extends PublicKeyPacket {
25796
26014
  throw new Error('A non-empty passphrase is required for key encryption.');
25797
26015
  }
25798
26016
 
25799
- this.s2k = new S2K(config$1);
25800
- this.s2k.salt = mod.random.getRandomBytes(8);
26017
+ this.s2k = newS2KFromConfig(config$1);
26018
+ this.s2k.generateSalt();
25801
26019
  const cleartext = mod.serializeParams(this.algorithm, this.privateParams);
25802
26020
  this.symmetric = enums.symmetric.aes256;
25803
26021
  const key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric);
@@ -27628,7 +27846,8 @@ function isValidDecryptionKeyPacket(signature, config) {
27628
27846
 
27629
27847
  return !signature.keyFlags ||
27630
27848
  (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 ||
27631
- (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0;
27849
+ (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0 ||
27850
+ (config.allowForwardedMessages && (signature.keyFlags[0] & enums.keyFlags.forwardedCommunication) !== 0);
27632
27851
  }
27633
27852
 
27634
27853
  /**
@@ -28576,7 +28795,7 @@ class Key {
28576
28795
  throw exception || new Error('Could not find primary user');
28577
28796
  }
28578
28797
  await Promise.all(users.map(async function (a) {
28579
- return a.user.revoked || a.user.isRevoked(a.selfCertification, null, date, config$1);
28798
+ return a.selfCertification.revoked || a.user.isRevoked(a.selfCertification, null, date, config$1);
28580
28799
  }));
28581
28800
  // sort by primary user flag and signature creation time
28582
28801
  const primaryUser = users.sort(function(a, b) {
@@ -28799,7 +29018,8 @@ class Key {
28799
29018
 
28800
29019
  results.push(...signatures.map(
28801
29020
  signature => ({
28802
- userID: user.userID.userID,
29021
+ userID: user.userID ? user.userID.userID : null,
29022
+ userAttribute: user.userAttribute,
28803
29023
  keyID: signature.keyID,
28804
29024
  valid: signature.valid
28805
29025
  }))
@@ -29675,6 +29895,9 @@ class Message {
29675
29895
  decryptedSessionKeyPackets.push(skeskPacket);
29676
29896
  } catch (err) {
29677
29897
  util.printDebugError(err);
29898
+ if (err instanceof Argon2OutOfMemoryError) {
29899
+ exception = err;
29900
+ }
29678
29901
  }
29679
29902
  }));
29680
29903
  }));
@@ -31329,4 +31552,4 @@ function formatObject(object, format, config) {
31329
31552
  }
31330
31553
  }
31331
31554
 
31332
- export { AEADEncryptedDataPacket, CleartextMessage, CompressedDataPacket, LiteralDataPacket, MarkerPacket, Message, OnePassSignaturePacket, PacketList, PrivateKey, PublicKey, PublicKeyEncryptedSessionKeyPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, Signature, SignaturePacket, Subkey, SymEncryptedIntegrityProtectedDataPacket, SymEncryptedSessionKeyPacket, SymmetricallyEncryptedDataPacket, TrustPacket, UnparseablePacket, UserAttributePacket, UserIDPacket, _224 as _, commonjsGlobal as a, armor, common$1 as b, createCommonjsModule as c, config, createCleartextMessage, createMessage, common as d, decrypt$4 as decrypt, decryptKey, decryptSessionKeys, _256 as e, encrypt$4 as encrypt, encryptKey, encryptSessionKey, enums, _384 as f, _512 as g, generateKey, generateSessionKey$1 as generateSessionKey, inherits_browser as i, minimalisticAssert as m, ripemd as r, readCleartextMessage, readKey, readKeys, readMessage, readPrivateKey, readPrivateKeys, readSignature, reformatKey, revokeKey, sign$5 as sign, utils as u, unarmor, verify$5 as verify };
31555
+ export { AEADEncryptedDataPacket, CleartextMessage, CompressedDataPacket, KDFParams, LiteralDataPacket, MarkerPacket, Message, OnePassSignaturePacket, PacketList, PrivateKey, PublicKey, PublicKeyEncryptedSessionKeyPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, Signature, SignaturePacket, Subkey, SymEncryptedIntegrityProtectedDataPacket, SymEncryptedSessionKeyPacket, SymmetricallyEncryptedDataPacket, TrustPacket, UnparseablePacket, UserAttributePacket, UserIDPacket, _224 as _, commonjsGlobal as a, armor, common$1 as b, createCommonjsModule as c, config, createCleartextMessage, createMessage, common as d, decrypt$4 as decrypt, decryptKey, decryptSessionKeys, _256 as e, encrypt$4 as encrypt, encryptKey, encryptSessionKey, enums, _384 as f, _512 as g, generateKey, generateSessionKey$1 as generateSessionKey, inherits_browser as i, minimalisticAssert as m, ripemd as r, readCleartextMessage, readKey, readKeys, readMessage, readPrivateKey, readPrivateKeys, readSignature, reformatKey, revokeKey, sign$5 as sign, utils as u, unarmor, verify$5 as verify };