@protontech/openpgp 6.0.0-beta.3.patch.1 → 6.0.1
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/README.md +34 -37
- package/dist/lightweight/argon2id.min.mjs +1 -1
- package/dist/lightweight/argon2id.min.mjs.map +1 -1
- package/dist/lightweight/argon2id.mjs +1 -1
- package/dist/lightweight/legacy_ciphers.min.mjs +1 -1
- package/dist/lightweight/legacy_ciphers.min.mjs.map +1 -1
- package/dist/lightweight/legacy_ciphers.mjs +1 -1
- package/dist/lightweight/noble_curves.min.mjs +11 -11
- package/dist/lightweight/noble_curves.min.mjs.map +1 -1
- package/dist/lightweight/noble_curves.mjs +260 -158
- package/dist/lightweight/noble_hashes.min.mjs +2 -2
- package/dist/lightweight/noble_hashes.min.mjs.map +1 -1
- package/dist/lightweight/noble_hashes.mjs +3 -2
- package/dist/lightweight/noble_post_quantum.min.mjs +5 -0
- package/dist/lightweight/noble_post_quantum.min.mjs.map +1 -0
- package/dist/lightweight/noble_post_quantum.mjs +1002 -0
- package/dist/lightweight/openpgp.min.mjs +4 -4
- package/dist/lightweight/openpgp.min.mjs.map +1 -1
- package/dist/lightweight/openpgp.mjs +863 -1056
- package/dist/lightweight/seek-bzip.min.mjs +3 -0
- package/dist/lightweight/seek-bzip.min.mjs.map +1 -0
- package/dist/lightweight/seek-bzip.mjs +866 -0
- package/dist/lightweight/sha3.min.mjs +3 -3
- package/dist/lightweight/sha3.min.mjs.map +1 -1
- package/dist/lightweight/sha3.mjs +27 -456
- package/dist/lightweight/sha512.min.mjs +3 -0
- package/dist/lightweight/sha512.min.mjs.map +1 -0
- package/dist/lightweight/sha512.mjs +436 -0
- package/dist/node/openpgp.cjs +14499 -12719
- package/dist/node/openpgp.min.cjs +16 -14
- package/dist/node/openpgp.min.cjs.map +1 -1
- package/dist/node/openpgp.min.mjs +16 -14
- package/dist/node/openpgp.min.mjs.map +1 -1
- package/dist/node/openpgp.mjs +11878 -10098
- package/dist/openpgp.js +11909 -10129
- package/dist/openpgp.min.js +16 -14
- package/dist/openpgp.min.js.map +1 -1
- package/dist/openpgp.min.mjs +16 -14
- package/dist/openpgp.min.mjs.map +1 -1
- package/dist/openpgp.mjs +11909 -10129
- package/openpgp.d.ts +3 -9
- package/package.json +27 -26
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! OpenPGP.js v6.0.
|
|
1
|
+
/*! OpenPGP.js v6.0.1 - 2024-11-25 - 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');
|
|
@@ -1047,6 +1047,11 @@ var enums = {
|
|
|
1047
1047
|
ed25519: 27,
|
|
1048
1048
|
/** Ed448 (Sign only) */
|
|
1049
1049
|
ed448: 28,
|
|
1050
|
+
/** Post-quantum ML-KEM-768 + X25519 (Encrypt only) */
|
|
1051
|
+
pqc_mlkem_x25519: 105,
|
|
1052
|
+
/** Post-quantum ML-DSA-64 + Ed25519 (Sign only) */
|
|
1053
|
+
pqc_mldsa_ed25519: 107,
|
|
1054
|
+
|
|
1050
1055
|
/** Persistent symmetric keys: encryption algorithm */
|
|
1051
1056
|
aead: 100,
|
|
1052
1057
|
/** Persistent symmetric keys: authentication algorithm */
|
|
@@ -1455,7 +1460,7 @@ var config = {
|
|
|
1455
1460
|
* @memberof module:config
|
|
1456
1461
|
* @property {Integer} preferredHashAlgorithm Default hash algorithm {@link module:enums.hash}
|
|
1457
1462
|
*/
|
|
1458
|
-
preferredHashAlgorithm: enums.hash.
|
|
1463
|
+
preferredHashAlgorithm: enums.hash.sha512,
|
|
1459
1464
|
/**
|
|
1460
1465
|
* @memberof module:config
|
|
1461
1466
|
* @property {Integer} preferredSymmetricAlgorithm Default encryption cipher {@link module:enums.symmetric}
|
|
@@ -1682,7 +1687,7 @@ var config = {
|
|
|
1682
1687
|
* @memberof module:config
|
|
1683
1688
|
* @property {String} versionString A version string to be included in armored messages
|
|
1684
1689
|
*/
|
|
1685
|
-
versionString: 'OpenPGP.js 6.0.
|
|
1690
|
+
versionString: 'OpenPGP.js 6.0.1',
|
|
1686
1691
|
/**
|
|
1687
1692
|
* @memberof module:config
|
|
1688
1693
|
* @property {String} commentString A comment string to be included in armored messages
|
|
@@ -1883,6 +1888,9 @@ const util = {
|
|
|
1883
1888
|
* @returns {Uint8Array} Padded bytes.
|
|
1884
1889
|
*/
|
|
1885
1890
|
leftPad(bytes, length) {
|
|
1891
|
+
if (bytes.length > length) {
|
|
1892
|
+
throw new Error('Input array too long');
|
|
1893
|
+
}
|
|
1886
1894
|
const padded = new Uint8Array(length);
|
|
1887
1895
|
const offset = length - bytes.length;
|
|
1888
1896
|
padded.set(bytes, offset);
|
|
@@ -2458,7 +2466,7 @@ function encode$1(data) {
|
|
|
2458
2466
|
* @returns {Uint8Array | ReadableStream<Uint8Array>} Binary array version of input string.
|
|
2459
2467
|
* @static
|
|
2460
2468
|
*/
|
|
2461
|
-
function decode$
|
|
2469
|
+
function decode$1(data) {
|
|
2462
2470
|
let buf = '';
|
|
2463
2471
|
return transform(data, value => {
|
|
2464
2472
|
buf += value;
|
|
@@ -2494,7 +2502,7 @@ function decode$2(data) {
|
|
|
2494
2502
|
* @returns {Uint8Array} An array of 8-bit integers.
|
|
2495
2503
|
*/
|
|
2496
2504
|
function b64ToUint8Array(base64) {
|
|
2497
|
-
return decode$
|
|
2505
|
+
return decode$1(base64.replace(/-/g, '+').replace(/_/g, '/'));
|
|
2498
2506
|
}
|
|
2499
2507
|
|
|
2500
2508
|
/**
|
|
@@ -2747,7 +2755,7 @@ function unarmor(input) {
|
|
|
2747
2755
|
let headersDone;
|
|
2748
2756
|
let text = [];
|
|
2749
2757
|
let textDone;
|
|
2750
|
-
const data = decode$
|
|
2758
|
+
const data = decode$1(transformPair(input, async (readable, writable) => {
|
|
2751
2759
|
const reader = getReader(readable);
|
|
2752
2760
|
try {
|
|
2753
2761
|
while (true) {
|
|
@@ -3820,7 +3828,7 @@ function applySbox(sbox2, s0, s1, s2, s3) {
|
|
|
3820
3828
|
return (sbox2[(s0 & 0xff) | (s1 & 0xff00)] |
|
|
3821
3829
|
(sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16));
|
|
3822
3830
|
}
|
|
3823
|
-
function encrypt$
|
|
3831
|
+
function encrypt$7(xk, s0, s1, s2, s3) {
|
|
3824
3832
|
const { sbox2, T01, T23 } = tableEncoding;
|
|
3825
3833
|
let k = 0;
|
|
3826
3834
|
(s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);
|
|
@@ -3840,7 +3848,7 @@ function encrypt$6(xk, s0, s1, s2, s3) {
|
|
|
3840
3848
|
return { s0: t0, s1: t1, s2: t2, s3: t3 };
|
|
3841
3849
|
}
|
|
3842
3850
|
// Can't be merged with encrypt: arg positions for apply0123 / applySbox are different
|
|
3843
|
-
function decrypt$
|
|
3851
|
+
function decrypt$7(xk, s0, s1, s2, s3) {
|
|
3844
3852
|
const { sbox2, T01, T23 } = tableDecoding;
|
|
3845
3853
|
let k = 0;
|
|
3846
3854
|
(s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);
|
|
@@ -3878,7 +3886,7 @@ function ctrCounter(xk, nonce, src, dst) {
|
|
|
3878
3886
|
const ctr = nonce;
|
|
3879
3887
|
const c32 = u32$1(ctr);
|
|
3880
3888
|
// Fill block (empty, ctr=0)
|
|
3881
|
-
let { s0, s1, s2, s3 } = encrypt$
|
|
3889
|
+
let { s0, s1, s2, s3 } = encrypt$7(xk, c32[0], c32[1], c32[2], c32[3]);
|
|
3882
3890
|
const src32 = u32$1(src);
|
|
3883
3891
|
const dst32 = u32$1(dst);
|
|
3884
3892
|
// process blocks
|
|
@@ -3894,7 +3902,7 @@ function ctrCounter(xk, nonce, src, dst) {
|
|
|
3894
3902
|
ctr[i] = carry & 0xff;
|
|
3895
3903
|
carry >>>= 8;
|
|
3896
3904
|
}
|
|
3897
|
-
({ s0, s1, s2, s3 } = encrypt$
|
|
3905
|
+
({ s0, s1, s2, s3 } = encrypt$7(xk, c32[0], c32[1], c32[2], c32[3]));
|
|
3898
3906
|
}
|
|
3899
3907
|
// leftovers (less than block)
|
|
3900
3908
|
// It's possible to handle > u32 fast, but is it worth it?
|
|
@@ -3924,7 +3932,7 @@ function ctr32(xk, isLE, nonce, src, dst) {
|
|
|
3924
3932
|
const srcLen = src.length;
|
|
3925
3933
|
// Fill block (empty, ctr=0)
|
|
3926
3934
|
let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value
|
|
3927
|
-
let { s0, s1, s2, s3 } = encrypt$
|
|
3935
|
+
let { s0, s1, s2, s3 } = encrypt$7(xk, c32[0], c32[1], c32[2], c32[3]);
|
|
3928
3936
|
// process blocks
|
|
3929
3937
|
for (let i = 0; i + 4 <= src32.length; i += 4) {
|
|
3930
3938
|
dst32[i + 0] = src32[i + 0] ^ s0;
|
|
@@ -3933,7 +3941,7 @@ function ctr32(xk, isLE, nonce, src, dst) {
|
|
|
3933
3941
|
dst32[i + 3] = src32[i + 3] ^ s3;
|
|
3934
3942
|
ctrNum = (ctrNum + 1) >>> 0; // u32 wrap
|
|
3935
3943
|
view.setUint32(ctrPos, ctrNum, isLE);
|
|
3936
|
-
({ s0, s1, s2, s3 } = encrypt$
|
|
3944
|
+
({ s0, s1, s2, s3 } = encrypt$7(xk, c32[0], c32[1], c32[2], c32[3]));
|
|
3937
3945
|
}
|
|
3938
3946
|
// leftovers (less than a block)
|
|
3939
3947
|
const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
|
|
@@ -4004,14 +4012,14 @@ function validatePCKS(data, pcks5) {
|
|
|
4004
4012
|
return data;
|
|
4005
4013
|
const len = data.length;
|
|
4006
4014
|
if (!len)
|
|
4007
|
-
throw new Error(
|
|
4015
|
+
throw new Error('aes/pcks5: empty ciphertext not allowed');
|
|
4008
4016
|
const lastByte = data[len - 1];
|
|
4009
4017
|
if (lastByte <= 0 || lastByte > 16)
|
|
4010
|
-
throw new Error(
|
|
4018
|
+
throw new Error('aes/pcks5: wrong padding');
|
|
4011
4019
|
const out = data.subarray(0, -lastByte);
|
|
4012
4020
|
for (let i = 0; i < lastByte; i++)
|
|
4013
4021
|
if (data[len - i - 1] !== lastByte)
|
|
4014
|
-
throw new Error(
|
|
4022
|
+
throw new Error('aes/pcks5: wrong padding');
|
|
4015
4023
|
return out;
|
|
4016
4024
|
}
|
|
4017
4025
|
function padPCKS(left) {
|
|
@@ -4045,13 +4053,13 @@ const cbc = wrapCipher({ blockSize: 16, nonceLength: 16 }, function cbc(key, iv,
|
|
|
4045
4053
|
let i = 0;
|
|
4046
4054
|
for (; i + 4 <= b.length;) {
|
|
4047
4055
|
(s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3]);
|
|
4048
|
-
({ s0, s1, s2, s3 } = encrypt$
|
|
4056
|
+
({ s0, s1, s2, s3 } = encrypt$7(xk, s0, s1, s2, s3));
|
|
4049
4057
|
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
|
4050
4058
|
}
|
|
4051
4059
|
if (pcks5) {
|
|
4052
4060
|
const tmp32 = padPCKS(plaintext.subarray(i * 4));
|
|
4053
4061
|
(s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3]);
|
|
4054
|
-
({ s0, s1, s2, s3 } = encrypt$
|
|
4062
|
+
({ s0, s1, s2, s3 } = encrypt$7(xk, s0, s1, s2, s3));
|
|
4055
4063
|
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
|
4056
4064
|
}
|
|
4057
4065
|
clean(...toClean);
|
|
@@ -4076,7 +4084,7 @@ const cbc = wrapCipher({ blockSize: 16, nonceLength: 16 }, function cbc(key, iv,
|
|
|
4076
4084
|
// prettier-ignore
|
|
4077
4085
|
const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3;
|
|
4078
4086
|
(s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3]);
|
|
4079
|
-
const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt$
|
|
4087
|
+
const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt$7(xk, s0, s1, s2, s3);
|
|
4080
4088
|
(o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3);
|
|
4081
4089
|
}
|
|
4082
4090
|
clean(...toClean);
|
|
@@ -4109,7 +4117,7 @@ const cfb$1 = wrapCipher({ blockSize: 16, nonceLength: 16 }, function cfb(key, i
|
|
|
4109
4117
|
// prettier-ignore
|
|
4110
4118
|
let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];
|
|
4111
4119
|
for (let i = 0; i + 4 <= src32.length;) {
|
|
4112
|
-
const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt$
|
|
4120
|
+
const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt$7(xk, s0, s1, s2, s3);
|
|
4113
4121
|
dst32[i + 0] = src32[i + 0] ^ e0;
|
|
4114
4122
|
dst32[i + 1] = src32[i + 1] ^ e1;
|
|
4115
4123
|
dst32[i + 2] = src32[i + 2] ^ e2;
|
|
@@ -4119,7 +4127,7 @@ const cfb$1 = wrapCipher({ blockSize: 16, nonceLength: 16 }, function cfb(key, i
|
|
|
4119
4127
|
// leftovers (less than block)
|
|
4120
4128
|
const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
|
|
4121
4129
|
if (start < srcLen) {
|
|
4122
|
-
({ s0, s1, s2, s3 } = encrypt$
|
|
4130
|
+
({ s0, s1, s2, s3 } = encrypt$7(xk, s0, s1, s2, s3));
|
|
4123
4131
|
const buf = u8$1(new Uint32Array([s0, s1, s2, s3]));
|
|
4124
4132
|
for (let i = start, pos = 0; i < srcLen; i++, pos++)
|
|
4125
4133
|
dst[i] = src[i] ^ buf[pos];
|
|
@@ -4152,17 +4160,21 @@ function computeTag(fn, isLE, key, data, AAD) {
|
|
|
4152
4160
|
}
|
|
4153
4161
|
/**
|
|
4154
4162
|
* GCM: Galois/Counter Mode.
|
|
4155
|
-
*
|
|
4163
|
+
* Modern, parallel version of CTR, with MAC.
|
|
4156
4164
|
* Be careful: MACs can be forged.
|
|
4165
|
+
* Unsafe to use random nonces under the same key, due to collision chance.
|
|
4166
|
+
* As for nonce size, prefer 12-byte, instead of 8-byte.
|
|
4157
4167
|
*/
|
|
4158
4168
|
const gcm = wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16 }, function gcm(key, nonce, AAD) {
|
|
4159
4169
|
bytes(key);
|
|
4160
4170
|
bytes(nonce);
|
|
4161
4171
|
if (AAD !== undefined)
|
|
4162
4172
|
bytes(AAD);
|
|
4163
|
-
//
|
|
4164
|
-
|
|
4165
|
-
|
|
4173
|
+
// NIST 800-38d doesn't enforce minimum nonce length.
|
|
4174
|
+
// We enforce 8 bytes for compat with openssl.
|
|
4175
|
+
// 12 bytes are recommended. More than 12 bytes would be converted into 12.
|
|
4176
|
+
if (nonce.length < 8)
|
|
4177
|
+
throw new Error('aes/gcm: invalid nonce length');
|
|
4166
4178
|
const tagLength = 16;
|
|
4167
4179
|
function _computeTag(authKey, tagMask, data) {
|
|
4168
4180
|
const tag = computeTag(ghash, false, authKey, data, AAD);
|
|
@@ -4175,12 +4187,11 @@ const gcm = wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16 }, functi
|
|
|
4175
4187
|
const authKey = EMPTY_BLOCK.slice();
|
|
4176
4188
|
const counter = EMPTY_BLOCK.slice();
|
|
4177
4189
|
ctr32(xk, false, counter, counter, authKey);
|
|
4190
|
+
// NIST 800-38d, page 15: different behavior for 96-bit and non-96-bit nonces
|
|
4178
4191
|
if (nonce.length === 12) {
|
|
4179
4192
|
counter.set(nonce);
|
|
4180
4193
|
}
|
|
4181
4194
|
else {
|
|
4182
|
-
// Spec (NIST 800-38d) supports variable size nonce.
|
|
4183
|
-
// Not supported for now, but can be useful.
|
|
4184
4195
|
const nonceLen = EMPTY_BLOCK.slice();
|
|
4185
4196
|
const view = createView(nonceLen);
|
|
4186
4197
|
setBigUint64(view, 8, BigInt(nonce.length * 8), false);
|
|
@@ -4237,7 +4248,7 @@ function encryptBlock(xk, block) {
|
|
|
4237
4248
|
if (!isBytes32(xk))
|
|
4238
4249
|
throw new Error('_encryptBlock accepts result of expandKeyLE');
|
|
4239
4250
|
const b32 = u32$1(block);
|
|
4240
|
-
let { s0, s1, s2, s3 } = encrypt$
|
|
4251
|
+
let { s0, s1, s2, s3 } = encrypt$7(xk, b32[0], b32[1], b32[2], b32[3]);
|
|
4241
4252
|
(b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);
|
|
4242
4253
|
return block;
|
|
4243
4254
|
}
|
|
@@ -4246,7 +4257,7 @@ function decryptBlock(xk, block) {
|
|
|
4246
4257
|
if (!isBytes32(xk))
|
|
4247
4258
|
throw new Error('_decryptBlock accepts result of expandKeyLE');
|
|
4248
4259
|
const b32 = u32$1(block);
|
|
4249
|
-
let { s0, s1, s2, s3 } = decrypt$
|
|
4260
|
+
let { s0, s1, s2, s3 } = decrypt$7(xk, b32[0], b32[1], b32[2], b32[3]);
|
|
4250
4261
|
(b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);
|
|
4251
4262
|
return block;
|
|
4252
4263
|
}
|
|
@@ -4287,7 +4298,7 @@ const AESW = {
|
|
|
4287
4298
|
let a0 = o32[0], a1 = o32[1]; // A
|
|
4288
4299
|
for (let j = 0, ctr = 1; j < 6; j++) {
|
|
4289
4300
|
for (let pos = 2; pos < o32.length; pos += 2, ctr++) {
|
|
4290
|
-
const { s0, s1, s2, s3 } = encrypt$
|
|
4301
|
+
const { s0, s1, s2, s3 } = encrypt$7(xk, a0, a1, o32[pos], o32[pos + 1]);
|
|
4291
4302
|
// A = MSB(64, B) ^ t where t = (n*j)+i
|
|
4292
4303
|
(a0 = s0), (a1 = s1 ^ byteSwap(ctr)), (o32[pos] = s2), (o32[pos + 1] = s3);
|
|
4293
4304
|
}
|
|
@@ -4310,7 +4321,7 @@ const AESW = {
|
|
|
4310
4321
|
for (let j = 0, ctr = chunks * 6; j < 6; j++) {
|
|
4311
4322
|
for (let pos = chunks * 2; pos >= 1; pos -= 2, ctr--) {
|
|
4312
4323
|
a1 ^= byteSwap(ctr);
|
|
4313
|
-
const { s0, s1, s2, s3 } = decrypt$
|
|
4324
|
+
const { s0, s1, s2, s3 } = decrypt$7(xk, a0, a1, o32[pos], o32[pos + 1]);
|
|
4314
4325
|
(a0 = s0), (a1 = s1), (o32[pos] = s2), (o32[pos + 1] = s3);
|
|
4315
4326
|
}
|
|
4316
4327
|
}
|
|
@@ -4331,7 +4342,7 @@ const aeskw = wrapCipher({ blockSize: 8 }, (kek) => ({
|
|
|
4331
4342
|
encrypt(plaintext) {
|
|
4332
4343
|
bytes(plaintext);
|
|
4333
4344
|
if (!plaintext.length || plaintext.length % 8 !== 0)
|
|
4334
|
-
throw new Error('plaintext length
|
|
4345
|
+
throw new Error('invalid plaintext length');
|
|
4335
4346
|
if (plaintext.length === 8)
|
|
4336
4347
|
throw new Error('8-byte keys not allowed in AESKW, use AESKWP instead');
|
|
4337
4348
|
const out = concatBytes$1(AESKW_IV, plaintext);
|
|
@@ -4340,10 +4351,11 @@ const aeskw = wrapCipher({ blockSize: 8 }, (kek) => ({
|
|
|
4340
4351
|
},
|
|
4341
4352
|
decrypt(ciphertext) {
|
|
4342
4353
|
bytes(ciphertext);
|
|
4354
|
+
// ciphertext must be at least 24 bytes and a multiple of 8 bytes
|
|
4343
4355
|
// 24 because should have at least two block (1 iv + 2).
|
|
4344
4356
|
// Replace with 16 to enable '8-byte keys'
|
|
4345
4357
|
if (ciphertext.length % 8 !== 0 || ciphertext.length < 3 * 8)
|
|
4346
|
-
throw new Error('ciphertext
|
|
4358
|
+
throw new Error('invalid ciphertext length');
|
|
4347
4359
|
const out = copyBytes(ciphertext);
|
|
4348
4360
|
AESW.decrypt(kek, out);
|
|
4349
4361
|
if (!equalBytes$1(out.subarray(0, 8), AESKW_IV))
|
|
@@ -4356,8 +4368,8 @@ const aeskw = wrapCipher({ blockSize: 8 }, (kek) => ({
|
|
|
4356
4368
|
const unsafe = {
|
|
4357
4369
|
expandKeyLE,
|
|
4358
4370
|
expandKeyDecLE,
|
|
4359
|
-
encrypt: encrypt$
|
|
4360
|
-
decrypt: decrypt$
|
|
4371
|
+
encrypt: encrypt$7,
|
|
4372
|
+
decrypt: decrypt$7,
|
|
4361
4373
|
encryptBlock,
|
|
4362
4374
|
decryptBlock,
|
|
4363
4375
|
ctrCounter,
|
|
@@ -4391,7 +4403,7 @@ const nodeAlgos = {
|
|
|
4391
4403
|
* @param {Object} config - full configuration, defaults to openpgp.config
|
|
4392
4404
|
* @returns MaybeStream<Uint8Array>
|
|
4393
4405
|
*/
|
|
4394
|
-
async function encrypt$
|
|
4406
|
+
async function encrypt$6(algo, key, plaintext, iv, config) {
|
|
4395
4407
|
const algoName = enums.read(enums.symmetric, algo);
|
|
4396
4408
|
if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
|
|
4397
4409
|
return nodeEncrypt$1(algo, key, plaintext, iv);
|
|
@@ -4434,7 +4446,7 @@ async function encrypt$5(algo, key, plaintext, iv, config) {
|
|
|
4434
4446
|
* @param {Uint8Array} iv
|
|
4435
4447
|
* @returns MaybeStream<Uint8Array>
|
|
4436
4448
|
*/
|
|
4437
|
-
async function decrypt$
|
|
4449
|
+
async function decrypt$6(algo, key, ciphertext, iv) {
|
|
4438
4450
|
const algoName = enums.read(enums.symmetric, algo);
|
|
4439
4451
|
if (nodeCrypto$a && nodeAlgos[algoName]) { // Node crypto library.
|
|
4440
4452
|
return nodeDecrypt$1(algo, key, ciphertext, iv);
|
|
@@ -4709,8 +4721,8 @@ function nodeDecrypt$1(algo, key, ct, iv) {
|
|
|
4709
4721
|
|
|
4710
4722
|
var cfb = /*#__PURE__*/Object.freeze({
|
|
4711
4723
|
__proto__: null,
|
|
4712
|
-
decrypt: decrypt$
|
|
4713
|
-
encrypt: encrypt$
|
|
4724
|
+
decrypt: decrypt$6,
|
|
4725
|
+
encrypt: encrypt$6
|
|
4714
4726
|
});
|
|
4715
4727
|
|
|
4716
4728
|
/**
|
|
@@ -5617,16 +5629,13 @@ const nodeCrypto$6 = util.getNodeCrypto();
|
|
|
5617
5629
|
* @returns {Uint8Array} Random byte array.
|
|
5618
5630
|
*/
|
|
5619
5631
|
function getRandomBytes(length) {
|
|
5620
|
-
const
|
|
5621
|
-
if (
|
|
5622
|
-
const
|
|
5623
|
-
|
|
5624
|
-
} else if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
5625
|
-
crypto.getRandomValues(buf);
|
|
5632
|
+
const webcrypto = typeof crypto !== 'undefined' ? crypto : nodeCrypto$6?.webcrypto;
|
|
5633
|
+
if (webcrypto?.getRandomValues) {
|
|
5634
|
+
const buf = new Uint8Array(length);
|
|
5635
|
+
return webcrypto.getRandomValues(buf);
|
|
5626
5636
|
} else {
|
|
5627
5637
|
throw new Error('No secure random number generator available.');
|
|
5628
5638
|
}
|
|
5629
|
-
return buf;
|
|
5630
5639
|
}
|
|
5631
5640
|
|
|
5632
5641
|
/**
|
|
@@ -6091,7 +6100,15 @@ const _1n$3 = BigInt(1);
|
|
|
6091
6100
|
* @returns {Promise<Uint8Array>} RSA Signature.
|
|
6092
6101
|
* @async
|
|
6093
6102
|
*/
|
|
6094
|
-
async function sign$
|
|
6103
|
+
async function sign$a(hashAlgo, data, n, e, d, p, q, u, hashed) {
|
|
6104
|
+
if (hash.getHashByteLength(hashAlgo) >= n.length) {
|
|
6105
|
+
// Throw here instead of `emsaEncode` below, to provide a clearer and consistent error
|
|
6106
|
+
// e.g. if a 512-bit RSA key is used with a SHA-512 digest.
|
|
6107
|
+
// The size limit is actually slightly different but here we only care about throwing
|
|
6108
|
+
// on common key sizes.
|
|
6109
|
+
throw new Error('Digest size cannot exceed key modulus size');
|
|
6110
|
+
}
|
|
6111
|
+
|
|
6095
6112
|
if (data && !util.isStream(data)) {
|
|
6096
6113
|
if (util.getWebCrypto()) {
|
|
6097
6114
|
try {
|
|
@@ -6117,7 +6134,7 @@ async function sign$7(hashAlgo, data, n, e, d, p, q, u, hashed) {
|
|
|
6117
6134
|
* @returns {Boolean}
|
|
6118
6135
|
* @async
|
|
6119
6136
|
*/
|
|
6120
|
-
async function verify$
|
|
6137
|
+
async function verify$b(hashAlgo, data, s, n, e, hashed) {
|
|
6121
6138
|
if (data && !util.isStream(data)) {
|
|
6122
6139
|
if (util.getWebCrypto()) {
|
|
6123
6140
|
try {
|
|
@@ -6140,7 +6157,7 @@ async function verify$8(hashAlgo, data, s, n, e, hashed) {
|
|
|
6140
6157
|
* @returns {Promise<Uint8Array>} RSA Ciphertext.
|
|
6141
6158
|
* @async
|
|
6142
6159
|
*/
|
|
6143
|
-
async function encrypt$
|
|
6160
|
+
async function encrypt$5(data, n, e) {
|
|
6144
6161
|
if (util.getNodeCrypto()) {
|
|
6145
6162
|
return nodeEncrypt(data, n, e);
|
|
6146
6163
|
}
|
|
@@ -6162,7 +6179,7 @@ async function encrypt$4(data, n, e) {
|
|
|
6162
6179
|
* @throws {Error} on decryption error, unless `randomPayload` is given
|
|
6163
6180
|
* @async
|
|
6164
6181
|
*/
|
|
6165
|
-
async function decrypt$
|
|
6182
|
+
async function decrypt$5(data, n, e, d, p, q, u, randomPayload) {
|
|
6166
6183
|
// Node v18.19.1, 20.11.1 and 21.6.2 have disabled support for PKCS#1 decryption,
|
|
6167
6184
|
// and we want to avoid checking the error type to decide if the random payload
|
|
6168
6185
|
// should indeed be returned.
|
|
@@ -6189,7 +6206,7 @@ async function decrypt$4(data, n, e, d, p, q, u, randomPayload) {
|
|
|
6189
6206
|
* RSA private prime p, RSA private prime q, u = p ** -1 mod q
|
|
6190
6207
|
* @async
|
|
6191
6208
|
*/
|
|
6192
|
-
async function generate$
|
|
6209
|
+
async function generate$b(bits, e) {
|
|
6193
6210
|
e = BigInt(e);
|
|
6194
6211
|
|
|
6195
6212
|
// Native RSA keygen using Web Crypto
|
|
@@ -6269,7 +6286,7 @@ async function generate$5(bits, e) {
|
|
|
6269
6286
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
6270
6287
|
* @async
|
|
6271
6288
|
*/
|
|
6272
|
-
async function validateParams$
|
|
6289
|
+
async function validateParams$e(n, e, d, p, q, u) {
|
|
6273
6290
|
n = uint8ArrayToBigInt(n);
|
|
6274
6291
|
p = uint8ArrayToBigInt(p);
|
|
6275
6292
|
q = uint8ArrayToBigInt(q);
|
|
@@ -6311,9 +6328,6 @@ async function bnSign(hashAlgo, n, d, hashed) {
|
|
|
6311
6328
|
n = uint8ArrayToBigInt(n);
|
|
6312
6329
|
const m = uint8ArrayToBigInt(emsaEncode(hashAlgo, hashed, byteLength(n)));
|
|
6313
6330
|
d = uint8ArrayToBigInt(d);
|
|
6314
|
-
if (m >= n) {
|
|
6315
|
-
throw new Error('Message size cannot exceed modulus size');
|
|
6316
|
-
}
|
|
6317
6331
|
return bigIntToUint8Array(modExp(m, d, n), 'be', byteLength(n));
|
|
6318
6332
|
}
|
|
6319
6333
|
|
|
@@ -6502,12 +6516,12 @@ function jwkToPrivate(jwk, e) {
|
|
|
6502
6516
|
|
|
6503
6517
|
var rsa = /*#__PURE__*/Object.freeze({
|
|
6504
6518
|
__proto__: null,
|
|
6505
|
-
decrypt: decrypt$
|
|
6506
|
-
encrypt: encrypt$
|
|
6507
|
-
generate: generate$
|
|
6508
|
-
sign: sign$
|
|
6509
|
-
validateParams: validateParams$
|
|
6510
|
-
verify: verify$
|
|
6519
|
+
decrypt: decrypt$5,
|
|
6520
|
+
encrypt: encrypt$5,
|
|
6521
|
+
generate: generate$b,
|
|
6522
|
+
sign: sign$a,
|
|
6523
|
+
validateParams: validateParams$e,
|
|
6524
|
+
verify: verify$b
|
|
6511
6525
|
});
|
|
6512
6526
|
|
|
6513
6527
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
@@ -6540,7 +6554,7 @@ const _1n$2 = BigInt(1);
|
|
|
6540
6554
|
* @returns {Promise<{ c1: Uint8Array, c2: Uint8Array }>}
|
|
6541
6555
|
* @async
|
|
6542
6556
|
*/
|
|
6543
|
-
async function encrypt$
|
|
6557
|
+
async function encrypt$4(data, p, g, y) {
|
|
6544
6558
|
p = uint8ArrayToBigInt(p);
|
|
6545
6559
|
g = uint8ArrayToBigInt(g);
|
|
6546
6560
|
y = uint8ArrayToBigInt(y);
|
|
@@ -6569,7 +6583,7 @@ async function encrypt$3(data, p, g, y) {
|
|
|
6569
6583
|
* @throws {Error} on decryption error, unless `randomPayload` is given
|
|
6570
6584
|
* @async
|
|
6571
6585
|
*/
|
|
6572
|
-
async function decrypt$
|
|
6586
|
+
async function decrypt$4(c1, c2, p, x, randomPayload) {
|
|
6573
6587
|
c1 = uint8ArrayToBigInt(c1);
|
|
6574
6588
|
c2 = uint8ArrayToBigInt(c2);
|
|
6575
6589
|
p = uint8ArrayToBigInt(p);
|
|
@@ -6588,7 +6602,7 @@ async function decrypt$3(c1, c2, p, x, randomPayload) {
|
|
|
6588
6602
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
6589
6603
|
* @async
|
|
6590
6604
|
*/
|
|
6591
|
-
async function validateParams$
|
|
6605
|
+
async function validateParams$d(p, g, y, x) {
|
|
6592
6606
|
p = uint8ArrayToBigInt(p);
|
|
6593
6607
|
g = uint8ArrayToBigInt(g);
|
|
6594
6608
|
y = uint8ArrayToBigInt(y);
|
|
@@ -6649,9 +6663,9 @@ async function validateParams$7(p, g, y, x) {
|
|
|
6649
6663
|
|
|
6650
6664
|
var elgamal = /*#__PURE__*/Object.freeze({
|
|
6651
6665
|
__proto__: null,
|
|
6652
|
-
decrypt: decrypt$
|
|
6653
|
-
encrypt: encrypt$
|
|
6654
|
-
validateParams: validateParams$
|
|
6666
|
+
decrypt: decrypt$4,
|
|
6667
|
+
encrypt: encrypt$4,
|
|
6668
|
+
validateParams: validateParams$d
|
|
6655
6669
|
});
|
|
6656
6670
|
|
|
6657
6671
|
// declare const globalThis: Record<string, any> | undefined;
|
|
@@ -9132,7 +9146,7 @@ function finishVerification(publicKey, r, SB, hashed) {
|
|
|
9132
9146
|
const RkA = ExtendedPoint.fromAffine(r).add(kA);
|
|
9133
9147
|
return RkA.subtract(SB).multiplyUnsafe(CURVE.h).equals(ExtendedPoint.ZERO);
|
|
9134
9148
|
}
|
|
9135
|
-
async function verify$
|
|
9149
|
+
async function verify$a(sig, message, publicKey) {
|
|
9136
9150
|
const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey);
|
|
9137
9151
|
const hashed = await utils.sha512(r.toRawBytes(), pub.toRawBytes(), msg);
|
|
9138
9152
|
return finishVerification(pub, r, SB, hashed);
|
|
@@ -9231,7 +9245,7 @@ Object.defineProperties(utils, {
|
|
|
9231
9245
|
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
9232
9246
|
* @returns {Promise<{ A: Uint8Array, seed: Uint8Array }>}
|
|
9233
9247
|
*/
|
|
9234
|
-
async function generate$
|
|
9248
|
+
async function generate$a(algo) {
|
|
9235
9249
|
switch (algo) {
|
|
9236
9250
|
case enums.publicKey.ed25519:
|
|
9237
9251
|
try {
|
|
@@ -9278,8 +9292,11 @@ async function generate$4(algo) {
|
|
|
9278
9292
|
* }>} Signature of the message
|
|
9279
9293
|
* @async
|
|
9280
9294
|
*/
|
|
9281
|
-
async function sign$
|
|
9295
|
+
async function sign$9(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
9282
9296
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo$2(algo))) {
|
|
9297
|
+
// Enforce digest sizes:
|
|
9298
|
+
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
|
9299
|
+
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
|
9283
9300
|
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
9284
9301
|
}
|
|
9285
9302
|
switch (algo) {
|
|
@@ -9325,8 +9342,11 @@ async function sign$6(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
9325
9342
|
* @returns {Boolean}
|
|
9326
9343
|
* @async
|
|
9327
9344
|
*/
|
|
9328
|
-
async function verify$
|
|
9345
|
+
async function verify$9(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
|
9329
9346
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo$2(algo))) {
|
|
9347
|
+
// Enforce digest sizes:
|
|
9348
|
+
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
|
9349
|
+
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
|
9330
9350
|
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
9331
9351
|
}
|
|
9332
9352
|
switch (algo) {
|
|
@@ -9341,7 +9361,7 @@ async function verify$6(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
|
|
9341
9361
|
if (err.name !== 'NotSupportedError') {
|
|
9342
9362
|
throw err;
|
|
9343
9363
|
}
|
|
9344
|
-
return verify$
|
|
9364
|
+
return verify$a(RS, hashed, publicKey);
|
|
9345
9365
|
}
|
|
9346
9366
|
|
|
9347
9367
|
case enums.publicKey.ed448: {
|
|
@@ -9361,7 +9381,7 @@ async function verify$6(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
|
|
9361
9381
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
9362
9382
|
* @async
|
|
9363
9383
|
*/
|
|
9364
|
-
async function validateParams$
|
|
9384
|
+
async function validateParams$c(algo, A, seed) {
|
|
9365
9385
|
switch (algo) {
|
|
9366
9386
|
case enums.publicKey.ed25519: {
|
|
9367
9387
|
/**
|
|
@@ -9438,12 +9458,12 @@ const privateKeyToJWK = (algo, publicKey, privateKey) => {
|
|
|
9438
9458
|
|
|
9439
9459
|
var eddsa = /*#__PURE__*/Object.freeze({
|
|
9440
9460
|
__proto__: null,
|
|
9441
|
-
generate: generate$
|
|
9461
|
+
generate: generate$a,
|
|
9442
9462
|
getPayloadSize: getPayloadSize$1,
|
|
9443
9463
|
getPreferredHashAlgo: getPreferredHashAlgo$2,
|
|
9444
|
-
sign: sign$
|
|
9445
|
-
validateParams: validateParams$
|
|
9446
|
-
verify: verify$
|
|
9464
|
+
sign: sign$9,
|
|
9465
|
+
validateParams: validateParams$c,
|
|
9466
|
+
verify: verify$9
|
|
9447
9467
|
});
|
|
9448
9468
|
|
|
9449
9469
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
@@ -9574,7 +9594,7 @@ const HKDF_INFO = {
|
|
|
9574
9594
|
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
9575
9595
|
* @returns {Promise<{ A: Uint8Array, k: Uint8Array }>}
|
|
9576
9596
|
*/
|
|
9577
|
-
async function generate$
|
|
9597
|
+
async function generate$9(algo) {
|
|
9578
9598
|
switch (algo) {
|
|
9579
9599
|
case enums.publicKey.x25519: {
|
|
9580
9600
|
// k stays in little-endian, unlike legacy ECDH over curve25519
|
|
@@ -9602,7 +9622,7 @@ async function generate$3(algo) {
|
|
|
9602
9622
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
9603
9623
|
* @async
|
|
9604
9624
|
*/
|
|
9605
|
-
async function validateParams$
|
|
9625
|
+
async function validateParams$b(algo, A, k) {
|
|
9606
9626
|
switch (algo) {
|
|
9607
9627
|
case enums.publicKey.x25519: {
|
|
9608
9628
|
/**
|
|
@@ -9639,7 +9659,7 @@ async function validateParams$5(algo, A, k) {
|
|
|
9639
9659
|
* }>} ephemeral public key (K_A) and encrypted key
|
|
9640
9660
|
* @async
|
|
9641
9661
|
*/
|
|
9642
|
-
async function encrypt$
|
|
9662
|
+
async function encrypt$3(algo, data, recipientA) {
|
|
9643
9663
|
const { ephemeralPublicKey, sharedSecret } = await generateEphemeralEncryptionMaterial(algo, recipientA);
|
|
9644
9664
|
const hkdfInput = util.concatUint8Array([
|
|
9645
9665
|
ephemeralPublicKey,
|
|
@@ -9678,7 +9698,7 @@ async function encrypt$2(algo, data, recipientA) {
|
|
|
9678
9698
|
* @returns {Promise<Uint8Array>} decrypted session key data
|
|
9679
9699
|
* @async
|
|
9680
9700
|
*/
|
|
9681
|
-
async function decrypt$
|
|
9701
|
+
async function decrypt$3(algo, ephemeralPublicKey, wrappedKey, A, k) {
|
|
9682
9702
|
const sharedSecret = await recomputeSharedSecret(algo, ephemeralPublicKey, A, k);
|
|
9683
9703
|
const hkdfInput = util.concatUint8Array([
|
|
9684
9704
|
ephemeralPublicKey,
|
|
@@ -9726,14 +9746,15 @@ async function generateEphemeralEncryptionMaterial(algo, recipientA) {
|
|
|
9726
9746
|
case enums.publicKey.x25519: {
|
|
9727
9747
|
const ephemeralSecretKey = getRandomBytes(getPayloadSize(algo));
|
|
9728
9748
|
const sharedSecret = nacl.scalarMult(ephemeralSecretKey, recipientA);
|
|
9749
|
+
assertNonZeroArray(sharedSecret);
|
|
9729
9750
|
const { publicKey: ephemeralPublicKey } = nacl.box.keyPair.fromSecretKey(ephemeralSecretKey);
|
|
9730
|
-
|
|
9731
9751
|
return { ephemeralPublicKey, sharedSecret };
|
|
9732
9752
|
}
|
|
9733
9753
|
case enums.publicKey.x448: {
|
|
9734
9754
|
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
|
9735
9755
|
const ephemeralSecretKey = x448.utils.randomPrivateKey();
|
|
9736
9756
|
const sharedSecret = x448.getSharedSecret(ephemeralSecretKey, recipientA);
|
|
9757
|
+
assertNonZeroArray(sharedSecret);
|
|
9737
9758
|
const ephemeralPublicKey = x448.getPublicKey(ephemeralSecretKey);
|
|
9738
9759
|
return { ephemeralPublicKey, sharedSecret };
|
|
9739
9760
|
}
|
|
@@ -9744,11 +9765,15 @@ async function generateEphemeralEncryptionMaterial(algo, recipientA) {
|
|
|
9744
9765
|
|
|
9745
9766
|
async function recomputeSharedSecret(algo, ephemeralPublicKey, A, k) {
|
|
9746
9767
|
switch (algo) {
|
|
9747
|
-
case enums.publicKey.x25519:
|
|
9748
|
-
|
|
9768
|
+
case enums.publicKey.x25519: {
|
|
9769
|
+
const sharedSecret = nacl.scalarMult(k, ephemeralPublicKey);
|
|
9770
|
+
assertNonZeroArray(sharedSecret);
|
|
9771
|
+
return sharedSecret;
|
|
9772
|
+
}
|
|
9749
9773
|
case enums.publicKey.x448: {
|
|
9750
9774
|
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
|
9751
9775
|
const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey);
|
|
9776
|
+
assertNonZeroArray(sharedSecret);
|
|
9752
9777
|
return sharedSecret;
|
|
9753
9778
|
}
|
|
9754
9779
|
default:
|
|
@@ -9756,15 +9781,31 @@ async function recomputeSharedSecret(algo, ephemeralPublicKey, A, k) {
|
|
|
9756
9781
|
}
|
|
9757
9782
|
}
|
|
9758
9783
|
|
|
9784
|
+
/**
|
|
9785
|
+
* x25519 and x448 produce an all-zero value when given as input a point with small order.
|
|
9786
|
+
* This does not lead to a security issue in the context of ECDH, but it is still unexpected,
|
|
9787
|
+
* hence we throw.
|
|
9788
|
+
* @param {Uint8Array} sharedSecret
|
|
9789
|
+
*/
|
|
9790
|
+
function assertNonZeroArray(sharedSecret) {
|
|
9791
|
+
let acc = 0;
|
|
9792
|
+
for (let i = 0; i < sharedSecret.length; i++) {
|
|
9793
|
+
acc |= sharedSecret[i];
|
|
9794
|
+
}
|
|
9795
|
+
if (acc === 0) {
|
|
9796
|
+
throw new Error('Unexpected low order point');
|
|
9797
|
+
}
|
|
9798
|
+
}
|
|
9799
|
+
|
|
9759
9800
|
var ecdh_x = /*#__PURE__*/Object.freeze({
|
|
9760
9801
|
__proto__: null,
|
|
9761
|
-
decrypt: decrypt$
|
|
9762
|
-
encrypt: encrypt$
|
|
9763
|
-
generate: generate$
|
|
9802
|
+
decrypt: decrypt$3,
|
|
9803
|
+
encrypt: encrypt$3,
|
|
9804
|
+
generate: generate$9,
|
|
9764
9805
|
generateEphemeralEncryptionMaterial: generateEphemeralEncryptionMaterial,
|
|
9765
9806
|
getPayloadSize: getPayloadSize,
|
|
9766
9807
|
recomputeSharedSecret: recomputeSharedSecret,
|
|
9767
|
-
validateParams: validateParams$
|
|
9808
|
+
validateParams: validateParams$b
|
|
9768
9809
|
});
|
|
9769
9810
|
|
|
9770
9811
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
@@ -9940,7 +9981,7 @@ class CurveWithOID {
|
|
|
9940
9981
|
return nodeGenKeyPair(this.name);
|
|
9941
9982
|
case 'curve25519Legacy': {
|
|
9942
9983
|
// the private key must be stored in big endian and already clamped: https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-13.html#section-5.5.5.6.1.1-3
|
|
9943
|
-
const { k, A } = await generate$
|
|
9984
|
+
const { k, A } = await generate$9(enums.publicKey.x25519);
|
|
9944
9985
|
const privateKey = k.slice().reverse();
|
|
9945
9986
|
privateKey[0] = (privateKey[0] & 127) | 64;
|
|
9946
9987
|
privateKey[31] &= 248;
|
|
@@ -9948,7 +9989,7 @@ class CurveWithOID {
|
|
|
9948
9989
|
return { publicKey, privateKey };
|
|
9949
9990
|
}
|
|
9950
9991
|
case 'ed25519Legacy': {
|
|
9951
|
-
const { seed: privateKey, A } = await generate$
|
|
9992
|
+
const { seed: privateKey, A } = await generate$a(enums.publicKey.ed25519);
|
|
9952
9993
|
const publicKey = util.concatUint8Array([new Uint8Array([this.wireFormatLeadingByte]), A]);
|
|
9953
9994
|
return { publicKey, privateKey };
|
|
9954
9995
|
}
|
|
@@ -9958,7 +9999,7 @@ class CurveWithOID {
|
|
|
9958
9999
|
}
|
|
9959
10000
|
}
|
|
9960
10001
|
|
|
9961
|
-
async function generate$
|
|
10002
|
+
async function generate$8(curveName) {
|
|
9962
10003
|
const curve = new CurveWithOID(curveName);
|
|
9963
10004
|
const { oid, hash, cipher } = curve;
|
|
9964
10005
|
const keyPair = await curve.genKeyPair();
|
|
@@ -10176,7 +10217,7 @@ const nodeCrypto$2 = util.getNodeCrypto();
|
|
|
10176
10217
|
* }>} Signature of the message
|
|
10177
10218
|
* @async
|
|
10178
10219
|
*/
|
|
10179
|
-
async function sign$
|
|
10220
|
+
async function sign$8(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
10180
10221
|
const curve = new CurveWithOID(oid);
|
|
10181
10222
|
checkPublicPointEnconding(curve, publicKey);
|
|
10182
10223
|
if (message && !util.isStream(message)) {
|
|
@@ -10223,7 +10264,7 @@ async function sign$5(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
10223
10264
|
* @returns {Boolean}
|
|
10224
10265
|
* @async
|
|
10225
10266
|
*/
|
|
10226
|
-
async function verify$
|
|
10267
|
+
async function verify$8(oid, hashAlgo, signature, message, publicKey, hashed) {
|
|
10227
10268
|
const curve = new CurveWithOID(oid);
|
|
10228
10269
|
checkPublicPointEnconding(curve, publicKey);
|
|
10229
10270
|
// See https://github.com/openpgpjs/openpgpjs/pull/948.
|
|
@@ -10274,7 +10315,7 @@ async function verify$5(oid, hashAlgo, signature, message, publicKey, hashed) {
|
|
|
10274
10315
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
10275
10316
|
* @async
|
|
10276
10317
|
*/
|
|
10277
|
-
async function validateParams$
|
|
10318
|
+
async function validateParams$a(oid, Q, d) {
|
|
10278
10319
|
const curve = new CurveWithOID(oid);
|
|
10279
10320
|
// Reject curves x25519 and ed25519
|
|
10280
10321
|
if (curve.keyType !== enums.publicKey.ecdsa) {
|
|
@@ -10290,9 +10331,9 @@ async function validateParams$4(oid, Q, d) {
|
|
|
10290
10331
|
const hashAlgo = enums.hash.sha256;
|
|
10291
10332
|
const hashed = await hash.digest(hashAlgo, message);
|
|
10292
10333
|
try {
|
|
10293
|
-
const signature = await sign$
|
|
10334
|
+
const signature = await sign$8(oid, hashAlgo, message, Q, d, hashed);
|
|
10294
10335
|
// eslint-disable-next-line @typescript-eslint/return-await
|
|
10295
|
-
return await verify$
|
|
10336
|
+
return await verify$8(oid, hashAlgo, signature, message, Q, hashed);
|
|
10296
10337
|
} catch (err) {
|
|
10297
10338
|
return false;
|
|
10298
10339
|
}
|
|
@@ -10423,9 +10464,9 @@ async function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) {
|
|
|
10423
10464
|
|
|
10424
10465
|
var ecdsa = /*#__PURE__*/Object.freeze({
|
|
10425
10466
|
__proto__: null,
|
|
10426
|
-
sign: sign$
|
|
10427
|
-
validateParams: validateParams$
|
|
10428
|
-
verify: verify$
|
|
10467
|
+
sign: sign$8,
|
|
10468
|
+
validateParams: validateParams$a,
|
|
10469
|
+
verify: verify$8
|
|
10429
10470
|
});
|
|
10430
10471
|
|
|
10431
10472
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
@@ -10460,14 +10501,16 @@ var ecdsa = /*#__PURE__*/Object.freeze({
|
|
|
10460
10501
|
* }>} Signature of the message
|
|
10461
10502
|
* @async
|
|
10462
10503
|
*/
|
|
10463
|
-
async function sign$
|
|
10504
|
+
async function sign$7(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
10464
10505
|
const curve = new CurveWithOID(oid);
|
|
10465
10506
|
checkPublicPointEnconding(curve, publicKey);
|
|
10466
10507
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
|
10508
|
+
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
|
10467
10509
|
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
10510
|
+
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
|
10468
10511
|
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
10469
10512
|
}
|
|
10470
|
-
const { RS: signature } = await sign$
|
|
10513
|
+
const { RS: signature } = await sign$9(enums.publicKey.ed25519, hashAlgo, message, publicKey.subarray(1), privateKey, hashed);
|
|
10471
10514
|
// EdDSA signature params are returned in little-endian format
|
|
10472
10515
|
return {
|
|
10473
10516
|
r: signature.subarray(0, 32),
|
|
@@ -10487,14 +10530,17 @@ async function sign$4(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
10487
10530
|
* @returns {Boolean}
|
|
10488
10531
|
* @async
|
|
10489
10532
|
*/
|
|
10490
|
-
async function verify$
|
|
10533
|
+
async function verify$7(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
|
10491
10534
|
const curve = new CurveWithOID(oid);
|
|
10492
10535
|
checkPublicPointEnconding(curve, publicKey);
|
|
10493
10536
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
|
10537
|
+
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
|
10538
|
+
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
10539
|
+
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
|
10494
10540
|
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
10495
10541
|
}
|
|
10496
10542
|
const RS = util.concatUint8Array([r, s]);
|
|
10497
|
-
return verify$
|
|
10543
|
+
return verify$9(enums.publicKey.ed25519, hashAlgo, { RS }, m, publicKey.subarray(1), hashed);
|
|
10498
10544
|
}
|
|
10499
10545
|
/**
|
|
10500
10546
|
* Validate legacy EdDSA parameters
|
|
@@ -10504,7 +10550,7 @@ async function verify$4(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
|
|
10504
10550
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
10505
10551
|
* @async
|
|
10506
10552
|
*/
|
|
10507
|
-
async function validateParams$
|
|
10553
|
+
async function validateParams$9(oid, Q, k) {
|
|
10508
10554
|
// Check whether the given curve is supported
|
|
10509
10555
|
if (oid.getName() !== enums.curve.ed25519Legacy) {
|
|
10510
10556
|
return false;
|
|
@@ -10522,9 +10568,9 @@ async function validateParams$3(oid, Q, k) {
|
|
|
10522
10568
|
|
|
10523
10569
|
var eddsa_legacy = /*#__PURE__*/Object.freeze({
|
|
10524
10570
|
__proto__: null,
|
|
10525
|
-
sign: sign$
|
|
10526
|
-
validateParams: validateParams$
|
|
10527
|
-
verify: verify$
|
|
10571
|
+
sign: sign$7,
|
|
10572
|
+
validateParams: validateParams$9,
|
|
10573
|
+
verify: verify$7
|
|
10528
10574
|
});
|
|
10529
10575
|
|
|
10530
10576
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
@@ -10569,7 +10615,7 @@ function encode(message) {
|
|
|
10569
10615
|
* @param {Uint8Array} message - message to remove padding from
|
|
10570
10616
|
* @returns {Uint8Array} Message without padding.
|
|
10571
10617
|
*/
|
|
10572
|
-
function decode
|
|
10618
|
+
function decode(message) {
|
|
10573
10619
|
const len = message.length;
|
|
10574
10620
|
if (len > 0) {
|
|
10575
10621
|
const c = message[len - 1];
|
|
@@ -10586,7 +10632,7 @@ function decode$1(message) {
|
|
|
10586
10632
|
|
|
10587
10633
|
var pkcs5 = /*#__PURE__*/Object.freeze({
|
|
10588
10634
|
__proto__: null,
|
|
10589
|
-
decode: decode
|
|
10635
|
+
decode: decode,
|
|
10590
10636
|
encode: encode
|
|
10591
10637
|
});
|
|
10592
10638
|
|
|
@@ -10619,7 +10665,7 @@ const nodeCrypto$1 = util.getNodeCrypto();
|
|
|
10619
10665
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
10620
10666
|
* @async
|
|
10621
10667
|
*/
|
|
10622
|
-
async function validateParams$
|
|
10668
|
+
async function validateParams$8(oid, Q, d) {
|
|
10623
10669
|
return validateStandardParams(enums.publicKey.ecdh, oid, Q, d);
|
|
10624
10670
|
}
|
|
10625
10671
|
|
|
@@ -10702,7 +10748,7 @@ async function genPublicEphemeralKey(curve, Q) {
|
|
|
10702
10748
|
* @returns {Promise<{publicKey: Uint8Array, wrappedKey: Uint8Array}>}
|
|
10703
10749
|
* @async
|
|
10704
10750
|
*/
|
|
10705
|
-
async function encrypt$
|
|
10751
|
+
async function encrypt$2(oid, kdfParams, data, Q, fingerprint) {
|
|
10706
10752
|
const m = encode(data);
|
|
10707
10753
|
|
|
10708
10754
|
const curve = new CurveWithOID(oid);
|
|
@@ -10767,7 +10813,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) {
|
|
|
10767
10813
|
* @returns {Promise<Uint8Array>} Value derived from session key.
|
|
10768
10814
|
* @async
|
|
10769
10815
|
*/
|
|
10770
|
-
async function decrypt$
|
|
10816
|
+
async function decrypt$2(oid, kdfParams, V, C, Q, d, fingerprint) {
|
|
10771
10817
|
const curve = new CurveWithOID(oid);
|
|
10772
10818
|
checkPublicPointEnconding(curve, Q);
|
|
10773
10819
|
checkPublicPointEnconding(curve, V);
|
|
@@ -10779,7 +10825,7 @@ async function decrypt$1(oid, kdfParams, V, C, Q, d, fingerprint) {
|
|
|
10779
10825
|
try {
|
|
10780
10826
|
// Work around old go crypto bug and old OpenPGP.js bug, respectively.
|
|
10781
10827
|
const Z = await kdf(kdfParams.hash, sharedKey, keySize, param, i === 1, i === 2);
|
|
10782
|
-
return decode
|
|
10828
|
+
return decode(await unwrap(kdfParams.cipher, Z, C));
|
|
10783
10829
|
} catch (e) {
|
|
10784
10830
|
err = e;
|
|
10785
10831
|
}
|
|
@@ -10941,9 +10987,9 @@ async function nodePublicEphemeralKey(curve, Q) {
|
|
|
10941
10987
|
|
|
10942
10988
|
var ecdh = /*#__PURE__*/Object.freeze({
|
|
10943
10989
|
__proto__: null,
|
|
10944
|
-
decrypt: decrypt$
|
|
10945
|
-
encrypt: encrypt$
|
|
10946
|
-
validateParams: validateParams$
|
|
10990
|
+
decrypt: decrypt$2,
|
|
10991
|
+
encrypt: encrypt$2,
|
|
10992
|
+
validateParams: validateParams$8
|
|
10947
10993
|
});
|
|
10948
10994
|
|
|
10949
10995
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
@@ -10971,7 +11017,7 @@ var elliptic = /*#__PURE__*/Object.freeze({
|
|
|
10971
11017
|
ecdsa: ecdsa,
|
|
10972
11018
|
eddsa: eddsa,
|
|
10973
11019
|
eddsaLegacy: eddsa_legacy,
|
|
10974
|
-
generate: generate$
|
|
11020
|
+
generate: generate$8,
|
|
10975
11021
|
getPreferredHashAlgo: getPreferredHashAlgo$1
|
|
10976
11022
|
});
|
|
10977
11023
|
|
|
@@ -11013,7 +11059,7 @@ const _1n = BigInt(1);
|
|
|
11013
11059
|
* @returns {Promise<{ r: Uint8Array, s: Uint8Array }>}
|
|
11014
11060
|
* @async
|
|
11015
11061
|
*/
|
|
11016
|
-
async function sign$
|
|
11062
|
+
async function sign$6(hashAlgo, hashed, g, p, q, x) {
|
|
11017
11063
|
const _0n = BigInt(0);
|
|
11018
11064
|
p = uint8ArrayToBigInt(p);
|
|
11019
11065
|
q = uint8ArrayToBigInt(q);
|
|
@@ -11071,7 +11117,7 @@ async function sign$3(hashAlgo, hashed, g, p, q, x) {
|
|
|
11071
11117
|
* @returns {boolean}
|
|
11072
11118
|
* @async
|
|
11073
11119
|
*/
|
|
11074
|
-
async function verify$
|
|
11120
|
+
async function verify$6(hashAlgo, r, s, hashed, g, p, q, y) {
|
|
11075
11121
|
r = uint8ArrayToBigInt(r);
|
|
11076
11122
|
s = uint8ArrayToBigInt(s);
|
|
11077
11123
|
|
|
@@ -11112,7 +11158,7 @@ async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
|
|
|
11112
11158
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
11113
11159
|
* @async
|
|
11114
11160
|
*/
|
|
11115
|
-
async function validateParams$
|
|
11161
|
+
async function validateParams$7(p, q, g, y, x) {
|
|
11116
11162
|
p = uint8ArrayToBigInt(p);
|
|
11117
11163
|
q = uint8ArrayToBigInt(q);
|
|
11118
11164
|
g = uint8ArrayToBigInt(g);
|
|
@@ -11165,9 +11211,9 @@ async function validateParams$1(p, q, g, y, x) {
|
|
|
11165
11211
|
|
|
11166
11212
|
var dsa = /*#__PURE__*/Object.freeze({
|
|
11167
11213
|
__proto__: null,
|
|
11168
|
-
sign: sign$
|
|
11169
|
-
validateParams: validateParams$
|
|
11170
|
-
verify: verify$
|
|
11214
|
+
sign: sign$6,
|
|
11215
|
+
validateParams: validateParams$7,
|
|
11216
|
+
verify: verify$6
|
|
11171
11217
|
});
|
|
11172
11218
|
|
|
11173
11219
|
const supportedHashAlgos = new Set([enums.hash.sha1, enums.hash.sha256, enums.hash.sha512]);
|
|
@@ -11175,7 +11221,7 @@ const supportedHashAlgos = new Set([enums.hash.sha1, enums.hash.sha256, enums.ha
|
|
|
11175
11221
|
const webCrypto = util.getWebCrypto();
|
|
11176
11222
|
const nodeCrypto = util.getNodeCrypto();
|
|
11177
11223
|
|
|
11178
|
-
async function generate$
|
|
11224
|
+
async function generate$7(hashAlgo) {
|
|
11179
11225
|
if (!supportedHashAlgos.has(hashAlgo)) {
|
|
11180
11226
|
throw new Error('Unsupported hash algorithm.');
|
|
11181
11227
|
}
|
|
@@ -11194,7 +11240,7 @@ async function generate$1(hashAlgo) {
|
|
|
11194
11240
|
return new Uint8Array(exportedKey);
|
|
11195
11241
|
}
|
|
11196
11242
|
|
|
11197
|
-
async function sign$
|
|
11243
|
+
async function sign$5(hashAlgo, key, data) {
|
|
11198
11244
|
if (!supportedHashAlgos.has(hashAlgo)) {
|
|
11199
11245
|
throw new Error('Unsupported hash algorithm.');
|
|
11200
11246
|
}
|
|
@@ -11215,7 +11261,7 @@ async function sign$2(hashAlgo, key, data) {
|
|
|
11215
11261
|
return new Uint8Array(mac);
|
|
11216
11262
|
}
|
|
11217
11263
|
|
|
11218
|
-
async function verify$
|
|
11264
|
+
async function verify$5(hashAlgo, key, mac, data) {
|
|
11219
11265
|
if (!supportedHashAlgos.has(hashAlgo)) {
|
|
11220
11266
|
throw new Error('Unsupported hash algorithm.');
|
|
11221
11267
|
}
|
|
@@ -11236,12 +11282,390 @@ async function verify$2(hashAlgo, key, mac, data) {
|
|
|
11236
11282
|
}
|
|
11237
11283
|
|
|
11238
11284
|
var hmac = /*#__PURE__*/Object.freeze({
|
|
11285
|
+
__proto__: null,
|
|
11286
|
+
generate: generate$7,
|
|
11287
|
+
sign: sign$5,
|
|
11288
|
+
verify: verify$5
|
|
11289
|
+
});
|
|
11290
|
+
|
|
11291
|
+
async function generate$6(algo) {
|
|
11292
|
+
switch (algo) {
|
|
11293
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
11294
|
+
const { A, k } = await generate$9(enums.publicKey.x25519);
|
|
11295
|
+
return {
|
|
11296
|
+
eccPublicKey: A,
|
|
11297
|
+
eccSecretKey: k
|
|
11298
|
+
};
|
|
11299
|
+
}
|
|
11300
|
+
default:
|
|
11301
|
+
throw new Error('Unsupported KEM algorithm');
|
|
11302
|
+
}
|
|
11303
|
+
}
|
|
11304
|
+
|
|
11305
|
+
async function encaps$1(eccAlgo, eccRecipientPublicKey) {
|
|
11306
|
+
switch (eccAlgo) {
|
|
11307
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
11308
|
+
const { ephemeralPublicKey: eccCipherText, sharedSecret: eccSharedSecret } = await generateEphemeralEncryptionMaterial(enums.publicKey.x25519, eccRecipientPublicKey);
|
|
11309
|
+
const eccKeyShare = await hash.sha3_256(util.concatUint8Array([
|
|
11310
|
+
eccSharedSecret,
|
|
11311
|
+
eccCipherText,
|
|
11312
|
+
eccRecipientPublicKey
|
|
11313
|
+
]));
|
|
11314
|
+
return {
|
|
11315
|
+
eccCipherText,
|
|
11316
|
+
eccKeyShare
|
|
11317
|
+
};
|
|
11318
|
+
}
|
|
11319
|
+
default:
|
|
11320
|
+
throw new Error('Unsupported KEM algorithm');
|
|
11321
|
+
}
|
|
11322
|
+
}
|
|
11323
|
+
|
|
11324
|
+
async function decaps$1(eccAlgo, eccCipherText, eccSecretKey, eccPublicKey) {
|
|
11325
|
+
switch (eccAlgo) {
|
|
11326
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
11327
|
+
const eccSharedSecret = await recomputeSharedSecret(enums.publicKey.x25519, eccCipherText, eccPublicKey, eccSecretKey);
|
|
11328
|
+
const eccKeyShare = await hash.sha3_256(util.concatUint8Array([
|
|
11329
|
+
eccSharedSecret,
|
|
11330
|
+
eccCipherText,
|
|
11331
|
+
eccPublicKey
|
|
11332
|
+
]));
|
|
11333
|
+
return eccKeyShare;
|
|
11334
|
+
}
|
|
11335
|
+
default:
|
|
11336
|
+
throw new Error('Unsupported KEM algorithm');
|
|
11337
|
+
}
|
|
11338
|
+
}
|
|
11339
|
+
|
|
11340
|
+
async function validateParams$6(algo, eccPublicKey, eccSecretKey) {
|
|
11341
|
+
switch (algo) {
|
|
11342
|
+
case enums.publicKey.pqc_mlkem_x25519:
|
|
11343
|
+
return validateParams$b(enums.publicKey.x25519, eccPublicKey, eccSecretKey);
|
|
11344
|
+
default:
|
|
11345
|
+
throw new Error('Unsupported KEM algorithm');
|
|
11346
|
+
}
|
|
11347
|
+
}
|
|
11348
|
+
|
|
11349
|
+
async function generate$5(algo) {
|
|
11350
|
+
switch (algo) {
|
|
11351
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
11352
|
+
const mlkemSeed = getRandomBytes(64);
|
|
11353
|
+
const { mlkemSecretKey, mlkemPublicKey } = await expandSecretSeed$1(algo, mlkemSeed);
|
|
11354
|
+
|
|
11355
|
+
return { mlkemSeed, mlkemSecretKey, mlkemPublicKey };
|
|
11356
|
+
}
|
|
11357
|
+
default:
|
|
11358
|
+
throw new Error('Unsupported KEM algorithm');
|
|
11359
|
+
}
|
|
11360
|
+
}
|
|
11361
|
+
|
|
11362
|
+
/**
|
|
11363
|
+
* Expand ML-KEM secret seed and retrieve the secret and public key material
|
|
11364
|
+
* @param {module:enums.publicKey} algo - Public key algorithm
|
|
11365
|
+
* @param {Uint8Array} seed - secret seed to expand
|
|
11366
|
+
* @returns {Promise<{ mlkemPublicKey: Uint8Array, mlkemSecretKey: Uint8Array }>}
|
|
11367
|
+
*/
|
|
11368
|
+
async function expandSecretSeed$1(algo, seed) {
|
|
11369
|
+
switch (algo) {
|
|
11370
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
11371
|
+
const { ml_kem768 } = await import('./noble_post_quantum.mjs');
|
|
11372
|
+
const { publicKey: encapsulationKey, secretKey: decapsulationKey } = ml_kem768.keygen(seed);
|
|
11373
|
+
|
|
11374
|
+
return { mlkemPublicKey: encapsulationKey, mlkemSecretKey: decapsulationKey };
|
|
11375
|
+
}
|
|
11376
|
+
default:
|
|
11377
|
+
throw new Error('Unsupported KEM algorithm');
|
|
11378
|
+
}
|
|
11379
|
+
}
|
|
11380
|
+
|
|
11381
|
+
async function encaps(algo, mlkemRecipientPublicKey) {
|
|
11382
|
+
switch (algo) {
|
|
11383
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
11384
|
+
const { ml_kem768 } = await import('./noble_post_quantum.mjs');
|
|
11385
|
+
const { cipherText: mlkemCipherText, sharedSecret: mlkemKeyShare } = ml_kem768.encapsulate(mlkemRecipientPublicKey);
|
|
11386
|
+
|
|
11387
|
+
return { mlkemCipherText, mlkemKeyShare };
|
|
11388
|
+
}
|
|
11389
|
+
default:
|
|
11390
|
+
throw new Error('Unsupported KEM algorithm');
|
|
11391
|
+
}
|
|
11392
|
+
}
|
|
11393
|
+
|
|
11394
|
+
async function decaps(algo, mlkemCipherText, mlkemSecretKey) {
|
|
11395
|
+
switch (algo) {
|
|
11396
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
11397
|
+
const { ml_kem768 } = await import('./noble_post_quantum.mjs');
|
|
11398
|
+
const mlkemKeyShare = ml_kem768.decapsulate(mlkemCipherText, mlkemSecretKey);
|
|
11399
|
+
|
|
11400
|
+
return mlkemKeyShare;
|
|
11401
|
+
}
|
|
11402
|
+
default:
|
|
11403
|
+
throw new Error('Unsupported KEM algorithm');
|
|
11404
|
+
}
|
|
11405
|
+
}
|
|
11406
|
+
|
|
11407
|
+
async function validateParams$5(algo, mlkemPublicKey, mlkemSeed) {
|
|
11408
|
+
switch (algo) {
|
|
11409
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
11410
|
+
const { mlkemPublicKey: expectedPublicKey } = await expandSecretSeed$1(algo, mlkemSeed);
|
|
11411
|
+
return util.equalsUint8Array(mlkemPublicKey, expectedPublicKey);
|
|
11412
|
+
}
|
|
11413
|
+
default:
|
|
11414
|
+
throw new Error('Unsupported KEM algorithm');
|
|
11415
|
+
}
|
|
11416
|
+
}
|
|
11417
|
+
|
|
11418
|
+
async function generate$4(algo) {
|
|
11419
|
+
const { eccPublicKey, eccSecretKey } = await generate$6(algo);
|
|
11420
|
+
const { mlkemPublicKey, mlkemSeed, mlkemSecretKey } = await generate$5(algo);
|
|
11421
|
+
|
|
11422
|
+
return { eccPublicKey, eccSecretKey, mlkemPublicKey, mlkemSeed, mlkemSecretKey };
|
|
11423
|
+
}
|
|
11424
|
+
|
|
11425
|
+
async function encrypt$1(algo, eccPublicKey, mlkemPublicKey, sessioneKeyData) {
|
|
11426
|
+
const { eccKeyShare, eccCipherText } = await encaps$1(algo, eccPublicKey);
|
|
11427
|
+
const { mlkemKeyShare, mlkemCipherText } = await encaps(algo, mlkemPublicKey);
|
|
11428
|
+
const kek = await multiKeyCombine(algo, eccKeyShare, eccCipherText, eccPublicKey, mlkemKeyShare, mlkemCipherText, mlkemPublicKey);
|
|
11429
|
+
const wrappedKey = await wrap(enums.symmetric.aes256, kek, sessioneKeyData); // C
|
|
11430
|
+
return { eccCipherText, mlkemCipherText, wrappedKey };
|
|
11431
|
+
}
|
|
11432
|
+
|
|
11433
|
+
async function decrypt$1(algo, eccCipherText, mlkemCipherText, eccSecretKey, eccPublicKey, mlkemSecretKey, mlkemPublicKey, encryptedSessionKeyData) {
|
|
11434
|
+
const eccKeyShare = await decaps$1(algo, eccCipherText, eccSecretKey, eccPublicKey);
|
|
11435
|
+
const mlkemKeyShare = await decaps(algo, mlkemCipherText, mlkemSecretKey);
|
|
11436
|
+
const kek = await multiKeyCombine(algo, eccKeyShare, eccCipherText, eccPublicKey, mlkemKeyShare, mlkemCipherText, mlkemPublicKey);
|
|
11437
|
+
const sessionKey = await unwrap(enums.symmetric.aes256, kek, encryptedSessionKeyData);
|
|
11438
|
+
return sessionKey;
|
|
11439
|
+
}
|
|
11440
|
+
|
|
11441
|
+
async function multiKeyCombine(algo, ecdhKeyShare, ecdhCipherText, ecdhPublicKey, mlkemKeyShare, mlkemCipherText, mlkemPublicKey) {
|
|
11442
|
+
// LAMPS-aligned and NIST compatible combiner, proposed in: https://mailarchive.ietf.org/arch/msg/openpgp/NMTCy707LICtxIhP3Xt1U5C8MF0/
|
|
11443
|
+
// 2a. KDF(mlkemSS || tradSS || tradCT || tradPK || Domain)
|
|
11444
|
+
// where Domain is "Domain" for LAMPS, and "mlkemCT || mlkemPK || algId" for OpenPGP
|
|
11445
|
+
const encData = util.concatUint8Array([
|
|
11446
|
+
mlkemKeyShare,
|
|
11447
|
+
ecdhKeyShare,
|
|
11448
|
+
ecdhCipherText,
|
|
11449
|
+
ecdhPublicKey,
|
|
11450
|
+
// domSep
|
|
11451
|
+
mlkemCipherText,
|
|
11452
|
+
mlkemPublicKey,
|
|
11453
|
+
new Uint8Array([algo])
|
|
11454
|
+
]);
|
|
11455
|
+
|
|
11456
|
+
const kek = await hash.digest(enums.hash.sha3_256, encData);
|
|
11457
|
+
return kek;
|
|
11458
|
+
}
|
|
11459
|
+
|
|
11460
|
+
async function validateParams$4(algo, eccPublicKey, eccSecretKey, mlkemPublicKey, mlkemSeed) {
|
|
11461
|
+
const eccValidationPromise = validateParams$6(algo, eccPublicKey, eccSecretKey);
|
|
11462
|
+
const mlkemValidationPromise = validateParams$5(algo, mlkemPublicKey, mlkemSeed);
|
|
11463
|
+
const valid = await eccValidationPromise && await mlkemValidationPromise;
|
|
11464
|
+
return valid;
|
|
11465
|
+
}
|
|
11466
|
+
|
|
11467
|
+
var index$1 = /*#__PURE__*/Object.freeze({
|
|
11468
|
+
__proto__: null,
|
|
11469
|
+
decrypt: decrypt$1,
|
|
11470
|
+
encrypt: encrypt$1,
|
|
11471
|
+
generate: generate$4,
|
|
11472
|
+
mlkemExpandSecretSeed: expandSecretSeed$1,
|
|
11473
|
+
validateParams: validateParams$4
|
|
11474
|
+
});
|
|
11475
|
+
|
|
11476
|
+
async function generate$3(algo) {
|
|
11477
|
+
switch (algo) {
|
|
11478
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11479
|
+
const mldsaSeed = getRandomBytes(32);
|
|
11480
|
+
const { mldsaSecretKey, mldsaPublicKey } = await expandSecretSeed(algo, mldsaSeed);
|
|
11481
|
+
|
|
11482
|
+
return { mldsaSeed, mldsaSecretKey, mldsaPublicKey };
|
|
11483
|
+
}
|
|
11484
|
+
default:
|
|
11485
|
+
throw new Error('Unsupported signature algorithm');
|
|
11486
|
+
}
|
|
11487
|
+
}
|
|
11488
|
+
|
|
11489
|
+
/**
|
|
11490
|
+
* Expand ML-DSA secret seed and retrieve the secret and public key material
|
|
11491
|
+
* @param {module:enums.publicKey} algo - Public key algorithm
|
|
11492
|
+
* @param {Uint8Array} seed - secret seed to expand
|
|
11493
|
+
* @returns {Promise<{ mldsaPublicKey: Uint8Array, mldsaSecretKey: Uint8Array }>}
|
|
11494
|
+
*/
|
|
11495
|
+
async function expandSecretSeed(algo, seed) {
|
|
11496
|
+
switch (algo) {
|
|
11497
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11498
|
+
const { ml_dsa65 } = await import('./noble_post_quantum.mjs');
|
|
11499
|
+
const { secretKey: mldsaSecretKey, publicKey: mldsaPublicKey } = ml_dsa65.keygen(seed);
|
|
11500
|
+
|
|
11501
|
+
return { mldsaSecretKey, mldsaPublicKey };
|
|
11502
|
+
}
|
|
11503
|
+
default:
|
|
11504
|
+
throw new Error('Unsupported signature algorithm');
|
|
11505
|
+
}
|
|
11506
|
+
}
|
|
11507
|
+
|
|
11508
|
+
async function sign$4(algo, mldsaSecretKey, dataDigest) {
|
|
11509
|
+
switch (algo) {
|
|
11510
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11511
|
+
const { ml_dsa65 } = await import('./noble_post_quantum.mjs');
|
|
11512
|
+
const mldsaSignature = ml_dsa65.sign(mldsaSecretKey, dataDigest);
|
|
11513
|
+
return { mldsaSignature };
|
|
11514
|
+
}
|
|
11515
|
+
default:
|
|
11516
|
+
throw new Error('Unsupported signature algorithm');
|
|
11517
|
+
}
|
|
11518
|
+
}
|
|
11519
|
+
|
|
11520
|
+
async function verify$4(algo, mldsaPublicKey, dataDigest, mldsaSignature) {
|
|
11521
|
+
switch (algo) {
|
|
11522
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11523
|
+
const { ml_dsa65 } = await import('./noble_post_quantum.mjs');
|
|
11524
|
+
return ml_dsa65.verify(mldsaPublicKey, dataDigest, mldsaSignature);
|
|
11525
|
+
}
|
|
11526
|
+
default:
|
|
11527
|
+
throw new Error('Unsupported signature algorithm');
|
|
11528
|
+
}
|
|
11529
|
+
}
|
|
11530
|
+
|
|
11531
|
+
async function validateParams$3(algo, mldsaPublicKey, mldsaSeed) {
|
|
11532
|
+
switch (algo) {
|
|
11533
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11534
|
+
const { mldsaPublicKey: expectedPublicKey } = await expandSecretSeed(algo, mldsaSeed);
|
|
11535
|
+
return util.equalsUint8Array(mldsaPublicKey, expectedPublicKey);
|
|
11536
|
+
}
|
|
11537
|
+
default:
|
|
11538
|
+
throw new Error('Unsupported signature algorithm');
|
|
11539
|
+
}
|
|
11540
|
+
}
|
|
11541
|
+
|
|
11542
|
+
async function generate$2(algo) {
|
|
11543
|
+
switch (algo) {
|
|
11544
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11545
|
+
const { A, seed } = await generate$a(enums.publicKey.ed25519);
|
|
11546
|
+
return {
|
|
11547
|
+
eccPublicKey: A,
|
|
11548
|
+
eccSecretKey: seed
|
|
11549
|
+
};
|
|
11550
|
+
}
|
|
11551
|
+
default:
|
|
11552
|
+
throw new Error('Unsupported signature algorithm');
|
|
11553
|
+
}
|
|
11554
|
+
}
|
|
11555
|
+
|
|
11556
|
+
async function sign$3(signatureAlgo, hashAlgo, eccSecretKey, eccPublicKey, dataDigest) {
|
|
11557
|
+
switch (signatureAlgo) {
|
|
11558
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11559
|
+
const { RS: eccSignature } = await sign$9(enums.publicKey.ed25519, hashAlgo, null, eccPublicKey, eccSecretKey, dataDigest);
|
|
11560
|
+
|
|
11561
|
+
return { eccSignature };
|
|
11562
|
+
}
|
|
11563
|
+
default:
|
|
11564
|
+
throw new Error('Unsupported signature algorithm');
|
|
11565
|
+
}
|
|
11566
|
+
}
|
|
11567
|
+
|
|
11568
|
+
async function verify$3(signatureAlgo, hashAlgo, eccPublicKey, dataDigest, eccSignature) {
|
|
11569
|
+
switch (signatureAlgo) {
|
|
11570
|
+
case enums.publicKey.pqc_mldsa_ed25519:
|
|
11571
|
+
return verify$9(enums.publicKey.ed25519, hashAlgo, { RS: eccSignature }, null, eccPublicKey, dataDigest);
|
|
11572
|
+
default:
|
|
11573
|
+
throw new Error('Unsupported signature algorithm');
|
|
11574
|
+
}
|
|
11575
|
+
}
|
|
11576
|
+
|
|
11577
|
+
async function validateParams$2(algo, eccPublicKey, eccSecretKey) {
|
|
11578
|
+
switch (algo) {
|
|
11579
|
+
case enums.publicKey.pqc_mldsa_ed25519:
|
|
11580
|
+
return validateParams$c(enums.publicKey.ed25519, eccPublicKey, eccSecretKey);
|
|
11581
|
+
default:
|
|
11582
|
+
throw new Error('Unsupported signature algorithm');
|
|
11583
|
+
}
|
|
11584
|
+
}
|
|
11585
|
+
|
|
11586
|
+
async function generate$1(algo) {
|
|
11587
|
+
switch (algo) {
|
|
11588
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11589
|
+
const { eccSecretKey, eccPublicKey } = await generate$2(algo);
|
|
11590
|
+
const { mldsaSeed, mldsaSecretKey, mldsaPublicKey } = await generate$3(algo);
|
|
11591
|
+
return { eccSecretKey, eccPublicKey, mldsaSeed, mldsaSecretKey, mldsaPublicKey };
|
|
11592
|
+
}
|
|
11593
|
+
default:
|
|
11594
|
+
throw new Error('Unsupported signature algorithm');
|
|
11595
|
+
}
|
|
11596
|
+
}
|
|
11597
|
+
|
|
11598
|
+
async function sign$2(signatureAlgo, hashAlgo, eccSecretKey, eccPublicKey, mldsaSecretKey, dataDigest) {
|
|
11599
|
+
if (hashAlgo !== getRequiredHashAlgo(signatureAlgo)) {
|
|
11600
|
+
// The signature hash algo MUST be set to the specified algorithm, see
|
|
11601
|
+
// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
|
|
11602
|
+
throw new Error('Unexpected hash algorithm for PQC signature');
|
|
11603
|
+
}
|
|
11604
|
+
|
|
11605
|
+
switch (signatureAlgo) {
|
|
11606
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11607
|
+
const { eccSignature } = await sign$3(signatureAlgo, hashAlgo, eccSecretKey, eccPublicKey, dataDigest);
|
|
11608
|
+
const { mldsaSignature } = await sign$4(signatureAlgo, mldsaSecretKey, dataDigest);
|
|
11609
|
+
|
|
11610
|
+
return { eccSignature, mldsaSignature };
|
|
11611
|
+
}
|
|
11612
|
+
default:
|
|
11613
|
+
throw new Error('Unsupported signature algorithm');
|
|
11614
|
+
}
|
|
11615
|
+
}
|
|
11616
|
+
|
|
11617
|
+
async function verify$2(signatureAlgo, hashAlgo, eccPublicKey, mldsaPublicKey, dataDigest, { eccSignature, mldsaSignature }) {
|
|
11618
|
+
if (hashAlgo !== getRequiredHashAlgo(signatureAlgo)) {
|
|
11619
|
+
// The signature hash algo MUST be set to the specified algorithm, see
|
|
11620
|
+
// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
|
|
11621
|
+
throw new Error('Unexpected hash algorithm for PQC signature');
|
|
11622
|
+
}
|
|
11623
|
+
|
|
11624
|
+
switch (signatureAlgo) {
|
|
11625
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11626
|
+
const eccVerifiedPromise = verify$3(signatureAlgo, hashAlgo, eccPublicKey, dataDigest, eccSignature);
|
|
11627
|
+
const mldsaVerifiedPromise = verify$4(signatureAlgo, mldsaPublicKey, dataDigest, mldsaSignature);
|
|
11628
|
+
const verified = await eccVerifiedPromise && await mldsaVerifiedPromise;
|
|
11629
|
+
return verified;
|
|
11630
|
+
}
|
|
11631
|
+
default:
|
|
11632
|
+
throw new Error('Unsupported signature algorithm');
|
|
11633
|
+
}
|
|
11634
|
+
}
|
|
11635
|
+
|
|
11636
|
+
function getRequiredHashAlgo(signatureAlgo) {
|
|
11637
|
+
// See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
|
|
11638
|
+
switch (signatureAlgo) {
|
|
11639
|
+
case enums.publicKey.pqc_mldsa_ed25519:
|
|
11640
|
+
return enums.hash.sha3_256;
|
|
11641
|
+
default:
|
|
11642
|
+
throw new Error('Unsupported signature algorithm');
|
|
11643
|
+
}
|
|
11644
|
+
}
|
|
11645
|
+
|
|
11646
|
+
async function validateParams$1(algo, eccPublicKey, eccSecretKey, mldsaPublicKey, mldsaSeed) {
|
|
11647
|
+
const eccValidationPromise = validateParams$2(algo, eccPublicKey, eccSecretKey);
|
|
11648
|
+
const mldsaValidationPromise = validateParams$3(algo, mldsaPublicKey, mldsaSeed);
|
|
11649
|
+
const valid = await eccValidationPromise && await mldsaValidationPromise;
|
|
11650
|
+
return valid;
|
|
11651
|
+
}
|
|
11652
|
+
|
|
11653
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
11239
11654
|
__proto__: null,
|
|
11240
11655
|
generate: generate$1,
|
|
11656
|
+
getRequiredHashAlgo: getRequiredHashAlgo,
|
|
11657
|
+
mldsaExpandSecretSeed: expandSecretSeed,
|
|
11241
11658
|
sign: sign$2,
|
|
11659
|
+
validateParams: validateParams$1,
|
|
11242
11660
|
verify: verify$2
|
|
11243
11661
|
});
|
|
11244
11662
|
|
|
11663
|
+
var postQuantum = /*#__PURE__*/Object.freeze({
|
|
11664
|
+
__proto__: null,
|
|
11665
|
+
kem: index$1,
|
|
11666
|
+
signature: index
|
|
11667
|
+
});
|
|
11668
|
+
|
|
11245
11669
|
/**
|
|
11246
11670
|
* @fileoverview Asymmetric cryptography functions
|
|
11247
11671
|
* @module crypto/public_key
|
|
@@ -11258,7 +11682,9 @@ var publicKey = {
|
|
|
11258
11682
|
/** @see module:crypto/public_key/dsa */
|
|
11259
11683
|
dsa: dsa,
|
|
11260
11684
|
/** @see module:crypto/public_key/hmac */
|
|
11261
|
-
hmac: hmac
|
|
11685
|
+
hmac: hmac,
|
|
11686
|
+
/** @see module:crypto/public_key/post_quantum */
|
|
11687
|
+
postQuantum
|
|
11262
11688
|
};
|
|
11263
11689
|
|
|
11264
11690
|
class ShortByteString {
|
|
@@ -11326,6 +11752,8 @@ function parseSignatureParams(algo, signature) {
|
|
|
11326
11752
|
case enums.publicKey.dsa:
|
|
11327
11753
|
case enums.publicKey.ecdsa:
|
|
11328
11754
|
{
|
|
11755
|
+
// If the signature payload sizes are unexpected, we will throw on verification,
|
|
11756
|
+
// where we also have access to the OID curve from the key.
|
|
11329
11757
|
const r = util.readMPI(signature.subarray(read)); read += r.length + 2;
|
|
11330
11758
|
const s = util.readMPI(signature.subarray(read)); read += s.length + 2;
|
|
11331
11759
|
return { read, signatureParams: { r, s } };
|
|
@@ -11334,12 +11762,11 @@ function parseSignatureParams(algo, signature) {
|
|
|
11334
11762
|
// - MPI of an EC point r.
|
|
11335
11763
|
// - EdDSA value s, in MPI, in the little endian representation
|
|
11336
11764
|
case enums.publicKey.eddsaLegacy: {
|
|
11337
|
-
//
|
|
11338
|
-
//
|
|
11339
|
-
|
|
11340
|
-
r = util.
|
|
11341
|
-
|
|
11342
|
-
s = util.leftPad(s, 32);
|
|
11765
|
+
// Only Curve25519Legacy is supported (no Curve448Legacy), but the relevant checks are done on key parsing and signature
|
|
11766
|
+
// verification: if the signature payload sizes are unexpected, we will throw on verification,
|
|
11767
|
+
// where we also have access to the OID curve from the key.
|
|
11768
|
+
const r = util.readMPI(signature.subarray(read)); read += r.length + 2;
|
|
11769
|
+
const s = util.readMPI(signature.subarray(read)); read += s.length + 2;
|
|
11343
11770
|
return { read, signatureParams: { r, s } };
|
|
11344
11771
|
}
|
|
11345
11772
|
// Algorithm-Specific Fields for Ed25519 signatures:
|
|
@@ -11356,6 +11783,12 @@ function parseSignatureParams(algo, signature) {
|
|
|
11356
11783
|
const mac = new ShortByteString(); read += mac.read(signature.subarray(read));
|
|
11357
11784
|
return { read, signatureParams: { mac } };
|
|
11358
11785
|
}
|
|
11786
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11787
|
+
const eccSignatureSize = 2 * publicKey.elliptic.eddsa.getPayloadSize(enums.publicKey.ed25519);
|
|
11788
|
+
const eccSignature = util.readExactSubarray(signature, read, read + eccSignatureSize); read += eccSignature.length;
|
|
11789
|
+
const mldsaSignature = util.readExactSubarray(signature, read, read + 3309); read += mldsaSignature.length;
|
|
11790
|
+
return { read, signatureParams: { eccSignature, mldsaSignature } };
|
|
11791
|
+
}
|
|
11359
11792
|
default:
|
|
11360
11793
|
throw new UnsupportedError('Unknown signature algorithm.');
|
|
11361
11794
|
}
|
|
@@ -11400,8 +11833,12 @@ async function verify$1(algo, hashAlgo, signature, publicParams, privateParams,
|
|
|
11400
11833
|
}
|
|
11401
11834
|
case enums.publicKey.eddsaLegacy: {
|
|
11402
11835
|
const { oid, Q } = publicParams;
|
|
11403
|
-
|
|
11404
|
-
|
|
11836
|
+
const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize;
|
|
11837
|
+
// When dealing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
|
|
11838
|
+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
|
|
11839
|
+
const r = util.leftPad(signature.r, curveSize);
|
|
11840
|
+
const s = util.leftPad(signature.s, curveSize);
|
|
11841
|
+
return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
|
11405
11842
|
}
|
|
11406
11843
|
case enums.publicKey.ed25519:
|
|
11407
11844
|
case enums.publicKey.ed448: {
|
|
@@ -11416,6 +11853,10 @@ async function verify$1(algo, hashAlgo, signature, publicParams, privateParams,
|
|
|
11416
11853
|
const { keyMaterial } = privateParams;
|
|
11417
11854
|
return publicKey.hmac.verify(algo.getValue(), keyMaterial, signature.mac.data, hashed);
|
|
11418
11855
|
}
|
|
11856
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11857
|
+
const { eccPublicKey, mldsaPublicKey } = publicParams;
|
|
11858
|
+
return publicKey.postQuantum.signature.verify(algo, hashAlgo, eccPublicKey, mldsaPublicKey, hashed, signature);
|
|
11859
|
+
}
|
|
11419
11860
|
default:
|
|
11420
11861
|
throw new Error('Unknown signature algorithm.');
|
|
11421
11862
|
}
|
|
@@ -11477,6 +11918,11 @@ async function sign$1(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
|
|
|
11477
11918
|
const mac = await publicKey.hmac.sign(algo.getValue(), keyMaterial, hashed);
|
|
11478
11919
|
return { mac: new ShortByteString(mac) };
|
|
11479
11920
|
}
|
|
11921
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
11922
|
+
const { eccPublicKey } = publicKeyParams;
|
|
11923
|
+
const { eccSecretKey, mldsaSecretKey } = privateKeyParams;
|
|
11924
|
+
return publicKey.postQuantum.signature.sign(algo, hashAlgo, eccSecretKey, eccPublicKey, mldsaSecretKey, hashed);
|
|
11925
|
+
}
|
|
11480
11926
|
default:
|
|
11481
11927
|
throw new Error('Unknown signature algorithm.');
|
|
11482
11928
|
}
|
|
@@ -11816,6 +12262,12 @@ async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, privatePar
|
|
|
11816
12262
|
const c = await modeInstance.encrypt(data, iv, new Uint8Array());
|
|
11817
12263
|
return { aeadMode: new AEADEnum(aeadMode), iv, c: new ShortByteString(c) };
|
|
11818
12264
|
}
|
|
12265
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
12266
|
+
const { eccPublicKey, mlkemPublicKey } = publicParams;
|
|
12267
|
+
const { eccCipherText, mlkemCipherText, wrappedKey } = await publicKey.postQuantum.kem.encrypt(keyAlgo, eccPublicKey, mlkemPublicKey, data);
|
|
12268
|
+
const C = ECDHXSymmetricKey.fromObject({ algorithm: symmetricAlgo, wrappedKey });
|
|
12269
|
+
return { eccCipherText, mlkemCipherText, C };
|
|
12270
|
+
}
|
|
11819
12271
|
default:
|
|
11820
12272
|
return [];
|
|
11821
12273
|
}
|
|
@@ -11835,8 +12287,8 @@ async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, privatePar
|
|
|
11835
12287
|
* @throws {Error} on sensitive decryption error, unless `randomPayload` is given
|
|
11836
12288
|
* @async
|
|
11837
12289
|
*/
|
|
11838
|
-
async function publicKeyDecrypt(
|
|
11839
|
-
switch (
|
|
12290
|
+
async function publicKeyDecrypt(keyAlgo, publicKeyParams, privateKeyParams, sessionKeyParams, fingerprint, randomPayload) {
|
|
12291
|
+
switch (keyAlgo) {
|
|
11840
12292
|
case enums.publicKey.rsaEncryptSign:
|
|
11841
12293
|
case enums.publicKey.rsaEncrypt: {
|
|
11842
12294
|
const { c } = sessionKeyParams;
|
|
@@ -11866,7 +12318,7 @@ async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, session
|
|
|
11866
12318
|
throw new Error('AES session key expected');
|
|
11867
12319
|
}
|
|
11868
12320
|
return publicKey.elliptic.ecdhX.decrypt(
|
|
11869
|
-
|
|
12321
|
+
keyAlgo, ephemeralPublicKey, C.wrappedKey, A, k);
|
|
11870
12322
|
}
|
|
11871
12323
|
case enums.publicKey.aead: {
|
|
11872
12324
|
const { cipher: algo } = publicKeyParams;
|
|
@@ -11879,6 +12331,12 @@ async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, session
|
|
|
11879
12331
|
const modeInstance = await mode(algoValue, keyMaterial);
|
|
11880
12332
|
return modeInstance.decrypt(c.data, iv, new Uint8Array());
|
|
11881
12333
|
}
|
|
12334
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
12335
|
+
const { eccSecretKey, mlkemSecretKey } = privateKeyParams;
|
|
12336
|
+
const { eccPublicKey, mlkemPublicKey } = publicKeyParams;
|
|
12337
|
+
const { eccCipherText, mlkemCipherText, C } = sessionKeyParams;
|
|
12338
|
+
return publicKey.postQuantum.kem.decrypt(keyAlgo, eccCipherText, mlkemCipherText, eccSecretKey, eccPublicKey, mlkemSecretKey, mlkemPublicKey, C.wrappedKey);
|
|
12339
|
+
}
|
|
11882
12340
|
default:
|
|
11883
12341
|
throw new Error('Unknown public key encryption algorithm.');
|
|
11884
12342
|
}
|
|
@@ -11950,6 +12408,16 @@ function parsePublicKeyParams(algo, bytes) {
|
|
|
11950
12408
|
const digest = bytes.subarray(read, read + digestLength); read += digestLength;
|
|
11951
12409
|
return { read: read, publicParams: { cipher: algo, digest } };
|
|
11952
12410
|
}
|
|
12411
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
12412
|
+
const eccPublicKey = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(enums.publicKey.x25519)); read += eccPublicKey.length;
|
|
12413
|
+
const mlkemPublicKey = util.readExactSubarray(bytes, read, read + 1184); read += mlkemPublicKey.length;
|
|
12414
|
+
return { read, publicParams: { eccPublicKey, mlkemPublicKey } };
|
|
12415
|
+
}
|
|
12416
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
12417
|
+
const eccPublicKey = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(enums.publicKey.ed25519)); read += eccPublicKey.length;
|
|
12418
|
+
const mldsaPublicKey = util.readExactSubarray(bytes, read, read + 1952); read += mldsaPublicKey.length;
|
|
12419
|
+
return { read, publicParams: { eccPublicKey, mldsaPublicKey } };
|
|
12420
|
+
}
|
|
11953
12421
|
default:
|
|
11954
12422
|
throw new UnsupportedError('Unknown public key encryption algorithm.');
|
|
11955
12423
|
}
|
|
@@ -11962,7 +12430,7 @@ function parsePublicKeyParams(algo, bytes) {
|
|
|
11962
12430
|
* @param {Object} publicParams - (ECC and symmetric only) public params, needed to format some private params
|
|
11963
12431
|
* @returns {{ read: Number, privateParams: Object }} Number of read bytes plus the key parameters referenced by name.
|
|
11964
12432
|
*/
|
|
11965
|
-
function parsePrivateKeyParams(algo, bytes, publicParams) {
|
|
12433
|
+
async function parsePrivateKeyParams(algo, bytes, publicParams) {
|
|
11966
12434
|
let read = 0;
|
|
11967
12435
|
switch (algo) {
|
|
11968
12436
|
case enums.publicKey.rsaEncrypt:
|
|
@@ -12021,6 +12489,18 @@ function parsePrivateKeyParams(algo, bytes, publicParams) {
|
|
|
12021
12489
|
const keyMaterial = bytes.subarray(read, read + keySize); read += keySize;
|
|
12022
12490
|
return { read, privateParams: { hashSeed, keyMaterial } };
|
|
12023
12491
|
}
|
|
12492
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
12493
|
+
const eccSecretKey = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(enums.publicKey.x25519)); read += eccSecretKey.length;
|
|
12494
|
+
const mlkemSeed = util.readExactSubarray(bytes, read, read + 64); read += mlkemSeed.length;
|
|
12495
|
+
const { mlkemSecretKey } = await publicKey.postQuantum.kem.mlkemExpandSecretSeed(algo, mlkemSeed);
|
|
12496
|
+
return { read, privateParams: { eccSecretKey, mlkemSecretKey, mlkemSeed } };
|
|
12497
|
+
}
|
|
12498
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
12499
|
+
const eccSecretKey = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(enums.publicKey.ed25519)); read += eccSecretKey.length;
|
|
12500
|
+
const mldsaSeed = util.readExactSubarray(bytes, read, read + 32); read += mldsaSeed.length;
|
|
12501
|
+
const { mldsaSecretKey } = await publicKey.postQuantum.signature.mldsaExpandSecretSeed(algo, mldsaSeed);
|
|
12502
|
+
return { read, privateParams: { eccSecretKey, mldsaSecretKey, mldsaSeed } };
|
|
12503
|
+
}
|
|
12024
12504
|
default:
|
|
12025
12505
|
throw new UnsupportedError('Unknown public key encryption algorithm.');
|
|
12026
12506
|
}
|
|
@@ -12084,6 +12564,12 @@ function parseEncSessionKeyParams(algo, bytes) {
|
|
|
12084
12564
|
|
|
12085
12565
|
return { aeadMode, iv, c };
|
|
12086
12566
|
}
|
|
12567
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
12568
|
+
const eccCipherText = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(enums.publicKey.x25519)); read += eccCipherText.length;
|
|
12569
|
+
const mlkemCipherText = util.readExactSubarray(bytes, read, read + 1088); read += mlkemCipherText.length;
|
|
12570
|
+
const C = new ECDHXSymmetricKey(); C.read(bytes.subarray(read));
|
|
12571
|
+
return { eccCipherText, mlkemCipherText, C }; // eccCipherText || mlkemCipherText || len(C) || C
|
|
12572
|
+
}
|
|
12087
12573
|
default:
|
|
12088
12574
|
throw new UnsupportedError('Unknown public key encryption algorithm.');
|
|
12089
12575
|
}
|
|
@@ -12103,9 +12589,21 @@ function serializeParams(algo, params) {
|
|
|
12103
12589
|
enums.publicKey.ed448,
|
|
12104
12590
|
enums.publicKey.x448,
|
|
12105
12591
|
enums.publicKey.aead,
|
|
12106
|
-
enums.publicKey.hmac
|
|
12592
|
+
enums.publicKey.hmac,
|
|
12593
|
+
enums.publicKey.pqc_mlkem_x25519,
|
|
12594
|
+
enums.publicKey.pqc_mldsa_ed25519
|
|
12107
12595
|
]);
|
|
12596
|
+
|
|
12597
|
+
const excludedFields = {
|
|
12598
|
+
[enums.publicKey.pqc_mlkem_x25519]: new Set(['mlkemSecretKey']), // only `mlkemSeed` is serialized
|
|
12599
|
+
[enums.publicKey.pqc_mldsa_ed25519]: new Set(['mldsaSecretKey']) // only `mldsaSeed` is serialized
|
|
12600
|
+
};
|
|
12601
|
+
|
|
12108
12602
|
const orderedParams = Object.keys(params).map(name => {
|
|
12603
|
+
if (excludedFields[algo]?.has(name)) {
|
|
12604
|
+
return new Uint8Array();
|
|
12605
|
+
}
|
|
12606
|
+
|
|
12109
12607
|
const param = params[name];
|
|
12110
12608
|
if (!util.isUint8Array(param)) return param.write();
|
|
12111
12609
|
return algosWithNativeRepresentation.has(algo) ? param : util.uint8ArrayToMPI(param);
|
|
@@ -12170,6 +12668,16 @@ async function generateParams(algo, bits, oid, symmetric) {
|
|
|
12170
12668
|
const keyMaterial = generateSessionKey$1(symmetric);
|
|
12171
12669
|
return createSymmetricParams(keyMaterial, new SymAlgoEnum(symmetric));
|
|
12172
12670
|
}
|
|
12671
|
+
case enums.publicKey.pqc_mlkem_x25519:
|
|
12672
|
+
return publicKey.postQuantum.kem.generate(algo).then(({ eccSecretKey, eccPublicKey, mlkemSeed, mlkemSecretKey, mlkemPublicKey }) => ({
|
|
12673
|
+
privateParams: { eccSecretKey, mlkemSeed, mlkemSecretKey },
|
|
12674
|
+
publicParams: { eccPublicKey, mlkemPublicKey }
|
|
12675
|
+
}));
|
|
12676
|
+
case enums.publicKey.pqc_mldsa_ed25519:
|
|
12677
|
+
return publicKey.postQuantum.signature.generate(algo).then(({ eccSecretKey, eccPublicKey, mldsaSeed, mldsaSecretKey, mldsaPublicKey }) => ({
|
|
12678
|
+
privateParams: { eccSecretKey, mldsaSeed, mldsaSecretKey },
|
|
12679
|
+
publicParams: { eccPublicKey, mldsaPublicKey }
|
|
12680
|
+
}));
|
|
12173
12681
|
case enums.publicKey.dsa:
|
|
12174
12682
|
case enums.publicKey.elgamal:
|
|
12175
12683
|
throw new Error('Unsupported algorithm for key generation.');
|
|
@@ -12261,6 +12769,16 @@ async function validateParams(algo, publicParams, privateParams) {
|
|
|
12261
12769
|
return keySize === keyMaterial.length &&
|
|
12262
12770
|
util.equalsUint8Array(digest, await hash.sha256(hashSeed));
|
|
12263
12771
|
}
|
|
12772
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
12773
|
+
const { eccSecretKey, mlkemSeed } = privateParams;
|
|
12774
|
+
const { eccPublicKey, mlkemPublicKey } = publicParams;
|
|
12775
|
+
return publicKey.postQuantum.kem.validateParams(algo, eccPublicKey, eccSecretKey, mlkemPublicKey, mlkemSeed);
|
|
12776
|
+
}
|
|
12777
|
+
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
12778
|
+
const { eccSecretKey, mldsaSeed } = privateParams;
|
|
12779
|
+
const { eccPublicKey, mldsaPublicKey } = publicParams;
|
|
12780
|
+
return publicKey.postQuantum.signature.validateParams(algo, eccPublicKey, eccSecretKey, mldsaPublicKey, mldsaSeed);
|
|
12781
|
+
}
|
|
12264
12782
|
default:
|
|
12265
12783
|
throw new Error('Unknown public key algorithm.');
|
|
12266
12784
|
}
|
|
@@ -13666,849 +14184,6 @@ try {
|
|
|
13666
14184
|
}
|
|
13667
14185
|
catch (e) { }
|
|
13668
14186
|
|
|
13669
|
-
/*
|
|
13670
|
-
node-bzip - a pure-javascript Node.JS module for decoding bzip2 data
|
|
13671
|
-
|
|
13672
|
-
Copyright (C) 2012 Eli Skeggs
|
|
13673
|
-
|
|
13674
|
-
This library is free software; you can redistribute it and/or
|
|
13675
|
-
modify it under the terms of the GNU Lesser General Public
|
|
13676
|
-
License as published by the Free Software Foundation; either
|
|
13677
|
-
version 2.1 of the License, or (at your option) any later version.
|
|
13678
|
-
|
|
13679
|
-
This library is distributed in the hope that it will be useful,
|
|
13680
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13681
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13682
|
-
Lesser General Public License for more details.
|
|
13683
|
-
|
|
13684
|
-
You should have received a copy of the GNU Lesser General Public
|
|
13685
|
-
License along with this library; if not, see
|
|
13686
|
-
http://www.gnu.org/licenses/lgpl-2.1.html
|
|
13687
|
-
|
|
13688
|
-
Adapted from bzip2.js, copyright 2011 antimatter15 (antimatter15@gmail.com).
|
|
13689
|
-
|
|
13690
|
-
Based on micro-bunzip by Rob Landley (rob@landley.net).
|
|
13691
|
-
|
|
13692
|
-
Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
|
|
13693
|
-
which also acknowledges contributions by Mike Burrows, David Wheeler,
|
|
13694
|
-
Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
|
|
13695
|
-
Robert Sedgewick, and Jon L. Bentley.
|
|
13696
|
-
*/
|
|
13697
|
-
|
|
13698
|
-
var BITMASK = [0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF];
|
|
13699
|
-
|
|
13700
|
-
// offset in bytes
|
|
13701
|
-
var BitReader$1 = function(stream) {
|
|
13702
|
-
this.stream = stream;
|
|
13703
|
-
this.bitOffset = 0;
|
|
13704
|
-
this.curByte = 0;
|
|
13705
|
-
this.hasByte = false;
|
|
13706
|
-
};
|
|
13707
|
-
|
|
13708
|
-
BitReader$1.prototype._ensureByte = function() {
|
|
13709
|
-
if (!this.hasByte) {
|
|
13710
|
-
this.curByte = this.stream.readByte();
|
|
13711
|
-
this.hasByte = true;
|
|
13712
|
-
}
|
|
13713
|
-
};
|
|
13714
|
-
|
|
13715
|
-
// reads bits from the buffer
|
|
13716
|
-
BitReader$1.prototype.read = function(bits) {
|
|
13717
|
-
var result = 0;
|
|
13718
|
-
while (bits > 0) {
|
|
13719
|
-
this._ensureByte();
|
|
13720
|
-
var remaining = 8 - this.bitOffset;
|
|
13721
|
-
// if we're in a byte
|
|
13722
|
-
if (bits >= remaining) {
|
|
13723
|
-
result <<= remaining;
|
|
13724
|
-
result |= BITMASK[remaining] & this.curByte;
|
|
13725
|
-
this.hasByte = false;
|
|
13726
|
-
this.bitOffset = 0;
|
|
13727
|
-
bits -= remaining;
|
|
13728
|
-
} else {
|
|
13729
|
-
result <<= bits;
|
|
13730
|
-
var shift = remaining - bits;
|
|
13731
|
-
result |= (this.curByte & (BITMASK[bits] << shift)) >> shift;
|
|
13732
|
-
this.bitOffset += bits;
|
|
13733
|
-
bits = 0;
|
|
13734
|
-
}
|
|
13735
|
-
}
|
|
13736
|
-
return result;
|
|
13737
|
-
};
|
|
13738
|
-
|
|
13739
|
-
// seek to an arbitrary point in the buffer (expressed in bits)
|
|
13740
|
-
BitReader$1.prototype.seek = function(pos) {
|
|
13741
|
-
var n_bit = pos % 8;
|
|
13742
|
-
var n_byte = (pos - n_bit) / 8;
|
|
13743
|
-
this.bitOffset = n_bit;
|
|
13744
|
-
this.stream.seek(n_byte);
|
|
13745
|
-
this.hasByte = false;
|
|
13746
|
-
};
|
|
13747
|
-
|
|
13748
|
-
// reads 6 bytes worth of data using the read method
|
|
13749
|
-
BitReader$1.prototype.pi = function() {
|
|
13750
|
-
var buf = new Uint8Array(6), i;
|
|
13751
|
-
for (i = 0; i < buf.length; i++) {
|
|
13752
|
-
buf[i] = this.read(8);
|
|
13753
|
-
}
|
|
13754
|
-
return bufToHex(buf);
|
|
13755
|
-
};
|
|
13756
|
-
|
|
13757
|
-
function bufToHex(buf) {
|
|
13758
|
-
return Array.prototype.map.call(buf, x => ('00' + x.toString(16)).slice(-2)).join('');
|
|
13759
|
-
}
|
|
13760
|
-
|
|
13761
|
-
var bitreader = BitReader$1;
|
|
13762
|
-
|
|
13763
|
-
/* very simple input/output stream interface */
|
|
13764
|
-
|
|
13765
|
-
var Stream$1 = function() {
|
|
13766
|
-
};
|
|
13767
|
-
|
|
13768
|
-
// input streams //////////////
|
|
13769
|
-
/** Returns the next byte, or -1 for EOF. */
|
|
13770
|
-
Stream$1.prototype.readByte = function() {
|
|
13771
|
-
throw new Error("abstract method readByte() not implemented");
|
|
13772
|
-
};
|
|
13773
|
-
/** Attempts to fill the buffer; returns number of bytes read, or
|
|
13774
|
-
* -1 for EOF. */
|
|
13775
|
-
Stream$1.prototype.read = function(buffer, bufOffset, length) {
|
|
13776
|
-
var bytesRead = 0;
|
|
13777
|
-
while (bytesRead < length) {
|
|
13778
|
-
var c = this.readByte();
|
|
13779
|
-
if (c < 0) { // EOF
|
|
13780
|
-
return (bytesRead===0) ? -1 : bytesRead;
|
|
13781
|
-
}
|
|
13782
|
-
buffer[bufOffset++] = c;
|
|
13783
|
-
bytesRead++;
|
|
13784
|
-
}
|
|
13785
|
-
return bytesRead;
|
|
13786
|
-
};
|
|
13787
|
-
Stream$1.prototype.seek = function(new_pos) {
|
|
13788
|
-
throw new Error("abstract method seek() not implemented");
|
|
13789
|
-
};
|
|
13790
|
-
|
|
13791
|
-
// output streams ///////////
|
|
13792
|
-
Stream$1.prototype.writeByte = function(_byte) {
|
|
13793
|
-
throw new Error("abstract method readByte() not implemented");
|
|
13794
|
-
};
|
|
13795
|
-
Stream$1.prototype.write = function(buffer, bufOffset, length) {
|
|
13796
|
-
var i;
|
|
13797
|
-
for (i=0; i<length; i++) {
|
|
13798
|
-
this.writeByte(buffer[bufOffset++]);
|
|
13799
|
-
}
|
|
13800
|
-
return length;
|
|
13801
|
-
};
|
|
13802
|
-
Stream$1.prototype.flush = function() {
|
|
13803
|
-
};
|
|
13804
|
-
|
|
13805
|
-
var stream = Stream$1;
|
|
13806
|
-
|
|
13807
|
-
/* CRC32, used in Bzip2 implementation.
|
|
13808
|
-
* This is a port of CRC32.java from the jbzip2 implementation at
|
|
13809
|
-
* https://code.google.com/p/jbzip2
|
|
13810
|
-
* which is:
|
|
13811
|
-
* Copyright (c) 2011 Matthew Francis
|
|
13812
|
-
*
|
|
13813
|
-
* Permission is hereby granted, free of charge, to any person
|
|
13814
|
-
* obtaining a copy of this software and associated documentation
|
|
13815
|
-
* files (the "Software"), to deal in the Software without
|
|
13816
|
-
* restriction, including without limitation the rights to use,
|
|
13817
|
-
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13818
|
-
* copies of the Software, and to permit persons to whom the
|
|
13819
|
-
* Software is furnished to do so, subject to the following
|
|
13820
|
-
* conditions:
|
|
13821
|
-
*
|
|
13822
|
-
* The above copyright notice and this permission notice shall be
|
|
13823
|
-
* included in all copies or substantial portions of the Software.
|
|
13824
|
-
*
|
|
13825
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
13826
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
13827
|
-
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
13828
|
-
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
13829
|
-
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
13830
|
-
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
13831
|
-
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
13832
|
-
* OTHER DEALINGS IN THE SOFTWARE.
|
|
13833
|
-
* This JavaScript implementation is:
|
|
13834
|
-
* Copyright (c) 2013 C. Scott Ananian
|
|
13835
|
-
* with the same licensing terms as Matthew Francis' original implementation.
|
|
13836
|
-
*/
|
|
13837
|
-
|
|
13838
|
-
var crc32 = (function() {
|
|
13839
|
-
|
|
13840
|
-
/**
|
|
13841
|
-
* A static CRC lookup table
|
|
13842
|
-
*/
|
|
13843
|
-
var crc32Lookup = new Uint32Array([
|
|
13844
|
-
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
|
|
13845
|
-
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
|
13846
|
-
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
|
13847
|
-
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
|
|
13848
|
-
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
|
|
13849
|
-
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
|
13850
|
-
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
|
13851
|
-
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
|
|
13852
|
-
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
|
13853
|
-
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
|
|
13854
|
-
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
|
|
13855
|
-
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
|
13856
|
-
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
|
|
13857
|
-
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
|
|
13858
|
-
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
|
13859
|
-
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
|
|
13860
|
-
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
|
13861
|
-
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
|
13862
|
-
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
|
|
13863
|
-
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
|
|
13864
|
-
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
|
13865
|
-
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
|
13866
|
-
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
|
|
13867
|
-
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
|
13868
|
-
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
|
|
13869
|
-
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
|
|
13870
|
-
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
|
13871
|
-
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
|
|
13872
|
-
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
|
|
13873
|
-
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
|
13874
|
-
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
|
|
13875
|
-
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
|
13876
|
-
]);
|
|
13877
|
-
|
|
13878
|
-
var CRC32 = function() {
|
|
13879
|
-
/**
|
|
13880
|
-
* The current CRC
|
|
13881
|
-
*/
|
|
13882
|
-
var crc = 0xffffffff;
|
|
13883
|
-
|
|
13884
|
-
/**
|
|
13885
|
-
* @return The current CRC
|
|
13886
|
-
*/
|
|
13887
|
-
this.getCRC = function() {
|
|
13888
|
-
return (~crc) >>> 0; // return an unsigned value
|
|
13889
|
-
};
|
|
13890
|
-
|
|
13891
|
-
/**
|
|
13892
|
-
* Update the CRC with a single byte
|
|
13893
|
-
* @param value The value to update the CRC with
|
|
13894
|
-
*/
|
|
13895
|
-
this.updateCRC = function(value) {
|
|
13896
|
-
crc = (crc << 8) ^ crc32Lookup[((crc >>> 24) ^ value) & 0xff];
|
|
13897
|
-
};
|
|
13898
|
-
|
|
13899
|
-
/**
|
|
13900
|
-
* Update the CRC with a sequence of identical bytes
|
|
13901
|
-
* @param value The value to update the CRC with
|
|
13902
|
-
* @param count The number of bytes
|
|
13903
|
-
*/
|
|
13904
|
-
this.updateCRCRun = function(value, count) {
|
|
13905
|
-
while (count-- > 0) {
|
|
13906
|
-
crc = (crc << 8) ^ crc32Lookup[((crc >>> 24) ^ value) & 0xff];
|
|
13907
|
-
}
|
|
13908
|
-
};
|
|
13909
|
-
};
|
|
13910
|
-
return CRC32;
|
|
13911
|
-
})();
|
|
13912
|
-
|
|
13913
|
-
/*
|
|
13914
|
-
seek-bzip - a pure-javascript module for seeking within bzip2 data
|
|
13915
|
-
|
|
13916
|
-
Copyright (C) 2013 C. Scott Ananian
|
|
13917
|
-
Copyright (C) 2012 Eli Skeggs
|
|
13918
|
-
Copyright (C) 2011 Kevin Kwok
|
|
13919
|
-
|
|
13920
|
-
This library is free software; you can redistribute it and/or
|
|
13921
|
-
modify it under the terms of the GNU Lesser General Public
|
|
13922
|
-
License as published by the Free Software Foundation; either
|
|
13923
|
-
version 2.1 of the License, or (at your option) any later version.
|
|
13924
|
-
|
|
13925
|
-
This library is distributed in the hope that it will be useful,
|
|
13926
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13927
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13928
|
-
Lesser General Public License for more details.
|
|
13929
|
-
|
|
13930
|
-
You should have received a copy of the GNU Lesser General Public
|
|
13931
|
-
License along with this library; if not, see
|
|
13932
|
-
http://www.gnu.org/licenses/lgpl-2.1.html
|
|
13933
|
-
|
|
13934
|
-
Adapted from node-bzip, copyright 2012 Eli Skeggs.
|
|
13935
|
-
Adapted from bzip2.js, copyright 2011 Kevin Kwok (antimatter15@gmail.com).
|
|
13936
|
-
|
|
13937
|
-
Based on micro-bunzip by Rob Landley (rob@landley.net).
|
|
13938
|
-
|
|
13939
|
-
Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
|
|
13940
|
-
which also acknowledges contributions by Mike Burrows, David Wheeler,
|
|
13941
|
-
Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
|
|
13942
|
-
Robert Sedgewick, and Jon L. Bentley.
|
|
13943
|
-
*/
|
|
13944
|
-
|
|
13945
|
-
var BitReader = bitreader;
|
|
13946
|
-
var Stream = stream;
|
|
13947
|
-
var CRC32 = crc32;
|
|
13948
|
-
|
|
13949
|
-
var MAX_HUFCODE_BITS = 20;
|
|
13950
|
-
var MAX_SYMBOLS = 258;
|
|
13951
|
-
var SYMBOL_RUNA = 0;
|
|
13952
|
-
var SYMBOL_RUNB = 1;
|
|
13953
|
-
var MIN_GROUPS = 2;
|
|
13954
|
-
var MAX_GROUPS = 6;
|
|
13955
|
-
var GROUP_SIZE = 50;
|
|
13956
|
-
|
|
13957
|
-
var WHOLEPI = "314159265359";
|
|
13958
|
-
var SQRTPI = "177245385090";
|
|
13959
|
-
|
|
13960
|
-
var mtf = function(array, index) {
|
|
13961
|
-
var src = array[index], i;
|
|
13962
|
-
for (i = index; i > 0; i--) {
|
|
13963
|
-
array[i] = array[i-1];
|
|
13964
|
-
}
|
|
13965
|
-
array[0] = src;
|
|
13966
|
-
return src;
|
|
13967
|
-
};
|
|
13968
|
-
|
|
13969
|
-
var Err = {
|
|
13970
|
-
OK: 0,
|
|
13971
|
-
LAST_BLOCK: -1,
|
|
13972
|
-
NOT_BZIP_DATA: -2,
|
|
13973
|
-
UNEXPECTED_INPUT_EOF: -3,
|
|
13974
|
-
UNEXPECTED_OUTPUT_EOF: -4,
|
|
13975
|
-
DATA_ERROR: -5,
|
|
13976
|
-
OUT_OF_MEMORY: -6,
|
|
13977
|
-
OBSOLETE_INPUT: -7,
|
|
13978
|
-
END_OF_BLOCK: -8
|
|
13979
|
-
};
|
|
13980
|
-
var ErrorMessages = {};
|
|
13981
|
-
ErrorMessages[Err.LAST_BLOCK] = "Bad file checksum";
|
|
13982
|
-
ErrorMessages[Err.NOT_BZIP_DATA] = "Not bzip data";
|
|
13983
|
-
ErrorMessages[Err.UNEXPECTED_INPUT_EOF] = "Unexpected input EOF";
|
|
13984
|
-
ErrorMessages[Err.UNEXPECTED_OUTPUT_EOF] = "Unexpected output EOF";
|
|
13985
|
-
ErrorMessages[Err.DATA_ERROR] = "Data error";
|
|
13986
|
-
ErrorMessages[Err.OUT_OF_MEMORY] = "Out of memory";
|
|
13987
|
-
ErrorMessages[Err.OBSOLETE_INPUT] = "Obsolete (pre 0.9.5) bzip format not supported.";
|
|
13988
|
-
|
|
13989
|
-
var _throw = function(status, optDetail) {
|
|
13990
|
-
var msg = ErrorMessages[status] || 'unknown error';
|
|
13991
|
-
if (optDetail) { msg += ': '+optDetail; }
|
|
13992
|
-
var e = new TypeError(msg);
|
|
13993
|
-
e.errorCode = status;
|
|
13994
|
-
throw e;
|
|
13995
|
-
};
|
|
13996
|
-
|
|
13997
|
-
var Bunzip = function(inputStream, outputStream) {
|
|
13998
|
-
this.writePos = this.writeCurrent = this.writeCount = 0;
|
|
13999
|
-
|
|
14000
|
-
this._start_bunzip(inputStream, outputStream);
|
|
14001
|
-
};
|
|
14002
|
-
Bunzip.prototype._init_block = function() {
|
|
14003
|
-
var moreBlocks = this._get_next_block();
|
|
14004
|
-
if ( !moreBlocks ) {
|
|
14005
|
-
this.writeCount = -1;
|
|
14006
|
-
return false; /* no more blocks */
|
|
14007
|
-
}
|
|
14008
|
-
this.blockCRC = new CRC32();
|
|
14009
|
-
return true;
|
|
14010
|
-
};
|
|
14011
|
-
/* XXX micro-bunzip uses (inputStream, inputBuffer, len) as arguments */
|
|
14012
|
-
Bunzip.prototype._start_bunzip = function(inputStream, outputStream) {
|
|
14013
|
-
/* Ensure that file starts with "BZh['1'-'9']." */
|
|
14014
|
-
var buf = new Uint8Array(4);
|
|
14015
|
-
if (inputStream.read(buf, 0, 4) !== 4 ||
|
|
14016
|
-
String.fromCharCode(buf[0], buf[1], buf[2]) !== 'BZh')
|
|
14017
|
-
_throw(Err.NOT_BZIP_DATA, 'bad magic');
|
|
14018
|
-
|
|
14019
|
-
var level = buf[3] - 0x30;
|
|
14020
|
-
if (level < 1 || level > 9)
|
|
14021
|
-
_throw(Err.NOT_BZIP_DATA, 'level out of range');
|
|
14022
|
-
|
|
14023
|
-
this.reader = new BitReader(inputStream);
|
|
14024
|
-
|
|
14025
|
-
/* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
|
|
14026
|
-
uncompressed data. Allocate intermediate buffer for block. */
|
|
14027
|
-
this.dbufSize = 100000 * level;
|
|
14028
|
-
this.nextoutput = 0;
|
|
14029
|
-
this.outputStream = outputStream;
|
|
14030
|
-
this.streamCRC = 0;
|
|
14031
|
-
};
|
|
14032
|
-
Bunzip.prototype._get_next_block = function() {
|
|
14033
|
-
var i, j, k;
|
|
14034
|
-
var reader = this.reader;
|
|
14035
|
-
// this is get_next_block() function from micro-bunzip:
|
|
14036
|
-
/* Read in header signature and CRC, then validate signature.
|
|
14037
|
-
(last block signature means CRC is for whole file, return now) */
|
|
14038
|
-
var h = reader.pi();
|
|
14039
|
-
if (h === SQRTPI) { // last block
|
|
14040
|
-
return false; /* no more blocks */
|
|
14041
|
-
}
|
|
14042
|
-
if (h !== WHOLEPI)
|
|
14043
|
-
_throw(Err.NOT_BZIP_DATA);
|
|
14044
|
-
this.targetBlockCRC = reader.read(32) >>> 0; // (convert to unsigned)
|
|
14045
|
-
this.streamCRC = (this.targetBlockCRC ^
|
|
14046
|
-
((this.streamCRC << 1) | (this.streamCRC>>>31))) >>> 0;
|
|
14047
|
-
/* We can add support for blockRandomised if anybody complains. There was
|
|
14048
|
-
some code for this in busybox 1.0.0-pre3, but nobody ever noticed that
|
|
14049
|
-
it didn't actually work. */
|
|
14050
|
-
if (reader.read(1))
|
|
14051
|
-
_throw(Err.OBSOLETE_INPUT);
|
|
14052
|
-
var origPointer = reader.read(24);
|
|
14053
|
-
if (origPointer > this.dbufSize)
|
|
14054
|
-
_throw(Err.DATA_ERROR, 'initial position out of bounds');
|
|
14055
|
-
/* mapping table: if some byte values are never used (encoding things
|
|
14056
|
-
like ascii text), the compression code removes the gaps to have fewer
|
|
14057
|
-
symbols to deal with, and writes a sparse bitfield indicating which
|
|
14058
|
-
values were present. We make a translation table to convert the symbols
|
|
14059
|
-
back to the corresponding bytes. */
|
|
14060
|
-
var t = reader.read(16);
|
|
14061
|
-
var symToByte = new Uint8Array(256), symTotal = 0;
|
|
14062
|
-
for (i = 0; i < 16; i++) {
|
|
14063
|
-
if (t & (1 << (0xF - i))) {
|
|
14064
|
-
var o = i * 16;
|
|
14065
|
-
k = reader.read(16);
|
|
14066
|
-
for (j = 0; j < 16; j++)
|
|
14067
|
-
if (k & (1 << (0xF - j)))
|
|
14068
|
-
symToByte[symTotal++] = o + j;
|
|
14069
|
-
}
|
|
14070
|
-
}
|
|
14071
|
-
|
|
14072
|
-
/* How many different huffman coding groups does this block use? */
|
|
14073
|
-
var groupCount = reader.read(3);
|
|
14074
|
-
if (groupCount < MIN_GROUPS || groupCount > MAX_GROUPS)
|
|
14075
|
-
_throw(Err.DATA_ERROR);
|
|
14076
|
-
/* nSelectors: Every GROUP_SIZE many symbols we select a new huffman coding
|
|
14077
|
-
group. Read in the group selector list, which is stored as MTF encoded
|
|
14078
|
-
bit runs. (MTF=Move To Front, as each value is used it's moved to the
|
|
14079
|
-
start of the list.) */
|
|
14080
|
-
var nSelectors = reader.read(15);
|
|
14081
|
-
if (nSelectors === 0)
|
|
14082
|
-
_throw(Err.DATA_ERROR);
|
|
14083
|
-
|
|
14084
|
-
var mtfSymbol = new Uint8Array(256);
|
|
14085
|
-
for (i = 0; i < groupCount; i++)
|
|
14086
|
-
mtfSymbol[i] = i;
|
|
14087
|
-
|
|
14088
|
-
var selectors = new Uint8Array(nSelectors); // was 32768...
|
|
14089
|
-
|
|
14090
|
-
for (i = 0; i < nSelectors; i++) {
|
|
14091
|
-
/* Get next value */
|
|
14092
|
-
for (j = 0; reader.read(1); j++)
|
|
14093
|
-
if (j >= groupCount) _throw(Err.DATA_ERROR);
|
|
14094
|
-
/* Decode MTF to get the next selector */
|
|
14095
|
-
selectors[i] = mtf(mtfSymbol, j);
|
|
14096
|
-
}
|
|
14097
|
-
|
|
14098
|
-
/* Read the huffman coding tables for each group, which code for symTotal
|
|
14099
|
-
literal symbols, plus two run symbols (RUNA, RUNB) */
|
|
14100
|
-
var symCount = symTotal + 2;
|
|
14101
|
-
var groups = [], hufGroup;
|
|
14102
|
-
for (j = 0; j < groupCount; j++) {
|
|
14103
|
-
var length = new Uint8Array(symCount), temp = new Uint16Array(MAX_HUFCODE_BITS + 1);
|
|
14104
|
-
/* Read huffman code lengths for each symbol. They're stored in
|
|
14105
|
-
a way similar to mtf; record a starting value for the first symbol,
|
|
14106
|
-
and an offset from the previous value for everys symbol after that. */
|
|
14107
|
-
t = reader.read(5); // lengths
|
|
14108
|
-
for (i = 0; i < symCount; i++) {
|
|
14109
|
-
for (;;) {
|
|
14110
|
-
if (t < 1 || t > MAX_HUFCODE_BITS) _throw(Err.DATA_ERROR);
|
|
14111
|
-
/* If first bit is 0, stop. Else second bit indicates whether
|
|
14112
|
-
to increment or decrement the value. */
|
|
14113
|
-
if(!reader.read(1))
|
|
14114
|
-
break;
|
|
14115
|
-
if(!reader.read(1))
|
|
14116
|
-
t++;
|
|
14117
|
-
else
|
|
14118
|
-
t--;
|
|
14119
|
-
}
|
|
14120
|
-
length[i] = t;
|
|
14121
|
-
}
|
|
14122
|
-
|
|
14123
|
-
/* Find largest and smallest lengths in this group */
|
|
14124
|
-
var minLen, maxLen;
|
|
14125
|
-
minLen = maxLen = length[0];
|
|
14126
|
-
for (i = 1; i < symCount; i++) {
|
|
14127
|
-
if (length[i] > maxLen)
|
|
14128
|
-
maxLen = length[i];
|
|
14129
|
-
else if (length[i] < minLen)
|
|
14130
|
-
minLen = length[i];
|
|
14131
|
-
}
|
|
14132
|
-
|
|
14133
|
-
/* Calculate permute[], base[], and limit[] tables from length[].
|
|
14134
|
-
*
|
|
14135
|
-
* permute[] is the lookup table for converting huffman coded symbols
|
|
14136
|
-
* into decoded symbols. base[] is the amount to subtract from the
|
|
14137
|
-
* value of a huffman symbol of a given length when using permute[].
|
|
14138
|
-
*
|
|
14139
|
-
* limit[] indicates the largest numerical value a symbol with a given
|
|
14140
|
-
* number of bits can have. This is how the huffman codes can vary in
|
|
14141
|
-
* length: each code with a value>limit[length] needs another bit.
|
|
14142
|
-
*/
|
|
14143
|
-
hufGroup = {};
|
|
14144
|
-
groups.push(hufGroup);
|
|
14145
|
-
hufGroup.permute = new Uint16Array(MAX_SYMBOLS);
|
|
14146
|
-
hufGroup.limit = new Uint32Array(MAX_HUFCODE_BITS + 2);
|
|
14147
|
-
hufGroup.base = new Uint32Array(MAX_HUFCODE_BITS + 1);
|
|
14148
|
-
hufGroup.minLen = minLen;
|
|
14149
|
-
hufGroup.maxLen = maxLen;
|
|
14150
|
-
/* Calculate permute[]. Concurently, initialize temp[] and limit[]. */
|
|
14151
|
-
var pp = 0;
|
|
14152
|
-
for (i = minLen; i <= maxLen; i++) {
|
|
14153
|
-
temp[i] = hufGroup.limit[i] = 0;
|
|
14154
|
-
for (t = 0; t < symCount; t++)
|
|
14155
|
-
if (length[t] === i)
|
|
14156
|
-
hufGroup.permute[pp++] = t;
|
|
14157
|
-
}
|
|
14158
|
-
/* Count symbols coded for at each bit length */
|
|
14159
|
-
for (i = 0; i < symCount; i++)
|
|
14160
|
-
temp[length[i]]++;
|
|
14161
|
-
/* Calculate limit[] (the largest symbol-coding value at each bit
|
|
14162
|
-
* length, which is (previous limit<<1)+symbols at this level), and
|
|
14163
|
-
* base[] (number of symbols to ignore at each bit length, which is
|
|
14164
|
-
* limit minus the cumulative count of symbols coded for already). */
|
|
14165
|
-
pp = t = 0;
|
|
14166
|
-
for (i = minLen; i < maxLen; i++) {
|
|
14167
|
-
pp += temp[i];
|
|
14168
|
-
/* We read the largest possible symbol size and then unget bits
|
|
14169
|
-
after determining how many we need, and those extra bits could
|
|
14170
|
-
be set to anything. (They're noise from future symbols.) At
|
|
14171
|
-
each level we're really only interested in the first few bits,
|
|
14172
|
-
so here we set all the trailing to-be-ignored bits to 1 so they
|
|
14173
|
-
don't affect the value>limit[length] comparison. */
|
|
14174
|
-
hufGroup.limit[i] = pp - 1;
|
|
14175
|
-
pp <<= 1;
|
|
14176
|
-
t += temp[i];
|
|
14177
|
-
hufGroup.base[i + 1] = pp - t;
|
|
14178
|
-
}
|
|
14179
|
-
hufGroup.limit[maxLen + 1] = Number.MAX_VALUE; /* Sentinal value for reading next sym. */
|
|
14180
|
-
hufGroup.limit[maxLen] = pp + temp[maxLen] - 1;
|
|
14181
|
-
hufGroup.base[minLen] = 0;
|
|
14182
|
-
}
|
|
14183
|
-
/* We've finished reading and digesting the block header. Now read this
|
|
14184
|
-
block's huffman coded symbols from the file and undo the huffman coding
|
|
14185
|
-
and run length encoding, saving the result into dbuf[dbufCount++]=uc */
|
|
14186
|
-
|
|
14187
|
-
/* Initialize symbol occurrence counters and symbol Move To Front table */
|
|
14188
|
-
var byteCount = new Uint32Array(256);
|
|
14189
|
-
for (i = 0; i < 256; i++)
|
|
14190
|
-
mtfSymbol[i] = i;
|
|
14191
|
-
/* Loop through compressed symbols. */
|
|
14192
|
-
var runPos = 0, dbufCount = 0, selector = 0, uc;
|
|
14193
|
-
var dbuf = this.dbuf = new Uint32Array(this.dbufSize);
|
|
14194
|
-
symCount = 0;
|
|
14195
|
-
for (;;) {
|
|
14196
|
-
/* Determine which huffman coding group to use. */
|
|
14197
|
-
if (!(symCount--)) {
|
|
14198
|
-
symCount = GROUP_SIZE - 1;
|
|
14199
|
-
if (selector >= nSelectors) { _throw(Err.DATA_ERROR); }
|
|
14200
|
-
hufGroup = groups[selectors[selector++]];
|
|
14201
|
-
}
|
|
14202
|
-
/* Read next huffman-coded symbol. */
|
|
14203
|
-
i = hufGroup.minLen;
|
|
14204
|
-
j = reader.read(i);
|
|
14205
|
-
for (;;i++) {
|
|
14206
|
-
if (i > hufGroup.maxLen) { _throw(Err.DATA_ERROR); }
|
|
14207
|
-
if (j <= hufGroup.limit[i])
|
|
14208
|
-
break;
|
|
14209
|
-
j = (j << 1) | reader.read(1);
|
|
14210
|
-
}
|
|
14211
|
-
/* Huffman decode value to get nextSym (with bounds checking) */
|
|
14212
|
-
j -= hufGroup.base[i];
|
|
14213
|
-
if (j < 0 || j >= MAX_SYMBOLS) { _throw(Err.DATA_ERROR); }
|
|
14214
|
-
var nextSym = hufGroup.permute[j];
|
|
14215
|
-
/* We have now decoded the symbol, which indicates either a new literal
|
|
14216
|
-
byte, or a repeated run of the most recent literal byte. First,
|
|
14217
|
-
check if nextSym indicates a repeated run, and if so loop collecting
|
|
14218
|
-
how many times to repeat the last literal. */
|
|
14219
|
-
if (nextSym === SYMBOL_RUNA || nextSym === SYMBOL_RUNB) {
|
|
14220
|
-
/* If this is the start of a new run, zero out counter */
|
|
14221
|
-
if (!runPos){
|
|
14222
|
-
runPos = 1;
|
|
14223
|
-
t = 0;
|
|
14224
|
-
}
|
|
14225
|
-
/* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
|
|
14226
|
-
each bit position, add 1 or 2 instead. For example,
|
|
14227
|
-
1011 is 1<<0 + 1<<1 + 2<<2. 1010 is 2<<0 + 2<<1 + 1<<2.
|
|
14228
|
-
You can make any bit pattern that way using 1 less symbol than
|
|
14229
|
-
the basic or 0/1 method (except all bits 0, which would use no
|
|
14230
|
-
symbols, but a run of length 0 doesn't mean anything in this
|
|
14231
|
-
context). Thus space is saved. */
|
|
14232
|
-
if (nextSym === SYMBOL_RUNA)
|
|
14233
|
-
t += runPos;
|
|
14234
|
-
else
|
|
14235
|
-
t += 2 * runPos;
|
|
14236
|
-
runPos <<= 1;
|
|
14237
|
-
continue;
|
|
14238
|
-
}
|
|
14239
|
-
/* When we hit the first non-run symbol after a run, we now know
|
|
14240
|
-
how many times to repeat the last literal, so append that many
|
|
14241
|
-
copies to our buffer of decoded symbols (dbuf) now. (The last
|
|
14242
|
-
literal used is the one at the head of the mtfSymbol array.) */
|
|
14243
|
-
if (runPos){
|
|
14244
|
-
runPos = 0;
|
|
14245
|
-
if (dbufCount + t > this.dbufSize) { _throw(Err.DATA_ERROR); }
|
|
14246
|
-
uc = symToByte[mtfSymbol[0]];
|
|
14247
|
-
byteCount[uc] += t;
|
|
14248
|
-
while (t--)
|
|
14249
|
-
dbuf[dbufCount++] = uc;
|
|
14250
|
-
}
|
|
14251
|
-
/* Is this the terminating symbol? */
|
|
14252
|
-
if (nextSym > symTotal)
|
|
14253
|
-
break;
|
|
14254
|
-
/* At this point, nextSym indicates a new literal character. Subtract
|
|
14255
|
-
one to get the position in the MTF array at which this literal is
|
|
14256
|
-
currently to be found. (Note that the result can't be -1 or 0,
|
|
14257
|
-
because 0 and 1 are RUNA and RUNB. But another instance of the
|
|
14258
|
-
first symbol in the mtf array, position 0, would have been handled
|
|
14259
|
-
as part of a run above. Therefore 1 unused mtf position minus
|
|
14260
|
-
2 non-literal nextSym values equals -1.) */
|
|
14261
|
-
if (dbufCount >= this.dbufSize) { _throw(Err.DATA_ERROR); }
|
|
14262
|
-
i = nextSym - 1;
|
|
14263
|
-
uc = mtf(mtfSymbol, i);
|
|
14264
|
-
uc = symToByte[uc];
|
|
14265
|
-
/* We have our literal byte. Save it into dbuf. */
|
|
14266
|
-
byteCount[uc]++;
|
|
14267
|
-
dbuf[dbufCount++] = uc;
|
|
14268
|
-
}
|
|
14269
|
-
/* At this point, we've read all the huffman-coded symbols (and repeated
|
|
14270
|
-
runs) for this block from the input stream, and decoded them into the
|
|
14271
|
-
intermediate buffer. There are dbufCount many decoded bytes in dbuf[].
|
|
14272
|
-
Now undo the Burrows-Wheeler transform on dbuf.
|
|
14273
|
-
See http://dogma.net/markn/articles/bwt/bwt.htm
|
|
14274
|
-
*/
|
|
14275
|
-
if (origPointer < 0 || origPointer >= dbufCount) { _throw(Err.DATA_ERROR); }
|
|
14276
|
-
/* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
|
|
14277
|
-
j = 0;
|
|
14278
|
-
for (i = 0; i < 256; i++) {
|
|
14279
|
-
k = j + byteCount[i];
|
|
14280
|
-
byteCount[i] = j;
|
|
14281
|
-
j = k;
|
|
14282
|
-
}
|
|
14283
|
-
/* Figure out what order dbuf would be in if we sorted it. */
|
|
14284
|
-
for (i = 0; i < dbufCount; i++) {
|
|
14285
|
-
uc = dbuf[i] & 0xff;
|
|
14286
|
-
dbuf[byteCount[uc]] |= (i << 8);
|
|
14287
|
-
byteCount[uc]++;
|
|
14288
|
-
}
|
|
14289
|
-
/* Decode first byte by hand to initialize "previous" byte. Note that it
|
|
14290
|
-
doesn't get output, and if the first three characters are identical
|
|
14291
|
-
it doesn't qualify as a run (hence writeRunCountdown=5). */
|
|
14292
|
-
var pos = 0, current = 0, run = 0;
|
|
14293
|
-
if (dbufCount) {
|
|
14294
|
-
pos = dbuf[origPointer];
|
|
14295
|
-
current = (pos & 0xff);
|
|
14296
|
-
pos >>= 8;
|
|
14297
|
-
run = -1;
|
|
14298
|
-
}
|
|
14299
|
-
this.writePos = pos;
|
|
14300
|
-
this.writeCurrent = current;
|
|
14301
|
-
this.writeCount = dbufCount;
|
|
14302
|
-
this.writeRun = run;
|
|
14303
|
-
|
|
14304
|
-
return true; /* more blocks to come */
|
|
14305
|
-
};
|
|
14306
|
-
/* Undo burrows-wheeler transform on intermediate buffer to produce output.
|
|
14307
|
-
If start_bunzip was initialized with out_fd=-1, then up to len bytes of
|
|
14308
|
-
data are written to outbuf. Return value is number of bytes written or
|
|
14309
|
-
error (all errors are negative numbers). If out_fd!=-1, outbuf and len
|
|
14310
|
-
are ignored, data is written to out_fd and return is RETVAL_OK or error.
|
|
14311
|
-
*/
|
|
14312
|
-
Bunzip.prototype._read_bunzip = function(outputBuffer, len) {
|
|
14313
|
-
var copies, previous, outbyte;
|
|
14314
|
-
/* james@jamestaylor.org: writeCount goes to -1 when the buffer is fully
|
|
14315
|
-
decoded, which results in this returning RETVAL_LAST_BLOCK, also
|
|
14316
|
-
equal to -1... Confusing, I'm returning 0 here to indicate no
|
|
14317
|
-
bytes written into the buffer */
|
|
14318
|
-
if (this.writeCount < 0) { return 0; }
|
|
14319
|
-
var dbuf = this.dbuf, pos = this.writePos, current = this.writeCurrent;
|
|
14320
|
-
var dbufCount = this.writeCount; this.outputsize;
|
|
14321
|
-
var run = this.writeRun;
|
|
14322
|
-
|
|
14323
|
-
while (dbufCount) {
|
|
14324
|
-
dbufCount--;
|
|
14325
|
-
previous = current;
|
|
14326
|
-
pos = dbuf[pos];
|
|
14327
|
-
current = pos & 0xff;
|
|
14328
|
-
pos >>= 8;
|
|
14329
|
-
if (run++ === 3){
|
|
14330
|
-
copies = current;
|
|
14331
|
-
outbyte = previous;
|
|
14332
|
-
current = -1;
|
|
14333
|
-
} else {
|
|
14334
|
-
copies = 1;
|
|
14335
|
-
outbyte = current;
|
|
14336
|
-
}
|
|
14337
|
-
this.blockCRC.updateCRCRun(outbyte, copies);
|
|
14338
|
-
while (copies--) {
|
|
14339
|
-
this.outputStream.writeByte(outbyte);
|
|
14340
|
-
this.nextoutput++;
|
|
14341
|
-
}
|
|
14342
|
-
if (current != previous)
|
|
14343
|
-
run = 0;
|
|
14344
|
-
}
|
|
14345
|
-
this.writeCount = dbufCount;
|
|
14346
|
-
// check CRC
|
|
14347
|
-
if (this.blockCRC.getCRC() !== this.targetBlockCRC) {
|
|
14348
|
-
_throw(Err.DATA_ERROR, "Bad block CRC "+
|
|
14349
|
-
"(got "+this.blockCRC.getCRC().toString(16)+
|
|
14350
|
-
" expected "+this.targetBlockCRC.toString(16)+")");
|
|
14351
|
-
}
|
|
14352
|
-
return this.nextoutput;
|
|
14353
|
-
};
|
|
14354
|
-
|
|
14355
|
-
var coerceInputStream = function(input) {
|
|
14356
|
-
if ('readByte' in input) { return input; }
|
|
14357
|
-
var inputStream = new Stream();
|
|
14358
|
-
inputStream.pos = 0;
|
|
14359
|
-
inputStream.readByte = function() { return input[this.pos++]; };
|
|
14360
|
-
inputStream.seek = function(pos) { this.pos = pos; };
|
|
14361
|
-
inputStream.eof = function() { return this.pos >= input.length; };
|
|
14362
|
-
return inputStream;
|
|
14363
|
-
};
|
|
14364
|
-
var coerceOutputStream = function(output) {
|
|
14365
|
-
var outputStream = new Stream();
|
|
14366
|
-
var resizeOk = true;
|
|
14367
|
-
if (output) {
|
|
14368
|
-
if (typeof(output)==='number') {
|
|
14369
|
-
outputStream.buffer = new Uint8Array(output);
|
|
14370
|
-
resizeOk = false;
|
|
14371
|
-
} else if ('writeByte' in output) {
|
|
14372
|
-
return output;
|
|
14373
|
-
} else {
|
|
14374
|
-
outputStream.buffer = output;
|
|
14375
|
-
resizeOk = false;
|
|
14376
|
-
}
|
|
14377
|
-
} else {
|
|
14378
|
-
outputStream.buffer = new Uint8Array(16384);
|
|
14379
|
-
}
|
|
14380
|
-
outputStream.pos = 0;
|
|
14381
|
-
outputStream.writeByte = function(_byte) {
|
|
14382
|
-
if (resizeOk && this.pos >= this.buffer.length) {
|
|
14383
|
-
var newBuffer = new Uint8Array(this.buffer.length*2);
|
|
14384
|
-
newBuffer.set(this.buffer);
|
|
14385
|
-
this.buffer = newBuffer;
|
|
14386
|
-
}
|
|
14387
|
-
this.buffer[this.pos++] = _byte;
|
|
14388
|
-
};
|
|
14389
|
-
outputStream.getBuffer = function() {
|
|
14390
|
-
// trim buffer
|
|
14391
|
-
if (this.pos !== this.buffer.length) {
|
|
14392
|
-
if (!resizeOk)
|
|
14393
|
-
throw new TypeError('outputsize does not match decoded input');
|
|
14394
|
-
var newBuffer = new Uint8Array(this.pos);
|
|
14395
|
-
newBuffer.set(this.buffer.subarray(0, this.pos));
|
|
14396
|
-
this.buffer = newBuffer;
|
|
14397
|
-
}
|
|
14398
|
-
return this.buffer;
|
|
14399
|
-
};
|
|
14400
|
-
outputStream._coerced = true;
|
|
14401
|
-
return outputStream;
|
|
14402
|
-
};
|
|
14403
|
-
|
|
14404
|
-
/* Static helper functions */
|
|
14405
|
-
// 'input' can be a stream or a buffer
|
|
14406
|
-
// 'output' can be a stream or a buffer or a number (buffer size)
|
|
14407
|
-
const decode = function(input, output, multistream) {
|
|
14408
|
-
// make a stream from a buffer, if necessary
|
|
14409
|
-
var inputStream = coerceInputStream(input);
|
|
14410
|
-
var outputStream = coerceOutputStream(output);
|
|
14411
|
-
|
|
14412
|
-
var bz = new Bunzip(inputStream, outputStream);
|
|
14413
|
-
while (true) {
|
|
14414
|
-
if ('eof' in inputStream && inputStream.eof()) break;
|
|
14415
|
-
if (bz._init_block()) {
|
|
14416
|
-
bz._read_bunzip();
|
|
14417
|
-
} else {
|
|
14418
|
-
var targetStreamCRC = bz.reader.read(32) >>> 0; // (convert to unsigned)
|
|
14419
|
-
if (targetStreamCRC !== bz.streamCRC) {
|
|
14420
|
-
_throw(Err.DATA_ERROR, "Bad stream CRC "+
|
|
14421
|
-
"(got "+bz.streamCRC.toString(16)+
|
|
14422
|
-
" expected "+targetStreamCRC.toString(16)+")");
|
|
14423
|
-
}
|
|
14424
|
-
if (multistream &&
|
|
14425
|
-
'eof' in inputStream &&
|
|
14426
|
-
!inputStream.eof()) {
|
|
14427
|
-
// note that start_bunzip will also resync the bit reader to next byte
|
|
14428
|
-
bz._start_bunzip(inputStream, outputStream);
|
|
14429
|
-
} else break;
|
|
14430
|
-
}
|
|
14431
|
-
}
|
|
14432
|
-
if ('getBuffer' in outputStream)
|
|
14433
|
-
return outputStream.getBuffer();
|
|
14434
|
-
};
|
|
14435
|
-
const decodeBlock = function(input, pos, output) {
|
|
14436
|
-
// make a stream from a buffer, if necessary
|
|
14437
|
-
var inputStream = coerceInputStream(input);
|
|
14438
|
-
var outputStream = coerceOutputStream(output);
|
|
14439
|
-
var bz = new Bunzip(inputStream, outputStream);
|
|
14440
|
-
bz.reader.seek(pos);
|
|
14441
|
-
/* Fill the decode buffer for the block */
|
|
14442
|
-
var moreBlocks = bz._get_next_block();
|
|
14443
|
-
if (moreBlocks) {
|
|
14444
|
-
/* Init the CRC for writing */
|
|
14445
|
-
bz.blockCRC = new CRC32();
|
|
14446
|
-
|
|
14447
|
-
/* Zero this so the current byte from before the seek is not written */
|
|
14448
|
-
bz.writeCopies = 0;
|
|
14449
|
-
|
|
14450
|
-
/* Decompress the block and write to stdout */
|
|
14451
|
-
bz._read_bunzip();
|
|
14452
|
-
// XXX keep writing?
|
|
14453
|
-
}
|
|
14454
|
-
if ('getBuffer' in outputStream)
|
|
14455
|
-
return outputStream.getBuffer();
|
|
14456
|
-
};
|
|
14457
|
-
/* Reads bzip2 file from stream or buffer `input`, and invoke
|
|
14458
|
-
* `callback(position, size)` once for each bzip2 block,
|
|
14459
|
-
* where position gives the starting position (in *bits*)
|
|
14460
|
-
* and size gives uncompressed size of the block (in *bytes*). */
|
|
14461
|
-
const table = function(input, callback, multistream) {
|
|
14462
|
-
// make a stream from a buffer, if necessary
|
|
14463
|
-
var inputStream = new Stream();
|
|
14464
|
-
inputStream.delegate = coerceInputStream(input);
|
|
14465
|
-
inputStream.pos = 0;
|
|
14466
|
-
inputStream.readByte = function() {
|
|
14467
|
-
this.pos++;
|
|
14468
|
-
return this.delegate.readByte();
|
|
14469
|
-
};
|
|
14470
|
-
if (inputStream.delegate.eof) {
|
|
14471
|
-
inputStream.eof = inputStream.delegate.eof.bind(inputStream.delegate);
|
|
14472
|
-
}
|
|
14473
|
-
var outputStream = new Stream();
|
|
14474
|
-
outputStream.pos = 0;
|
|
14475
|
-
outputStream.writeByte = function() { this.pos++; };
|
|
14476
|
-
|
|
14477
|
-
var bz = new Bunzip(inputStream, outputStream);
|
|
14478
|
-
var blockSize = bz.dbufSize;
|
|
14479
|
-
while (true) {
|
|
14480
|
-
if ('eof' in inputStream && inputStream.eof()) break;
|
|
14481
|
-
|
|
14482
|
-
var position = inputStream.pos*8 + bz.reader.bitOffset;
|
|
14483
|
-
if (bz.reader.hasByte) { position -= 8; }
|
|
14484
|
-
|
|
14485
|
-
if (bz._init_block()) {
|
|
14486
|
-
var start = outputStream.pos;
|
|
14487
|
-
bz._read_bunzip();
|
|
14488
|
-
callback(position, outputStream.pos - start);
|
|
14489
|
-
} else {
|
|
14490
|
-
bz.reader.read(32); // (but we ignore the crc)
|
|
14491
|
-
if (multistream &&
|
|
14492
|
-
'eof' in inputStream &&
|
|
14493
|
-
!inputStream.eof()) {
|
|
14494
|
-
// note that start_bunzip will also resync the bit reader to next byte
|
|
14495
|
-
bz._start_bunzip(inputStream, outputStream);
|
|
14496
|
-
console.assert(bz.dbufSize === blockSize,
|
|
14497
|
-
"shouldn't change block size within multistream file");
|
|
14498
|
-
} else break;
|
|
14499
|
-
}
|
|
14500
|
-
}
|
|
14501
|
-
};
|
|
14502
|
-
|
|
14503
|
-
var lib = {
|
|
14504
|
-
Bunzip,
|
|
14505
|
-
Stream,
|
|
14506
|
-
Err,
|
|
14507
|
-
decode,
|
|
14508
|
-
decodeBlock,
|
|
14509
|
-
table
|
|
14510
|
-
};
|
|
14511
|
-
|
|
14512
14187
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
14513
14188
|
// Copyright (C) 2011 Recurity Labs GmbH
|
|
14514
14189
|
//
|
|
@@ -16161,12 +15836,12 @@ class CompressedDataPacket {
|
|
|
16161
15836
|
*/
|
|
16162
15837
|
async decompress(config$1 = config) {
|
|
16163
15838
|
const compressionName = enums.read(enums.compression, this.algorithm);
|
|
16164
|
-
const decompressionFn = decompress_fns[compressionName];
|
|
15839
|
+
const decompressionFn = decompress_fns[compressionName]; // bzip decompression is async
|
|
16165
15840
|
if (!decompressionFn) {
|
|
16166
15841
|
throw new Error(`${compressionName} decompression not supported`);
|
|
16167
15842
|
}
|
|
16168
15843
|
|
|
16169
|
-
this.packets = await PacketList.fromBinary(decompressionFn(this.compressed), allowedPackets$5, config$1);
|
|
15844
|
+
this.packets = await PacketList.fromBinary(await decompressionFn(this.compressed), allowedPackets$5, config$1);
|
|
16170
15845
|
}
|
|
16171
15846
|
|
|
16172
15847
|
/**
|
|
@@ -16253,9 +15928,10 @@ function zlib(compressionStreamInstantiator, ZlibStreamedConstructor) {
|
|
|
16253
15928
|
};
|
|
16254
15929
|
}
|
|
16255
15930
|
|
|
16256
|
-
function
|
|
16257
|
-
return function(data) {
|
|
16258
|
-
|
|
15931
|
+
function bzip2Decompress() {
|
|
15932
|
+
return async function(data) {
|
|
15933
|
+
const { decode: bunzipDecode } = await import('./seek-bzip.mjs').then(function (n) { return n.i; });
|
|
15934
|
+
return fromAsync(async () => bunzipDecode(await readToEnd(data)));
|
|
16259
15935
|
};
|
|
16260
15936
|
}
|
|
16261
15937
|
|
|
@@ -16280,7 +15956,7 @@ const decompress_fns = {
|
|
|
16280
15956
|
uncompressed: data => data,
|
|
16281
15957
|
zip: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate-raw').decompressor, Inflate),
|
|
16282
15958
|
zlib: /*#__PURE__*/ zlib(getCompressionStreamInstantiators('deflate').decompressor, Unzlib),
|
|
16283
|
-
bzip2: /*#__PURE__*/
|
|
15959
|
+
bzip2: /*#__PURE__*/ bzip2Decompress() // NB: async due to dynamic lib import
|
|
16284
15960
|
};
|
|
16285
15961
|
|
|
16286
15962
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
@@ -16400,6 +16076,16 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
|
|
16400
16076
|
* @async
|
|
16401
16077
|
*/
|
|
16402
16078
|
async encrypt(sessionKeyAlgorithm, key, config$1 = config) {
|
|
16079
|
+
// We check that the session key size matches the one expected by the symmetric algorithm.
|
|
16080
|
+
// This is especially important for SEIPDv2 session keys, as a key derivation step is run where the resulting key will always match the expected cipher size,
|
|
16081
|
+
// but we want to ensure that the input key isn't e.g. too short.
|
|
16082
|
+
// The check is done here, instead of on encrypted session key (ESK) encryption, because v6 ESK packets do not store the session key algorithm,
|
|
16083
|
+
// which is instead included in the SEIPDv2 data.
|
|
16084
|
+
const { blockSize, keySize } = mod.getCipherParams(sessionKeyAlgorithm);
|
|
16085
|
+
if (key.length !== keySize) {
|
|
16086
|
+
throw new Error('Unexpected session key size');
|
|
16087
|
+
}
|
|
16088
|
+
|
|
16403
16089
|
let bytes = this.packets.write();
|
|
16404
16090
|
if (isArrayStream(bytes)) bytes = await readToEnd(bytes);
|
|
16405
16091
|
|
|
@@ -16410,8 +16096,6 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
|
|
16410
16096
|
this.chunkSizeByte = config$1.aeadChunkSizeByte;
|
|
16411
16097
|
this.encrypted = await runAEAD(this, 'encrypt', key, bytes);
|
|
16412
16098
|
} else {
|
|
16413
|
-
const { blockSize } = mod.getCipherParams(sessionKeyAlgorithm);
|
|
16414
|
-
|
|
16415
16099
|
const prefix = await mod.getPrefixRandom(sessionKeyAlgorithm);
|
|
16416
16100
|
const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet
|
|
16417
16101
|
|
|
@@ -16434,11 +16118,24 @@ class SymEncryptedIntegrityProtectedDataPacket {
|
|
|
16434
16118
|
* @async
|
|
16435
16119
|
*/
|
|
16436
16120
|
async decrypt(sessionKeyAlgorithm, key, config$1 = config) {
|
|
16121
|
+
// We check that the session key size matches the one expected by the symmetric algorithm.
|
|
16122
|
+
// This is especially important for SEIPDv2 session keys, as a key derivation step is run where the resulting key will always match the expected cipher size,
|
|
16123
|
+
// but we want to ensure that the input key isn't e.g. too short.
|
|
16124
|
+
// The check is done here, instead of on encrypted session key (ESK) decryption, because v6 ESK packets do not store the session key algorithm,
|
|
16125
|
+
// which is instead included in the SEIPDv2 data.
|
|
16126
|
+
if (key.length !== mod.getCipherParams(sessionKeyAlgorithm).keySize) {
|
|
16127
|
+
throw new Error('Unexpected session key size');
|
|
16128
|
+
}
|
|
16129
|
+
|
|
16437
16130
|
let encrypted = clone(this.encrypted);
|
|
16438
16131
|
if (isArrayStream(encrypted)) encrypted = await readToEnd(encrypted);
|
|
16439
16132
|
|
|
16440
16133
|
let packetbytes;
|
|
16441
16134
|
if (this.version === 2) {
|
|
16135
|
+
if (this.cipherAlgorithm !== sessionKeyAlgorithm) {
|
|
16136
|
+
// sanity check
|
|
16137
|
+
throw new Error('Unexpected session key algorithm');
|
|
16138
|
+
}
|
|
16442
16139
|
packetbytes = await runAEAD(this, 'decrypt', key, encrypted);
|
|
16443
16140
|
} else {
|
|
16444
16141
|
const { blockSize } = mod.getCipherParams(sessionKeyAlgorithm);
|
|
@@ -16718,6 +16415,12 @@ class AEADEncryptedDataPacket {
|
|
|
16718
16415
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
16719
16416
|
|
|
16720
16417
|
|
|
16418
|
+
const algosWithV3CleartextSessionKeyAlgorithm = new Set([
|
|
16419
|
+
enums.publicKey.x25519,
|
|
16420
|
+
enums.publicKey.x448,
|
|
16421
|
+
enums.publicKey.pqc_mlkem_x25519
|
|
16422
|
+
]);
|
|
16423
|
+
|
|
16721
16424
|
/**
|
|
16722
16425
|
* Public-Key Encrypted Session Key Packets (Tag 1)
|
|
16723
16426
|
*
|
|
@@ -16825,7 +16528,7 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
16825
16528
|
}
|
|
16826
16529
|
this.publicKeyAlgorithm = bytes[offset++];
|
|
16827
16530
|
this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(offset));
|
|
16828
|
-
if (
|
|
16531
|
+
if (algosWithV3CleartextSessionKeyAlgorithm.has(this.publicKeyAlgorithm)) {
|
|
16829
16532
|
if (this.version === 3) {
|
|
16830
16533
|
this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm);
|
|
16831
16534
|
} else if (this.encrypted.C.algorithm !== null) {
|
|
@@ -16906,11 +16609,14 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
16906
16609
|
|
|
16907
16610
|
const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey);
|
|
16908
16611
|
|
|
16909
|
-
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
|
|
16913
|
-
|
|
16612
|
+
if (this.version === 3) {
|
|
16613
|
+
// v3 Montgomery curves have cleartext cipher algo
|
|
16614
|
+
const hasEncryptedAlgo = !algosWithV3CleartextSessionKeyAlgorithm.has(this.publicKeyAlgorithm);
|
|
16615
|
+
this.sessionKeyAlgorithm = hasEncryptedAlgo ? sessionKeyAlgorithm : this.sessionKeyAlgorithm;
|
|
16616
|
+
|
|
16617
|
+
if (sessionKey.length !== mod.getCipherParams(this.sessionKeyAlgorithm).keySize) {
|
|
16618
|
+
throw new Error('Unexpected session key size');
|
|
16619
|
+
}
|
|
16914
16620
|
}
|
|
16915
16621
|
this.sessionKey = sessionKey;
|
|
16916
16622
|
}
|
|
@@ -16932,6 +16638,7 @@ function encodeSessionKey(version, keyAlgo, cipherAlgo, sessionKeyData) {
|
|
|
16932
16638
|
]);
|
|
16933
16639
|
case enums.publicKey.x25519:
|
|
16934
16640
|
case enums.publicKey.x448:
|
|
16641
|
+
case enums.publicKey.pqc_mlkem_x25519:
|
|
16935
16642
|
return sessionKeyData;
|
|
16936
16643
|
default:
|
|
16937
16644
|
throw new Error('Unsupported public key algorithm');
|
|
@@ -16980,6 +16687,7 @@ function decodeSessionKey(version, keyAlgo, decryptedData, randomSessionKey) {
|
|
|
16980
16687
|
}
|
|
16981
16688
|
case enums.publicKey.x25519:
|
|
16982
16689
|
case enums.publicKey.x448:
|
|
16690
|
+
case enums.publicKey.pqc_mlkem_x25519:
|
|
16983
16691
|
return {
|
|
16984
16692
|
sessionKeyAlgorithm: null,
|
|
16985
16693
|
sessionKey: decryptedData
|
|
@@ -17040,7 +16748,7 @@ class SymEncryptedSessionKeyPacket {
|
|
|
17040
16748
|
* Algorithm to encrypt the message with
|
|
17041
16749
|
* @type {enums.symmetric}
|
|
17042
16750
|
*/
|
|
17043
|
-
this.sessionKeyAlgorithm =
|
|
16751
|
+
this.sessionKeyAlgorithm = null;
|
|
17044
16752
|
/**
|
|
17045
16753
|
* AEAD mode to encrypt the session key with (if AEAD protection is enabled)
|
|
17046
16754
|
* @type {enums.aead}
|
|
@@ -17161,7 +16869,11 @@ class SymEncryptedSessionKeyPacket {
|
|
|
17161
16869
|
|
|
17162
16870
|
this.sessionKeyAlgorithm = enums.write(enums.symmetric, decrypted[0]);
|
|
17163
16871
|
this.sessionKey = decrypted.subarray(1, decrypted.length);
|
|
16872
|
+
if (this.sessionKey.length !== mod.getCipherParams(this.sessionKeyAlgorithm).keySize) {
|
|
16873
|
+
throw new Error('Unexpected session key size');
|
|
16874
|
+
}
|
|
17164
16875
|
} else {
|
|
16876
|
+
// session key size is checked as part of SEIPDv2 decryption, where we know the expected symmetric algo
|
|
17165
16877
|
this.sessionKey = key;
|
|
17166
16878
|
}
|
|
17167
16879
|
}
|
|
@@ -17341,6 +17053,14 @@ class PublicKeyPacket {
|
|
|
17341
17053
|
) {
|
|
17342
17054
|
throw new Error('Legacy curve25519 cannot be used with v6 keys');
|
|
17343
17055
|
}
|
|
17056
|
+
// The composite ML-DSA + EdDSA schemes MUST be used only with v6 keys.
|
|
17057
|
+
// The composite ML-KEM + ECDH schemes MUST be used only with v6 keys.
|
|
17058
|
+
if (this.version !== 6 && (
|
|
17059
|
+
this.algorithm === enums.publicKey.pqc_mldsa_ed25519 ||
|
|
17060
|
+
this.algorithm === enums.publicKey.pqc_mlkem_x25519
|
|
17061
|
+
)) {
|
|
17062
|
+
throw new Error('Unexpected key version: ML-DSA and ML-KEM algorithms can only be used with v6 keys');
|
|
17063
|
+
}
|
|
17344
17064
|
this.publicParams = publicParams;
|
|
17345
17065
|
pos += read;
|
|
17346
17066
|
|
|
@@ -18024,7 +17744,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
18024
17744
|
}
|
|
18025
17745
|
}
|
|
18026
17746
|
try {
|
|
18027
|
-
const { read, privateParams } = mod.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
|
|
17747
|
+
const { read, privateParams } = await mod.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
|
|
18028
17748
|
if (read < cleartext.length) {
|
|
18029
17749
|
throw new Error('Error reading MPIs');
|
|
18030
17750
|
}
|
|
@@ -18282,7 +18002,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
18282
18002
|
}
|
|
18283
18003
|
|
|
18284
18004
|
try {
|
|
18285
|
-
const { privateParams } = mod.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
|
|
18005
|
+
const { privateParams } = await mod.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
|
|
18286
18006
|
this.privateParams = privateParams;
|
|
18287
18007
|
} catch (err) {
|
|
18288
18008
|
throw new Error('Error reading MPIs');
|
|
@@ -18335,6 +18055,12 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
18335
18055
|
)) {
|
|
18336
18056
|
throw new Error(`Cannot generate v6 keys of type 'ecc' with curve ${curve}. Generate a key of type 'curve25519' instead`);
|
|
18337
18057
|
}
|
|
18058
|
+
if (this.version !== 6 && (
|
|
18059
|
+
this.algorithm === enums.publicKey.pqc_mldsa_ed25519 ||
|
|
18060
|
+
this.algorithm === enums.publicKey.pqc_mlkem_x25519
|
|
18061
|
+
)) {
|
|
18062
|
+
throw new Error(`Cannot generate v${this.version} keys of type 'pqc'. Generate a v6 key instead`);
|
|
18063
|
+
}
|
|
18338
18064
|
const { privateParams, publicParams } = await mod.generateParams(this.algorithm, bits, curve, symmetric);
|
|
18339
18065
|
this.privateParams = privateParams;
|
|
18340
18066
|
this.publicParams = publicParams;
|
|
@@ -18810,7 +18536,7 @@ async function createBindingSignature(subkey, primaryKey, options, config) {
|
|
|
18810
18536
|
const signatureProperties = { signatureType: enums.signature.subkeyBinding };
|
|
18811
18537
|
if (options.sign) {
|
|
18812
18538
|
signatureProperties.keyFlags = [enums.keyFlags.signData];
|
|
18813
|
-
signatureProperties.embeddedSignature = await createSignaturePacket(dataToSign,
|
|
18539
|
+
signatureProperties.embeddedSignature = await createSignaturePacket(dataToSign, [], subkey, {
|
|
18814
18540
|
signatureType: enums.signature.keyBinding
|
|
18815
18541
|
}, options.date, undefined, undefined, undefined, config);
|
|
18816
18542
|
} else {
|
|
@@ -18822,41 +18548,101 @@ async function createBindingSignature(subkey, primaryKey, options, config) {
|
|
|
18822
18548
|
signatureProperties.keyExpirationTime = options.keyExpirationTime;
|
|
18823
18549
|
signatureProperties.keyNeverExpires = false;
|
|
18824
18550
|
}
|
|
18825
|
-
const subkeySignaturePacket = await createSignaturePacket(dataToSign,
|
|
18551
|
+
const subkeySignaturePacket = await createSignaturePacket(dataToSign, [], primaryKey, signatureProperties, options.date, undefined, undefined, undefined, config);
|
|
18826
18552
|
return subkeySignaturePacket;
|
|
18827
18553
|
}
|
|
18828
18554
|
|
|
18829
18555
|
/**
|
|
18830
|
-
* Returns the preferred signature hash algorithm
|
|
18831
|
-
* @param {Key} [
|
|
18832
|
-
* @param {SecretKeyPacket|SecretSubkeyPacket}
|
|
18556
|
+
* Returns the preferred signature hash algorithm for a set of keys.
|
|
18557
|
+
* @param {Array<Key>} [targetKeys] - The keys to get preferences from
|
|
18558
|
+
* @param {SecretKeyPacket|SecretSubkeyPacket} signingKeyPacket - key packet used for signing
|
|
18833
18559
|
* @param {Date} [date] - Use the given date for verification instead of the current time
|
|
18834
|
-
* @param {Object} [
|
|
18560
|
+
* @param {Object} [targetUserID] - User IDs corresponding to `targetKeys` to get preferences from
|
|
18835
18561
|
* @param {Object} config - full configuration
|
|
18836
18562
|
* @returns {Promise<enums.hash>}
|
|
18837
18563
|
* @async
|
|
18838
18564
|
*/
|
|
18839
|
-
async function getPreferredHashAlgo(
|
|
18840
|
-
|
|
18841
|
-
|
|
18842
|
-
|
|
18843
|
-
|
|
18844
|
-
|
|
18845
|
-
|
|
18846
|
-
|
|
18847
|
-
|
|
18565
|
+
async function getPreferredHashAlgo(targetKeys, signingKeyPacket, date = new Date(), targetUserIDs = [], config) {
|
|
18566
|
+
if (signingKeyPacket.algorithm === enums.publicKey.pqc_mldsa_ed25519) {
|
|
18567
|
+
// For PQC, the returned hash algo MUST be set to the specified algorithm, see
|
|
18568
|
+
// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
|
|
18569
|
+
return mod.publicKey.postQuantum.signature.getRequiredHashAlgo(signingKeyPacket.algorithm);
|
|
18570
|
+
}
|
|
18571
|
+
|
|
18572
|
+
/**
|
|
18573
|
+
* If `preferredSenderAlgo` appears in the prefs of all recipients, we pick it; otherwise, we use the
|
|
18574
|
+
* strongest supported algo (`defaultAlgo` is always implicitly supported by all keys).
|
|
18575
|
+
* if no keys are available, `preferredSenderAlgo` is returned.
|
|
18576
|
+
* For ECC signing key, the curve preferred hash is taken into account as well (see logic below).
|
|
18577
|
+
*/
|
|
18578
|
+
const defaultAlgo = enums.hash.sha256; // MUST implement
|
|
18579
|
+
const preferredSenderAlgo = config.preferredHashAlgorithm;
|
|
18580
|
+
|
|
18581
|
+
const supportedAlgosPerTarget = await Promise.all(targetKeys.map(async (key, i) => {
|
|
18582
|
+
const selfCertification = await key.getPrimarySelfSignature(date, targetUserIDs[i], config);
|
|
18583
|
+
const targetPrefs = selfCertification.preferredHashAlgorithms;
|
|
18584
|
+
return targetPrefs;
|
|
18585
|
+
}));
|
|
18586
|
+
const supportedAlgosMap = new Map(); // use Map over object to preserve numeric keys
|
|
18587
|
+
for (const supportedAlgos of supportedAlgosPerTarget) {
|
|
18588
|
+
for (const hashAlgo of supportedAlgos) {
|
|
18589
|
+
try {
|
|
18590
|
+
// ensure that `hashAlgo` is recognized/implemented by us, otherwise e.g. `getHashByteLength` will throw later on
|
|
18591
|
+
const supportedAlgo = enums.write(enums.hash, hashAlgo);
|
|
18592
|
+
supportedAlgosMap.set(
|
|
18593
|
+
supportedAlgo,
|
|
18594
|
+
supportedAlgosMap.has(supportedAlgo) ? supportedAlgosMap.get(supportedAlgo) + 1 : 1
|
|
18595
|
+
);
|
|
18596
|
+
} catch {}
|
|
18848
18597
|
}
|
|
18849
18598
|
}
|
|
18850
|
-
|
|
18851
|
-
|
|
18852
|
-
|
|
18853
|
-
|
|
18854
|
-
|
|
18855
|
-
|
|
18599
|
+
const isSupportedHashAlgo = hashAlgo => targetKeys.length === 0 || supportedAlgosMap.get(hashAlgo) === targetKeys.length || hashAlgo === defaultAlgo;
|
|
18600
|
+
const getStrongestSupportedHashAlgo = () => {
|
|
18601
|
+
if (supportedAlgosMap.size === 0) {
|
|
18602
|
+
return defaultAlgo;
|
|
18603
|
+
}
|
|
18604
|
+
const sortedHashAlgos = Array.from(supportedAlgosMap.keys())
|
|
18605
|
+
.filter(hashAlgo => isSupportedHashAlgo(hashAlgo))
|
|
18606
|
+
.sort((algoA, algoB) => mod.hash.getHashByteLength(algoA) - mod.hash.getHashByteLength(algoB));
|
|
18607
|
+
const strongestHashAlgo = sortedHashAlgos[0];
|
|
18608
|
+
// defaultAlgo is always implicilty supported, and might be stronger than the rest
|
|
18609
|
+
return mod.hash.getHashByteLength(strongestHashAlgo) >= mod.hash.getHashByteLength(defaultAlgo) ? strongestHashAlgo : defaultAlgo;
|
|
18610
|
+
};
|
|
18611
|
+
|
|
18612
|
+
const eccAlgos = new Set([
|
|
18613
|
+
enums.publicKey.ecdsa,
|
|
18614
|
+
enums.publicKey.eddsaLegacy,
|
|
18615
|
+
enums.publicKey.ed25519,
|
|
18616
|
+
enums.publicKey.ed448
|
|
18617
|
+
]);
|
|
18618
|
+
|
|
18619
|
+
if (eccAlgos.has(signingKeyPacket.algorithm)) {
|
|
18620
|
+
// For ECC, the returned hash algo MUST be at least as strong as `preferredCurveHashAlgo`, see:
|
|
18621
|
+
// - ECDSA: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.2-5
|
|
18622
|
+
// - EdDSALegacy: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
|
18623
|
+
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
|
18624
|
+
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
|
18625
|
+
// Hence, we return the `preferredHashAlgo` as long as it's supported and strong enough;
|
|
18626
|
+
// Otherwise, we look at the strongest supported algo, and ultimately fallback to the curve
|
|
18627
|
+
// preferred algo, even if not supported by all targets.
|
|
18628
|
+
const preferredCurveAlgo = mod.getPreferredCurveHashAlgo(signingKeyPacket.algorithm, signingKeyPacket.publicParams.oid);
|
|
18629
|
+
|
|
18630
|
+
const preferredSenderAlgoIsSupported = isSupportedHashAlgo(preferredSenderAlgo);
|
|
18631
|
+
const preferredSenderAlgoStrongerThanCurveAlgo = mod.hash.getHashByteLength(preferredSenderAlgo) >= mod.hash.getHashByteLength(preferredCurveAlgo);
|
|
18632
|
+
|
|
18633
|
+
if (preferredSenderAlgoIsSupported && preferredSenderAlgoStrongerThanCurveAlgo) {
|
|
18634
|
+
return preferredSenderAlgo;
|
|
18635
|
+
} else {
|
|
18636
|
+
const strongestSupportedAlgo = getStrongestSupportedHashAlgo();
|
|
18637
|
+
return mod.hash.getHashByteLength(strongestSupportedAlgo) >= mod.hash.getHashByteLength(preferredCurveAlgo) ?
|
|
18638
|
+
strongestSupportedAlgo :
|
|
18639
|
+
preferredCurveAlgo;
|
|
18640
|
+
}
|
|
18856
18641
|
}
|
|
18857
18642
|
|
|
18858
|
-
|
|
18859
|
-
|
|
18643
|
+
// `preferredSenderAlgo` may be weaker than the default, but we do not guard against this,
|
|
18644
|
+
// since it was manually set by the sender.
|
|
18645
|
+
return isSupportedHashAlgo(preferredSenderAlgo) ? preferredSenderAlgo : getStrongestSupportedHashAlgo();
|
|
18860
18646
|
}
|
|
18861
18647
|
|
|
18862
18648
|
/**
|
|
@@ -18927,7 +18713,7 @@ async function getPreferredCipherSuite(keys = [], date = new Date(), userIDs = [
|
|
|
18927
18713
|
/**
|
|
18928
18714
|
* Create signature packet
|
|
18929
18715
|
* @param {Object} dataToSign - Contains packets to be signed
|
|
18930
|
-
* @param {
|
|
18716
|
+
* @param {Array<Key>} recipientKeys - keys to get preferences from
|
|
18931
18717
|
* @param {SecretKeyPacket|
|
|
18932
18718
|
* SecretSubkeyPacket} signingKeyPacket secret key packet for signing
|
|
18933
18719
|
* @param {Object} [signatureProperties] - Properties to write on the signature packet before signing
|
|
@@ -18938,7 +18724,7 @@ async function getPreferredCipherSuite(keys = [], date = new Date(), userIDs = [
|
|
|
18938
18724
|
* @param {Object} config - full configuration
|
|
18939
18725
|
* @returns {Promise<SignaturePacket>} Signature packet.
|
|
18940
18726
|
*/
|
|
18941
|
-
async function createSignaturePacket(dataToSign,
|
|
18727
|
+
async function createSignaturePacket(dataToSign, recipientKeys, signingKeyPacket, signatureProperties, date, recipientUserIDs, notations = [], detached = false, config) {
|
|
18942
18728
|
if (signingKeyPacket.isDummy()) {
|
|
18943
18729
|
throw new Error('Cannot sign with a gnu-dummy key.');
|
|
18944
18730
|
}
|
|
@@ -18948,7 +18734,7 @@ async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, s
|
|
|
18948
18734
|
const signaturePacket = new SignaturePacket();
|
|
18949
18735
|
Object.assign(signaturePacket, signatureProperties);
|
|
18950
18736
|
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
|
18951
|
-
signaturePacket.hashAlgorithm = await getPreferredHashAlgo(
|
|
18737
|
+
signaturePacket.hashAlgorithm = await getPreferredHashAlgo(recipientKeys, signingKeyPacket, date, recipientUserIDs, config);
|
|
18952
18738
|
signaturePacket.rawNotations = [...notations];
|
|
18953
18739
|
await signaturePacket.sign(signingKeyPacket, dataToSign, date, detached, config);
|
|
18954
18740
|
return signaturePacket;
|
|
@@ -19069,6 +18855,13 @@ function sanitizeKeyOptions(options, subkeyDefaults = {}) {
|
|
|
19069
18855
|
}
|
|
19070
18856
|
|
|
19071
18857
|
switch (options.type) {
|
|
18858
|
+
case 'pqc':
|
|
18859
|
+
if (options.sign) {
|
|
18860
|
+
options.algorithm = enums.publicKey.pqc_mldsa_ed25519;
|
|
18861
|
+
} else {
|
|
18862
|
+
options.algorithm = enums.publicKey.pqc_mlkem_x25519;
|
|
18863
|
+
}
|
|
18864
|
+
break;
|
|
19072
18865
|
case 'ecc': // NB: this case also handles legacy eddsa and x25519 keys, based on `options.curve`
|
|
19073
18866
|
try {
|
|
19074
18867
|
options.curve = enums.write(enums.curve, options.curve);
|
|
@@ -19127,6 +18920,7 @@ function validateSigningKeyPacket(keyPacket, signature, config) {
|
|
|
19127
18920
|
case enums.publicKey.ed25519:
|
|
19128
18921
|
case enums.publicKey.ed448:
|
|
19129
18922
|
case enums.publicKey.hmac:
|
|
18923
|
+
case enums.publicKey.pqc_mldsa_ed25519:
|
|
19130
18924
|
if (!signature.keyFlags && !config.allowMissingKeyFlags) {
|
|
19131
18925
|
throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`');
|
|
19132
18926
|
}
|
|
@@ -19146,6 +18940,7 @@ function validateEncryptionKeyPacket(keyPacket, signature, config) {
|
|
|
19146
18940
|
case enums.publicKey.x25519:
|
|
19147
18941
|
case enums.publicKey.x448:
|
|
19148
18942
|
case enums.publicKey.aead:
|
|
18943
|
+
case enums.publicKey.pqc_mlkem_x25519:
|
|
19149
18944
|
if (!signature.keyFlags && !config.allowMissingKeyFlags) {
|
|
19150
18945
|
throw new Error('None of the key flags is set: consider passing `config.allowMissingKeyFlags`');
|
|
19151
18946
|
}
|
|
@@ -19168,7 +18963,8 @@ function validateDecryptionKeyPacket(keyPacket, signature, config) {
|
|
|
19168
18963
|
case enums.publicKey.elgamal:
|
|
19169
18964
|
case enums.publicKey.ecdh:
|
|
19170
18965
|
case enums.publicKey.x25519:
|
|
19171
|
-
case enums.publicKey.x448:
|
|
18966
|
+
case enums.publicKey.x448:
|
|
18967
|
+
case enums.publicKey.pqc_mlkem_x25519: {
|
|
19172
18968
|
const isValidSigningKeyPacket = !signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.signData) !== 0;
|
|
19173
18969
|
if (isValidSigningKeyPacket && config.allowInsecureDecryptionWithSigningKeys) {
|
|
19174
18970
|
// This is only relevant for RSA keys, all other signing algorithms cannot decrypt
|
|
@@ -19285,7 +19081,7 @@ class User {
|
|
|
19285
19081
|
throw new Error("The user's own key can only be used for self-certifications");
|
|
19286
19082
|
}
|
|
19287
19083
|
const signingKey = await privateKey.getSigningKey(undefined, date, undefined, config);
|
|
19288
|
-
return createSignaturePacket(dataToSign, privateKey, signingKey.keyPacket, {
|
|
19084
|
+
return createSignaturePacket(dataToSign, [privateKey], signingKey.keyPacket, {
|
|
19289
19085
|
// Most OpenPGP implementations use generic certification (0x10)
|
|
19290
19086
|
signatureType: enums.signature.certGeneric,
|
|
19291
19087
|
keyFlags: [enums.keyFlags.certifyKeys | enums.keyFlags.signData]
|
|
@@ -19473,7 +19269,7 @@ class User {
|
|
|
19473
19269
|
key: primaryKey
|
|
19474
19270
|
};
|
|
19475
19271
|
const user = new User(dataToSign.userID || dataToSign.userAttribute, this.mainKey);
|
|
19476
|
-
user.revocationSignatures.push(await createSignaturePacket(dataToSign,
|
|
19272
|
+
user.revocationSignatures.push(await createSignaturePacket(dataToSign, [], primaryKey, {
|
|
19477
19273
|
signatureType: enums.signature.certRevocation,
|
|
19478
19274
|
reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
|
|
19479
19275
|
reasonForRevocationString
|
|
@@ -19666,7 +19462,7 @@ class Subkey {
|
|
|
19666
19462
|
) {
|
|
19667
19463
|
const dataToSign = { key: primaryKey, bind: this.keyPacket };
|
|
19668
19464
|
const subkey = new Subkey(this.keyPacket, this.mainKey);
|
|
19669
|
-
subkey.revocationSignatures.push(await createSignaturePacket(dataToSign,
|
|
19465
|
+
subkey.revocationSignatures.push(await createSignaturePacket(dataToSign, [], primaryKey, {
|
|
19670
19466
|
signatureType: enums.signature.subkeyRevocation,
|
|
19671
19467
|
reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
|
|
19672
19468
|
reasonForRevocationString
|
|
@@ -20699,7 +20495,7 @@ class PrivateKey extends PublicKey {
|
|
|
20699
20495
|
}
|
|
20700
20496
|
const dataToSign = { key: this.keyPacket };
|
|
20701
20497
|
const key = this.clone();
|
|
20702
|
-
key.revocationSignatures.push(await createSignaturePacket(dataToSign,
|
|
20498
|
+
key.revocationSignatures.push(await createSignaturePacket(dataToSign, [], this.keyPacket, {
|
|
20703
20499
|
signatureType: enums.signature.keyRevocation,
|
|
20704
20500
|
reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
|
|
20705
20501
|
reasonForRevocationString
|
|
@@ -20981,10 +20777,9 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
|
|
|
20981
20777
|
});
|
|
20982
20778
|
}
|
|
20983
20779
|
signatureProperties.preferredHashAlgorithms = createPreferredAlgos([
|
|
20984
|
-
// prefer fast asm.js implementations (SHA-256)
|
|
20985
|
-
enums.hash.sha256,
|
|
20986
20780
|
enums.hash.sha512,
|
|
20987
|
-
|
|
20781
|
+
enums.hash.sha256,
|
|
20782
|
+
...(secretKeyPacket.version === 6 ? [enums.hash.sha3_512, enums.hash.sha3_256] : [])
|
|
20988
20783
|
], config.preferredHashAlgorithm);
|
|
20989
20784
|
signatureProperties.preferredCompressionAlgorithms = createPreferredAlgos([
|
|
20990
20785
|
enums.compression.uncompressed,
|
|
@@ -21012,7 +20807,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
|
|
|
21012
20807
|
const signatureProperties = getKeySignatureProperties();
|
|
21013
20808
|
signatureProperties.signatureType = enums.signature.key;
|
|
21014
20809
|
|
|
21015
|
-
const signaturePacket = await createSignaturePacket(dataToSign,
|
|
20810
|
+
const signaturePacket = await createSignaturePacket(dataToSign, [], secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config);
|
|
21016
20811
|
packetlist.push(signaturePacket);
|
|
21017
20812
|
}
|
|
21018
20813
|
|
|
@@ -21028,7 +20823,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
|
|
|
21028
20823
|
signatureProperties.isPrimaryUserID = true;
|
|
21029
20824
|
}
|
|
21030
20825
|
|
|
21031
|
-
const signaturePacket = await createSignaturePacket(dataToSign,
|
|
20826
|
+
const signaturePacket = await createSignaturePacket(dataToSign, [], secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config);
|
|
21032
20827
|
|
|
21033
20828
|
return { userIDPacket, signaturePacket };
|
|
21034
20829
|
})).then(list => {
|
|
@@ -21052,7 +20847,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
|
|
|
21052
20847
|
// Add revocation signature packet for creating a revocation certificate.
|
|
21053
20848
|
// This packet should be removed before returning the key.
|
|
21054
20849
|
const dataToSign = { key: secretKeyPacket };
|
|
21055
|
-
packetlist.push(await createSignaturePacket(dataToSign,
|
|
20850
|
+
packetlist.push(await createSignaturePacket(dataToSign, [], secretKeyPacket, {
|
|
21056
20851
|
signatureType: enums.signature.keyRevocation,
|
|
21057
20852
|
reasonForRevocationFlag: enums.reasonForRevocation.noReason,
|
|
21058
20853
|
reasonForRevocationString: ''
|
|
@@ -21727,16 +21522,18 @@ class Message {
|
|
|
21727
21522
|
/**
|
|
21728
21523
|
* Sign the message (the literal data packet of the message)
|
|
21729
21524
|
* @param {Array<PrivateKey>} signingKeys - private keys with decrypted secret key data for signing
|
|
21525
|
+
* @param {Array<Key>} recipientKeys - recipient keys to get the signing preferences from
|
|
21730
21526
|
* @param {Signature} [signature] - Any existing detached signature to add to the message
|
|
21731
21527
|
* @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i]
|
|
21732
21528
|
* @param {Date} [date] - Override the creation time of the signature
|
|
21733
|
-
* @param {Array} [
|
|
21529
|
+
* @param {Array<UserID>} [signingUserIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
|
|
21530
|
+
* @param {Array<UserID>} [recipientUserIDs] - User IDs associated with `recipientKeys` to get the signing preferences from
|
|
21734
21531
|
* @param {Array} [notations] - Notation Data to add to the signatures, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }]
|
|
21735
21532
|
* @param {Object} [config] - Full configuration, defaults to openpgp.config
|
|
21736
21533
|
* @returns {Promise<Message>} New message with signed content.
|
|
21737
21534
|
* @async
|
|
21738
21535
|
*/
|
|
21739
|
-
async sign(signingKeys = [], signature = null, signingKeyIDs = [], date = new Date(),
|
|
21536
|
+
async sign(signingKeys = [], recipientKeys = [], signature = null, signingKeyIDs = [], date = new Date(), signingUserIDs = [], recipientUserIDs = [], notations = [], config$1 = config) {
|
|
21740
21537
|
const packetlist = new PacketList();
|
|
21741
21538
|
|
|
21742
21539
|
const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
|
|
@@ -21744,7 +21541,7 @@ class Message {
|
|
|
21744
21541
|
throw new Error('No literal data packet to sign.');
|
|
21745
21542
|
}
|
|
21746
21543
|
|
|
21747
|
-
const signaturePackets = await createSignaturePackets(literalDataPacket, signingKeys, signature, signingKeyIDs, date,
|
|
21544
|
+
const signaturePackets = await createSignaturePackets(literalDataPacket, signingKeys, recipientKeys, signature, signingKeyIDs, date, signingUserIDs, recipientUserIDs, notations, false, config$1); // this returns the existing signature packets as well
|
|
21748
21545
|
const onePassSignaturePackets = signaturePackets.map(
|
|
21749
21546
|
(signaturePacket, i) => OnePassSignaturePacket.fromSignaturePacket(signaturePacket, i === 0))
|
|
21750
21547
|
.reverse(); // innermost OPS refers to the first signature packet
|
|
@@ -21780,21 +21577,23 @@ class Message {
|
|
|
21780
21577
|
/**
|
|
21781
21578
|
* Create a detached signature for the message (the literal data packet of the message)
|
|
21782
21579
|
* @param {Array<PrivateKey>} signingKeys - private keys with decrypted secret key data for signing
|
|
21580
|
+
* @param {Array<Key>} recipientKeys - recipient keys to get the signing preferences from
|
|
21783
21581
|
* @param {Signature} [signature] - Any existing detached signature
|
|
21784
21582
|
* @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i]
|
|
21785
21583
|
* @param {Date} [date] - Override the creation time of the signature
|
|
21786
|
-
* @param {Array} [
|
|
21584
|
+
* @param {Array<UserID>} [signingUserIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
|
|
21585
|
+
* @param {Array<UserID>} [recipientUserIDs] - User IDs associated with `recipientKeys` to get the signing preferences from
|
|
21787
21586
|
* @param {Array} [notations] - Notation Data to add to the signatures, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }]
|
|
21788
21587
|
* @param {Object} [config] - Full configuration, defaults to openpgp.config
|
|
21789
21588
|
* @returns {Promise<Signature>} New detached signature of message content.
|
|
21790
21589
|
* @async
|
|
21791
21590
|
*/
|
|
21792
|
-
async signDetached(signingKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], notations = [], config$1 = config) {
|
|
21591
|
+
async signDetached(signingKeys = [], recipientKeys = [], signature = null, signingKeyIDs = [], recipientKeyIDs = [], date = new Date(), userIDs = [], notations = [], config$1 = config) {
|
|
21793
21592
|
const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
|
|
21794
21593
|
if (!literalDataPacket) {
|
|
21795
21594
|
throw new Error('No literal data packet to sign.');
|
|
21796
21595
|
}
|
|
21797
|
-
return new Signature(await createSignaturePackets(literalDataPacket, signingKeys, signature, signingKeyIDs, date, userIDs, notations, true, config$1));
|
|
21596
|
+
return new Signature(await createSignaturePackets(literalDataPacket, signingKeys, recipientKeys, signature, signingKeyIDs, recipientKeyIDs, date, userIDs, notations, true, config$1));
|
|
21798
21597
|
}
|
|
21799
21598
|
|
|
21800
21599
|
/**
|
|
@@ -21929,10 +21728,12 @@ class Message {
|
|
|
21929
21728
|
* Create signature packets for the message
|
|
21930
21729
|
* @param {LiteralDataPacket} literalDataPacket - the literal data packet to sign
|
|
21931
21730
|
* @param {Array<PrivateKey>} [signingKeys] - private keys with decrypted secret key data for signing
|
|
21731
|
+
* @param {Array<Key>} [recipientKeys] - recipient keys to get the signing preferences from
|
|
21932
21732
|
* @param {Signature} [signature] - Any existing detached signature to append
|
|
21933
21733
|
* @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i]
|
|
21934
21734
|
* @param {Date} [date] - Override the creationtime of the signature
|
|
21935
|
-
* @param {Array} [
|
|
21735
|
+
* @param {Array<UserID>} [signingUserIDs] - User IDs to sign to, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
|
|
21736
|
+
* @param {Array<UserID>} [recipientUserIDs] - User IDs associated with `recipientKeys` to get the signing preferences from
|
|
21936
21737
|
* @param {Array} [notations] - Notation Data to add to the signatures, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }]
|
|
21937
21738
|
* @param {Array} [signatureSalts] - A list of signature salts matching the number of signingKeys that should be used for v6 signatures
|
|
21938
21739
|
* @param {Boolean} [detached] - Whether to create detached signature packets
|
|
@@ -21941,7 +21742,7 @@ class Message {
|
|
|
21941
21742
|
* @async
|
|
21942
21743
|
* @private
|
|
21943
21744
|
*/
|
|
21944
|
-
async function createSignaturePackets(literalDataPacket, signingKeys, signature = null, signingKeyIDs = [], date = new Date(),
|
|
21745
|
+
async function createSignaturePackets(literalDataPacket, signingKeys, recipientKeys = [], signature = null, signingKeyIDs = [], date = new Date(), signingUserIDs = [], recipientUserIDs = [], notations = [], detached = false, config$1 = config) {
|
|
21945
21746
|
const packetlist = new PacketList();
|
|
21946
21747
|
|
|
21947
21748
|
// If data packet was created from Uint8Array, use binary, otherwise use text
|
|
@@ -21949,12 +21750,12 @@ async function createSignaturePackets(literalDataPacket, signingKeys, signature
|
|
|
21949
21750
|
enums.signature.binary : enums.signature.text;
|
|
21950
21751
|
|
|
21951
21752
|
await Promise.all(signingKeys.map(async (primaryKey, i) => {
|
|
21952
|
-
const
|
|
21753
|
+
const signingUserID = signingUserIDs[i];
|
|
21953
21754
|
if (!primaryKey.isPrivate()) {
|
|
21954
21755
|
throw new Error('Need private key for signing');
|
|
21955
21756
|
}
|
|
21956
|
-
const signingKey = await primaryKey.getSigningKey(signingKeyIDs[i], date,
|
|
21957
|
-
return createSignaturePacket(literalDataPacket, primaryKey, signingKey.keyPacket, { signatureType }, date,
|
|
21757
|
+
const signingKey = await primaryKey.getSigningKey(signingKeyIDs[i], date, signingUserID, config$1);
|
|
21758
|
+
return createSignaturePacket(literalDataPacket, recipientKeys.length ? recipientKeys : [primaryKey], signingKey.keyPacket, { signatureType }, date, recipientUserIDs, notations, detached, config$1);
|
|
21958
21759
|
})).then(signatureList => {
|
|
21959
21760
|
packetlist.push(...signatureList);
|
|
21960
21761
|
});
|
|
@@ -22204,20 +22005,22 @@ class CleartextMessage {
|
|
|
22204
22005
|
|
|
22205
22006
|
/**
|
|
22206
22007
|
* Sign the cleartext message
|
|
22207
|
-
* @param {Array<Key>}
|
|
22008
|
+
* @param {Array<Key>} signingKeys - private keys with decrypted secret key data for signing
|
|
22009
|
+
* @param {Array<Key>} recipientKeys - recipient keys to get the signing preferences from
|
|
22208
22010
|
* @param {Signature} [signature] - Any existing detached signature
|
|
22209
22011
|
* @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i]
|
|
22210
22012
|
* @param {Date} [date] - The creation time of the signature that should be created
|
|
22211
|
-
* @param {Array} [
|
|
22013
|
+
* @param {Array} [signingKeyIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
|
|
22014
|
+
* @param {Array} [recipientUserIDs] - User IDs associated with `recipientKeys` to get the signing preferences from
|
|
22212
22015
|
* @param {Array} [notations] - Notation Data to add to the signatures, e.g. [{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }]
|
|
22213
22016
|
* @param {Object} [config] - Full configuration, defaults to openpgp.config
|
|
22214
22017
|
* @returns {Promise<CleartextMessage>} New cleartext message with signed content.
|
|
22215
22018
|
* @async
|
|
22216
22019
|
*/
|
|
22217
|
-
async sign(
|
|
22020
|
+
async sign(signingKeys, recipientKeys = [], signature = null, signingKeyIDs = [], date = new Date(), signingUserIDs = [], recipientUserIDs = [], notations = [], config$1 = config) {
|
|
22218
22021
|
const literalDataPacket = new LiteralDataPacket();
|
|
22219
22022
|
literalDataPacket.setText(this.text);
|
|
22220
|
-
const newSignature = new Signature(await createSignaturePackets(literalDataPacket,
|
|
22023
|
+
const newSignature = new Signature(await createSignaturePackets(literalDataPacket, signingKeys, recipientKeys, signature, signingKeyIDs, date, signingUserIDs, recipientUserIDs, notations, true, config$1));
|
|
22221
22024
|
return new CleartextMessage(this.text, newSignature);
|
|
22222
22025
|
}
|
|
22223
22026
|
|
|
@@ -22653,7 +22456,7 @@ async function encrypt({ message, encryptionKeys, signingKeys, passwords, sessio
|
|
|
22653
22456
|
|
|
22654
22457
|
try {
|
|
22655
22458
|
if (signingKeys.length || signature) { // sign the message only if signing keys or signature is specified
|
|
22656
|
-
message = await message.sign(signingKeys, signature, signingKeyIDs, date, signingUserIDs, signatureNotations, config$1);
|
|
22459
|
+
message = await message.sign(signingKeys, encryptionKeys, signature, signingKeyIDs, date, signingUserIDs, encryptionKeyIDs, signatureNotations, config$1);
|
|
22657
22460
|
}
|
|
22658
22461
|
message = message.compress(
|
|
22659
22462
|
await getPreferredCompressionAlgo(encryptionKeys, date, encryptionUserIDs, config$1),
|
|
@@ -22732,6 +22535,7 @@ async function decrypt({ message, decryptionKeys, passwords, sessionKeys, verifi
|
|
|
22732
22535
|
result.data,
|
|
22733
22536
|
fromAsync(async () => {
|
|
22734
22537
|
await util.anyPromise(result.signatures.map(sig => sig.verified));
|
|
22538
|
+
return format === 'binary' ? new Uint8Array() : '';
|
|
22735
22539
|
})
|
|
22736
22540
|
]);
|
|
22737
22541
|
}
|
|
@@ -22755,21 +22559,23 @@ async function decrypt({ message, decryptionKeys, passwords, sessionKeys, verifi
|
|
|
22755
22559
|
* @param {Object} options
|
|
22756
22560
|
* @param {CleartextMessage|Message} options.message - (cleartext) message to be signed
|
|
22757
22561
|
* @param {PrivateKey|PrivateKey[]} options.signingKeys - Array of keys or single key with decrypted secret key data to sign cleartext
|
|
22562
|
+
* @param {Key|Key[]} options.recipientKeys - Array of keys or single to get the signing preferences from
|
|
22758
22563
|
* @param {'armored'|'binary'|'object'} [options.format='armored'] - Format of the returned message
|
|
22759
22564
|
* @param {Boolean} [options.detached=false] - If the return value should contain a detached signature
|
|
22760
22565
|
* @param {KeyID|KeyID[]} [options.signingKeyIDs=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i]
|
|
22761
22566
|
* @param {Date} [options.date=current date] - Override the creation date of the signature
|
|
22762
22567
|
* @param {Object|Object[]} [options.signingUserIDs=primary user IDs] - Array of user IDs to sign with, one per key in `signingKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]`
|
|
22568
|
+
* @param {Object|Object[]} [options.recipientUserIDs=primary user IDs] - Array of user IDs to get the signing preferences from, one per key in `recipientKeys`
|
|
22763
22569
|
* @param {Object|Object[]} [options.signatureNotations=[]] - Array of notations to add to the signatures, e.g. `[{ name: 'test@example.org', value: new TextEncoder().encode('test'), humanReadable: true, critical: false }]`
|
|
22764
22570
|
* @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
|
|
22765
22571
|
* @returns {Promise<MaybeStream<String|Uint8Array>>} Signed message (string if `armor` was true, the default; Uint8Array if `armor` was false).
|
|
22766
22572
|
* @async
|
|
22767
22573
|
* @static
|
|
22768
22574
|
*/
|
|
22769
|
-
async function sign({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
|
|
22575
|
+
async function sign({ message, signingKeys, recipientKeys = [], format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], recipientUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
|
|
22770
22576
|
config$1 = { ...config, ...config$1 }; checkConfig(config$1);
|
|
22771
22577
|
checkCleartextOrMessage(message); checkOutputMessageFormat(format);
|
|
22772
|
-
signingKeys = toArray(signingKeys); signingKeyIDs = toArray(signingKeyIDs); signingUserIDs = toArray(signingUserIDs); signatureNotations = toArray(signatureNotations);
|
|
22578
|
+
signingKeys = toArray(signingKeys); signingKeyIDs = toArray(signingKeyIDs); signingUserIDs = toArray(signingUserIDs); recipientKeys = toArray(recipientKeys); recipientUserIDs = toArray(recipientUserIDs); signatureNotations = toArray(signatureNotations);
|
|
22773
22579
|
|
|
22774
22580
|
if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.sign, pass `signingKeys` instead');
|
|
22775
22581
|
if (rest.armor !== undefined) throw new Error('The `armor` option has been removed from openpgp.sign, pass `format` instead.');
|
|
@@ -22785,9 +22591,9 @@ async function sign({ message, signingKeys, format = 'armored', detached = false
|
|
|
22785
22591
|
try {
|
|
22786
22592
|
let signature;
|
|
22787
22593
|
if (detached) {
|
|
22788
|
-
signature = await message.signDetached(signingKeys, undefined, signingKeyIDs, date, signingUserIDs, signatureNotations, config$1);
|
|
22594
|
+
signature = await message.signDetached(signingKeys, recipientKeys, undefined, signingKeyIDs, date, signingUserIDs, recipientUserIDs, signatureNotations, config$1);
|
|
22789
22595
|
} else {
|
|
22790
|
-
signature = await message.sign(signingKeys, undefined, signingKeyIDs, date, signingUserIDs, signatureNotations, config$1);
|
|
22596
|
+
signature = await message.sign(signingKeys, recipientKeys, undefined, signingKeyIDs, date, signingUserIDs, recipientUserIDs, signatureNotations, config$1);
|
|
22791
22597
|
}
|
|
22792
22598
|
if (format === 'object') return signature;
|
|
22793
22599
|
|
|
@@ -22861,6 +22667,7 @@ async function verify({ message, verificationKeys, expectSigned = false, format
|
|
|
22861
22667
|
result.data,
|
|
22862
22668
|
fromAsync(async () => {
|
|
22863
22669
|
await util.anyPromise(result.signatures.map(sig => sig.verified));
|
|
22670
|
+
return format === 'binary' ? new Uint8Array() : '';
|
|
22864
22671
|
})
|
|
22865
22672
|
]);
|
|
22866
22673
|
}
|