@protontech/openpgp 6.1.1-patch.2 → 6.1.1-patch.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lightweight/argon2id.min.mjs +1 -1
- package/dist/lightweight/argon2id.mjs +1 -1
- package/dist/lightweight/legacy_ciphers.min.mjs +1 -1
- package/dist/lightweight/legacy_ciphers.mjs +1 -1
- package/dist/lightweight/noble_curves.min.mjs +1 -1
- package/dist/lightweight/noble_curves.mjs +1 -1
- package/dist/lightweight/noble_hashes.min.mjs +1 -1
- package/dist/lightweight/noble_hashes.mjs +1 -1
- package/dist/lightweight/noble_post_quantum.min.mjs +1 -1
- package/dist/lightweight/noble_post_quantum.mjs +1 -1
- package/dist/lightweight/openpgp.min.mjs +4 -4
- package/dist/lightweight/openpgp.min.mjs.map +1 -1
- package/dist/lightweight/openpgp.mjs +178 -95
- package/dist/lightweight/seek-bzip.min.mjs +1 -1
- package/dist/lightweight/seek-bzip.mjs +1 -1
- package/dist/lightweight/sha3.min.mjs +1 -1
- package/dist/lightweight/sha3.mjs +1 -1
- package/dist/lightweight/sha512.min.mjs +1 -1
- package/dist/lightweight/sha512.mjs +1 -1
- package/dist/node/openpgp.cjs +178 -95
- package/dist/node/openpgp.min.cjs +16 -16
- package/dist/node/openpgp.min.cjs.map +1 -1
- package/dist/node/openpgp.min.mjs +16 -16
- package/dist/node/openpgp.min.mjs.map +1 -1
- package/dist/node/openpgp.mjs +178 -95
- package/dist/openpgp.js +178 -95
- package/dist/openpgp.min.js +16 -16
- package/dist/openpgp.min.js.map +1 -1
- package/dist/openpgp.min.mjs +16 -16
- package/dist/openpgp.min.mjs.map +1 -1
- package/dist/openpgp.mjs +178 -95
- package/package.json +1 -1
- package/src/enums.d.ts +2 -2
package/dist/openpgp.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! OpenPGP.js v6.1.1-patch.
|
|
1
|
+
/*! OpenPGP.js v6.1.1-patch.3 - 2025-06-18 - 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
|
function _mergeNamespaces(n, m) {
|
|
@@ -1062,11 +1062,10 @@ var enums = {
|
|
|
1062
1062
|
ed25519: 27,
|
|
1063
1063
|
/** Ed448 (Sign only) */
|
|
1064
1064
|
ed448: 28,
|
|
1065
|
-
/** Post-quantum ML-KEM-768 + X25519 (Encrypt only) */
|
|
1066
|
-
pqc_mlkem_x25519: 105,
|
|
1067
1065
|
/** Post-quantum ML-DSA-64 + Ed25519 (Sign only) */
|
|
1068
|
-
pqc_mldsa_ed25519:
|
|
1069
|
-
|
|
1066
|
+
pqc_mldsa_ed25519: 30,
|
|
1067
|
+
/** Post-quantum ML-KEM-768 + X25519 (Encrypt only) */
|
|
1068
|
+
pqc_mlkem_x25519: 35,
|
|
1070
1069
|
/** Persistent symmetric keys: encryption algorithm */
|
|
1071
1070
|
aead: 100,
|
|
1072
1071
|
/** Persistent symmetric keys: authentication algorithm */
|
|
@@ -1717,7 +1716,7 @@ var config = {
|
|
|
1717
1716
|
* @memberof module:config
|
|
1718
1717
|
* @property {String} versionString A version string to be included in armored messages
|
|
1719
1718
|
*/
|
|
1720
|
-
versionString: 'OpenPGP.js 6.1.1-patch.
|
|
1719
|
+
versionString: 'OpenPGP.js 6.1.1-patch.3',
|
|
1721
1720
|
/**
|
|
1722
1721
|
* @memberof module:config
|
|
1723
1722
|
* @property {String} commentString A comment string to be included in armored messages
|
|
@@ -6957,17 +6956,11 @@ async function generate$a(algo) {
|
|
|
6957
6956
|
* @async
|
|
6958
6957
|
*/
|
|
6959
6958
|
async function sign$9(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
6960
|
-
if (getHashByteLength(hashAlgo) < getHashByteLength(getPreferredHashAlgo$2(algo))) {
|
|
6961
|
-
// Enforce digest sizes:
|
|
6962
|
-
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
|
6963
|
-
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
|
6964
|
-
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
6965
|
-
}
|
|
6966
6959
|
switch (algo) {
|
|
6967
6960
|
case enums.publicKey.ed25519:
|
|
6968
6961
|
try {
|
|
6969
6962
|
const webCrypto = util.getWebCrypto();
|
|
6970
|
-
const jwk = privateKeyToJWK(algo, publicKey, privateKey);
|
|
6963
|
+
const jwk = privateKeyToJWK$1(algo, publicKey, privateKey);
|
|
6971
6964
|
const key = await webCrypto.importKey('jwk', jwk, 'Ed25519', false, ['sign']);
|
|
6972
6965
|
|
|
6973
6966
|
const signature = new Uint8Array(
|
|
@@ -7007,17 +7000,11 @@ async function sign$9(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
7007
7000
|
* @async
|
|
7008
7001
|
*/
|
|
7009
7002
|
async function verify$9(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
|
7010
|
-
if (getHashByteLength(hashAlgo) < getHashByteLength(getPreferredHashAlgo$2(algo))) {
|
|
7011
|
-
// Enforce digest sizes:
|
|
7012
|
-
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
|
7013
|
-
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
|
7014
|
-
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
7015
|
-
}
|
|
7016
7003
|
switch (algo) {
|
|
7017
7004
|
case enums.publicKey.ed25519:
|
|
7018
7005
|
try {
|
|
7019
7006
|
const webCrypto = util.getWebCrypto();
|
|
7020
|
-
const jwk = publicKeyToJWK(algo, publicKey);
|
|
7007
|
+
const jwk = publicKeyToJWK$1(algo, publicKey);
|
|
7021
7008
|
const key = await webCrypto.importKey('jwk', jwk, 'Ed25519', false, ['verify']);
|
|
7022
7009
|
const verified = await webCrypto.verify('Ed25519', key, RS, hashed);
|
|
7023
7010
|
return verified;
|
|
@@ -7092,7 +7079,7 @@ function getPreferredHashAlgo$2(algo) {
|
|
|
7092
7079
|
}
|
|
7093
7080
|
}
|
|
7094
7081
|
|
|
7095
|
-
const publicKeyToJWK = (algo, publicKey) => {
|
|
7082
|
+
const publicKeyToJWK$1 = (algo, publicKey) => {
|
|
7096
7083
|
switch (algo) {
|
|
7097
7084
|
case enums.publicKey.ed25519: {
|
|
7098
7085
|
const jwk = {
|
|
@@ -7108,10 +7095,10 @@ const publicKeyToJWK = (algo, publicKey) => {
|
|
|
7108
7095
|
}
|
|
7109
7096
|
};
|
|
7110
7097
|
|
|
7111
|
-
const privateKeyToJWK = (algo, publicKey, privateKey) => {
|
|
7098
|
+
const privateKeyToJWK$1 = (algo, publicKey, privateKey) => {
|
|
7112
7099
|
switch (algo) {
|
|
7113
7100
|
case enums.publicKey.ed25519: {
|
|
7114
|
-
const jwk = publicKeyToJWK(algo, publicKey);
|
|
7101
|
+
const jwk = publicKeyToJWK$1(algo, publicKey);
|
|
7115
7102
|
jwk.d = uint8ArrayToB64(privateKey);
|
|
7116
7103
|
return jwk;
|
|
7117
7104
|
}
|
|
@@ -8351,12 +8338,27 @@ const HKDF_INFO = {
|
|
|
8351
8338
|
*/
|
|
8352
8339
|
async function generate$9(algo) {
|
|
8353
8340
|
switch (algo) {
|
|
8354
|
-
case enums.publicKey.x25519:
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8341
|
+
case enums.publicKey.x25519:
|
|
8342
|
+
try {
|
|
8343
|
+
const webCrypto = util.getWebCrypto();
|
|
8344
|
+
const webCryptoKey = await webCrypto.generateKey('X25519', true, ['deriveKey', 'deriveBits']);
|
|
8345
|
+
|
|
8346
|
+
const privateKey = await webCrypto.exportKey('jwk', webCryptoKey.privateKey);
|
|
8347
|
+
const publicKey = await webCrypto.exportKey('jwk', webCryptoKey.publicKey);
|
|
8348
|
+
|
|
8349
|
+
return {
|
|
8350
|
+
A: new Uint8Array(b64ToUint8Array(publicKey.x)),
|
|
8351
|
+
k: b64ToUint8Array(privateKey.d)
|
|
8352
|
+
};
|
|
8353
|
+
} catch (err) {
|
|
8354
|
+
if (err.name !== 'NotSupportedError') {
|
|
8355
|
+
throw err;
|
|
8356
|
+
}
|
|
8357
|
+
// k stays in little-endian, unlike legacy ECDH over curve25519
|
|
8358
|
+
const k = getRandomBytes(32);
|
|
8359
|
+
const { publicKey: A } = nacl.box.keyPair.fromSecretKey(k);
|
|
8360
|
+
return { A, k };
|
|
8361
|
+
}
|
|
8360
8362
|
|
|
8361
8363
|
case enums.publicKey.x448: {
|
|
8362
8364
|
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
|
@@ -8498,13 +8500,32 @@ function getPayloadSize(algo) {
|
|
|
8498
8500
|
*/
|
|
8499
8501
|
async function generateEphemeralEncryptionMaterial(algo, recipientA) {
|
|
8500
8502
|
switch (algo) {
|
|
8501
|
-
case enums.publicKey.x25519:
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
|
|
8506
|
-
|
|
8507
|
-
|
|
8503
|
+
case enums.publicKey.x25519:
|
|
8504
|
+
try {
|
|
8505
|
+
const webCrypto = util.getWebCrypto();
|
|
8506
|
+
const jwk = publicKeyToJWK(algo, recipientA);
|
|
8507
|
+
const ephemeralKeyPair = await webCrypto.generateKey('X25519', true, ['deriveKey', 'deriveBits']);
|
|
8508
|
+
const recipientPublicKey = await webCrypto.importKey('jwk', jwk, 'X25519', false, []);
|
|
8509
|
+
const sharedSecretBuffer = await webCrypto.deriveBits(
|
|
8510
|
+
{ name: 'X25519', public: recipientPublicKey },
|
|
8511
|
+
ephemeralKeyPair.privateKey,
|
|
8512
|
+
getPayloadSize(algo) * 8 // in bits
|
|
8513
|
+
);
|
|
8514
|
+
const ephemeralPublicKeyJwt = await webCrypto.exportKey('jwk', ephemeralKeyPair.publicKey);
|
|
8515
|
+
return {
|
|
8516
|
+
sharedSecret: new Uint8Array(sharedSecretBuffer),
|
|
8517
|
+
ephemeralPublicKey: new Uint8Array(b64ToUint8Array(ephemeralPublicKeyJwt.x))
|
|
8518
|
+
};
|
|
8519
|
+
} catch (err) {
|
|
8520
|
+
if (err.name !== 'NotSupportedError') {
|
|
8521
|
+
throw err;
|
|
8522
|
+
}
|
|
8523
|
+
const ephemeralSecretKey = getRandomBytes(getPayloadSize(algo));
|
|
8524
|
+
const sharedSecret = nacl.scalarMult(ephemeralSecretKey, recipientA);
|
|
8525
|
+
assertNonZeroArray(sharedSecret);
|
|
8526
|
+
const { publicKey: ephemeralPublicKey } = nacl.box.keyPair.fromSecretKey(ephemeralSecretKey);
|
|
8527
|
+
return { ephemeralPublicKey, sharedSecret };
|
|
8528
|
+
}
|
|
8508
8529
|
case enums.publicKey.x448: {
|
|
8509
8530
|
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
|
8510
8531
|
const ephemeralSecretKey = x448.utils.randomPrivateKey();
|
|
@@ -8520,11 +8541,27 @@ async function generateEphemeralEncryptionMaterial(algo, recipientA) {
|
|
|
8520
8541
|
|
|
8521
8542
|
async function recomputeSharedSecret(algo, ephemeralPublicKey, A, k) {
|
|
8522
8543
|
switch (algo) {
|
|
8523
|
-
case enums.publicKey.x25519:
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8544
|
+
case enums.publicKey.x25519:
|
|
8545
|
+
try {
|
|
8546
|
+
const webCrypto = util.getWebCrypto();
|
|
8547
|
+
const privateKeyJWK = privateKeyToJWK(algo, A, k);
|
|
8548
|
+
const ephemeralPublicKeyJWK = publicKeyToJWK(algo, ephemeralPublicKey);
|
|
8549
|
+
const privateKey = await webCrypto.importKey('jwk', privateKeyJWK, 'X25519', false, ['deriveKey', 'deriveBits']);
|
|
8550
|
+
const ephemeralPublicKeyReference = await webCrypto.importKey('jwk', ephemeralPublicKeyJWK, 'X25519', false, []);
|
|
8551
|
+
const sharedSecretBuffer = await webCrypto.deriveBits(
|
|
8552
|
+
{ name: 'X25519', public: ephemeralPublicKeyReference },
|
|
8553
|
+
privateKey,
|
|
8554
|
+
getPayloadSize(algo) * 8 // in bits
|
|
8555
|
+
);
|
|
8556
|
+
return new Uint8Array(sharedSecretBuffer);
|
|
8557
|
+
} catch (err) {
|
|
8558
|
+
if (err.name !== 'NotSupportedError') {
|
|
8559
|
+
throw err;
|
|
8560
|
+
}
|
|
8561
|
+
const sharedSecret = nacl.scalarMult(k, ephemeralPublicKey);
|
|
8562
|
+
assertNonZeroArray(sharedSecret);
|
|
8563
|
+
return sharedSecret;
|
|
8564
|
+
}
|
|
8528
8565
|
case enums.publicKey.x448: {
|
|
8529
8566
|
const x448 = await util.getNobleCurve(enums.publicKey.x448);
|
|
8530
8567
|
const sharedSecret = x448.getSharedSecret(k, ephemeralPublicKey);
|
|
@@ -8552,6 +8589,35 @@ function assertNonZeroArray(sharedSecret) {
|
|
|
8552
8589
|
}
|
|
8553
8590
|
}
|
|
8554
8591
|
|
|
8592
|
+
|
|
8593
|
+
function publicKeyToJWK(algo, publicKey) {
|
|
8594
|
+
switch (algo) {
|
|
8595
|
+
case enums.publicKey.x25519: {
|
|
8596
|
+
const jwk = {
|
|
8597
|
+
kty: 'OKP',
|
|
8598
|
+
crv: 'X25519',
|
|
8599
|
+
x: uint8ArrayToB64(publicKey),
|
|
8600
|
+
ext: true
|
|
8601
|
+
};
|
|
8602
|
+
return jwk;
|
|
8603
|
+
}
|
|
8604
|
+
default:
|
|
8605
|
+
throw new Error('Unsupported ECDH algorithm');
|
|
8606
|
+
}
|
|
8607
|
+
}
|
|
8608
|
+
|
|
8609
|
+
function privateKeyToJWK(algo, publicKey, privateKey) {
|
|
8610
|
+
switch (algo) {
|
|
8611
|
+
case enums.publicKey.x25519: {
|
|
8612
|
+
const jwk = publicKeyToJWK(algo, publicKey);
|
|
8613
|
+
jwk.d = uint8ArrayToB64(privateKey);
|
|
8614
|
+
return jwk;
|
|
8615
|
+
}
|
|
8616
|
+
default:
|
|
8617
|
+
throw new Error('Unsupported ECDH algorithm');
|
|
8618
|
+
}
|
|
8619
|
+
}
|
|
8620
|
+
|
|
8555
8621
|
var ecdh_x = /*#__PURE__*/Object.freeze({
|
|
8556
8622
|
__proto__: null,
|
|
8557
8623
|
decrypt: decrypt$4,
|
|
@@ -9259,12 +9325,6 @@ var ecdsa = /*#__PURE__*/Object.freeze({
|
|
|
9259
9325
|
async function sign$7(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
9260
9326
|
const curve = new CurveWithOID(oid);
|
|
9261
9327
|
checkPublicPointEnconding(curve, publicKey);
|
|
9262
|
-
if (getHashByteLength(hashAlgo) < getHashByteLength(enums.hash.sha256)) {
|
|
9263
|
-
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
|
9264
|
-
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
9265
|
-
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
|
9266
|
-
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
9267
|
-
}
|
|
9268
9328
|
const { RS: signature } = await sign$9(enums.publicKey.ed25519, hashAlgo, message, publicKey.subarray(1), privateKey, hashed);
|
|
9269
9329
|
// EdDSA signature params are returned in little-endian format
|
|
9270
9330
|
return {
|
|
@@ -9288,12 +9348,6 @@ async function sign$7(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
9288
9348
|
async function verify$7(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
|
9289
9349
|
const curve = new CurveWithOID(oid);
|
|
9290
9350
|
checkPublicPointEnconding(curve, publicKey);
|
|
9291
|
-
if (getHashByteLength(hashAlgo) < getHashByteLength(enums.hash.sha256)) {
|
|
9292
|
-
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
|
9293
|
-
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
9294
|
-
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
|
9295
|
-
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
9296
|
-
}
|
|
9297
9351
|
const RS = util.concatUint8Array([r, s]);
|
|
9298
9352
|
return verify$9(enums.publicKey.ed25519, hashAlgo, { RS }, m, publicKey.subarray(1), hashed);
|
|
9299
9353
|
}
|
|
@@ -10151,7 +10205,7 @@ async function generate$4(algo) {
|
|
|
10151
10205
|
async function encrypt$2(algo, eccPublicKey, mlkemPublicKey, sessioneKeyData) {
|
|
10152
10206
|
const { eccKeyShare, eccCipherText } = await encaps$1(algo, eccPublicKey);
|
|
10153
10207
|
const { mlkemKeyShare, mlkemCipherText } = await encaps(algo, mlkemPublicKey);
|
|
10154
|
-
const kek = await multiKeyCombine(algo, eccKeyShare, eccCipherText, eccPublicKey
|
|
10208
|
+
const kek = await multiKeyCombine(algo, mlkemKeyShare, eccKeyShare, eccCipherText, eccPublicKey);
|
|
10155
10209
|
const wrappedKey = await wrap(enums.symmetric.aes256, kek, sessioneKeyData); // C
|
|
10156
10210
|
return { eccCipherText, mlkemCipherText, wrappedKey };
|
|
10157
10211
|
}
|
|
@@ -10159,25 +10213,24 @@ async function encrypt$2(algo, eccPublicKey, mlkemPublicKey, sessioneKeyData) {
|
|
|
10159
10213
|
async function decrypt$2(algo, eccCipherText, mlkemCipherText, eccSecretKey, eccPublicKey, mlkemSecretKey, mlkemPublicKey, encryptedSessionKeyData) {
|
|
10160
10214
|
const eccKeyShare = await decaps$1(algo, eccCipherText, eccSecretKey, eccPublicKey);
|
|
10161
10215
|
const mlkemKeyShare = await decaps(algo, mlkemCipherText, mlkemSecretKey);
|
|
10162
|
-
const kek = await multiKeyCombine(algo, eccKeyShare, eccCipherText, eccPublicKey
|
|
10216
|
+
const kek = await multiKeyCombine(algo, mlkemKeyShare, eccKeyShare, eccCipherText, eccPublicKey);
|
|
10163
10217
|
const sessionKey = await unwrap(enums.symmetric.aes256, kek, encryptedSessionKeyData);
|
|
10164
10218
|
return sessionKey;
|
|
10165
10219
|
}
|
|
10166
10220
|
|
|
10167
|
-
|
|
10168
|
-
|
|
10169
|
-
|
|
10170
|
-
|
|
10221
|
+
/**
|
|
10222
|
+
* KEM key combiner
|
|
10223
|
+
*/
|
|
10224
|
+
async function multiKeyCombine(algo, mlkemKeyShare, ecdhKeyShare, ecdhCipherText, ecdhPublicKey) {
|
|
10225
|
+
const domSep = util.encodeUTF8('OpenPGPCompositeKDFv1');
|
|
10171
10226
|
const encData = util.concatUint8Array([
|
|
10172
10227
|
mlkemKeyShare,
|
|
10173
10228
|
ecdhKeyShare,
|
|
10174
10229
|
ecdhCipherText,
|
|
10175
10230
|
ecdhPublicKey,
|
|
10176
|
-
// domSep
|
|
10177
|
-
mlkemCipherText,
|
|
10178
|
-
mlkemPublicKey,
|
|
10179
10231
|
new Uint8Array([algo]),
|
|
10180
|
-
|
|
10232
|
+
domSep,
|
|
10233
|
+
new Uint8Array([domSep.length])
|
|
10181
10234
|
]);
|
|
10182
10235
|
|
|
10183
10236
|
const kek = await computeDigest(enums.hash.sha3_256, encData);
|
|
@@ -10314,12 +10367,6 @@ async function generate$1(algo) {
|
|
|
10314
10367
|
}
|
|
10315
10368
|
|
|
10316
10369
|
async function sign$2(signatureAlgo, hashAlgo, eccSecretKey, eccPublicKey, mldsaSecretKey, dataDigest) {
|
|
10317
|
-
if (hashAlgo !== getRequiredHashAlgo(signatureAlgo)) {
|
|
10318
|
-
// The signature hash algo MUST be set to the specified algorithm, see
|
|
10319
|
-
// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
|
|
10320
|
-
throw new Error('Unexpected hash algorithm for PQC signature');
|
|
10321
|
-
}
|
|
10322
|
-
|
|
10323
10370
|
switch (signatureAlgo) {
|
|
10324
10371
|
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
10325
10372
|
const { eccSignature } = await sign$3(signatureAlgo, hashAlgo, eccSecretKey, eccPublicKey, dataDigest);
|
|
@@ -10333,12 +10380,6 @@ async function sign$2(signatureAlgo, hashAlgo, eccSecretKey, eccPublicKey, mldsa
|
|
|
10333
10380
|
}
|
|
10334
10381
|
|
|
10335
10382
|
async function verify$2(signatureAlgo, hashAlgo, eccPublicKey, mldsaPublicKey, dataDigest, { eccSignature, mldsaSignature }) {
|
|
10336
|
-
if (hashAlgo !== getRequiredHashAlgo(signatureAlgo)) {
|
|
10337
|
-
// The signature hash algo MUST be set to the specified algorithm, see
|
|
10338
|
-
// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
|
|
10339
|
-
throw new Error('Unexpected hash algorithm for PQC signature');
|
|
10340
|
-
}
|
|
10341
|
-
|
|
10342
10383
|
switch (signatureAlgo) {
|
|
10343
10384
|
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
10344
10385
|
const eccVerifiedPromise = verify$3(signatureAlgo, hashAlgo, eccPublicKey, dataDigest, eccSignature);
|
|
@@ -10351,11 +10392,12 @@ async function verify$2(signatureAlgo, hashAlgo, eccPublicKey, mldsaPublicKey, d
|
|
|
10351
10392
|
}
|
|
10352
10393
|
}
|
|
10353
10394
|
|
|
10354
|
-
function
|
|
10355
|
-
//
|
|
10395
|
+
function isCompatibleHashAlgo(signatureAlgo, hashAlgo) {
|
|
10396
|
+
// The signature hash algo MUST have digest larger than 256 bits
|
|
10397
|
+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-10.html#section-9.4
|
|
10356
10398
|
switch (signatureAlgo) {
|
|
10357
10399
|
case enums.publicKey.pqc_mldsa_ed25519:
|
|
10358
|
-
return
|
|
10400
|
+
return getHashByteLength(hashAlgo) >= 32;
|
|
10359
10401
|
default:
|
|
10360
10402
|
throw new Error('Unsupported signature algorithm');
|
|
10361
10403
|
}
|
|
@@ -12478,6 +12520,12 @@ async function verify$1(algo, hashAlgo, signature, publicParams, privateParams,
|
|
|
12478
12520
|
return verify$8(oid, hashAlgo, { r, s }, data, Q, hashed);
|
|
12479
12521
|
}
|
|
12480
12522
|
case enums.publicKey.eddsaLegacy: {
|
|
12523
|
+
if (getHashByteLength(hashAlgo) < getHashByteLength(enums.hash.sha256)) {
|
|
12524
|
+
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
|
12525
|
+
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
12526
|
+
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
|
12527
|
+
throw new Error('Hash algorithm too weak for EdDSALegacy.');
|
|
12528
|
+
}
|
|
12481
12529
|
const { oid, Q } = publicParams;
|
|
12482
12530
|
const curveSize = new CurveWithOID(oid).payloadSize;
|
|
12483
12531
|
// When dealing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
|
|
@@ -12488,6 +12536,13 @@ async function verify$1(algo, hashAlgo, signature, publicParams, privateParams,
|
|
|
12488
12536
|
}
|
|
12489
12537
|
case enums.publicKey.ed25519:
|
|
12490
12538
|
case enums.publicKey.ed448: {
|
|
12539
|
+
if (getHashByteLength(hashAlgo) < getHashByteLength(getPreferredHashAlgo$2(algo))) {
|
|
12540
|
+
// Enforce digest sizes:
|
|
12541
|
+
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
|
12542
|
+
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
|
12543
|
+
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
12544
|
+
}
|
|
12545
|
+
|
|
12491
12546
|
const { A } = publicParams;
|
|
12492
12547
|
return verify$9(algo, hashAlgo, signature, data, A, hashed);
|
|
12493
12548
|
}
|
|
@@ -12500,6 +12555,11 @@ async function verify$1(algo, hashAlgo, signature, publicParams, privateParams,
|
|
|
12500
12555
|
return verify$5(algo.getValue(), keyMaterial, signature.mac.data, hashed);
|
|
12501
12556
|
}
|
|
12502
12557
|
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
12558
|
+
if (!isCompatibleHashAlgo(algo, hashAlgo)) {
|
|
12559
|
+
// The signature hash algo MUST have digest larger than 256 bits
|
|
12560
|
+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-10.html#section-9.4
|
|
12561
|
+
throw new Error('Unexpected hash algorithm for PQC signature: digest size too short');
|
|
12562
|
+
}
|
|
12503
12563
|
const { eccPublicKey, mldsaPublicKey } = publicParams;
|
|
12504
12564
|
return verify$2(algo, hashAlgo, eccPublicKey, mldsaPublicKey, hashed, signature);
|
|
12505
12565
|
}
|
|
@@ -12548,12 +12608,24 @@ async function sign$1(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
|
|
|
12548
12608
|
return sign$8(oid, hashAlgo, data, Q, d, hashed);
|
|
12549
12609
|
}
|
|
12550
12610
|
case enums.publicKey.eddsaLegacy: {
|
|
12611
|
+
if (getHashByteLength(hashAlgo) < getHashByteLength(enums.hash.sha256)) {
|
|
12612
|
+
// Enforce digest sizes, since the constraint was already present in RFC4880bis:
|
|
12613
|
+
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
12614
|
+
// and https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.3-3
|
|
12615
|
+
throw new Error('Hash algorithm too weak for EdDSALegacy.');
|
|
12616
|
+
}
|
|
12551
12617
|
const { oid, Q } = publicKeyParams;
|
|
12552
12618
|
const { seed } = privateKeyParams;
|
|
12553
12619
|
return sign$7(oid, hashAlgo, data, Q, seed, hashed);
|
|
12554
12620
|
}
|
|
12555
12621
|
case enums.publicKey.ed25519:
|
|
12556
12622
|
case enums.publicKey.ed448: {
|
|
12623
|
+
if (getHashByteLength(hashAlgo) < getHashByteLength(getPreferredHashAlgo$2(algo))) {
|
|
12624
|
+
// Enforce digest sizes:
|
|
12625
|
+
// - Ed25519: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.4-4
|
|
12626
|
+
// - Ed448: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.5-4
|
|
12627
|
+
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
12628
|
+
}
|
|
12557
12629
|
const { A } = publicKeyParams;
|
|
12558
12630
|
const { seed } = privateKeyParams;
|
|
12559
12631
|
return sign$9(algo, hashAlgo, data, A, seed, hashed);
|
|
@@ -12565,6 +12637,11 @@ async function sign$1(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
|
|
|
12565
12637
|
return { mac: new ShortByteString(mac) };
|
|
12566
12638
|
}
|
|
12567
12639
|
case enums.publicKey.pqc_mldsa_ed25519: {
|
|
12640
|
+
if (!isCompatibleHashAlgo(algo, hashAlgo)) {
|
|
12641
|
+
// The signature hash algo MUST have digest larger than 256 bits
|
|
12642
|
+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-10.html#section-9.4
|
|
12643
|
+
throw new Error('Unexpected hash algorithm for PQC signature: digest size too short');
|
|
12644
|
+
}
|
|
12568
12645
|
const { eccPublicKey } = publicKeyParams;
|
|
12569
12646
|
const { eccSecretKey, mldsaSecretKey } = privateKeyParams;
|
|
12570
12647
|
return sign$2(algo, hashAlgo, eccSecretKey, eccPublicKey, mldsaSecretKey, hashed);
|
|
@@ -16833,12 +16910,8 @@ class PublicKeyPacket {
|
|
|
16833
16910
|
throw new Error('Legacy curve25519 cannot be used with v6 keys');
|
|
16834
16911
|
}
|
|
16835
16912
|
// The composite ML-DSA + EdDSA schemes MUST be used only with v6 keys.
|
|
16836
|
-
|
|
16837
|
-
|
|
16838
|
-
this.algorithm === enums.publicKey.pqc_mldsa_ed25519 ||
|
|
16839
|
-
this.algorithm === enums.publicKey.pqc_mlkem_x25519
|
|
16840
|
-
)) {
|
|
16841
|
-
throw new Error('Unexpected key version: ML-DSA and ML-KEM algorithms can only be used with v6 keys');
|
|
16913
|
+
if (this.version !== 6 && this.algorithm === enums.publicKey.pqc_mldsa_ed25519) {
|
|
16914
|
+
throw new Error('Unexpected key version: ML-DSA algorithms can only be used with v6 keys');
|
|
16842
16915
|
}
|
|
16843
16916
|
this.publicParams = publicParams;
|
|
16844
16917
|
pos += read;
|
|
@@ -17838,11 +17911,8 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
17838
17911
|
)) {
|
|
17839
17912
|
throw new Error(`Cannot generate v6 keys of type 'ecc' with curve ${curve}. Generate a key of type 'curve25519' instead`);
|
|
17840
17913
|
}
|
|
17841
|
-
if (this.version !== 6 &&
|
|
17842
|
-
this.
|
|
17843
|
-
this.algorithm === enums.publicKey.pqc_mlkem_x25519
|
|
17844
|
-
)) {
|
|
17845
|
-
throw new Error(`Cannot generate v${this.version} keys of type 'pqc'. Generate a v6 key instead`);
|
|
17914
|
+
if (this.version !== 6 && this.algorithm === enums.publicKey.pqc_mldsa_ed25519) {
|
|
17915
|
+
throw new Error(`Cannot generate v${this.version} signing keys of type 'pqc'. Generate a v6 key instead`);
|
|
17846
17916
|
}
|
|
17847
17917
|
const { privateParams, publicParams } = await generateParams(this.algorithm, bits, curve, symmetric);
|
|
17848
17918
|
this.privateParams = privateParams;
|
|
@@ -18346,12 +18416,6 @@ async function createBindingSignature(subkey, primaryKey, options, config) {
|
|
|
18346
18416
|
* @async
|
|
18347
18417
|
*/
|
|
18348
18418
|
async function getPreferredHashAlgo(targetKeys, signingKeyPacket, date = new Date(), targetUserIDs = [], config) {
|
|
18349
|
-
if (signingKeyPacket.algorithm === enums.publicKey.pqc_mldsa_ed25519) {
|
|
18350
|
-
// For PQC, the returned hash algo MUST be set to the specified algorithm, see
|
|
18351
|
-
// https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-pqc#section-5.2.1.
|
|
18352
|
-
return getRequiredHashAlgo(signingKeyPacket.algorithm);
|
|
18353
|
-
}
|
|
18354
|
-
|
|
18355
18419
|
/**
|
|
18356
18420
|
* If `preferredSenderAlgo` appears in the prefs of all recipients, we pick it; otherwise, we use the
|
|
18357
18421
|
* strongest supported algo (`defaultAlgo` is always implicitly supported by all keys).
|
|
@@ -18399,6 +18463,10 @@ async function getPreferredHashAlgo(targetKeys, signingKeyPacket, date = new Dat
|
|
|
18399
18463
|
enums.publicKey.ed448
|
|
18400
18464
|
]);
|
|
18401
18465
|
|
|
18466
|
+
const pqcAlgos = new Set([
|
|
18467
|
+
enums.publicKey.pqc_mldsa_ed25519
|
|
18468
|
+
]);
|
|
18469
|
+
|
|
18402
18470
|
if (eccAlgos.has(signingKeyPacket.algorithm)) {
|
|
18403
18471
|
// For ECC, the returned hash algo MUST be at least as strong as `preferredCurveHashAlgo`, see:
|
|
18404
18472
|
// - ECDSA: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.2-5
|
|
@@ -18421,6 +18489,21 @@ async function getPreferredHashAlgo(targetKeys, signingKeyPacket, date = new Dat
|
|
|
18421
18489
|
strongestSupportedAlgo :
|
|
18422
18490
|
preferredCurveAlgo;
|
|
18423
18491
|
}
|
|
18492
|
+
} else if (pqcAlgos.has(signingKeyPacket.algorithm)) {
|
|
18493
|
+
// For PQC, the returned hash algo MUST be at least 256 bit long, see:
|
|
18494
|
+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-10.html#section-9.4 .
|
|
18495
|
+
// Hence, we return the `preferredHashAlgo` as long as it's supported and long enough;
|
|
18496
|
+
// Otherwise, we look at the strongest supported algo, and ultimately fallback the default algo (SHA-256).
|
|
18497
|
+
const preferredSenderAlgoIsSupported = isSupportedHashAlgo(preferredSenderAlgo) && isCompatibleHashAlgo(signingKeyPacket.algorithm, preferredSenderAlgo);
|
|
18498
|
+
|
|
18499
|
+
if (preferredSenderAlgoIsSupported) {
|
|
18500
|
+
return preferredSenderAlgo;
|
|
18501
|
+
} else {
|
|
18502
|
+
const strongestSupportedAlgo = getStrongestSupportedHashAlgo();
|
|
18503
|
+
return isCompatibleHashAlgo(signingKeyPacket.algorithm, strongestSupportedAlgo) ?
|
|
18504
|
+
strongestSupportedAlgo :
|
|
18505
|
+
defaultAlgo;
|
|
18506
|
+
}
|
|
18424
18507
|
}
|
|
18425
18508
|
|
|
18426
18509
|
// `preferredSenderAlgo` may be weaker than the default, but we do not guard against this,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protontech/openpgp",
|
|
3
3
|
"description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.",
|
|
4
|
-
"version": "6.1.1-patch.
|
|
4
|
+
"version": "6.1.1-patch.3",
|
|
5
5
|
"license": "LGPL-3.0+",
|
|
6
6
|
"homepage": "https://openpgpjs.org/",
|
|
7
7
|
"engines": {
|