@protontech/openpgp 5.9.1-1 → 5.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lightweight/argon2id.min.mjs +1 -1
- package/dist/lightweight/argon2id.mjs +1 -1
- package/dist/lightweight/bn.interface.min.mjs +1 -1
- package/dist/lightweight/bn.interface.mjs +1 -1
- package/dist/lightweight/bn.min.mjs +1 -1
- package/dist/lightweight/bn.mjs +1 -1
- package/dist/lightweight/elliptic.min.mjs +1 -1
- package/dist/lightweight/elliptic.mjs +1 -1
- package/dist/lightweight/openpgp.min.mjs +2 -2
- package/dist/lightweight/openpgp.min.mjs.map +1 -1
- package/dist/lightweight/openpgp.mjs +1870 -1288
- package/dist/lightweight/ponyfill.es6.min.mjs +1 -1
- package/dist/lightweight/ponyfill.es6.mjs +1 -1
- package/dist/lightweight/web-streams-adapter.min.mjs +1 -1
- package/dist/lightweight/web-streams-adapter.mjs +1 -1
- package/dist/node/openpgp.js +1346 -764
- package/dist/node/openpgp.min.js +3 -3
- package/dist/node/openpgp.min.js.map +1 -1
- package/dist/node/openpgp.min.mjs +3 -3
- package/dist/node/openpgp.min.mjs.map +1 -1
- package/dist/node/openpgp.mjs +1343 -761
- package/dist/openpgp.js +1346 -764
- package/dist/openpgp.min.js +3 -3
- package/dist/openpgp.min.js.map +1 -1
- package/dist/openpgp.min.mjs +3 -3
- package/dist/openpgp.min.mjs.map +1 -1
- package/dist/openpgp.mjs +1343 -761
- package/openpgp.d.ts +9 -2
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! OpenPGP.js v5.
|
|
1
|
+
/*! OpenPGP.js v5.11.0 - 2023-11-27 - 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');
|
|
@@ -241,18 +241,17 @@ if (NodeReadableStream$1) {
|
|
|
241
241
|
this.push(null);
|
|
242
242
|
break;
|
|
243
243
|
}
|
|
244
|
-
if (!this.push(value)
|
|
245
|
-
this._reading = false;
|
|
244
|
+
if (!this.push(value)) {
|
|
246
245
|
break;
|
|
247
246
|
}
|
|
248
247
|
}
|
|
249
|
-
} catch(e) {
|
|
250
|
-
this.
|
|
248
|
+
} catch (e) {
|
|
249
|
+
this.destroy(e);
|
|
251
250
|
}
|
|
252
251
|
}
|
|
253
252
|
|
|
254
|
-
_destroy(
|
|
255
|
-
this._reader.cancel(
|
|
253
|
+
async _destroy(error, callback) {
|
|
254
|
+
this._reader.cancel(error).then(callback, callback);
|
|
256
255
|
}
|
|
257
256
|
}
|
|
258
257
|
|
|
@@ -287,7 +286,7 @@ function Reader(input) {
|
|
|
287
286
|
const reader = input.getReader();
|
|
288
287
|
this._read = reader.read.bind(reader);
|
|
289
288
|
this._releaseLock = () => {};
|
|
290
|
-
this._cancel = () => {};
|
|
289
|
+
this._cancel = async () => {};
|
|
291
290
|
return;
|
|
292
291
|
}
|
|
293
292
|
let streamType = isStream(input);
|
|
@@ -1507,1211 +1506,1233 @@ async function getBigInteger() {
|
|
|
1507
1506
|
}
|
|
1508
1507
|
}
|
|
1509
1508
|
|
|
1510
|
-
|
|
1509
|
+
/**
|
|
1510
|
+
* @module enums
|
|
1511
|
+
*/
|
|
1511
1512
|
|
|
1512
|
-
const
|
|
1513
|
-
try {
|
|
1514
|
-
return process.env.NODE_ENV === 'development'; // eslint-disable-line no-process-env
|
|
1515
|
-
} catch (e) {}
|
|
1516
|
-
return false;
|
|
1517
|
-
})();
|
|
1513
|
+
const byValue = Symbol('byValue');
|
|
1518
1514
|
|
|
1519
|
-
|
|
1520
|
-
isString: function(data) {
|
|
1521
|
-
return typeof data === 'string' || data instanceof String;
|
|
1522
|
-
},
|
|
1515
|
+
var enums = {
|
|
1523
1516
|
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1517
|
+
/** Maps curve names under various standards to one
|
|
1518
|
+
* @see {@link https://wiki.gnupg.org/ECC|ECC - GnuPG wiki}
|
|
1519
|
+
* @enum {String}
|
|
1520
|
+
* @readonly
|
|
1521
|
+
*/
|
|
1522
|
+
curve: {
|
|
1523
|
+
/** NIST P-256 Curve */
|
|
1524
|
+
'p256': 'p256',
|
|
1525
|
+
'P-256': 'p256',
|
|
1526
|
+
'secp256r1': 'p256',
|
|
1527
|
+
'prime256v1': 'p256',
|
|
1528
|
+
'1.2.840.10045.3.1.7': 'p256',
|
|
1529
|
+
'2a8648ce3d030107': 'p256',
|
|
1530
|
+
'2A8648CE3D030107': 'p256',
|
|
1527
1531
|
|
|
1528
|
-
|
|
1532
|
+
/** NIST P-384 Curve */
|
|
1533
|
+
'p384': 'p384',
|
|
1534
|
+
'P-384': 'p384',
|
|
1535
|
+
'secp384r1': 'p384',
|
|
1536
|
+
'1.3.132.0.34': 'p384',
|
|
1537
|
+
'2b81040022': 'p384',
|
|
1538
|
+
'2B81040022': 'p384',
|
|
1529
1539
|
|
|
1530
|
-
|
|
1540
|
+
/** NIST P-521 Curve */
|
|
1541
|
+
'p521': 'p521',
|
|
1542
|
+
'P-521': 'p521',
|
|
1543
|
+
'secp521r1': 'p521',
|
|
1544
|
+
'1.3.132.0.35': 'p521',
|
|
1545
|
+
'2b81040023': 'p521',
|
|
1546
|
+
'2B81040023': 'p521',
|
|
1531
1547
|
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
return n;
|
|
1538
|
-
},
|
|
1548
|
+
/** SECG SECP256k1 Curve */
|
|
1549
|
+
'secp256k1': 'secp256k1',
|
|
1550
|
+
'1.3.132.0.10': 'secp256k1',
|
|
1551
|
+
'2b8104000a': 'secp256k1',
|
|
1552
|
+
'2B8104000A': 'secp256k1',
|
|
1539
1553
|
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1554
|
+
/** Ed25519 - deprecated by crypto-refresh (replaced by standaone Ed25519 algo) */
|
|
1555
|
+
'ed25519Legacy': 'ed25519',
|
|
1556
|
+
'ED25519': 'ed25519',
|
|
1557
|
+
/** @deprecated use `ed25519Legacy` instead */
|
|
1558
|
+
'ed25519': 'ed25519',
|
|
1559
|
+
'Ed25519': 'ed25519',
|
|
1560
|
+
'1.3.6.1.4.1.11591.15.1': 'ed25519',
|
|
1561
|
+
'2b06010401da470f01': 'ed25519',
|
|
1562
|
+
'2B06010401DA470F01': 'ed25519',
|
|
1545
1563
|
|
|
1546
|
-
|
|
1547
|
-
|
|
1564
|
+
/** Curve25519 - deprecated by crypto-refresh (replaced by standaone X25519 algo) */
|
|
1565
|
+
'curve25519Legacy': 'curve25519',
|
|
1566
|
+
'X25519': 'curve25519',
|
|
1567
|
+
'cv25519': 'curve25519',
|
|
1568
|
+
/** @deprecated use `curve25519Legacy` instead */
|
|
1569
|
+
'curve25519': 'curve25519',
|
|
1570
|
+
'Curve25519': 'curve25519',
|
|
1571
|
+
'1.3.6.1.4.1.3029.1.5.1': 'curve25519',
|
|
1572
|
+
'2b060104019755010501': 'curve25519',
|
|
1573
|
+
'2B060104019755010501': 'curve25519',
|
|
1548
1574
|
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1575
|
+
/** BrainpoolP256r1 Curve */
|
|
1576
|
+
'brainpoolP256r1': 'brainpoolP256r1',
|
|
1577
|
+
'1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1',
|
|
1578
|
+
'2b2403030208010107': 'brainpoolP256r1',
|
|
1579
|
+
'2B2403030208010107': 'brainpoolP256r1',
|
|
1554
1580
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1581
|
+
/** BrainpoolP384r1 Curve */
|
|
1582
|
+
'brainpoolP384r1': 'brainpoolP384r1',
|
|
1583
|
+
'1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1',
|
|
1584
|
+
'2b240303020801010b': 'brainpoolP384r1',
|
|
1585
|
+
'2B240303020801010B': 'brainpoolP384r1',
|
|
1557
1586
|
|
|
1558
|
-
|
|
1587
|
+
/** BrainpoolP512r1 Curve */
|
|
1588
|
+
'brainpoolP512r1': 'brainpoolP512r1',
|
|
1589
|
+
'1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1',
|
|
1590
|
+
'2b240303020801010d': 'brainpoolP512r1',
|
|
1591
|
+
'2B240303020801010D': 'brainpoolP512r1'
|
|
1559
1592
|
},
|
|
1560
1593
|
|
|
1561
|
-
|
|
1562
|
-
|
|
1594
|
+
/** KDF parameters flags
|
|
1595
|
+
* Non-standard extensions (for now) to allow email forwarding
|
|
1596
|
+
* @enum {Integer}
|
|
1597
|
+
* @readonly
|
|
1598
|
+
*/
|
|
1599
|
+
kdfFlags: {
|
|
1600
|
+
/** Specify fingerprint to use instead of the recipient's */
|
|
1601
|
+
replace_fingerprint: 0x01,
|
|
1602
|
+
/** Specify custom parameters to use in the KDF digest computation */
|
|
1603
|
+
replace_kdf_params: 0x02
|
|
1563
1604
|
},
|
|
1564
1605
|
|
|
1565
|
-
/**
|
|
1566
|
-
*
|
|
1567
|
-
* @
|
|
1568
|
-
* @returns {Uint8Array} Parsed MPI.
|
|
1606
|
+
/** A string to key specifier type
|
|
1607
|
+
* @enum {Integer}
|
|
1608
|
+
* @readonly
|
|
1569
1609
|
*/
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1610
|
+
s2k: {
|
|
1611
|
+
simple: 0,
|
|
1612
|
+
salted: 1,
|
|
1613
|
+
iterated: 3,
|
|
1614
|
+
argon2: 4,
|
|
1615
|
+
gnu: 101
|
|
1574
1616
|
},
|
|
1575
1617
|
|
|
1576
|
-
/**
|
|
1577
|
-
*
|
|
1578
|
-
* @
|
|
1579
|
-
* @param {Number} length - Padded length
|
|
1580
|
-
* @returns {Uint8Array} Padded bytes.
|
|
1618
|
+
/** {@link https://tools.ietf.org/html/draft-ietf-openpgp-crypto-refresh-08.html#section-9.1|crypto-refresh RFC, section 9.1}
|
|
1619
|
+
* @enum {Integer}
|
|
1620
|
+
* @readonly
|
|
1581
1621
|
*/
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1622
|
+
publicKey: {
|
|
1623
|
+
/** RSA (Encrypt or Sign) [HAC] */
|
|
1624
|
+
rsaEncryptSign: 1,
|
|
1625
|
+
/** RSA (Encrypt only) [HAC] */
|
|
1626
|
+
rsaEncrypt: 2,
|
|
1627
|
+
/** RSA (Sign only) [HAC] */
|
|
1628
|
+
rsaSign: 3,
|
|
1629
|
+
/** Elgamal (Encrypt only) [ELGAMAL] [HAC] */
|
|
1630
|
+
elgamal: 16,
|
|
1631
|
+
/** DSA (Sign only) [FIPS186] [HAC] */
|
|
1632
|
+
dsa: 17,
|
|
1633
|
+
/** ECDH (Encrypt only) [RFC6637] */
|
|
1634
|
+
ecdh: 18,
|
|
1635
|
+
/** ECDSA (Sign only) [RFC6637] */
|
|
1636
|
+
ecdsa: 19,
|
|
1637
|
+
/** EdDSA (Sign only) - deprecated by crypto-refresh (replaced by `ed25519` identifier below)
|
|
1638
|
+
* [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */
|
|
1639
|
+
eddsaLegacy: 22, // NB: this is declared before `eddsa` to translate 22 to 'eddsa' for backwards compatibility
|
|
1640
|
+
/** @deprecated use `eddsaLegacy` instead */
|
|
1641
|
+
ed25519Legacy: 22,
|
|
1642
|
+
/** @deprecated use `eddsaLegacy` instead */
|
|
1643
|
+
eddsa: 22,
|
|
1644
|
+
/** Reserved for AEDH */
|
|
1645
|
+
aedh: 23,
|
|
1646
|
+
/** Reserved for AEDSA */
|
|
1647
|
+
aedsa: 24,
|
|
1648
|
+
/** X25519 (Encrypt only) */
|
|
1649
|
+
x25519: 25,
|
|
1650
|
+
/** X448 (Encrypt only) */
|
|
1651
|
+
x448: 26,
|
|
1652
|
+
/** Ed25519 (Sign only) */
|
|
1653
|
+
ed25519: 27,
|
|
1654
|
+
/** Ed448 (Sign only) */
|
|
1655
|
+
ed448: 28,
|
|
1656
|
+
/** Symmetric authenticated encryption algorithms */
|
|
1657
|
+
aead: 100,
|
|
1658
|
+
/** Authentication using CMAC */
|
|
1659
|
+
hmac: 101
|
|
1587
1660
|
},
|
|
1588
1661
|
|
|
1589
|
-
/**
|
|
1590
|
-
*
|
|
1591
|
-
* @
|
|
1592
|
-
* @returns {Uint8Array} MPI-formatted Uint8Array.
|
|
1662
|
+
/** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
|
|
1663
|
+
* @enum {Integer}
|
|
1664
|
+
* @readonly
|
|
1593
1665
|
*/
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1666
|
+
symmetric: {
|
|
1667
|
+
plaintext: 0,
|
|
1668
|
+
/** Not implemented! */
|
|
1669
|
+
idea: 1,
|
|
1670
|
+
tripledes: 2,
|
|
1671
|
+
cast5: 3,
|
|
1672
|
+
blowfish: 4,
|
|
1673
|
+
aes128: 7,
|
|
1674
|
+
aes192: 8,
|
|
1675
|
+
aes256: 9,
|
|
1676
|
+
twofish: 10
|
|
1602
1677
|
},
|
|
1603
1678
|
|
|
1604
|
-
/**
|
|
1605
|
-
*
|
|
1606
|
-
* @
|
|
1607
|
-
* @returns bit length
|
|
1679
|
+
/** {@link https://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
|
|
1680
|
+
* @enum {Integer}
|
|
1681
|
+
* @readonly
|
|
1608
1682
|
*/
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
return (stripped.length - 1) * 8 + util.nbits(stripped[0]);
|
|
1683
|
+
compression: {
|
|
1684
|
+
uncompressed: 0,
|
|
1685
|
+
/** RFC1951 */
|
|
1686
|
+
zip: 1,
|
|
1687
|
+
/** RFC1950 */
|
|
1688
|
+
zlib: 2,
|
|
1689
|
+
bzip2: 3
|
|
1617
1690
|
},
|
|
1618
1691
|
|
|
1619
|
-
/**
|
|
1620
|
-
*
|
|
1621
|
-
* @
|
|
1622
|
-
* @returns {Uint8Array} An array of 8-bit integers.
|
|
1692
|
+
/** {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
|
|
1693
|
+
* @enum {Integer}
|
|
1694
|
+
* @readonly
|
|
1623
1695
|
*/
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1696
|
+
hash: {
|
|
1697
|
+
md5: 1,
|
|
1698
|
+
sha1: 2,
|
|
1699
|
+
ripemd: 3,
|
|
1700
|
+
sha256: 8,
|
|
1701
|
+
sha384: 9,
|
|
1702
|
+
sha512: 10,
|
|
1703
|
+
sha224: 11
|
|
1630
1704
|
},
|
|
1631
1705
|
|
|
1632
|
-
/**
|
|
1633
|
-
*
|
|
1634
|
-
* @
|
|
1635
|
-
* @returns {String} Hexadecimal representation of the array.
|
|
1706
|
+
/** A list of hash names as accepted by webCrypto functions.
|
|
1707
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest|Parameters, algo}
|
|
1708
|
+
* @enum {String}
|
|
1636
1709
|
*/
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
while (c < e) {
|
|
1643
|
-
h = bytes[c++].toString(16);
|
|
1644
|
-
while (h.length < 2) {
|
|
1645
|
-
h = '0' + h;
|
|
1646
|
-
}
|
|
1647
|
-
r.push('' + h);
|
|
1648
|
-
}
|
|
1649
|
-
return r.join('');
|
|
1650
|
-
},
|
|
1651
|
-
|
|
1652
|
-
/**
|
|
1653
|
-
* Convert a string to an array of 8-bit integers
|
|
1654
|
-
* @param {String} str - String to convert
|
|
1655
|
-
* @returns {Uint8Array} An array of 8-bit integers.
|
|
1656
|
-
*/
|
|
1657
|
-
stringToUint8Array: function (str) {
|
|
1658
|
-
return transform(str, str => {
|
|
1659
|
-
if (!util.isString(str)) {
|
|
1660
|
-
throw new Error('stringToUint8Array: Data must be in the form of a string');
|
|
1661
|
-
}
|
|
1662
|
-
|
|
1663
|
-
const result = new Uint8Array(str.length);
|
|
1664
|
-
for (let i = 0; i < str.length; i++) {
|
|
1665
|
-
result[i] = str.charCodeAt(i);
|
|
1666
|
-
}
|
|
1667
|
-
return result;
|
|
1668
|
-
});
|
|
1669
|
-
},
|
|
1670
|
-
|
|
1671
|
-
/**
|
|
1672
|
-
* Convert an array of 8-bit integers to a string
|
|
1673
|
-
* @param {Uint8Array} bytes - An array of 8-bit integers to convert
|
|
1674
|
-
* @returns {String} String representation of the array.
|
|
1675
|
-
*/
|
|
1676
|
-
uint8ArrayToString: function (bytes) {
|
|
1677
|
-
bytes = new Uint8Array(bytes);
|
|
1678
|
-
const result = [];
|
|
1679
|
-
const bs = 1 << 14;
|
|
1680
|
-
const j = bytes.length;
|
|
1681
|
-
|
|
1682
|
-
for (let i = 0; i < j; i += bs) {
|
|
1683
|
-
result.push(String.fromCharCode.apply(String, bytes.subarray(i, i + bs < j ? i + bs : j)));
|
|
1684
|
-
}
|
|
1685
|
-
return result.join('');
|
|
1686
|
-
},
|
|
1687
|
-
|
|
1688
|
-
/**
|
|
1689
|
-
* Convert a native javascript string to a Uint8Array of utf8 bytes
|
|
1690
|
-
* @param {String|ReadableStream} str - The string to convert
|
|
1691
|
-
* @returns {Uint8Array|ReadableStream} A valid squence of utf8 bytes.
|
|
1692
|
-
*/
|
|
1693
|
-
encodeUTF8: function (str) {
|
|
1694
|
-
const encoder = new TextEncoder('utf-8');
|
|
1695
|
-
// eslint-disable-next-line no-inner-declarations
|
|
1696
|
-
function process(value, lastChunk = false) {
|
|
1697
|
-
return encoder.encode(value, { stream: !lastChunk });
|
|
1698
|
-
}
|
|
1699
|
-
return transform(str, process, () => process('', true));
|
|
1700
|
-
},
|
|
1701
|
-
|
|
1702
|
-
/**
|
|
1703
|
-
* Convert a Uint8Array of utf8 bytes to a native javascript string
|
|
1704
|
-
* @param {Uint8Array|ReadableStream} utf8 - A valid squence of utf8 bytes
|
|
1705
|
-
* @returns {String|ReadableStream} A native javascript string.
|
|
1706
|
-
*/
|
|
1707
|
-
decodeUTF8: function (utf8) {
|
|
1708
|
-
const decoder = new TextDecoder('utf-8');
|
|
1709
|
-
// eslint-disable-next-line no-inner-declarations
|
|
1710
|
-
function process(value, lastChunk = false) {
|
|
1711
|
-
return decoder.decode(value, { stream: !lastChunk });
|
|
1712
|
-
}
|
|
1713
|
-
return transform(utf8, process, () => process(new Uint8Array(), true));
|
|
1714
|
-
},
|
|
1715
|
-
|
|
1716
|
-
/**
|
|
1717
|
-
* Concat a list of Uint8Arrays, Strings or Streams
|
|
1718
|
-
* The caller must not mix Uint8Arrays with Strings, but may mix Streams with non-Streams.
|
|
1719
|
-
* @param {Array<Uint8Array|String|ReadableStream>} Array - Of Uint8Arrays/Strings/Streams to concatenate
|
|
1720
|
-
* @returns {Uint8Array|String|ReadableStream} Concatenated array.
|
|
1721
|
-
*/
|
|
1722
|
-
concat: concat,
|
|
1723
|
-
|
|
1724
|
-
/**
|
|
1725
|
-
* Concat Uint8Arrays
|
|
1726
|
-
* @param {Array<Uint8Array>} Array - Of Uint8Arrays to concatenate
|
|
1727
|
-
* @returns {Uint8Array} Concatenated array.
|
|
1728
|
-
*/
|
|
1729
|
-
concatUint8Array: concatUint8Array,
|
|
1730
|
-
|
|
1731
|
-
/**
|
|
1732
|
-
* Check Uint8Array equality
|
|
1733
|
-
* @param {Uint8Array} array1 - First array
|
|
1734
|
-
* @param {Uint8Array} array2 - Second array
|
|
1735
|
-
* @returns {Boolean} Equality.
|
|
1736
|
-
*/
|
|
1737
|
-
equalsUint8Array: function (array1, array2) {
|
|
1738
|
-
if (!util.isUint8Array(array1) || !util.isUint8Array(array2)) {
|
|
1739
|
-
throw new Error('Data must be in the form of a Uint8Array');
|
|
1740
|
-
}
|
|
1741
|
-
|
|
1742
|
-
if (array1.length !== array2.length) {
|
|
1743
|
-
return false;
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
for (let i = 0; i < array1.length; i++) {
|
|
1747
|
-
if (array1[i] !== array2[i]) {
|
|
1748
|
-
return false;
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
return true;
|
|
1710
|
+
webHash: {
|
|
1711
|
+
'SHA-1': 2,
|
|
1712
|
+
'SHA-256': 8,
|
|
1713
|
+
'SHA-384': 9,
|
|
1714
|
+
'SHA-512': 10
|
|
1752
1715
|
},
|
|
1753
1716
|
|
|
1754
|
-
/**
|
|
1755
|
-
*
|
|
1756
|
-
*
|
|
1757
|
-
* @param {Uint8Array} Uint8Array - To create a sum of
|
|
1758
|
-
* @returns {Uint8Array} 2 bytes containing the sum of all charcodes % 65535.
|
|
1717
|
+
/** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.6|RFC4880bis-04, section 9.6}
|
|
1718
|
+
* @enum {Integer}
|
|
1719
|
+
* @readonly
|
|
1759
1720
|
*/
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
}
|
|
1765
|
-
return util.writeNumber(s, 2);
|
|
1721
|
+
aead: {
|
|
1722
|
+
eax: 1,
|
|
1723
|
+
ocb: 2,
|
|
1724
|
+
experimentalGCM: 100 // Private algorithm
|
|
1766
1725
|
},
|
|
1767
1726
|
|
|
1768
|
-
/**
|
|
1769
|
-
*
|
|
1770
|
-
*
|
|
1771
|
-
* @param {String} str - String of the debug message
|
|
1727
|
+
/** A list of packet types and numeric tags associated with them.
|
|
1728
|
+
* @enum {Integer}
|
|
1729
|
+
* @readonly
|
|
1772
1730
|
*/
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1731
|
+
packet: {
|
|
1732
|
+
publicKeyEncryptedSessionKey: 1,
|
|
1733
|
+
signature: 2,
|
|
1734
|
+
symEncryptedSessionKey: 3,
|
|
1735
|
+
onePassSignature: 4,
|
|
1736
|
+
secretKey: 5,
|
|
1737
|
+
publicKey: 6,
|
|
1738
|
+
secretSubkey: 7,
|
|
1739
|
+
compressedData: 8,
|
|
1740
|
+
symmetricallyEncryptedData: 9,
|
|
1741
|
+
marker: 10,
|
|
1742
|
+
literalData: 11,
|
|
1743
|
+
trust: 12,
|
|
1744
|
+
userID: 13,
|
|
1745
|
+
publicSubkey: 14,
|
|
1746
|
+
userAttribute: 17,
|
|
1747
|
+
symEncryptedIntegrityProtectedData: 18,
|
|
1748
|
+
modificationDetectionCode: 19,
|
|
1749
|
+
aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
|
|
1777
1750
|
},
|
|
1778
1751
|
|
|
1779
|
-
/**
|
|
1780
|
-
*
|
|
1781
|
-
*
|
|
1782
|
-
* @param {String} str - String of the debug message
|
|
1752
|
+
/** Data types in the literal packet
|
|
1753
|
+
* @enum {Integer}
|
|
1754
|
+
* @readonly
|
|
1783
1755
|
*/
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1756
|
+
literal: {
|
|
1757
|
+
/** Binary data 'b' */
|
|
1758
|
+
binary: 'b'.charCodeAt(),
|
|
1759
|
+
/** Text data 't' */
|
|
1760
|
+
text: 't'.charCodeAt(),
|
|
1761
|
+
/** Utf8 data 'u' */
|
|
1762
|
+
utf8: 'u'.charCodeAt(),
|
|
1763
|
+
/** MIME message body part 'm' */
|
|
1764
|
+
mime: 'm'.charCodeAt()
|
|
1788
1765
|
},
|
|
1789
1766
|
|
|
1790
|
-
// returns bit length of the integer x
|
|
1791
|
-
nbits: function (x) {
|
|
1792
|
-
let r = 1;
|
|
1793
|
-
let t = x >>> 16;
|
|
1794
|
-
if (t !== 0) {
|
|
1795
|
-
x = t;
|
|
1796
|
-
r += 16;
|
|
1797
|
-
}
|
|
1798
|
-
t = x >> 8;
|
|
1799
|
-
if (t !== 0) {
|
|
1800
|
-
x = t;
|
|
1801
|
-
r += 8;
|
|
1802
|
-
}
|
|
1803
|
-
t = x >> 4;
|
|
1804
|
-
if (t !== 0) {
|
|
1805
|
-
x = t;
|
|
1806
|
-
r += 4;
|
|
1807
|
-
}
|
|
1808
|
-
t = x >> 2;
|
|
1809
|
-
if (t !== 0) {
|
|
1810
|
-
x = t;
|
|
1811
|
-
r += 2;
|
|
1812
|
-
}
|
|
1813
|
-
t = x >> 1;
|
|
1814
|
-
if (t !== 0) {
|
|
1815
|
-
x = t;
|
|
1816
|
-
r += 1;
|
|
1817
|
-
}
|
|
1818
|
-
return r;
|
|
1819
|
-
},
|
|
1820
1767
|
|
|
1821
|
-
/**
|
|
1822
|
-
*
|
|
1823
|
-
*
|
|
1824
|
-
* (zeros(120) || 10000111).
|
|
1825
|
-
*
|
|
1826
|
-
* Both OCB and EAX (through CMAC) require this function to be constant-time.
|
|
1827
|
-
*
|
|
1828
|
-
* @param {Uint8Array} data
|
|
1768
|
+
/** One pass signature packet type
|
|
1769
|
+
* @enum {Integer}
|
|
1770
|
+
* @readonly
|
|
1829
1771
|
*/
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1772
|
+
signature: {
|
|
1773
|
+
/** 0x00: Signature of a binary document. */
|
|
1774
|
+
binary: 0,
|
|
1775
|
+
/** 0x01: Signature of a canonical text document.
|
|
1776
|
+
*
|
|
1777
|
+
* Canonicalyzing the document by converting line endings. */
|
|
1778
|
+
text: 1,
|
|
1779
|
+
/** 0x02: Standalone signature.
|
|
1780
|
+
*
|
|
1781
|
+
* This signature is a signature of only its own subpacket contents.
|
|
1782
|
+
* It is calculated identically to a signature over a zero-lengh
|
|
1783
|
+
* binary document. Note that it doesn't make sense to have a V3
|
|
1784
|
+
* standalone signature. */
|
|
1785
|
+
standalone: 2,
|
|
1786
|
+
/** 0x10: Generic certification of a User ID and Public-Key packet.
|
|
1787
|
+
*
|
|
1788
|
+
* The issuer of this certification does not make any particular
|
|
1789
|
+
* assertion as to how well the certifier has checked that the owner
|
|
1790
|
+
* of the key is in fact the person described by the User ID. */
|
|
1791
|
+
certGeneric: 16,
|
|
1792
|
+
/** 0x11: Persona certification of a User ID and Public-Key packet.
|
|
1793
|
+
*
|
|
1794
|
+
* The issuer of this certification has not done any verification of
|
|
1795
|
+
* the claim that the owner of this key is the User ID specified. */
|
|
1796
|
+
certPersona: 17,
|
|
1797
|
+
/** 0x12: Casual certification of a User ID and Public-Key packet.
|
|
1798
|
+
*
|
|
1799
|
+
* The issuer of this certification has done some casual
|
|
1800
|
+
* verification of the claim of identity. */
|
|
1801
|
+
certCasual: 18,
|
|
1802
|
+
/** 0x13: Positive certification of a User ID and Public-Key packet.
|
|
1803
|
+
*
|
|
1804
|
+
* The issuer of this certification has done substantial
|
|
1805
|
+
* verification of the claim of identity.
|
|
1806
|
+
*
|
|
1807
|
+
* Most OpenPGP implementations make their "key signatures" as 0x10
|
|
1808
|
+
* certifications. Some implementations can issue 0x11-0x13
|
|
1809
|
+
* certifications, but few differentiate between the types. */
|
|
1810
|
+
certPositive: 19,
|
|
1811
|
+
/** 0x30: Certification revocation signature
|
|
1812
|
+
*
|
|
1813
|
+
* This signature revokes an earlier User ID certification signature
|
|
1814
|
+
* (signature class 0x10 through 0x13) or direct-key signature
|
|
1815
|
+
* (0x1F). It should be issued by the same key that issued the
|
|
1816
|
+
* revoked signature or an authorized revocation key. The signature
|
|
1817
|
+
* is computed over the same data as the certificate that it
|
|
1818
|
+
* revokes, and should have a later creation date than that
|
|
1819
|
+
* certificate. */
|
|
1820
|
+
certRevocation: 48,
|
|
1821
|
+
/** 0x18: Subkey Binding Signature
|
|
1822
|
+
*
|
|
1823
|
+
* This signature is a statement by the top-level signing key that
|
|
1824
|
+
* indicates that it owns the subkey. This signature is calculated
|
|
1825
|
+
* directly on the primary key and subkey, and not on any User ID or
|
|
1826
|
+
* other packets. A signature that binds a signing subkey MUST have
|
|
1827
|
+
* an Embedded Signature subpacket in this binding signature that
|
|
1828
|
+
* contains a 0x19 signature made by the signing subkey on the
|
|
1829
|
+
* primary key and subkey. */
|
|
1830
|
+
subkeyBinding: 24,
|
|
1831
|
+
/** 0x19: Primary Key Binding Signature
|
|
1832
|
+
*
|
|
1833
|
+
* This signature is a statement by a signing subkey, indicating
|
|
1834
|
+
* that it is owned by the primary key and subkey. This signature
|
|
1835
|
+
* is calculated the same way as a 0x18 signature: directly on the
|
|
1836
|
+
* primary key and subkey, and not on any User ID or other packets.
|
|
1837
|
+
*
|
|
1838
|
+
* When a signature is made over a key, the hash data starts with the
|
|
1839
|
+
* octet 0x99, followed by a two-octet length of the key, and then body
|
|
1840
|
+
* of the key packet. (Note that this is an old-style packet header for
|
|
1841
|
+
* a key packet with two-octet length.) A subkey binding signature
|
|
1842
|
+
* (type 0x18) or primary key binding signature (type 0x19) then hashes
|
|
1843
|
+
* the subkey using the same format as the main key (also using 0x99 as
|
|
1844
|
+
* the first octet). */
|
|
1845
|
+
keyBinding: 25,
|
|
1846
|
+
/** 0x1F: Signature directly on a key
|
|
1847
|
+
*
|
|
1848
|
+
* This signature is calculated directly on a key. It binds the
|
|
1849
|
+
* information in the Signature subpackets to the key, and is
|
|
1850
|
+
* appropriate to be used for subpackets that provide information
|
|
1851
|
+
* about the key, such as the Revocation Key subpacket. It is also
|
|
1852
|
+
* appropriate for statements that non-self certifiers want to make
|
|
1853
|
+
* about the key itself, rather than the binding between a key and a
|
|
1854
|
+
* name. */
|
|
1855
|
+
key: 31,
|
|
1856
|
+
/** 0x20: Key revocation signature
|
|
1857
|
+
*
|
|
1858
|
+
* The signature is calculated directly on the key being revoked. A
|
|
1859
|
+
* revoked key is not to be used. Only revocation signatures by the
|
|
1860
|
+
* key being revoked, or by an authorized revocation key, should be
|
|
1861
|
+
* considered valid revocation signatures.a */
|
|
1862
|
+
keyRevocation: 32,
|
|
1863
|
+
/** 0x28: Subkey revocation signature
|
|
1864
|
+
*
|
|
1865
|
+
* The signature is calculated directly on the subkey being revoked.
|
|
1866
|
+
* A revoked subkey is not to be used. Only revocation signatures
|
|
1867
|
+
* by the top-level signature key that is bound to this subkey, or
|
|
1868
|
+
* by an authorized revocation key, should be considered valid
|
|
1869
|
+
* revocation signatures.
|
|
1870
|
+
*
|
|
1871
|
+
* Key revocation signatures (types 0x20 and 0x28)
|
|
1872
|
+
* hash only the key being revoked. */
|
|
1873
|
+
subkeyRevocation: 40,
|
|
1874
|
+
/** 0x40: Timestamp signature.
|
|
1875
|
+
* This signature is only meaningful for the timestamp contained in
|
|
1876
|
+
* it. */
|
|
1877
|
+
timestamp: 64,
|
|
1878
|
+
/** 0x50: Third-Party Confirmation signature.
|
|
1879
|
+
*
|
|
1880
|
+
* This signature is a signature over some other OpenPGP Signature
|
|
1881
|
+
* packet(s). It is analogous to a notary seal on the signed data.
|
|
1882
|
+
* A third-party signature SHOULD include Signature Target
|
|
1883
|
+
* subpacket(s) to give easy identification. Note that we really do
|
|
1884
|
+
* mean SHOULD. There are plausible uses for this (such as a blind
|
|
1885
|
+
* party that only sees the signature, not the key or source
|
|
1886
|
+
* document) that cannot include a target subpacket. */
|
|
1887
|
+
thirdParty: 80
|
|
1838
1888
|
},
|
|
1839
1889
|
|
|
1840
|
-
/**
|
|
1841
|
-
*
|
|
1842
|
-
* @
|
|
1843
|
-
* @param {Integer} bits - Amount of bits to shift (MUST be smaller
|
|
1844
|
-
* than 8)
|
|
1845
|
-
* @returns {String} Resulting array.
|
|
1890
|
+
/** Signature subpacket type
|
|
1891
|
+
* @enum {Integer}
|
|
1892
|
+
* @readonly
|
|
1846
1893
|
*/
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1894
|
+
signatureSubpacket: {
|
|
1895
|
+
signatureCreationTime: 2,
|
|
1896
|
+
signatureExpirationTime: 3,
|
|
1897
|
+
exportableCertification: 4,
|
|
1898
|
+
trustSignature: 5,
|
|
1899
|
+
regularExpression: 6,
|
|
1900
|
+
revocable: 7,
|
|
1901
|
+
keyExpirationTime: 9,
|
|
1902
|
+
placeholderBackwardsCompatibility: 10,
|
|
1903
|
+
preferredSymmetricAlgorithms: 11,
|
|
1904
|
+
revocationKey: 12,
|
|
1905
|
+
issuer: 16,
|
|
1906
|
+
notationData: 20,
|
|
1907
|
+
preferredHashAlgorithms: 21,
|
|
1908
|
+
preferredCompressionAlgorithms: 22,
|
|
1909
|
+
keyServerPreferences: 23,
|
|
1910
|
+
preferredKeyServer: 24,
|
|
1911
|
+
primaryUserID: 25,
|
|
1912
|
+
policyURI: 26,
|
|
1913
|
+
keyFlags: 27,
|
|
1914
|
+
signersUserID: 28,
|
|
1915
|
+
reasonForRevocation: 29,
|
|
1916
|
+
features: 30,
|
|
1917
|
+
signatureTarget: 31,
|
|
1918
|
+
embeddedSignature: 32,
|
|
1919
|
+
issuerFingerprint: 33,
|
|
1920
|
+
preferredAEADAlgorithms: 34
|
|
1857
1921
|
},
|
|
1858
1922
|
|
|
1859
|
-
/**
|
|
1860
|
-
*
|
|
1861
|
-
* @
|
|
1923
|
+
/** Key flags
|
|
1924
|
+
* @enum {Integer}
|
|
1925
|
+
* @readonly
|
|
1862
1926
|
*/
|
|
1863
|
-
|
|
1864
|
-
|
|
1927
|
+
keyFlags: {
|
|
1928
|
+
/** 0x01 - This key may be used to certify other keys. */
|
|
1929
|
+
certifyKeys: 1,
|
|
1930
|
+
/** 0x02 - This key may be used to sign data. */
|
|
1931
|
+
signData: 2,
|
|
1932
|
+
/** 0x04 - This key may be used to encrypt communications. */
|
|
1933
|
+
encryptCommunication: 4,
|
|
1934
|
+
/** 0x08 - This key may be used to encrypt storage. */
|
|
1935
|
+
encryptStorage: 8,
|
|
1936
|
+
/** 0x10 - The private component of this key may have been split
|
|
1937
|
+
* by a secret-sharing mechanism. */
|
|
1938
|
+
splitPrivateKey: 16,
|
|
1939
|
+
/** 0x20 - This key may be used for authentication. */
|
|
1940
|
+
authentication: 32,
|
|
1941
|
+
/** This key may be used for forwarded communications */
|
|
1942
|
+
forwardedCommunication: 64,
|
|
1943
|
+
/** 0x80 - The private component of this key may be in the
|
|
1944
|
+
* possession of more than one person. */
|
|
1945
|
+
sharedPrivateKey: 128
|
|
1865
1946
|
},
|
|
1866
1947
|
|
|
1867
|
-
/**
|
|
1868
|
-
*
|
|
1869
|
-
*
|
|
1870
|
-
* Otherwise it relies on bn.js
|
|
1871
|
-
* @returns {BigInteger}
|
|
1872
|
-
* @async
|
|
1948
|
+
/** Armor type
|
|
1949
|
+
* @enum {Integer}
|
|
1950
|
+
* @readonly
|
|
1873
1951
|
*/
|
|
1874
|
-
|
|
1952
|
+
armor: {
|
|
1953
|
+
multipartSection: 0,
|
|
1954
|
+
multipartLast: 1,
|
|
1955
|
+
signed: 2,
|
|
1956
|
+
message: 3,
|
|
1957
|
+
publicKey: 4,
|
|
1958
|
+
privateKey: 5,
|
|
1959
|
+
signature: 6
|
|
1960
|
+
},
|
|
1875
1961
|
|
|
1876
|
-
/**
|
|
1877
|
-
*
|
|
1878
|
-
* @
|
|
1962
|
+
/** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
|
|
1963
|
+
* @enum {Integer}
|
|
1964
|
+
* @readonly
|
|
1879
1965
|
*/
|
|
1880
|
-
|
|
1881
|
-
|
|
1966
|
+
reasonForRevocation: {
|
|
1967
|
+
/** No reason specified (key revocations or cert revocations) */
|
|
1968
|
+
noReason: 0,
|
|
1969
|
+
/** Key is superseded (key revocations) */
|
|
1970
|
+
keySuperseded: 1,
|
|
1971
|
+
/** Key material has been compromised (key revocations) */
|
|
1972
|
+
keyCompromised: 2,
|
|
1973
|
+
/** Key is retired and no longer used (key revocations) */
|
|
1974
|
+
keyRetired: 3,
|
|
1975
|
+
/** User ID information is no longer valid (cert revocations) */
|
|
1976
|
+
userIDInvalid: 32
|
|
1882
1977
|
},
|
|
1883
1978
|
|
|
1884
|
-
|
|
1885
|
-
|
|
1979
|
+
/** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
|
|
1980
|
+
* @enum {Integer}
|
|
1981
|
+
* @readonly
|
|
1982
|
+
*/
|
|
1983
|
+
features: {
|
|
1984
|
+
/** 0x01 - Modification Detection (packets 18 and 19) */
|
|
1985
|
+
modificationDetection: 1,
|
|
1986
|
+
/** 0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
|
|
1987
|
+
* Symmetric-Key Encrypted Session Key Packets (packet 3) */
|
|
1988
|
+
aead: 2,
|
|
1989
|
+
/** 0x04 - Version 5 Public-Key Packet format and corresponding new
|
|
1990
|
+
* fingerprint format */
|
|
1991
|
+
v5Keys: 4
|
|
1886
1992
|
},
|
|
1887
1993
|
|
|
1888
1994
|
/**
|
|
1889
|
-
*
|
|
1890
|
-
*
|
|
1891
|
-
* @
|
|
1995
|
+
* Asserts validity of given value and converts from string/integer to integer.
|
|
1996
|
+
* @param {Object} type target enum type
|
|
1997
|
+
* @param {String|Integer} e value to check and/or convert
|
|
1998
|
+
* @returns {Integer} enum value if it exists
|
|
1999
|
+
* @throws {Error} if the value is invalid
|
|
1892
2000
|
*/
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
getHardwareConcurrency: function() {
|
|
1898
|
-
if (typeof navigator !== 'undefined') {
|
|
1899
|
-
return navigator.hardwareConcurrency || 1;
|
|
2001
|
+
write: function(type, e) {
|
|
2002
|
+
if (typeof e === 'number') {
|
|
2003
|
+
e = this.read(type, e);
|
|
1900
2004
|
}
|
|
1901
2005
|
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
},
|
|
1905
|
-
|
|
1906
|
-
isEmailAddress: function(data) {
|
|
1907
|
-
if (!util.isString(data)) {
|
|
1908
|
-
return false;
|
|
2006
|
+
if (type[e] !== undefined) {
|
|
2007
|
+
return type[e];
|
|
1909
2008
|
}
|
|
1910
|
-
|
|
1911
|
-
|
|
2009
|
+
|
|
2010
|
+
throw new Error('Invalid enum value.');
|
|
1912
2011
|
},
|
|
1913
2012
|
|
|
1914
2013
|
/**
|
|
1915
|
-
*
|
|
1916
|
-
*
|
|
2014
|
+
* Converts enum integer value to the corresponding string, if it exists.
|
|
2015
|
+
* @param {Object} type target enum type
|
|
2016
|
+
* @param {Integer} e value to convert
|
|
2017
|
+
* @returns {String} name of enum value if it exists
|
|
2018
|
+
* @throws {Error} if the value is invalid
|
|
1917
2019
|
*/
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
2020
|
+
read: function(type, e) {
|
|
2021
|
+
if (!type[byValue]) {
|
|
2022
|
+
type[byValue] = [];
|
|
2023
|
+
Object.entries(type).forEach(([key, value]) => {
|
|
2024
|
+
type[byValue][value] = key;
|
|
2025
|
+
});
|
|
2026
|
+
}
|
|
1922
2027
|
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
}
|
|
2028
|
+
if (type[byValue][e] !== undefined) {
|
|
2029
|
+
return type[byValue][e];
|
|
2030
|
+
}
|
|
1927
2031
|
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
} else {
|
|
1932
|
-
carryOverCR = false;
|
|
1933
|
-
}
|
|
2032
|
+
throw new Error('Invalid enum value.');
|
|
2033
|
+
}
|
|
2034
|
+
};
|
|
1934
2035
|
|
|
1935
|
-
|
|
1936
|
-
const indices = [];
|
|
1937
|
-
for (let i = 0; ; i = index) {
|
|
1938
|
-
index = bytes.indexOf(LF, i) + 1;
|
|
1939
|
-
if (index) {
|
|
1940
|
-
if (bytes[index - 2] !== CR) indices.push(index);
|
|
1941
|
-
} else {
|
|
1942
|
-
break;
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
if (!indices.length) {
|
|
1946
|
-
return bytes;
|
|
1947
|
-
}
|
|
2036
|
+
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
1948
2037
|
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
normalized.set(bytes.subarray(indices[indices.length - 1] || 0), j);
|
|
1960
|
-
return normalized;
|
|
1961
|
-
}, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
|
|
2038
|
+
const debugMode = (() => {
|
|
2039
|
+
try {
|
|
2040
|
+
return process.env.NODE_ENV === 'development'; // eslint-disable-line no-process-env
|
|
2041
|
+
} catch (e) {}
|
|
2042
|
+
return false;
|
|
2043
|
+
})();
|
|
2044
|
+
|
|
2045
|
+
const util = {
|
|
2046
|
+
isString: function(data) {
|
|
2047
|
+
return typeof data === 'string' || data instanceof String;
|
|
1962
2048
|
},
|
|
1963
2049
|
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
*/
|
|
1968
|
-
nativeEOL: function(data) {
|
|
1969
|
-
const CR = 13;
|
|
1970
|
-
const LF = 10;
|
|
1971
|
-
let carryOverCR = false;
|
|
2050
|
+
isArray: function(data) {
|
|
2051
|
+
return data instanceof Array;
|
|
2052
|
+
},
|
|
1972
2053
|
|
|
1973
|
-
|
|
1974
|
-
if (carryOverCR && bytes[0] !== LF) {
|
|
1975
|
-
bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
|
|
1976
|
-
} else {
|
|
1977
|
-
bytes = new Uint8Array(bytes); // Don't mutate passed bytes
|
|
1978
|
-
}
|
|
2054
|
+
isUint8Array: isUint8Array,
|
|
1979
2055
|
|
|
1980
|
-
|
|
1981
|
-
carryOverCR = true;
|
|
1982
|
-
bytes = bytes.subarray(0, -1);
|
|
1983
|
-
} else {
|
|
1984
|
-
carryOverCR = false;
|
|
1985
|
-
}
|
|
2056
|
+
isStream: isStream,
|
|
1986
2057
|
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
if (i) bytes.copyWithin(j, i, last);
|
|
1994
|
-
j += last - i;
|
|
1995
|
-
}
|
|
1996
|
-
return bytes.subarray(0, j);
|
|
1997
|
-
}, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
|
|
2058
|
+
readNumber: function (bytes) {
|
|
2059
|
+
let n = 0;
|
|
2060
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
2061
|
+
n += (256 ** i) * bytes[bytes.length - 1 - i];
|
|
2062
|
+
}
|
|
2063
|
+
return n;
|
|
1998
2064
|
},
|
|
1999
2065
|
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
return line.substr(0, i + 1);
|
|
2008
|
-
}).join('\n');
|
|
2066
|
+
writeNumber: function (n, bytes) {
|
|
2067
|
+
const b = new Uint8Array(bytes);
|
|
2068
|
+
for (let i = 0; i < bytes; i++) {
|
|
2069
|
+
b[i] = (n >> (8 * (bytes - i - 1))) & 0xFF;
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
return b;
|
|
2009
2073
|
},
|
|
2010
2074
|
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2075
|
+
readDate: function (bytes) {
|
|
2076
|
+
const n = util.readNumber(bytes);
|
|
2077
|
+
const d = new Date(n * 1000);
|
|
2078
|
+
return d;
|
|
2079
|
+
},
|
|
2080
|
+
|
|
2081
|
+
writeDate: function (time) {
|
|
2082
|
+
const numeric = Math.floor(time.getTime() / 1000);
|
|
2015
2083
|
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
error.message = message + ': ' + error.message;
|
|
2019
|
-
} catch (e) {}
|
|
2084
|
+
return util.writeNumber(numeric, 4);
|
|
2085
|
+
},
|
|
2020
2086
|
|
|
2021
|
-
|
|
2087
|
+
normalizeDate: function (time = Date.now()) {
|
|
2088
|
+
return time === null || time === Infinity ? time : new Date(Math.floor(+time / 1000) * 1000);
|
|
2022
2089
|
},
|
|
2023
2090
|
|
|
2024
2091
|
/**
|
|
2025
|
-
*
|
|
2026
|
-
*
|
|
2027
|
-
* @
|
|
2028
|
-
* @returns {Object} map from enum.packet to corresponding *Packet class
|
|
2092
|
+
* Read one MPI from bytes in input
|
|
2093
|
+
* @param {Uint8Array} bytes - Input data to parse
|
|
2094
|
+
* @returns {Uint8Array} Parsed MPI.
|
|
2029
2095
|
*/
|
|
2030
|
-
|
|
2031
|
-
const
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
throw new Error('Invalid input: expected a packet class');
|
|
2035
|
-
}
|
|
2036
|
-
map[PacketClass.tag] = PacketClass;
|
|
2037
|
-
});
|
|
2038
|
-
return map;
|
|
2096
|
+
readMPI: function (bytes) {
|
|
2097
|
+
const bits = (bytes[0] << 8) | bytes[1];
|
|
2098
|
+
const bytelen = (bits + 7) >>> 3;
|
|
2099
|
+
return bytes.subarray(2, 2 + bytelen);
|
|
2039
2100
|
},
|
|
2040
2101
|
|
|
2041
2102
|
/**
|
|
2042
|
-
*
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
* @
|
|
2046
|
-
* @return {Promise<Any>} Promise resolving to the result of the fastest fulfilled promise
|
|
2047
|
-
* or rejected with the Error of the last resolved Promise (if all promises are rejected)
|
|
2103
|
+
* Left-pad Uint8Array to length by adding 0x0 bytes
|
|
2104
|
+
* @param {Uint8Array} bytes - Data to pad
|
|
2105
|
+
* @param {Number} length - Padded length
|
|
2106
|
+
* @returns {Uint8Array} Padded bytes.
|
|
2048
2107
|
*/
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
try {
|
|
2055
|
-
resolve(await promise);
|
|
2056
|
-
} catch (e) {
|
|
2057
|
-
exception = e;
|
|
2058
|
-
}
|
|
2059
|
-
}));
|
|
2060
|
-
reject(exception);
|
|
2061
|
-
});
|
|
2108
|
+
leftPad(bytes, length) {
|
|
2109
|
+
const padded = new Uint8Array(length);
|
|
2110
|
+
const offset = length - bytes.length;
|
|
2111
|
+
padded.set(bytes, offset);
|
|
2112
|
+
return padded;
|
|
2062
2113
|
},
|
|
2063
2114
|
|
|
2064
2115
|
/**
|
|
2065
|
-
*
|
|
2066
|
-
* @param {
|
|
2067
|
-
* @
|
|
2068
|
-
* @param {Uint8Array} b
|
|
2069
|
-
* @returns `a` if `cond` is true, `b` otherwise
|
|
2116
|
+
* Convert a Uint8Array to an MPI-formatted Uint8Array.
|
|
2117
|
+
* @param {Uint8Array} bin - An array of 8-bit integers to convert
|
|
2118
|
+
* @returns {Uint8Array} MPI-formatted Uint8Array.
|
|
2070
2119
|
*/
|
|
2071
|
-
|
|
2072
|
-
const
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
for (let i = 0; i < result.length; i++) {
|
|
2076
|
-
result[i] = (a[i] & (256 - cond)) | (b[i] & (255 + cond));
|
|
2077
|
-
end += (cond & i < a.length) | ((1 - cond) & i < b.length);
|
|
2120
|
+
uint8ArrayToMPI: function (bin) {
|
|
2121
|
+
const bitSize = util.uint8ArrayBitLength(bin);
|
|
2122
|
+
if (bitSize === 0) {
|
|
2123
|
+
throw new Error('Zero MPI');
|
|
2078
2124
|
}
|
|
2079
|
-
|
|
2125
|
+
const stripped = bin.subarray(bin.length - Math.ceil(bitSize / 8));
|
|
2126
|
+
const prefix = new Uint8Array([(bitSize & 0xFF00) >> 8, bitSize & 0xFF]);
|
|
2127
|
+
return util.concatUint8Array([prefix, stripped]);
|
|
2080
2128
|
},
|
|
2129
|
+
|
|
2081
2130
|
/**
|
|
2082
|
-
* Return
|
|
2083
|
-
*
|
|
2084
|
-
* @
|
|
2085
|
-
* @param {Uint8} a
|
|
2086
|
-
* @param {Uint8} b
|
|
2087
|
-
* @returns `a` if `cond` is true, `b` otherwise
|
|
2131
|
+
* Return bit length of the input data
|
|
2132
|
+
* @param {Uint8Array} bin input data (big endian)
|
|
2133
|
+
* @returns bit length
|
|
2088
2134
|
*/
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
* This software is provided as-is, without express or implied warranty.
|
|
2099
|
-
* Permission to use, copy, modify, distribute or sell this software, with or
|
|
2100
|
-
* without fee, for any purpose and by any individual or organization, is hereby
|
|
2101
|
-
* granted, provided that the above copyright notice and this paragraph appear
|
|
2102
|
-
* in all copies. Distribution as a part of an application or binary must
|
|
2103
|
-
* include the above copyright notice in the documentation and/or other materials
|
|
2104
|
-
* provided with the application or distribution.
|
|
2105
|
-
*/
|
|
2106
|
-
|
|
2107
|
-
const Buffer = util.getNodeBuffer();
|
|
2135
|
+
uint8ArrayBitLength: function (bin) {
|
|
2136
|
+
let i; // index of leading non-zero byte
|
|
2137
|
+
for (i = 0; i < bin.length; i++) if (bin[i] !== 0) break;
|
|
2138
|
+
if (i === bin.length) {
|
|
2139
|
+
return 0;
|
|
2140
|
+
}
|
|
2141
|
+
const stripped = bin.subarray(i);
|
|
2142
|
+
return (stripped.length - 1) * 8 + util.nbits(stripped[0]);
|
|
2143
|
+
},
|
|
2108
2144
|
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
}
|
|
2145
|
+
/**
|
|
2146
|
+
* Convert a hex string to an array of 8-bit integers
|
|
2147
|
+
* @param {String} hex - A hex string to convert
|
|
2148
|
+
* @returns {Uint8Array} An array of 8-bit integers.
|
|
2149
|
+
*/
|
|
2150
|
+
hexToUint8Array: function (hex) {
|
|
2151
|
+
const result = new Uint8Array(hex.length >> 1);
|
|
2152
|
+
for (let k = 0; k < hex.length >> 1; k++) {
|
|
2153
|
+
result[k] = parseInt(hex.substr(k << 1, 2), 16);
|
|
2154
|
+
}
|
|
2155
|
+
return result;
|
|
2156
|
+
},
|
|
2121
2157
|
|
|
2122
|
-
/**
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
function encode(data) {
|
|
2129
|
-
let buf = new Uint8Array();
|
|
2130
|
-
return transform(data, value => {
|
|
2131
|
-
buf = util.concatUint8Array([buf, value]);
|
|
2158
|
+
/**
|
|
2159
|
+
* Convert an array of 8-bit integers to a hex string
|
|
2160
|
+
* @param {Uint8Array} bytes - Array of 8-bit integers to convert
|
|
2161
|
+
* @returns {String} Hexadecimal representation of the array.
|
|
2162
|
+
*/
|
|
2163
|
+
uint8ArrayToHex: function (bytes) {
|
|
2132
2164
|
const r = [];
|
|
2133
|
-
const
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2165
|
+
const e = bytes.length;
|
|
2166
|
+
let c = 0;
|
|
2167
|
+
let h;
|
|
2168
|
+
while (c < e) {
|
|
2169
|
+
h = bytes[c++].toString(16);
|
|
2170
|
+
while (h.length < 2) {
|
|
2171
|
+
h = '0' + h;
|
|
2172
|
+
}
|
|
2173
|
+
r.push('' + h);
|
|
2140
2174
|
}
|
|
2141
|
-
buf = buf.subarray(bytes);
|
|
2142
2175
|
return r.join('');
|
|
2143
|
-
},
|
|
2144
|
-
}
|
|
2145
|
-
|
|
2146
|
-
/**
|
|
2147
|
-
* Convert radix-64 to binary array
|
|
2148
|
-
* @param {String | ReadableStream<String>} data - Radix-64 string to convert
|
|
2149
|
-
* @returns {Uint8Array | ReadableStream<Uint8Array>} Binary array version of input string.
|
|
2150
|
-
* @static
|
|
2151
|
-
*/
|
|
2152
|
-
function decode(data) {
|
|
2153
|
-
let buf = '';
|
|
2154
|
-
return transform(data, value => {
|
|
2155
|
-
buf += value;
|
|
2176
|
+
},
|
|
2156
2177
|
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2178
|
+
/**
|
|
2179
|
+
* Convert a string to an array of 8-bit integers
|
|
2180
|
+
* @param {String} str - String to convert
|
|
2181
|
+
* @returns {Uint8Array} An array of 8-bit integers.
|
|
2182
|
+
*/
|
|
2183
|
+
stringToUint8Array: function (str) {
|
|
2184
|
+
return transform(str, str => {
|
|
2185
|
+
if (!util.isString(str)) {
|
|
2186
|
+
throw new Error('stringToUint8Array: Data must be in the form of a string');
|
|
2164
2187
|
}
|
|
2165
|
-
}
|
|
2166
|
-
|
|
2167
|
-
// Backtrack until we have 4n non-whitespace characters
|
|
2168
|
-
// that we can safely base64-decode
|
|
2169
|
-
let length = buf.length;
|
|
2170
|
-
for (; length > 0 && (length - spaces) % 4 !== 0; length--) {
|
|
2171
|
-
if (spacechars.includes(buf[length])) spaces--;
|
|
2172
|
-
}
|
|
2173
|
-
|
|
2174
|
-
const decoded = decodeChunk(buf.substr(0, length));
|
|
2175
|
-
buf = buf.substr(length);
|
|
2176
|
-
return decoded;
|
|
2177
|
-
}, () => decodeChunk(buf));
|
|
2178
|
-
}
|
|
2179
|
-
|
|
2180
|
-
/**
|
|
2181
|
-
* Convert a Base-64 encoded string an array of 8-bit integer
|
|
2182
|
-
*
|
|
2183
|
-
* Note: accepts both Radix-64 and URL-safe strings
|
|
2184
|
-
* @param {String} base64 - Base-64 encoded string to convert
|
|
2185
|
-
* @returns {Uint8Array} An array of 8-bit integers.
|
|
2186
|
-
*/
|
|
2187
|
-
function b64ToUint8Array(base64) {
|
|
2188
|
-
return decode(base64.replace(/-/g, '+').replace(/_/g, '/'));
|
|
2189
|
-
}
|
|
2190
|
-
|
|
2191
|
-
/**
|
|
2192
|
-
* Convert an array of 8-bit integer to a Base-64 encoded string
|
|
2193
|
-
* @param {Uint8Array} bytes - An array of 8-bit integers to convert
|
|
2194
|
-
* @param {bool} url - If true, output is URL-safe
|
|
2195
|
-
* @returns {String} Base-64 encoded string.
|
|
2196
|
-
*/
|
|
2197
|
-
function uint8ArrayToB64(bytes, url) {
|
|
2198
|
-
let encoded = encode(bytes).replace(/[\r\n]/g, '');
|
|
2199
|
-
if (url) {
|
|
2200
|
-
encoded = encoded.replace(/[+]/g, '-').replace(/[/]/g, '_').replace(/[=]/g, '');
|
|
2201
|
-
}
|
|
2202
|
-
return encoded;
|
|
2203
|
-
}
|
|
2204
|
-
|
|
2205
|
-
/**
|
|
2206
|
-
* @module enums
|
|
2207
|
-
*/
|
|
2208
2188
|
|
|
2209
|
-
const
|
|
2210
|
-
|
|
2211
|
-
|
|
2189
|
+
const result = new Uint8Array(str.length);
|
|
2190
|
+
for (let i = 0; i < str.length; i++) {
|
|
2191
|
+
result[i] = str.charCodeAt(i);
|
|
2192
|
+
}
|
|
2193
|
+
return result;
|
|
2194
|
+
});
|
|
2195
|
+
},
|
|
2212
2196
|
|
|
2213
|
-
/**
|
|
2214
|
-
*
|
|
2215
|
-
* @
|
|
2216
|
-
* @
|
|
2197
|
+
/**
|
|
2198
|
+
* Convert an array of 8-bit integers to a string
|
|
2199
|
+
* @param {Uint8Array} bytes - An array of 8-bit integers to convert
|
|
2200
|
+
* @returns {String} String representation of the array.
|
|
2217
2201
|
*/
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
'prime256v1': 'p256',
|
|
2224
|
-
'1.2.840.10045.3.1.7': 'p256',
|
|
2225
|
-
'2a8648ce3d030107': 'p256',
|
|
2226
|
-
'2A8648CE3D030107': 'p256',
|
|
2202
|
+
uint8ArrayToString: function (bytes) {
|
|
2203
|
+
bytes = new Uint8Array(bytes);
|
|
2204
|
+
const result = [];
|
|
2205
|
+
const bs = 1 << 14;
|
|
2206
|
+
const j = bytes.length;
|
|
2227
2207
|
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
'
|
|
2232
|
-
|
|
2233
|
-
'2b81040022': 'p384',
|
|
2234
|
-
'2B81040022': 'p384',
|
|
2208
|
+
for (let i = 0; i < j; i += bs) {
|
|
2209
|
+
result.push(String.fromCharCode.apply(String, bytes.subarray(i, i + bs < j ? i + bs : j)));
|
|
2210
|
+
}
|
|
2211
|
+
return result.join('');
|
|
2212
|
+
},
|
|
2235
2213
|
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
'
|
|
2214
|
+
/**
|
|
2215
|
+
* Convert a native javascript string to a Uint8Array of utf8 bytes
|
|
2216
|
+
* @param {String|ReadableStream} str - The string to convert
|
|
2217
|
+
* @returns {Uint8Array|ReadableStream} A valid squence of utf8 bytes.
|
|
2218
|
+
*/
|
|
2219
|
+
encodeUTF8: function (str) {
|
|
2220
|
+
const encoder = new TextEncoder('utf-8');
|
|
2221
|
+
// eslint-disable-next-line no-inner-declarations
|
|
2222
|
+
function process(value, lastChunk = false) {
|
|
2223
|
+
return encoder.encode(value, { stream: !lastChunk });
|
|
2224
|
+
}
|
|
2225
|
+
return transform(str, process, () => process('', true));
|
|
2226
|
+
},
|
|
2243
2227
|
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2228
|
+
/**
|
|
2229
|
+
* Convert a Uint8Array of utf8 bytes to a native javascript string
|
|
2230
|
+
* @param {Uint8Array|ReadableStream} utf8 - A valid squence of utf8 bytes
|
|
2231
|
+
* @returns {String|ReadableStream} A native javascript string.
|
|
2232
|
+
*/
|
|
2233
|
+
decodeUTF8: function (utf8) {
|
|
2234
|
+
const decoder = new TextDecoder('utf-8');
|
|
2235
|
+
// eslint-disable-next-line no-inner-declarations
|
|
2236
|
+
function process(value, lastChunk = false) {
|
|
2237
|
+
return decoder.decode(value, { stream: !lastChunk });
|
|
2238
|
+
}
|
|
2239
|
+
return transform(utf8, process, () => process(new Uint8Array(), true));
|
|
2240
|
+
},
|
|
2249
2241
|
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2242
|
+
/**
|
|
2243
|
+
* Concat a list of Uint8Arrays, Strings or Streams
|
|
2244
|
+
* The caller must not mix Uint8Arrays with Strings, but may mix Streams with non-Streams.
|
|
2245
|
+
* @param {Array<Uint8Array|String|ReadableStream>} Array - Of Uint8Arrays/Strings/Streams to concatenate
|
|
2246
|
+
* @returns {Uint8Array|String|ReadableStream} Concatenated array.
|
|
2247
|
+
*/
|
|
2248
|
+
concat: concat,
|
|
2257
2249
|
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
'2b060104019755010501': 'curve25519',
|
|
2265
|
-
'2B060104019755010501': 'curve25519',
|
|
2250
|
+
/**
|
|
2251
|
+
* Concat Uint8Arrays
|
|
2252
|
+
* @param {Array<Uint8Array>} Array - Of Uint8Arrays to concatenate
|
|
2253
|
+
* @returns {Uint8Array} Concatenated array.
|
|
2254
|
+
*/
|
|
2255
|
+
concatUint8Array: concatUint8Array,
|
|
2266
2256
|
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2257
|
+
/**
|
|
2258
|
+
* Check Uint8Array equality
|
|
2259
|
+
* @param {Uint8Array} array1 - First array
|
|
2260
|
+
* @param {Uint8Array} array2 - Second array
|
|
2261
|
+
* @returns {Boolean} Equality.
|
|
2262
|
+
*/
|
|
2263
|
+
equalsUint8Array: function (array1, array2) {
|
|
2264
|
+
if (!util.isUint8Array(array1) || !util.isUint8Array(array2)) {
|
|
2265
|
+
throw new Error('Data must be in the form of a Uint8Array');
|
|
2266
|
+
}
|
|
2272
2267
|
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
'2b240303020801010b': 'brainpoolP384r1',
|
|
2277
|
-
'2B240303020801010B': 'brainpoolP384r1',
|
|
2268
|
+
if (array1.length !== array2.length) {
|
|
2269
|
+
return false;
|
|
2270
|
+
}
|
|
2278
2271
|
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2272
|
+
for (let i = 0; i < array1.length; i++) {
|
|
2273
|
+
if (array1[i] !== array2[i]) {
|
|
2274
|
+
return false;
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
return true;
|
|
2284
2278
|
},
|
|
2285
2279
|
|
|
2286
|
-
/**
|
|
2287
|
-
*
|
|
2288
|
-
*
|
|
2289
|
-
* @
|
|
2280
|
+
/**
|
|
2281
|
+
* Calculates a 16bit sum of a Uint8Array by adding each character
|
|
2282
|
+
* codes modulus 65535
|
|
2283
|
+
* @param {Uint8Array} Uint8Array - To create a sum of
|
|
2284
|
+
* @returns {Uint8Array} 2 bytes containing the sum of all charcodes % 65535.
|
|
2290
2285
|
*/
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2286
|
+
writeChecksum: function (text) {
|
|
2287
|
+
let s = 0;
|
|
2288
|
+
for (let i = 0; i < text.length; i++) {
|
|
2289
|
+
s = (s + text[i]) & 0xFFFF;
|
|
2290
|
+
}
|
|
2291
|
+
return util.writeNumber(s, 2);
|
|
2296
2292
|
},
|
|
2297
2293
|
|
|
2298
|
-
/**
|
|
2299
|
-
*
|
|
2300
|
-
*
|
|
2294
|
+
/**
|
|
2295
|
+
* Helper function to print a debug message. Debug
|
|
2296
|
+
* messages are only printed if
|
|
2297
|
+
* @param {String} str - String of the debug message
|
|
2301
2298
|
*/
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
argon2: 4,
|
|
2307
|
-
gnu: 101
|
|
2299
|
+
printDebug: function (str) {
|
|
2300
|
+
if (debugMode) {
|
|
2301
|
+
console.log('[OpenPGP.js debug]', str);
|
|
2302
|
+
}
|
|
2308
2303
|
},
|
|
2309
2304
|
|
|
2310
|
-
/**
|
|
2311
|
-
*
|
|
2312
|
-
*
|
|
2305
|
+
/**
|
|
2306
|
+
* Helper function to print a debug error. Debug
|
|
2307
|
+
* messages are only printed if
|
|
2308
|
+
* @param {String} str - String of the debug message
|
|
2313
2309
|
*/
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
rsaEncrypt: 2,
|
|
2319
|
-
/** RSA (Sign only) [HAC] */
|
|
2320
|
-
rsaSign: 3,
|
|
2321
|
-
/** Elgamal (Encrypt only) [ELGAMAL] [HAC] */
|
|
2322
|
-
elgamal: 16,
|
|
2323
|
-
/** DSA (Sign only) [FIPS186] [HAC] */
|
|
2324
|
-
dsa: 17,
|
|
2325
|
-
/** ECDH (Encrypt only) [RFC6637] */
|
|
2326
|
-
ecdh: 18,
|
|
2327
|
-
/** ECDSA (Sign only) [RFC6637] */
|
|
2328
|
-
ecdsa: 19,
|
|
2329
|
-
/** EdDSA (Sign only)
|
|
2330
|
-
* [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */
|
|
2331
|
-
eddsa: 22,
|
|
2332
|
-
/** Reserved for AEDH */
|
|
2333
|
-
aedh: 23,
|
|
2334
|
-
/** Reserved for AEDSA */
|
|
2335
|
-
aedsa: 24,
|
|
2336
|
-
/** Symmetric authenticated encryption algorithms */
|
|
2337
|
-
aead: 100,
|
|
2338
|
-
/** Authentication using CMAC */
|
|
2339
|
-
hmac: 101
|
|
2310
|
+
printDebugError: function (error) {
|
|
2311
|
+
if (debugMode) {
|
|
2312
|
+
console.error('[OpenPGP.js debug]', error);
|
|
2313
|
+
}
|
|
2340
2314
|
},
|
|
2341
2315
|
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2316
|
+
// returns bit length of the integer x
|
|
2317
|
+
nbits: function (x) {
|
|
2318
|
+
let r = 1;
|
|
2319
|
+
let t = x >>> 16;
|
|
2320
|
+
if (t !== 0) {
|
|
2321
|
+
x = t;
|
|
2322
|
+
r += 16;
|
|
2323
|
+
}
|
|
2324
|
+
t = x >> 8;
|
|
2325
|
+
if (t !== 0) {
|
|
2326
|
+
x = t;
|
|
2327
|
+
r += 8;
|
|
2328
|
+
}
|
|
2329
|
+
t = x >> 4;
|
|
2330
|
+
if (t !== 0) {
|
|
2331
|
+
x = t;
|
|
2332
|
+
r += 4;
|
|
2333
|
+
}
|
|
2334
|
+
t = x >> 2;
|
|
2335
|
+
if (t !== 0) {
|
|
2336
|
+
x = t;
|
|
2337
|
+
r += 2;
|
|
2338
|
+
}
|
|
2339
|
+
t = x >> 1;
|
|
2340
|
+
if (t !== 0) {
|
|
2341
|
+
x = t;
|
|
2342
|
+
r += 1;
|
|
2343
|
+
}
|
|
2344
|
+
return r;
|
|
2345
|
+
},
|
|
2346
|
+
|
|
2347
|
+
/**
|
|
2348
|
+
* If S[1] == 0, then double(S) == (S[2..128] || 0);
|
|
2349
|
+
* otherwise, double(S) == (S[2..128] || 0) xor
|
|
2350
|
+
* (zeros(120) || 10000111).
|
|
2351
|
+
*
|
|
2352
|
+
* Both OCB and EAX (through CMAC) require this function to be constant-time.
|
|
2353
|
+
*
|
|
2354
|
+
* @param {Uint8Array} data
|
|
2355
|
+
*/
|
|
2356
|
+
double: function(data) {
|
|
2357
|
+
const doubleVar = new Uint8Array(data.length);
|
|
2358
|
+
const last = data.length - 1;
|
|
2359
|
+
for (let i = 0; i < last; i++) {
|
|
2360
|
+
doubleVar[i] = (data[i] << 1) ^ (data[i + 1] >> 7);
|
|
2361
|
+
}
|
|
2362
|
+
doubleVar[last] = (data[last] << 1) ^ ((data[0] >> 7) * 0x87);
|
|
2363
|
+
return doubleVar;
|
|
2357
2364
|
},
|
|
2358
2365
|
|
|
2359
|
-
/**
|
|
2360
|
-
*
|
|
2361
|
-
* @
|
|
2366
|
+
/**
|
|
2367
|
+
* Shift a Uint8Array to the right by n bits
|
|
2368
|
+
* @param {Uint8Array} array - The array to shift
|
|
2369
|
+
* @param {Integer} bits - Amount of bits to shift (MUST be smaller
|
|
2370
|
+
* than 8)
|
|
2371
|
+
* @returns {String} Resulting array.
|
|
2362
2372
|
*/
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2373
|
+
shiftRight: function (array, bits) {
|
|
2374
|
+
if (bits) {
|
|
2375
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
2376
|
+
array[i] >>= bits;
|
|
2377
|
+
if (i > 0) {
|
|
2378
|
+
array[i] |= (array[i - 1] << (8 - bits));
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
return array;
|
|
2370
2383
|
},
|
|
2371
2384
|
|
|
2372
|
-
/**
|
|
2373
|
-
*
|
|
2374
|
-
* @
|
|
2385
|
+
/**
|
|
2386
|
+
* Get native Web Cryptography api, only the current version of the spec.
|
|
2387
|
+
* @returns {Object} The SubtleCrypto api or 'undefined'.
|
|
2375
2388
|
*/
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
sha1: 2,
|
|
2379
|
-
ripemd: 3,
|
|
2380
|
-
sha256: 8,
|
|
2381
|
-
sha384: 9,
|
|
2382
|
-
sha512: 10,
|
|
2383
|
-
sha224: 11
|
|
2389
|
+
getWebCrypto: function() {
|
|
2390
|
+
return typeof globalThis !== 'undefined' && globalThis.crypto && globalThis.crypto.subtle;
|
|
2384
2391
|
},
|
|
2385
2392
|
|
|
2386
|
-
/**
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2393
|
+
/**
|
|
2394
|
+
* Get BigInteger class
|
|
2395
|
+
* It wraps the native BigInt type if it's available
|
|
2396
|
+
* Otherwise it relies on bn.js
|
|
2397
|
+
* @returns {BigInteger}
|
|
2398
|
+
* @async
|
|
2389
2399
|
*/
|
|
2390
|
-
|
|
2391
|
-
'SHA-1': 2,
|
|
2392
|
-
'SHA-256': 8,
|
|
2393
|
-
'SHA-384': 9,
|
|
2394
|
-
'SHA-512': 10
|
|
2395
|
-
},
|
|
2400
|
+
getBigInteger,
|
|
2396
2401
|
|
|
2397
|
-
/**
|
|
2398
|
-
*
|
|
2399
|
-
* @
|
|
2402
|
+
/**
|
|
2403
|
+
* Get native Node.js crypto api.
|
|
2404
|
+
* @returns {Object} The crypto module or 'undefined'.
|
|
2400
2405
|
*/
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
ocb: 2,
|
|
2404
|
-
experimentalGCM: 100 // Private algorithm
|
|
2406
|
+
getNodeCrypto: function() {
|
|
2407
|
+
return void('crypto');
|
|
2405
2408
|
},
|
|
2406
2409
|
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
* @readonly
|
|
2410
|
-
*/
|
|
2411
|
-
packet: {
|
|
2412
|
-
publicKeyEncryptedSessionKey: 1,
|
|
2413
|
-
signature: 2,
|
|
2414
|
-
symEncryptedSessionKey: 3,
|
|
2415
|
-
onePassSignature: 4,
|
|
2416
|
-
secretKey: 5,
|
|
2417
|
-
publicKey: 6,
|
|
2418
|
-
secretSubkey: 7,
|
|
2419
|
-
compressedData: 8,
|
|
2420
|
-
symmetricallyEncryptedData: 9,
|
|
2421
|
-
marker: 10,
|
|
2422
|
-
literalData: 11,
|
|
2423
|
-
trust: 12,
|
|
2424
|
-
userID: 13,
|
|
2425
|
-
publicSubkey: 14,
|
|
2426
|
-
userAttribute: 17,
|
|
2427
|
-
symEncryptedIntegrityProtectedData: 18,
|
|
2428
|
-
modificationDetectionCode: 19,
|
|
2429
|
-
aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
|
|
2410
|
+
getNodeZlib: function() {
|
|
2411
|
+
return void('zlib');
|
|
2430
2412
|
},
|
|
2431
2413
|
|
|
2432
|
-
/**
|
|
2433
|
-
*
|
|
2434
|
-
*
|
|
2414
|
+
/**
|
|
2415
|
+
* Get native Node.js Buffer constructor. This should be used since
|
|
2416
|
+
* Buffer is not available under browserify.
|
|
2417
|
+
* @returns {Function} The Buffer constructor or 'undefined'.
|
|
2435
2418
|
*/
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
binary: 'b'.charCodeAt(),
|
|
2439
|
-
/** Text data 't' */
|
|
2440
|
-
text: 't'.charCodeAt(),
|
|
2441
|
-
/** Utf8 data 'u' */
|
|
2442
|
-
utf8: 'u'.charCodeAt(),
|
|
2443
|
-
/** MIME message body part 'm' */
|
|
2444
|
-
mime: 'm'.charCodeAt()
|
|
2419
|
+
getNodeBuffer: function() {
|
|
2420
|
+
return ({}).Buffer;
|
|
2445
2421
|
},
|
|
2446
2422
|
|
|
2423
|
+
getHardwareConcurrency: function() {
|
|
2424
|
+
if (typeof navigator !== 'undefined') {
|
|
2425
|
+
return navigator.hardwareConcurrency || 1;
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
const os = void('os'); // Assume we're on Node.js.
|
|
2429
|
+
return os.cpus().length;
|
|
2430
|
+
},
|
|
2447
2431
|
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
binary: 0,
|
|
2455
|
-
/** 0x01: Signature of a canonical text document.
|
|
2456
|
-
*
|
|
2457
|
-
* Canonicalyzing the document by converting line endings. */
|
|
2458
|
-
text: 1,
|
|
2459
|
-
/** 0x02: Standalone signature.
|
|
2460
|
-
*
|
|
2461
|
-
* This signature is a signature of only its own subpacket contents.
|
|
2462
|
-
* It is calculated identically to a signature over a zero-lengh
|
|
2463
|
-
* binary document. Note that it doesn't make sense to have a V3
|
|
2464
|
-
* standalone signature. */
|
|
2465
|
-
standalone: 2,
|
|
2466
|
-
/** 0x10: Generic certification of a User ID and Public-Key packet.
|
|
2467
|
-
*
|
|
2468
|
-
* The issuer of this certification does not make any particular
|
|
2469
|
-
* assertion as to how well the certifier has checked that the owner
|
|
2470
|
-
* of the key is in fact the person described by the User ID. */
|
|
2471
|
-
certGeneric: 16,
|
|
2472
|
-
/** 0x11: Persona certification of a User ID and Public-Key packet.
|
|
2473
|
-
*
|
|
2474
|
-
* The issuer of this certification has not done any verification of
|
|
2475
|
-
* the claim that the owner of this key is the User ID specified. */
|
|
2476
|
-
certPersona: 17,
|
|
2477
|
-
/** 0x12: Casual certification of a User ID and Public-Key packet.
|
|
2478
|
-
*
|
|
2479
|
-
* The issuer of this certification has done some casual
|
|
2480
|
-
* verification of the claim of identity. */
|
|
2481
|
-
certCasual: 18,
|
|
2482
|
-
/** 0x13: Positive certification of a User ID and Public-Key packet.
|
|
2483
|
-
*
|
|
2484
|
-
* The issuer of this certification has done substantial
|
|
2485
|
-
* verification of the claim of identity.
|
|
2486
|
-
*
|
|
2487
|
-
* Most OpenPGP implementations make their "key signatures" as 0x10
|
|
2488
|
-
* certifications. Some implementations can issue 0x11-0x13
|
|
2489
|
-
* certifications, but few differentiate between the types. */
|
|
2490
|
-
certPositive: 19,
|
|
2491
|
-
/** 0x30: Certification revocation signature
|
|
2492
|
-
*
|
|
2493
|
-
* This signature revokes an earlier User ID certification signature
|
|
2494
|
-
* (signature class 0x10 through 0x13) or direct-key signature
|
|
2495
|
-
* (0x1F). It should be issued by the same key that issued the
|
|
2496
|
-
* revoked signature or an authorized revocation key. The signature
|
|
2497
|
-
* is computed over the same data as the certificate that it
|
|
2498
|
-
* revokes, and should have a later creation date than that
|
|
2499
|
-
* certificate. */
|
|
2500
|
-
certRevocation: 48,
|
|
2501
|
-
/** 0x18: Subkey Binding Signature
|
|
2502
|
-
*
|
|
2503
|
-
* This signature is a statement by the top-level signing key that
|
|
2504
|
-
* indicates that it owns the subkey. This signature is calculated
|
|
2505
|
-
* directly on the primary key and subkey, and not on any User ID or
|
|
2506
|
-
* other packets. A signature that binds a signing subkey MUST have
|
|
2507
|
-
* an Embedded Signature subpacket in this binding signature that
|
|
2508
|
-
* contains a 0x19 signature made by the signing subkey on the
|
|
2509
|
-
* primary key and subkey. */
|
|
2510
|
-
subkeyBinding: 24,
|
|
2511
|
-
/** 0x19: Primary Key Binding Signature
|
|
2512
|
-
*
|
|
2513
|
-
* This signature is a statement by a signing subkey, indicating
|
|
2514
|
-
* that it is owned by the primary key and subkey. This signature
|
|
2515
|
-
* is calculated the same way as a 0x18 signature: directly on the
|
|
2516
|
-
* primary key and subkey, and not on any User ID or other packets.
|
|
2517
|
-
*
|
|
2518
|
-
* When a signature is made over a key, the hash data starts with the
|
|
2519
|
-
* octet 0x99, followed by a two-octet length of the key, and then body
|
|
2520
|
-
* of the key packet. (Note that this is an old-style packet header for
|
|
2521
|
-
* a key packet with two-octet length.) A subkey binding signature
|
|
2522
|
-
* (type 0x18) or primary key binding signature (type 0x19) then hashes
|
|
2523
|
-
* the subkey using the same format as the main key (also using 0x99 as
|
|
2524
|
-
* the first octet). */
|
|
2525
|
-
keyBinding: 25,
|
|
2526
|
-
/** 0x1F: Signature directly on a key
|
|
2527
|
-
*
|
|
2528
|
-
* This signature is calculated directly on a key. It binds the
|
|
2529
|
-
* information in the Signature subpackets to the key, and is
|
|
2530
|
-
* appropriate to be used for subpackets that provide information
|
|
2531
|
-
* about the key, such as the Revocation Key subpacket. It is also
|
|
2532
|
-
* appropriate for statements that non-self certifiers want to make
|
|
2533
|
-
* about the key itself, rather than the binding between a key and a
|
|
2534
|
-
* name. */
|
|
2535
|
-
key: 31,
|
|
2536
|
-
/** 0x20: Key revocation signature
|
|
2537
|
-
*
|
|
2538
|
-
* The signature is calculated directly on the key being revoked. A
|
|
2539
|
-
* revoked key is not to be used. Only revocation signatures by the
|
|
2540
|
-
* key being revoked, or by an authorized revocation key, should be
|
|
2541
|
-
* considered valid revocation signatures.a */
|
|
2542
|
-
keyRevocation: 32,
|
|
2543
|
-
/** 0x28: Subkey revocation signature
|
|
2544
|
-
*
|
|
2545
|
-
* The signature is calculated directly on the subkey being revoked.
|
|
2546
|
-
* A revoked subkey is not to be used. Only revocation signatures
|
|
2547
|
-
* by the top-level signature key that is bound to this subkey, or
|
|
2548
|
-
* by an authorized revocation key, should be considered valid
|
|
2549
|
-
* revocation signatures.
|
|
2550
|
-
*
|
|
2551
|
-
* Key revocation signatures (types 0x20 and 0x28)
|
|
2552
|
-
* hash only the key being revoked. */
|
|
2553
|
-
subkeyRevocation: 40,
|
|
2554
|
-
/** 0x40: Timestamp signature.
|
|
2555
|
-
* This signature is only meaningful for the timestamp contained in
|
|
2556
|
-
* it. */
|
|
2557
|
-
timestamp: 64,
|
|
2558
|
-
/** 0x50: Third-Party Confirmation signature.
|
|
2559
|
-
*
|
|
2560
|
-
* This signature is a signature over some other OpenPGP Signature
|
|
2561
|
-
* packet(s). It is analogous to a notary seal on the signed data.
|
|
2562
|
-
* A third-party signature SHOULD include Signature Target
|
|
2563
|
-
* subpacket(s) to give easy identification. Note that we really do
|
|
2564
|
-
* mean SHOULD. There are plausible uses for this (such as a blind
|
|
2565
|
-
* party that only sees the signature, not the key or source
|
|
2566
|
-
* document) that cannot include a target subpacket. */
|
|
2567
|
-
thirdParty: 80
|
|
2432
|
+
isEmailAddress: function(data) {
|
|
2433
|
+
if (!util.isString(data)) {
|
|
2434
|
+
return false;
|
|
2435
|
+
}
|
|
2436
|
+
const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+([a-zA-Z]{2,}[0-9]*|xn--[a-zA-Z\-0-9]+)))$/;
|
|
2437
|
+
return re.test(data);
|
|
2568
2438
|
},
|
|
2569
2439
|
|
|
2570
|
-
/**
|
|
2571
|
-
*
|
|
2572
|
-
*
|
|
2440
|
+
/**
|
|
2441
|
+
* Normalize line endings to <CR><LF>
|
|
2442
|
+
* Support any encoding where CR=0x0D, LF=0x0A
|
|
2573
2443
|
*/
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2444
|
+
canonicalizeEOL: function(data) {
|
|
2445
|
+
const CR = 13;
|
|
2446
|
+
const LF = 10;
|
|
2447
|
+
let carryOverCR = false;
|
|
2448
|
+
|
|
2449
|
+
return transform(data, bytes => {
|
|
2450
|
+
if (carryOverCR) {
|
|
2451
|
+
bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
if (bytes[bytes.length - 1] === CR) {
|
|
2455
|
+
carryOverCR = true;
|
|
2456
|
+
bytes = bytes.subarray(0, -1);
|
|
2457
|
+
} else {
|
|
2458
|
+
carryOverCR = false;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
let index;
|
|
2462
|
+
const indices = [];
|
|
2463
|
+
for (let i = 0; ; i = index) {
|
|
2464
|
+
index = bytes.indexOf(LF, i) + 1;
|
|
2465
|
+
if (index) {
|
|
2466
|
+
if (bytes[index - 2] !== CR) indices.push(index);
|
|
2467
|
+
} else {
|
|
2468
|
+
break;
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
if (!indices.length) {
|
|
2472
|
+
return bytes;
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
const normalized = new Uint8Array(bytes.length + indices.length);
|
|
2476
|
+
let j = 0;
|
|
2477
|
+
for (let i = 0; i < indices.length; i++) {
|
|
2478
|
+
const sub = bytes.subarray(indices[i - 1] || 0, indices[i]);
|
|
2479
|
+
normalized.set(sub, j);
|
|
2480
|
+
j += sub.length;
|
|
2481
|
+
normalized[j - 1] = CR;
|
|
2482
|
+
normalized[j] = LF;
|
|
2483
|
+
j++;
|
|
2484
|
+
}
|
|
2485
|
+
normalized.set(bytes.subarray(indices[indices.length - 1] || 0), j);
|
|
2486
|
+
return normalized;
|
|
2487
|
+
}, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
|
|
2601
2488
|
},
|
|
2602
2489
|
|
|
2603
|
-
/**
|
|
2604
|
-
*
|
|
2605
|
-
*
|
|
2490
|
+
/**
|
|
2491
|
+
* Convert line endings from canonicalized <CR><LF> to native <LF>
|
|
2492
|
+
* Support any encoding where CR=0x0D, LF=0x0A
|
|
2606
2493
|
*/
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2494
|
+
nativeEOL: function(data) {
|
|
2495
|
+
const CR = 13;
|
|
2496
|
+
const LF = 10;
|
|
2497
|
+
let carryOverCR = false;
|
|
2498
|
+
|
|
2499
|
+
return transform(data, bytes => {
|
|
2500
|
+
if (carryOverCR && bytes[0] !== LF) {
|
|
2501
|
+
bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
|
|
2502
|
+
} else {
|
|
2503
|
+
bytes = new Uint8Array(bytes); // Don't mutate passed bytes
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
if (bytes[bytes.length - 1] === CR) {
|
|
2507
|
+
carryOverCR = true;
|
|
2508
|
+
bytes = bytes.subarray(0, -1);
|
|
2509
|
+
} else {
|
|
2510
|
+
carryOverCR = false;
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
let index;
|
|
2514
|
+
let j = 0;
|
|
2515
|
+
for (let i = 0; i !== bytes.length; i = index) {
|
|
2516
|
+
index = bytes.indexOf(CR, i) + 1;
|
|
2517
|
+
if (!index) index = bytes.length;
|
|
2518
|
+
const last = index - (bytes[index] === LF ? 1 : 0);
|
|
2519
|
+
if (i) bytes.copyWithin(j, i, last);
|
|
2520
|
+
j += last - i;
|
|
2521
|
+
}
|
|
2522
|
+
return bytes.subarray(0, j);
|
|
2523
|
+
}, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
|
|
2626
2524
|
},
|
|
2627
2525
|
|
|
2628
|
-
/**
|
|
2629
|
-
*
|
|
2630
|
-
* @readonly
|
|
2526
|
+
/**
|
|
2527
|
+
* Remove trailing spaces, carriage returns and tabs from each line
|
|
2631
2528
|
*/
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
privateKey: 5,
|
|
2639
|
-
signature: 6
|
|
2529
|
+
removeTrailingSpaces: function(text) {
|
|
2530
|
+
return text.split('\n').map(line => {
|
|
2531
|
+
let i = line.length - 1;
|
|
2532
|
+
for (; i >= 0 && (line[i] === ' ' || line[i] === '\t' || line[i] === '\r'); i--);
|
|
2533
|
+
return line.substr(0, i + 1);
|
|
2534
|
+
}).join('\n');
|
|
2640
2535
|
},
|
|
2641
2536
|
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2537
|
+
wrapError: function(message, error) {
|
|
2538
|
+
if (!error) {
|
|
2539
|
+
return new Error(message);
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
// update error message
|
|
2543
|
+
try {
|
|
2544
|
+
error.message = message + ': ' + error.message;
|
|
2545
|
+
} catch (e) {}
|
|
2546
|
+
|
|
2547
|
+
return error;
|
|
2548
|
+
},
|
|
2549
|
+
|
|
2550
|
+
/**
|
|
2551
|
+
* Map allowed packet tags to corresponding classes
|
|
2552
|
+
* Meant to be used to format `allowedPacket` for Packetlist.read
|
|
2553
|
+
* @param {Array<Object>} allowedClasses
|
|
2554
|
+
* @returns {Object} map from enum.packet to corresponding *Packet class
|
|
2645
2555
|
*/
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
/** User ID information is no longer valid (cert revocations) */
|
|
2656
|
-
userIDInvalid: 32
|
|
2556
|
+
constructAllowedPackets: function(allowedClasses) {
|
|
2557
|
+
const map = {};
|
|
2558
|
+
allowedClasses.forEach(PacketClass => {
|
|
2559
|
+
if (!PacketClass.tag) {
|
|
2560
|
+
throw new Error('Invalid input: expected a packet class');
|
|
2561
|
+
}
|
|
2562
|
+
map[PacketClass.tag] = PacketClass;
|
|
2563
|
+
});
|
|
2564
|
+
return map;
|
|
2657
2565
|
},
|
|
2658
2566
|
|
|
2659
|
-
/**
|
|
2660
|
-
*
|
|
2661
|
-
*
|
|
2567
|
+
/**
|
|
2568
|
+
* Return a Promise that will resolve as soon as one of the promises in input resolves
|
|
2569
|
+
* or will reject if all input promises all rejected
|
|
2570
|
+
* (similar to Promise.any, but with slightly different error handling)
|
|
2571
|
+
* @param {Array<Promise>} promises
|
|
2572
|
+
* @return {Promise<Any>} Promise resolving to the result of the fastest fulfilled promise
|
|
2573
|
+
* or rejected with the Error of the last resolved Promise (if all promises are rejected)
|
|
2662
2574
|
*/
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2575
|
+
anyPromise: function(promises) {
|
|
2576
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
2577
|
+
return new Promise(async (resolve, reject) => {
|
|
2578
|
+
let exception;
|
|
2579
|
+
await Promise.all(promises.map(async promise => {
|
|
2580
|
+
try {
|
|
2581
|
+
resolve(await promise);
|
|
2582
|
+
} catch (e) {
|
|
2583
|
+
exception = e;
|
|
2584
|
+
}
|
|
2585
|
+
}));
|
|
2586
|
+
reject(exception);
|
|
2587
|
+
});
|
|
2672
2588
|
},
|
|
2673
2589
|
|
|
2674
2590
|
/**
|
|
2675
|
-
*
|
|
2676
|
-
* @param {
|
|
2677
|
-
* @param {
|
|
2678
|
-
* @
|
|
2679
|
-
* @
|
|
2591
|
+
* Return either `a` or `b` based on `cond`, in algorithmic constant time.
|
|
2592
|
+
* @param {Boolean} cond
|
|
2593
|
+
* @param {Uint8Array} a
|
|
2594
|
+
* @param {Uint8Array} b
|
|
2595
|
+
* @returns `a` if `cond` is true, `b` otherwise
|
|
2596
|
+
*/
|
|
2597
|
+
selectUint8Array: function(cond, a, b) {
|
|
2598
|
+
const length = Math.max(a.length, b.length);
|
|
2599
|
+
const result = new Uint8Array(length);
|
|
2600
|
+
let end = 0;
|
|
2601
|
+
for (let i = 0; i < result.length; i++) {
|
|
2602
|
+
result[i] = (a[i] & (256 - cond)) | (b[i] & (255 + cond));
|
|
2603
|
+
end += (cond & i < a.length) | ((1 - cond) & i < b.length);
|
|
2604
|
+
}
|
|
2605
|
+
return result.subarray(0, end);
|
|
2606
|
+
},
|
|
2607
|
+
/**
|
|
2608
|
+
* Return either `a` or `b` based on `cond`, in algorithmic constant time.
|
|
2609
|
+
* NB: it only supports `a, b` with values between 0-255.
|
|
2610
|
+
* @param {Boolean} cond
|
|
2611
|
+
* @param {Uint8} a
|
|
2612
|
+
* @param {Uint8} b
|
|
2613
|
+
* @returns `a` if `cond` is true, `b` otherwise
|
|
2614
|
+
*/
|
|
2615
|
+
selectUint8: function(cond, a, b) {
|
|
2616
|
+
return (a & (256 - cond)) | (b & (255 + cond));
|
|
2617
|
+
},
|
|
2618
|
+
/**
|
|
2619
|
+
* @param {module:enums.symmetric} cipherAlgo
|
|
2680
2620
|
*/
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2621
|
+
isAES: function(cipherAlgo) {
|
|
2622
|
+
return cipherAlgo === enums.symmetric.aes128 || cipherAlgo === enums.symmetric.aes192 || cipherAlgo === enums.symmetric.aes256;
|
|
2623
|
+
}
|
|
2624
|
+
};
|
|
2685
2625
|
|
|
2686
|
-
|
|
2687
|
-
|
|
2626
|
+
/* OpenPGP radix-64/base64 string encoding/decoding
|
|
2627
|
+
* Copyright 2005 Herbert Hanewinkel, www.haneWIN.de
|
|
2628
|
+
* version 1.0, check www.haneWIN.de for the latest version
|
|
2629
|
+
*
|
|
2630
|
+
* This software is provided as-is, without express or implied warranty.
|
|
2631
|
+
* Permission to use, copy, modify, distribute or sell this software, with or
|
|
2632
|
+
* without fee, for any purpose and by any individual or organization, is hereby
|
|
2633
|
+
* granted, provided that the above copyright notice and this paragraph appear
|
|
2634
|
+
* in all copies. Distribution as a part of an application or binary must
|
|
2635
|
+
* include the above copyright notice in the documentation and/or other materials
|
|
2636
|
+
* provided with the application or distribution.
|
|
2637
|
+
*/
|
|
2638
|
+
|
|
2639
|
+
const Buffer = util.getNodeBuffer();
|
|
2640
|
+
|
|
2641
|
+
let encodeChunk;
|
|
2642
|
+
let decodeChunk;
|
|
2643
|
+
if (Buffer) {
|
|
2644
|
+
encodeChunk = buf => Buffer.from(buf).toString('base64');
|
|
2645
|
+
decodeChunk = str => {
|
|
2646
|
+
const b = Buffer.from(str, 'base64');
|
|
2647
|
+
return new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
|
|
2648
|
+
};
|
|
2649
|
+
} else {
|
|
2650
|
+
encodeChunk = buf => btoa(util.uint8ArrayToString(buf));
|
|
2651
|
+
decodeChunk = str => util.stringToUint8Array(atob(str));
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
/**
|
|
2655
|
+
* Convert binary array to radix-64
|
|
2656
|
+
* @param {Uint8Array | ReadableStream<Uint8Array>} data - Uint8Array to convert
|
|
2657
|
+
* @returns {String | ReadableStream<String>} Radix-64 version of input string.
|
|
2658
|
+
* @static
|
|
2659
|
+
*/
|
|
2660
|
+
function encode(data) {
|
|
2661
|
+
let buf = new Uint8Array();
|
|
2662
|
+
return transform(data, value => {
|
|
2663
|
+
buf = util.concatUint8Array([buf, value]);
|
|
2664
|
+
const r = [];
|
|
2665
|
+
const bytesPerLine = 45; // 60 chars per line * (3 bytes / 4 chars of base64).
|
|
2666
|
+
const lines = Math.floor(buf.length / bytesPerLine);
|
|
2667
|
+
const bytes = lines * bytesPerLine;
|
|
2668
|
+
const encoded = encodeChunk(buf.subarray(0, bytes));
|
|
2669
|
+
for (let i = 0; i < lines; i++) {
|
|
2670
|
+
r.push(encoded.substr(i * 60, 60));
|
|
2671
|
+
r.push('\n');
|
|
2688
2672
|
}
|
|
2673
|
+
buf = buf.subarray(bytes);
|
|
2674
|
+
return r.join('');
|
|
2675
|
+
}, () => (buf.length ? encodeChunk(buf) + '\n' : ''));
|
|
2676
|
+
}
|
|
2689
2677
|
|
|
2690
|
-
|
|
2691
|
-
|
|
2678
|
+
/**
|
|
2679
|
+
* Convert radix-64 to binary array
|
|
2680
|
+
* @param {String | ReadableStream<String>} data - Radix-64 string to convert
|
|
2681
|
+
* @returns {Uint8Array | ReadableStream<Uint8Array>} Binary array version of input string.
|
|
2682
|
+
* @static
|
|
2683
|
+
*/
|
|
2684
|
+
function decode(data) {
|
|
2685
|
+
let buf = '';
|
|
2686
|
+
return transform(data, value => {
|
|
2687
|
+
buf += value;
|
|
2692
2688
|
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
if (!type[byValue]) {
|
|
2702
|
-
type[byValue] = [];
|
|
2703
|
-
Object.entries(type).forEach(([key, value]) => {
|
|
2704
|
-
type[byValue][value] = key;
|
|
2705
|
-
});
|
|
2689
|
+
// Count how many whitespace characters there are in buf
|
|
2690
|
+
let spaces = 0;
|
|
2691
|
+
const spacechars = [' ', '\t', '\r', '\n'];
|
|
2692
|
+
for (let i = 0; i < spacechars.length; i++) {
|
|
2693
|
+
const spacechar = spacechars[i];
|
|
2694
|
+
for (let pos = buf.indexOf(spacechar); pos !== -1; pos = buf.indexOf(spacechar, pos + 1)) {
|
|
2695
|
+
spaces++;
|
|
2696
|
+
}
|
|
2706
2697
|
}
|
|
2707
2698
|
|
|
2708
|
-
|
|
2709
|
-
|
|
2699
|
+
// Backtrack until we have 4n non-whitespace characters
|
|
2700
|
+
// that we can safely base64-decode
|
|
2701
|
+
let length = buf.length;
|
|
2702
|
+
for (; length > 0 && (length - spaces) % 4 !== 0; length--) {
|
|
2703
|
+
if (spacechars.includes(buf[length])) spaces--;
|
|
2710
2704
|
}
|
|
2711
2705
|
|
|
2712
|
-
|
|
2706
|
+
const decoded = decodeChunk(buf.substr(0, length));
|
|
2707
|
+
buf = buf.substr(length);
|
|
2708
|
+
return decoded;
|
|
2709
|
+
}, () => decodeChunk(buf));
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2712
|
+
/**
|
|
2713
|
+
* Convert a Base-64 encoded string an array of 8-bit integer
|
|
2714
|
+
*
|
|
2715
|
+
* Note: accepts both Radix-64 and URL-safe strings
|
|
2716
|
+
* @param {String} base64 - Base-64 encoded string to convert
|
|
2717
|
+
* @returns {Uint8Array} An array of 8-bit integers.
|
|
2718
|
+
*/
|
|
2719
|
+
function b64ToUint8Array(base64) {
|
|
2720
|
+
return decode(base64.replace(/-/g, '+').replace(/_/g, '/'));
|
|
2721
|
+
}
|
|
2722
|
+
|
|
2723
|
+
/**
|
|
2724
|
+
* Convert an array of 8-bit integer to a Base-64 encoded string
|
|
2725
|
+
* @param {Uint8Array} bytes - An array of 8-bit integers to convert
|
|
2726
|
+
* @param {bool} url - If true, output is URL-safe
|
|
2727
|
+
* @returns {String} Base-64 encoded string.
|
|
2728
|
+
*/
|
|
2729
|
+
function uint8ArrayToB64(bytes, url) {
|
|
2730
|
+
let encoded = encode(bytes).replace(/[\r\n]/g, '');
|
|
2731
|
+
if (url) {
|
|
2732
|
+
encoded = encoded.replace(/[+]/g, '-').replace(/[/]/g, '_').replace(/[=]/g, '');
|
|
2713
2733
|
}
|
|
2714
|
-
|
|
2734
|
+
return encoded;
|
|
2735
|
+
}
|
|
2715
2736
|
|
|
2716
2737
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
2717
2738
|
|
|
@@ -2929,7 +2950,7 @@ var config = {
|
|
|
2929
2950
|
* @memberof module:config
|
|
2930
2951
|
* @property {String} versionString A version string to be included in armored messages
|
|
2931
2952
|
*/
|
|
2932
|
-
versionString: 'OpenPGP.js 5.
|
|
2953
|
+
versionString: 'OpenPGP.js 5.11.0',
|
|
2933
2954
|
/**
|
|
2934
2955
|
* @memberof module:config
|
|
2935
2956
|
* @property {String} commentString A comment string to be included in armored messages
|
|
@@ -2980,7 +3001,14 @@ var config = {
|
|
|
2980
3001
|
* @memberof module:config
|
|
2981
3002
|
* @property {Set<String>} rejectCurves {@link module:enums.curve}
|
|
2982
3003
|
*/
|
|
2983
|
-
rejectCurves: new Set([enums.curve.secp256k1])
|
|
3004
|
+
rejectCurves: new Set([enums.curve.secp256k1]),
|
|
3005
|
+
/**
|
|
3006
|
+
* Whether to validate generated EdDSA signatures before returning them, to ensure they are not faulty signatures.
|
|
3007
|
+
* This check will make signing 2-3 times slower.
|
|
3008
|
+
* Faulty signatures may be generated (in principle) if random bitflips occur at specific points in the signature
|
|
3009
|
+
* computation, and could be used to recover the signer's secret key given a second signature over the same data.
|
|
3010
|
+
*/
|
|
3011
|
+
checkEdDSAFaultySignatures: true
|
|
2984
3012
|
};
|
|
2985
3013
|
|
|
2986
3014
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
@@ -3415,6 +3443,7 @@ class KeyID {
|
|
|
3415
3443
|
*/
|
|
3416
3444
|
read(bytes) {
|
|
3417
3445
|
this.bytes = util.uint8ArrayToString(bytes.subarray(0, 8));
|
|
3446
|
+
return this.bytes.length;
|
|
3418
3447
|
}
|
|
3419
3448
|
|
|
3420
3449
|
/**
|
|
@@ -9961,7 +9990,7 @@ async function encrypt(algo, key, plaintext, iv, config) {
|
|
|
9961
9990
|
if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
|
|
9962
9991
|
return nodeEncrypt(algo, key, plaintext, iv);
|
|
9963
9992
|
}
|
|
9964
|
-
if (
|
|
9993
|
+
if (util.isAES(algo)) {
|
|
9965
9994
|
return aesEncrypt(algo, key, plaintext, iv, config);
|
|
9966
9995
|
}
|
|
9967
9996
|
|
|
@@ -10004,7 +10033,7 @@ async function decrypt(algo, key, ciphertext, iv) {
|
|
|
10004
10033
|
if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
|
|
10005
10034
|
return nodeDecrypt(algo, key, ciphertext, iv);
|
|
10006
10035
|
}
|
|
10007
|
-
if (
|
|
10036
|
+
if (util.isAES(algo)) {
|
|
10008
10037
|
return aesDecrypt(algo, key, ciphertext, iv);
|
|
10009
10038
|
}
|
|
10010
10039
|
|
|
@@ -10023,7 +10052,7 @@ async function decrypt(algo, key, ciphertext, iv) {
|
|
|
10023
10052
|
let j = 0;
|
|
10024
10053
|
while (chunk ? ct.length >= block_size : ct.length) {
|
|
10025
10054
|
const decblock = cipherfn.encrypt(blockp);
|
|
10026
|
-
blockp = ct;
|
|
10055
|
+
blockp = ct.subarray(0, block_size);
|
|
10027
10056
|
for (i = 0; i < block_size; i++) {
|
|
10028
10057
|
plaintext[j++] = blockp[i] ^ decblock[i];
|
|
10029
10058
|
}
|
|
@@ -10949,42 +10978,42 @@ async function GCM(cipher, key) {
|
|
|
10949
10978
|
throw new Error('GCM mode supports only AES cipher');
|
|
10950
10979
|
}
|
|
10951
10980
|
|
|
10952
|
-
if (util.
|
|
10953
|
-
const _key = await webCrypto$4.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
|
|
10954
|
-
|
|
10981
|
+
if (util.getNodeCrypto()) { // Node crypto library
|
|
10955
10982
|
return {
|
|
10956
10983
|
encrypt: async function(pt, iv, adata = new Uint8Array()) {
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
|
|
10960
|
-
const ct = await webCrypto$4.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, pt);
|
|
10984
|
+
const en = new nodeCrypto$4.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
|
10985
|
+
en.setAAD(adata);
|
|
10986
|
+
const ct = Buffer$2.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
|
|
10961
10987
|
return new Uint8Array(ct);
|
|
10962
10988
|
},
|
|
10963
10989
|
|
|
10964
10990
|
decrypt: async function(ct, iv, adata = new Uint8Array()) {
|
|
10965
|
-
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
const pt =
|
|
10991
|
+
const de = new nodeCrypto$4.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
|
10992
|
+
de.setAAD(adata);
|
|
10993
|
+
de.setAuthTag(ct.slice(ct.length - tagLength$2, ct.length)); // read auth tag at end of ciphertext
|
|
10994
|
+
const pt = Buffer$2.concat([de.update(ct.slice(0, ct.length - tagLength$2)), de.final()]);
|
|
10969
10995
|
return new Uint8Array(pt);
|
|
10970
10996
|
}
|
|
10971
10997
|
};
|
|
10972
10998
|
}
|
|
10973
10999
|
|
|
10974
|
-
if (util.
|
|
11000
|
+
if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
|
|
11001
|
+
const _key = await webCrypto$4.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
|
|
11002
|
+
|
|
10975
11003
|
return {
|
|
10976
11004
|
encrypt: async function(pt, iv, adata = new Uint8Array()) {
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
11005
|
+
if (!pt.length) { // iOS does not support GCM-en/decrypting empty messages
|
|
11006
|
+
return AES_GCM.encrypt(pt, key, iv, adata);
|
|
11007
|
+
}
|
|
11008
|
+
const ct = await webCrypto$4.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, pt);
|
|
10980
11009
|
return new Uint8Array(ct);
|
|
10981
11010
|
},
|
|
10982
11011
|
|
|
10983
11012
|
decrypt: async function(ct, iv, adata = new Uint8Array()) {
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
const pt =
|
|
11013
|
+
if (ct.length === tagLength$2) { // iOS does not support GCM-en/decrypting empty messages
|
|
11014
|
+
return AES_GCM.decrypt(ct, key, iv, adata);
|
|
11015
|
+
}
|
|
11016
|
+
const pt = await webCrypto$4.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, ct);
|
|
10988
11017
|
return new Uint8Array(pt);
|
|
10989
11018
|
}
|
|
10990
11019
|
};
|
|
@@ -11987,11 +12016,11 @@ const nodeCrypto$5 = util.getNodeCrypto();
|
|
|
11987
12016
|
*/
|
|
11988
12017
|
function getRandomBytes(length) {
|
|
11989
12018
|
const buf = new Uint8Array(length);
|
|
11990
|
-
if (
|
|
11991
|
-
crypto.getRandomValues(buf);
|
|
11992
|
-
} else if (nodeCrypto$5) {
|
|
12019
|
+
if (nodeCrypto$5) {
|
|
11993
12020
|
const bytes = nodeCrypto$5.randomBytes(buf.length);
|
|
11994
12021
|
buf.set(bytes);
|
|
12022
|
+
} else if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
12023
|
+
crypto.getRandomValues(buf);
|
|
11995
12024
|
} else {
|
|
11996
12025
|
throw new Error('No secure random number generator available.');
|
|
11997
12026
|
}
|
|
@@ -13553,7 +13582,7 @@ const curves = {
|
|
|
13553
13582
|
},
|
|
13554
13583
|
ed25519: {
|
|
13555
13584
|
oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01],
|
|
13556
|
-
keyType: enums.publicKey.
|
|
13585
|
+
keyType: enums.publicKey.eddsaLegacy,
|
|
13557
13586
|
hash: enums.hash.sha512,
|
|
13558
13587
|
node: false, // nodeCurves.ed25519 TODO
|
|
13559
13588
|
payloadSize: 32
|
|
@@ -13592,7 +13621,7 @@ const curves = {
|
|
|
13592
13621
|
}
|
|
13593
13622
|
};
|
|
13594
13623
|
|
|
13595
|
-
class
|
|
13624
|
+
class CurveWithOID {
|
|
13596
13625
|
constructor(oidOrName, params) {
|
|
13597
13626
|
try {
|
|
13598
13627
|
if (util.isArray(oidOrName) ||
|
|
@@ -13669,7 +13698,7 @@ class Curve {
|
|
|
13669
13698
|
async function generate$1(curve) {
|
|
13670
13699
|
const BigInteger = await util.getBigInteger();
|
|
13671
13700
|
|
|
13672
|
-
curve = new
|
|
13701
|
+
curve = new CurveWithOID(curve);
|
|
13673
13702
|
const keyPair = await curve.genKeyPair();
|
|
13674
13703
|
const Q = new BigInteger(keyPair.publicKey).toUint8Array();
|
|
13675
13704
|
const secret = new BigInteger(keyPair.privateKey).toUint8Array('be', curve.payloadSize);
|
|
@@ -13860,7 +13889,7 @@ const nodeCrypto$8 = util.getNodeCrypto();
|
|
|
13860
13889
|
* @async
|
|
13861
13890
|
*/
|
|
13862
13891
|
async function sign$1(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
13863
|
-
const curve = new
|
|
13892
|
+
const curve = new CurveWithOID(oid);
|
|
13864
13893
|
if (message && !util.isStream(message)) {
|
|
13865
13894
|
const keyPair = { publicKey, privateKey };
|
|
13866
13895
|
switch (curve.type) {
|
|
@@ -13905,7 +13934,7 @@ async function sign$1(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
13905
13934
|
* @async
|
|
13906
13935
|
*/
|
|
13907
13936
|
async function verify$1(oid, hashAlgo, signature, message, publicKey, hashed) {
|
|
13908
|
-
const curve = new
|
|
13937
|
+
const curve = new CurveWithOID(oid);
|
|
13909
13938
|
if (message && !util.isStream(message)) {
|
|
13910
13939
|
switch (curve.type) {
|
|
13911
13940
|
case 'web':
|
|
@@ -13939,7 +13968,7 @@ async function verify$1(oid, hashAlgo, signature, message, publicKey, hashed) {
|
|
|
13939
13968
|
* @async
|
|
13940
13969
|
*/
|
|
13941
13970
|
async function validateParams$2(oid, Q, d) {
|
|
13942
|
-
const curve = new
|
|
13971
|
+
const curve = new CurveWithOID(oid);
|
|
13943
13972
|
// Reject curves x25519 and ed25519
|
|
13944
13973
|
if (curve.keyType !== enums.publicKey.ecdsa) {
|
|
13945
13974
|
return false;
|
|
@@ -14142,7 +14171,7 @@ var ecdsa = /*#__PURE__*/Object.freeze({
|
|
|
14142
14171
|
naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
|
|
14143
14172
|
|
|
14144
14173
|
/**
|
|
14145
|
-
* Sign a message using the provided key
|
|
14174
|
+
* Sign a message using the provided legacy EdDSA key
|
|
14146
14175
|
* @param {module:type/oid} oid - Elliptic curve object identifier
|
|
14147
14176
|
* @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
|
|
14148
14177
|
* @param {Uint8Array} message - Message to sign
|
|
@@ -14158,10 +14187,24 @@ naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
|
|
|
14158
14187
|
async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
14159
14188
|
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
|
14160
14189
|
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
14161
|
-
throw new Error('Hash algorithm too weak
|
|
14190
|
+
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
14162
14191
|
}
|
|
14163
14192
|
const secretKey = util.concatUint8Array([privateKey, publicKey.subarray(1)]);
|
|
14164
14193
|
const signature = naclFastLight.sign.detached(hashed, secretKey);
|
|
14194
|
+
if (config.checkEdDSAFaultySignatures && !naclFastLight.sign.detached.verify(hashed, signature, publicKey.subarray(1))) {
|
|
14195
|
+
/**
|
|
14196
|
+
* Detect faulty signatures caused by random bitflips during `crypto_sign` which could lead to private key extraction
|
|
14197
|
+
* if two signatures over the same message are obtained.
|
|
14198
|
+
* See https://github.com/jedisct1/libsodium/issues/170.
|
|
14199
|
+
* If the input data is not deterministic, e.g. thanks to the random salt in v6 OpenPGP signatures (not yet implemented),
|
|
14200
|
+
* then the generated signature is always safe, and the verification step is skipped.
|
|
14201
|
+
* Otherwise, we need to verify the generated to ensure that no bitflip occured:
|
|
14202
|
+
* - in M between the computation of `r` and `h`.
|
|
14203
|
+
* - in the public key before computing `h`
|
|
14204
|
+
* The verification step is almost 2-3 times as slow as signing, but it's faster than re-signing + re-deriving the public key for separate checks.
|
|
14205
|
+
*/
|
|
14206
|
+
throw new Error('Transient signing failure');
|
|
14207
|
+
}
|
|
14165
14208
|
// EdDSA signature params are returned in little-endian format
|
|
14166
14209
|
return {
|
|
14167
14210
|
r: signature.subarray(0, 32),
|
|
@@ -14170,7 +14213,7 @@ async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
14170
14213
|
}
|
|
14171
14214
|
|
|
14172
14215
|
/**
|
|
14173
|
-
* Verifies if a signature is valid for a message
|
|
14216
|
+
* Verifies if a legacy EdDSA signature is valid for a message
|
|
14174
14217
|
* @param {module:type/oid} oid - Elliptic curve object identifier
|
|
14175
14218
|
* @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
|
|
14176
14219
|
* @param {{r: Uint8Array,
|
|
@@ -14182,11 +14225,14 @@ async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
14182
14225
|
* @async
|
|
14183
14226
|
*/
|
|
14184
14227
|
async function verify$2(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
|
14228
|
+
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
|
14229
|
+
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
14230
|
+
}
|
|
14185
14231
|
const signature = util.concatUint8Array([r, s]);
|
|
14186
14232
|
return naclFastLight.sign.detached.verify(hashed, signature, publicKey.subarray(1));
|
|
14187
14233
|
}
|
|
14188
14234
|
/**
|
|
14189
|
-
* Validate EdDSA parameters
|
|
14235
|
+
* Validate legacy EdDSA parameters
|
|
14190
14236
|
* @param {module:type/oid} oid - Elliptic curve object identifier
|
|
14191
14237
|
* @param {Uint8Array} Q - EdDSA public point
|
|
14192
14238
|
* @param {Uint8Array} k - EdDSA secret seed
|
|
@@ -14199,20 +14245,154 @@ async function validateParams$3(oid, Q, k) {
|
|
|
14199
14245
|
return false;
|
|
14200
14246
|
}
|
|
14201
14247
|
|
|
14202
|
-
/**
|
|
14203
|
-
* Derive public point Q' = dG from private key
|
|
14204
|
-
* and expect Q == Q'
|
|
14205
|
-
*/
|
|
14206
|
-
const { publicKey } = naclFastLight.sign.keyPair.fromSeed(k);
|
|
14207
|
-
const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
|
|
14208
|
-
return util.equalsUint8Array(Q, dG);
|
|
14248
|
+
/**
|
|
14249
|
+
* Derive public point Q' = dG from private key
|
|
14250
|
+
* and expect Q == Q'
|
|
14251
|
+
*/
|
|
14252
|
+
const { publicKey } = naclFastLight.sign.keyPair.fromSeed(k);
|
|
14253
|
+
const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
|
|
14254
|
+
return util.equalsUint8Array(Q, dG);
|
|
14255
|
+
|
|
14256
|
+
}
|
|
14257
|
+
|
|
14258
|
+
var eddsa_legacy = /*#__PURE__*/Object.freeze({
|
|
14259
|
+
__proto__: null,
|
|
14260
|
+
sign: sign$2,
|
|
14261
|
+
verify: verify$2,
|
|
14262
|
+
validateParams: validateParams$3
|
|
14263
|
+
});
|
|
14264
|
+
|
|
14265
|
+
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
14266
|
+
|
|
14267
|
+
naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
|
|
14268
|
+
|
|
14269
|
+
/**
|
|
14270
|
+
* Generate (non-legacy) EdDSA key
|
|
14271
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14272
|
+
* @returns {Promise<{ A: Uint8Array, seed: Uint8Array }>}
|
|
14273
|
+
*/
|
|
14274
|
+
async function generate$2(algo) {
|
|
14275
|
+
switch (algo) {
|
|
14276
|
+
case enums.publicKey.ed25519: {
|
|
14277
|
+
const seed = getRandomBytes(32);
|
|
14278
|
+
const { publicKey: A } = naclFastLight.sign.keyPair.fromSeed(seed);
|
|
14279
|
+
return { A, seed };
|
|
14280
|
+
}
|
|
14281
|
+
default:
|
|
14282
|
+
throw new Error('Unsupported EdDSA algorithm');
|
|
14283
|
+
}
|
|
14284
|
+
}
|
|
14285
|
+
|
|
14286
|
+
/**
|
|
14287
|
+
* Sign a message using the provided key
|
|
14288
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14289
|
+
* @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
|
|
14290
|
+
* @param {Uint8Array} message - Message to sign
|
|
14291
|
+
* @param {Uint8Array} publicKey - Public key
|
|
14292
|
+
* @param {Uint8Array} privateKey - Private key used to sign the message
|
|
14293
|
+
* @param {Uint8Array} hashed - The hashed message
|
|
14294
|
+
* @returns {Promise<{
|
|
14295
|
+
* RS: Uint8Array
|
|
14296
|
+
* }>} Signature of the message
|
|
14297
|
+
* @async
|
|
14298
|
+
*/
|
|
14299
|
+
async function sign$3(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
14300
|
+
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo$1(algo))) {
|
|
14301
|
+
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
14302
|
+
}
|
|
14303
|
+
switch (algo) {
|
|
14304
|
+
case enums.publicKey.ed25519: {
|
|
14305
|
+
const secretKey = util.concatUint8Array([privateKey, publicKey]);
|
|
14306
|
+
const signature = naclFastLight.sign.detached(hashed, secretKey);
|
|
14307
|
+
if (config.checkEdDSAFaultySignatures && !naclFastLight.sign.detached.verify(hashed, signature, publicKey)) {
|
|
14308
|
+
/**
|
|
14309
|
+
* Detect faulty signatures caused by random bitflips during `crypto_sign` which could lead to private key extraction
|
|
14310
|
+
* if two signatures over the same message are obtained.
|
|
14311
|
+
* See https://github.com/jedisct1/libsodium/issues/170.
|
|
14312
|
+
* If the input data is not deterministic, e.g. thanks to the random salt in v6 OpenPGP signatures (not yet implemented),
|
|
14313
|
+
* then the generated signature is always safe, and the verification step is skipped.
|
|
14314
|
+
* Otherwise, we need to verify the generated to ensure that no bitflip occured:
|
|
14315
|
+
* - in M between the computation of `r` and `h`.
|
|
14316
|
+
* - in the public key before computing `h`
|
|
14317
|
+
* The verification step is almost 2-3 times as slow as signing, but it's faster than re-signing + re-deriving the public key for separate checks.
|
|
14318
|
+
*/
|
|
14319
|
+
throw new Error('Transient signing failure');
|
|
14320
|
+
}
|
|
14321
|
+
return { RS: signature };
|
|
14322
|
+
}
|
|
14323
|
+
case enums.publicKey.ed448:
|
|
14324
|
+
default:
|
|
14325
|
+
throw new Error('Unsupported EdDSA algorithm');
|
|
14326
|
+
}
|
|
14327
|
+
|
|
14328
|
+
}
|
|
14329
|
+
|
|
14330
|
+
/**
|
|
14331
|
+
* Verifies if a signature is valid for a message
|
|
14332
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14333
|
+
* @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
|
|
14334
|
+
* @param {{ RS: Uint8Array }} signature Signature to verify the message
|
|
14335
|
+
* @param {Uint8Array} m - Message to verify
|
|
14336
|
+
* @param {Uint8Array} publicKey - Public key used to verify the message
|
|
14337
|
+
* @param {Uint8Array} hashed - The hashed message
|
|
14338
|
+
* @returns {Boolean}
|
|
14339
|
+
* @async
|
|
14340
|
+
*/
|
|
14341
|
+
async function verify$3(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
|
14342
|
+
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo$1(algo))) {
|
|
14343
|
+
throw new Error('Hash algorithm too weak for EdDSA.');
|
|
14344
|
+
}
|
|
14345
|
+
switch (algo) {
|
|
14346
|
+
case enums.publicKey.ed25519: {
|
|
14347
|
+
return naclFastLight.sign.detached.verify(hashed, RS, publicKey);
|
|
14348
|
+
}
|
|
14349
|
+
case enums.publicKey.ed448:
|
|
14350
|
+
default:
|
|
14351
|
+
throw new Error('Unsupported EdDSA algorithm');
|
|
14352
|
+
}
|
|
14353
|
+
}
|
|
14354
|
+
/**
|
|
14355
|
+
* Validate (non-legacy) EdDSA parameters
|
|
14356
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14357
|
+
* @param {Uint8Array} A - EdDSA public point
|
|
14358
|
+
* @param {Uint8Array} seed - EdDSA secret seed
|
|
14359
|
+
* @param {Uint8Array} oid - (legacy only) EdDSA OID
|
|
14360
|
+
* @returns {Promise<Boolean>} Whether params are valid.
|
|
14361
|
+
* @async
|
|
14362
|
+
*/
|
|
14363
|
+
async function validateParams$4(algo, A, seed) {
|
|
14364
|
+
switch (algo) {
|
|
14365
|
+
case enums.publicKey.ed25519: {
|
|
14366
|
+
/**
|
|
14367
|
+
* Derive public point A' from private key
|
|
14368
|
+
* and expect A == A'
|
|
14369
|
+
*/
|
|
14370
|
+
const { publicKey } = naclFastLight.sign.keyPair.fromSeed(seed);
|
|
14371
|
+
return util.equalsUint8Array(A, publicKey);
|
|
14372
|
+
}
|
|
14373
|
+
|
|
14374
|
+
case enums.publicKey.ed448: // unsupported
|
|
14375
|
+
default:
|
|
14376
|
+
return false;
|
|
14377
|
+
}
|
|
14378
|
+
}
|
|
14379
|
+
|
|
14380
|
+
function getPreferredHashAlgo$1(algo) {
|
|
14381
|
+
switch (algo) {
|
|
14382
|
+
case enums.publicKey.ed25519:
|
|
14383
|
+
return enums.hash.sha256;
|
|
14384
|
+
default:
|
|
14385
|
+
throw new Error('Unknown EdDSA algo');
|
|
14386
|
+
}
|
|
14209
14387
|
}
|
|
14210
14388
|
|
|
14211
14389
|
var eddsa = /*#__PURE__*/Object.freeze({
|
|
14212
14390
|
__proto__: null,
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14391
|
+
generate: generate$2,
|
|
14392
|
+
sign: sign$3,
|
|
14393
|
+
verify: verify$3,
|
|
14394
|
+
validateParams: validateParams$4,
|
|
14395
|
+
getPreferredHashAlgo: getPreferredHashAlgo$1
|
|
14216
14396
|
});
|
|
14217
14397
|
|
|
14218
14398
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
@@ -14404,7 +14584,7 @@ const nodeCrypto$9 = util.getNodeCrypto();
|
|
|
14404
14584
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
14405
14585
|
* @async
|
|
14406
14586
|
*/
|
|
14407
|
-
async function validateParams$
|
|
14587
|
+
async function validateParams$5(oid, Q, d) {
|
|
14408
14588
|
return validateStandardParams(enums.publicKey.ecdh, oid, Q, d);
|
|
14409
14589
|
}
|
|
14410
14590
|
|
|
@@ -14446,7 +14626,7 @@ async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTraili
|
|
|
14446
14626
|
/**
|
|
14447
14627
|
* Generate ECDHE ephemeral key and secret from public key
|
|
14448
14628
|
*
|
|
14449
|
-
* @param {
|
|
14629
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14450
14630
|
* @param {Uint8Array} Q - Recipient public key
|
|
14451
14631
|
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
14452
14632
|
* @async
|
|
@@ -14489,7 +14669,7 @@ async function genPublicEphemeralKey(curve, Q) {
|
|
|
14489
14669
|
async function encrypt$3(oid, kdfParams, data, Q, fingerprint) {
|
|
14490
14670
|
const m = encode$1(data);
|
|
14491
14671
|
|
|
14492
|
-
const curve = new
|
|
14672
|
+
const curve = new CurveWithOID(oid);
|
|
14493
14673
|
const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
|
|
14494
14674
|
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
|
|
14495
14675
|
const { keySize } = getCipher(kdfParams.cipher);
|
|
@@ -14501,7 +14681,7 @@ async function encrypt$3(oid, kdfParams, data, Q, fingerprint) {
|
|
|
14501
14681
|
/**
|
|
14502
14682
|
* Generate ECDHE secret from private key and public part of ephemeral key
|
|
14503
14683
|
*
|
|
14504
|
-
* @param {
|
|
14684
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14505
14685
|
* @param {Uint8Array} V - Public part of ephemeral key
|
|
14506
14686
|
* @param {Uint8Array} Q - Recipient public key
|
|
14507
14687
|
* @param {Uint8Array} d - Recipient private key
|
|
@@ -14549,7 +14729,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) {
|
|
|
14549
14729
|
* @async
|
|
14550
14730
|
*/
|
|
14551
14731
|
async function decrypt$3(oid, kdfParams, V, C, Q, d, fingerprint) {
|
|
14552
|
-
const curve = new
|
|
14732
|
+
const curve = new CurveWithOID(oid);
|
|
14553
14733
|
const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
|
|
14554
14734
|
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
|
|
14555
14735
|
const { keySize } = getCipher(kdfParams.cipher);
|
|
@@ -14569,7 +14749,7 @@ async function decrypt$3(oid, kdfParams, V, C, Q, d, fingerprint) {
|
|
|
14569
14749
|
/**
|
|
14570
14750
|
* Generate ECDHE secret from private key and public part of ephemeral key using webCrypto
|
|
14571
14751
|
*
|
|
14572
|
-
* @param {
|
|
14752
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14573
14753
|
* @param {Uint8Array} V - Public part of ephemeral key
|
|
14574
14754
|
* @param {Uint8Array} Q - Recipient public key
|
|
14575
14755
|
* @param {Uint8Array} d - Recipient private key
|
|
@@ -14622,7 +14802,7 @@ async function webPrivateEphemeralKey(curve, V, Q, d) {
|
|
|
14622
14802
|
/**
|
|
14623
14803
|
* Generate ECDHE ephemeral key and secret from public key using webCrypto
|
|
14624
14804
|
*
|
|
14625
|
-
* @param {
|
|
14805
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14626
14806
|
* @param {Uint8Array} Q - Recipient public key
|
|
14627
14807
|
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
14628
14808
|
* @async
|
|
@@ -14670,7 +14850,7 @@ async function webPublicEphemeralKey(curve, Q) {
|
|
|
14670
14850
|
/**
|
|
14671
14851
|
* Generate ECDHE secret from private key and public part of ephemeral key using indutny/elliptic
|
|
14672
14852
|
*
|
|
14673
|
-
* @param {
|
|
14853
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14674
14854
|
* @param {Uint8Array} V - Public part of ephemeral key
|
|
14675
14855
|
* @param {Uint8Array} d - Recipient private key
|
|
14676
14856
|
* @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
@@ -14690,7 +14870,7 @@ async function ellipticPrivateEphemeralKey(curve, V, d) {
|
|
|
14690
14870
|
/**
|
|
14691
14871
|
* Generate ECDHE ephemeral key and secret from public key using indutny/elliptic
|
|
14692
14872
|
*
|
|
14693
|
-
* @param {
|
|
14873
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14694
14874
|
* @param {Uint8Array} Q - Recipient public key
|
|
14695
14875
|
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
14696
14876
|
* @async
|
|
@@ -14710,7 +14890,7 @@ async function ellipticPublicEphemeralKey(curve, Q) {
|
|
|
14710
14890
|
/**
|
|
14711
14891
|
* Generate ECDHE secret from private key and public part of ephemeral key using nodeCrypto
|
|
14712
14892
|
*
|
|
14713
|
-
* @param {
|
|
14893
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14714
14894
|
* @param {Uint8Array} V - Public part of ephemeral key
|
|
14715
14895
|
* @param {Uint8Array} d - Recipient private key
|
|
14716
14896
|
* @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
@@ -14727,7 +14907,7 @@ async function nodePrivateEphemeralKey(curve, V, d) {
|
|
|
14727
14907
|
/**
|
|
14728
14908
|
* Generate ECDHE ephemeral key and secret from public key using nodeCrypto
|
|
14729
14909
|
*
|
|
14730
|
-
* @param {
|
|
14910
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14731
14911
|
* @param {Uint8Array} Q - Recipient public key
|
|
14732
14912
|
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
14733
14913
|
* @async
|
|
@@ -14742,18 +14922,202 @@ async function nodePublicEphemeralKey(curve, Q) {
|
|
|
14742
14922
|
|
|
14743
14923
|
var ecdh = /*#__PURE__*/Object.freeze({
|
|
14744
14924
|
__proto__: null,
|
|
14745
|
-
validateParams: validateParams$
|
|
14925
|
+
validateParams: validateParams$5,
|
|
14746
14926
|
encrypt: encrypt$3,
|
|
14747
14927
|
decrypt: decrypt$3
|
|
14748
14928
|
});
|
|
14749
14929
|
|
|
14930
|
+
/**
|
|
14931
|
+
* @fileoverview This module implements HKDF using either the WebCrypto API or Node.js' crypto API.
|
|
14932
|
+
* @module crypto/hkdf
|
|
14933
|
+
* @private
|
|
14934
|
+
*/
|
|
14935
|
+
|
|
14936
|
+
const webCrypto$9 = util.getWebCrypto();
|
|
14937
|
+
const nodeCrypto$a = util.getNodeCrypto();
|
|
14938
|
+
const nodeSubtleCrypto = nodeCrypto$a && nodeCrypto$a.webcrypto && nodeCrypto$a.webcrypto.subtle;
|
|
14939
|
+
|
|
14940
|
+
async function HKDF(hashAlgo, inputKey, salt, info, outLen) {
|
|
14941
|
+
const hash = enums.read(enums.webHash, hashAlgo);
|
|
14942
|
+
if (!hash) throw new Error('Hash algo not supported with HKDF');
|
|
14943
|
+
|
|
14944
|
+
if (webCrypto$9 || nodeSubtleCrypto) {
|
|
14945
|
+
const crypto = webCrypto$9 || nodeSubtleCrypto;
|
|
14946
|
+
const importedKey = await crypto.importKey('raw', inputKey, 'HKDF', false, ['deriveBits']);
|
|
14947
|
+
const bits = await crypto.deriveBits({ name: 'HKDF', hash, salt, info }, importedKey, outLen * 8);
|
|
14948
|
+
return new Uint8Array(bits);
|
|
14949
|
+
}
|
|
14950
|
+
|
|
14951
|
+
if (nodeCrypto$a) {
|
|
14952
|
+
const hashAlgoName = enums.read(enums.hash, hashAlgo);
|
|
14953
|
+
// Node-only HKDF implementation based on https://www.rfc-editor.org/rfc/rfc5869
|
|
14954
|
+
|
|
14955
|
+
const computeHMAC = (hmacKey, hmacMessage) => nodeCrypto$a.createHmac(hashAlgoName, hmacKey).update(hmacMessage).digest();
|
|
14956
|
+
// Step 1: Extract
|
|
14957
|
+
// PRK = HMAC-Hash(salt, IKM)
|
|
14958
|
+
const pseudoRandomKey = computeHMAC(salt, inputKey);
|
|
14959
|
+
|
|
14960
|
+
const hashLen = pseudoRandomKey.length;
|
|
14961
|
+
|
|
14962
|
+
// Step 2: Expand
|
|
14963
|
+
// HKDF-Expand(PRK, info, L) -> OKM
|
|
14964
|
+
const n = Math.ceil(outLen / hashLen);
|
|
14965
|
+
const outputKeyingMaterial = new Uint8Array(n * hashLen);
|
|
14966
|
+
|
|
14967
|
+
// HMAC input buffer updated at each iteration
|
|
14968
|
+
const roundInput = new Uint8Array(hashLen + info.length + 1);
|
|
14969
|
+
// T_i and last byte are updated at each iteration, but `info` remains constant
|
|
14970
|
+
roundInput.set(info, hashLen);
|
|
14971
|
+
|
|
14972
|
+
for (let i = 0; i < n; i++) {
|
|
14973
|
+
// T(0) = empty string (zero length)
|
|
14974
|
+
// T(i) = HMAC-Hash(PRK, T(i-1) | info | i)
|
|
14975
|
+
roundInput[roundInput.length - 1] = i + 1;
|
|
14976
|
+
// t = T(i+1)
|
|
14977
|
+
const t = computeHMAC(pseudoRandomKey, i > 0 ? roundInput : roundInput.subarray(hashLen));
|
|
14978
|
+
roundInput.set(t, 0);
|
|
14979
|
+
|
|
14980
|
+
outputKeyingMaterial.set(t, i * hashLen);
|
|
14981
|
+
}
|
|
14982
|
+
|
|
14983
|
+
return outputKeyingMaterial.subarray(0, outLen);
|
|
14984
|
+
}
|
|
14985
|
+
|
|
14986
|
+
throw new Error('No HKDF implementation available');
|
|
14987
|
+
}
|
|
14988
|
+
|
|
14989
|
+
/**
|
|
14990
|
+
* @fileoverview Key encryption and decryption for RFC 6637 ECDH
|
|
14991
|
+
* @module crypto/public_key/elliptic/ecdh
|
|
14992
|
+
* @private
|
|
14993
|
+
*/
|
|
14994
|
+
|
|
14995
|
+
const HKDF_INFO = {
|
|
14996
|
+
x25519: util.encodeUTF8('OpenPGP X25519')
|
|
14997
|
+
};
|
|
14998
|
+
|
|
14999
|
+
/**
|
|
15000
|
+
* Generate ECDH key for Montgomery curves
|
|
15001
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
15002
|
+
* @returns {Promise<{ A: Uint8Array, k: Uint8Array }>}
|
|
15003
|
+
*/
|
|
15004
|
+
async function generate$3(algo) {
|
|
15005
|
+
switch (algo) {
|
|
15006
|
+
case enums.publicKey.x25519: {
|
|
15007
|
+
// k stays in little-endian, unlike legacy ECDH over curve25519
|
|
15008
|
+
const k = getRandomBytes(32);
|
|
15009
|
+
const { publicKey: A } = naclFastLight.box.keyPair.fromSecretKey(k);
|
|
15010
|
+
return { A, k };
|
|
15011
|
+
}
|
|
15012
|
+
default:
|
|
15013
|
+
throw new Error('Unsupported ECDH algorithm');
|
|
15014
|
+
}
|
|
15015
|
+
}
|
|
15016
|
+
|
|
15017
|
+
/**
|
|
15018
|
+
* Validate ECDH parameters
|
|
15019
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
15020
|
+
* @param {Uint8Array} A - ECDH public point
|
|
15021
|
+
* @param {Uint8Array} k - ECDH secret scalar
|
|
15022
|
+
* @returns {Promise<Boolean>} Whether params are valid.
|
|
15023
|
+
* @async
|
|
15024
|
+
*/
|
|
15025
|
+
async function validateParams$6(algo, A, k) {
|
|
15026
|
+
switch (algo) {
|
|
15027
|
+
case enums.publicKey.x25519: {
|
|
15028
|
+
/**
|
|
15029
|
+
* Derive public point A' from private key
|
|
15030
|
+
* and expect A == A'
|
|
15031
|
+
*/
|
|
15032
|
+
const { publicKey } = naclFastLight.box.keyPair.fromSecretKey(k);
|
|
15033
|
+
return util.equalsUint8Array(A, publicKey);
|
|
15034
|
+
}
|
|
15035
|
+
|
|
15036
|
+
default:
|
|
15037
|
+
return false;
|
|
15038
|
+
}
|
|
15039
|
+
}
|
|
15040
|
+
|
|
15041
|
+
/**
|
|
15042
|
+
* Wrap and encrypt a session key
|
|
15043
|
+
*
|
|
15044
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
15045
|
+
* @param {Uint8Array} data - session key data to be encrypted
|
|
15046
|
+
* @param {Uint8Array} recipientA - Recipient public key (K_B)
|
|
15047
|
+
* @returns {Promise<{
|
|
15048
|
+
* ephemeralPublicKey: Uint8Array,
|
|
15049
|
+
* wrappedKey: Uint8Array
|
|
15050
|
+
* }>} ephemeral public key (K_A) and encrypted key
|
|
15051
|
+
* @async
|
|
15052
|
+
*/
|
|
15053
|
+
async function encrypt$4(algo, data, recipientA) {
|
|
15054
|
+
switch (algo) {
|
|
15055
|
+
case enums.publicKey.x25519: {
|
|
15056
|
+
const ephemeralSecretKey = getRandomBytes(32);
|
|
15057
|
+
const sharedSecret = naclFastLight.scalarMult(ephemeralSecretKey, recipientA);
|
|
15058
|
+
const { publicKey: ephemeralPublicKey } = naclFastLight.box.keyPair.fromSecretKey(ephemeralSecretKey);
|
|
15059
|
+
const hkdfInput = util.concatUint8Array([
|
|
15060
|
+
ephemeralPublicKey,
|
|
15061
|
+
recipientA,
|
|
15062
|
+
sharedSecret
|
|
15063
|
+
]);
|
|
15064
|
+
const { keySize } = getCipher(enums.symmetric.aes128);
|
|
15065
|
+
const encryptionKey = await HKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
|
|
15066
|
+
const wrappedKey = wrap(encryptionKey, data);
|
|
15067
|
+
return { ephemeralPublicKey, wrappedKey };
|
|
15068
|
+
}
|
|
15069
|
+
|
|
15070
|
+
default:
|
|
15071
|
+
throw new Error('Unsupported ECDH algorithm');
|
|
15072
|
+
}
|
|
15073
|
+
}
|
|
15074
|
+
|
|
15075
|
+
/**
|
|
15076
|
+
* Decrypt and unwrap the session key
|
|
15077
|
+
*
|
|
15078
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
15079
|
+
* @param {Uint8Array} ephemeralPublicKey - (K_A)
|
|
15080
|
+
* @param {Uint8Array} wrappedKey,
|
|
15081
|
+
* @param {Uint8Array} A - Recipient public key (K_b), needed for KDF
|
|
15082
|
+
* @param {Uint8Array} k - Recipient secret key (b)
|
|
15083
|
+
* @returns {Promise<Uint8Array>} decrypted session key data
|
|
15084
|
+
* @async
|
|
15085
|
+
*/
|
|
15086
|
+
async function decrypt$4(algo, ephemeralPublicKey, wrappedKey, A, k) {
|
|
15087
|
+
switch (algo) {
|
|
15088
|
+
case enums.publicKey.x25519: {
|
|
15089
|
+
const sharedSecret = naclFastLight.scalarMult(k, ephemeralPublicKey);
|
|
15090
|
+
const hkdfInput = util.concatUint8Array([
|
|
15091
|
+
ephemeralPublicKey,
|
|
15092
|
+
A,
|
|
15093
|
+
sharedSecret
|
|
15094
|
+
]);
|
|
15095
|
+
const { keySize } = getCipher(enums.symmetric.aes128);
|
|
15096
|
+
const encryptionKey = await HKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
|
|
15097
|
+
return unwrap(encryptionKey, wrappedKey);
|
|
15098
|
+
}
|
|
15099
|
+
default:
|
|
15100
|
+
throw new Error('Unsupported ECDH algorithm');
|
|
15101
|
+
}
|
|
15102
|
+
}
|
|
15103
|
+
|
|
15104
|
+
var ecdh_x = /*#__PURE__*/Object.freeze({
|
|
15105
|
+
__proto__: null,
|
|
15106
|
+
generate: generate$3,
|
|
15107
|
+
validateParams: validateParams$6,
|
|
15108
|
+
encrypt: encrypt$4,
|
|
15109
|
+
decrypt: decrypt$4
|
|
15110
|
+
});
|
|
15111
|
+
|
|
14750
15112
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
14751
15113
|
|
|
14752
15114
|
var elliptic = /*#__PURE__*/Object.freeze({
|
|
14753
15115
|
__proto__: null,
|
|
14754
|
-
|
|
15116
|
+
CurveWithOID: CurveWithOID,
|
|
14755
15117
|
ecdh: ecdh,
|
|
15118
|
+
ecdhX: ecdh_x,
|
|
14756
15119
|
ecdsa: ecdsa,
|
|
15120
|
+
eddsaLegacy: eddsa_legacy,
|
|
14757
15121
|
eddsa: eddsa,
|
|
14758
15122
|
generate: generate$1,
|
|
14759
15123
|
getPreferredHashAlgo: getPreferredHashAlgo
|
|
@@ -14778,7 +15142,7 @@ var elliptic = /*#__PURE__*/Object.freeze({
|
|
|
14778
15142
|
* @returns {Promise<{ r: Uint8Array, s: Uint8Array }>}
|
|
14779
15143
|
* @async
|
|
14780
15144
|
*/
|
|
14781
|
-
async function sign$
|
|
15145
|
+
async function sign$4(hashAlgo, hashed, g, p, q, x) {
|
|
14782
15146
|
const BigInteger = await util.getBigInteger();
|
|
14783
15147
|
const one = new BigInteger(1);
|
|
14784
15148
|
p = new BigInteger(p);
|
|
@@ -14837,7 +15201,7 @@ async function sign$3(hashAlgo, hashed, g, p, q, x) {
|
|
|
14837
15201
|
* @returns {boolean}
|
|
14838
15202
|
* @async
|
|
14839
15203
|
*/
|
|
14840
|
-
async function verify$
|
|
15204
|
+
async function verify$4(hashAlgo, r, s, hashed, g, p, q, y) {
|
|
14841
15205
|
const BigInteger = await util.getBigInteger();
|
|
14842
15206
|
const zero = new BigInteger(0);
|
|
14843
15207
|
r = new BigInteger(r);
|
|
@@ -14880,7 +15244,7 @@ async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
|
|
|
14880
15244
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
14881
15245
|
* @async
|
|
14882
15246
|
*/
|
|
14883
|
-
async function validateParams$
|
|
15247
|
+
async function validateParams$7(p, q, g, y, x) {
|
|
14884
15248
|
const BigInteger = await util.getBigInteger();
|
|
14885
15249
|
p = new BigInteger(p);
|
|
14886
15250
|
q = new BigInteger(q);
|
|
@@ -14935,9 +15299,9 @@ async function validateParams$5(p, q, g, y, x) {
|
|
|
14935
15299
|
|
|
14936
15300
|
var dsa = /*#__PURE__*/Object.freeze({
|
|
14937
15301
|
__proto__: null,
|
|
14938
|
-
sign: sign$
|
|
14939
|
-
verify: verify$
|
|
14940
|
-
validateParams: validateParams$
|
|
15302
|
+
sign: sign$4,
|
|
15303
|
+
verify: verify$4,
|
|
15304
|
+
validateParams: validateParams$7
|
|
14941
15305
|
});
|
|
14942
15306
|
|
|
14943
15307
|
/**
|
|
@@ -15073,10 +15437,10 @@ function parseSignatureParams(algo, signature) {
|
|
|
15073
15437
|
const s = util.readMPI(signature.subarray(read));
|
|
15074
15438
|
return { r, s };
|
|
15075
15439
|
}
|
|
15076
|
-
// Algorithm-Specific Fields for EdDSA signatures:
|
|
15440
|
+
// Algorithm-Specific Fields for legacy EdDSA signatures:
|
|
15077
15441
|
// - MPI of an EC point r.
|
|
15078
15442
|
// - EdDSA value s, in MPI, in the little endian representation
|
|
15079
|
-
case enums.publicKey.
|
|
15443
|
+
case enums.publicKey.eddsaLegacy: {
|
|
15080
15444
|
// When parsing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
|
|
15081
15445
|
// https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
|
|
15082
15446
|
let r = util.readMPI(signature.subarray(read)); read += r.length + 2;
|
|
@@ -15085,7 +15449,12 @@ function parseSignatureParams(algo, signature) {
|
|
|
15085
15449
|
s = util.leftPad(s, 32);
|
|
15086
15450
|
return { r, s };
|
|
15087
15451
|
}
|
|
15088
|
-
|
|
15452
|
+
// Algorithm-Specific Fields for Ed25519 signatures:
|
|
15453
|
+
// - 64 octets of the native signature
|
|
15454
|
+
case enums.publicKey.ed25519: {
|
|
15455
|
+
const RS = signature.subarray(read, read + 64); read += RS.length;
|
|
15456
|
+
return { RS };
|
|
15457
|
+
}
|
|
15089
15458
|
case enums.publicKey.hmac: {
|
|
15090
15459
|
const mac = new ShortByteString(); mac.read(signature.subarray(read));
|
|
15091
15460
|
return { mac };
|
|
@@ -15110,7 +15479,7 @@ function parseSignatureParams(algo, signature) {
|
|
|
15110
15479
|
* @returns {Promise<Boolean>} True if signature is valid.
|
|
15111
15480
|
* @async
|
|
15112
15481
|
*/
|
|
15113
|
-
async function verify$
|
|
15482
|
+
async function verify$5(algo, hashAlgo, signature, publicParams, privateParams, data, hashed) {
|
|
15114
15483
|
switch (algo) {
|
|
15115
15484
|
case enums.publicKey.rsaEncryptSign:
|
|
15116
15485
|
case enums.publicKey.rsaEncrypt:
|
|
@@ -15126,16 +15495,20 @@ async function verify$4(algo, hashAlgo, signature, publicParams, privateParams,
|
|
|
15126
15495
|
}
|
|
15127
15496
|
case enums.publicKey.ecdsa: {
|
|
15128
15497
|
const { oid, Q } = publicParams;
|
|
15129
|
-
const curveSize = new publicKey.elliptic.
|
|
15498
|
+
const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize;
|
|
15130
15499
|
// padding needed for webcrypto
|
|
15131
15500
|
const r = util.leftPad(signature.r, curveSize);
|
|
15132
15501
|
const s = util.leftPad(signature.s, curveSize);
|
|
15133
15502
|
return publicKey.elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
|
15134
15503
|
}
|
|
15135
|
-
case enums.publicKey.
|
|
15504
|
+
case enums.publicKey.eddsaLegacy: {
|
|
15136
15505
|
const { oid, Q } = publicParams;
|
|
15137
15506
|
// signature already padded on parsing
|
|
15138
|
-
return publicKey.elliptic.
|
|
15507
|
+
return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, signature, data, Q, hashed);
|
|
15508
|
+
}
|
|
15509
|
+
case enums.publicKey.ed25519: {
|
|
15510
|
+
const { A } = publicParams;
|
|
15511
|
+
return publicKey.elliptic.eddsa.verify(algo, hashAlgo, signature, data, A, hashed);
|
|
15139
15512
|
}
|
|
15140
15513
|
case enums.publicKey.hmac: {
|
|
15141
15514
|
if (!privateParams) {
|
|
@@ -15165,7 +15538,7 @@ async function verify$4(algo, hashAlgo, signature, publicParams, privateParams,
|
|
|
15165
15538
|
* @returns {Promise<Object>} Signature Object containing named signature parameters.
|
|
15166
15539
|
* @async
|
|
15167
15540
|
*/
|
|
15168
|
-
async function sign$
|
|
15541
|
+
async function sign$5(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) {
|
|
15169
15542
|
if (!publicKeyParams || !privateKeyParams) {
|
|
15170
15543
|
throw new Error('Missing key parameters');
|
|
15171
15544
|
}
|
|
@@ -15191,10 +15564,15 @@ async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
|
|
|
15191
15564
|
const { d } = privateKeyParams;
|
|
15192
15565
|
return publicKey.elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
|
|
15193
15566
|
}
|
|
15194
|
-
case enums.publicKey.
|
|
15567
|
+
case enums.publicKey.eddsaLegacy: {
|
|
15195
15568
|
const { oid, Q } = publicKeyParams;
|
|
15196
15569
|
const { seed } = privateKeyParams;
|
|
15197
|
-
return publicKey.elliptic.
|
|
15570
|
+
return publicKey.elliptic.eddsaLegacy.sign(oid, hashAlgo, data, Q, seed, hashed);
|
|
15571
|
+
}
|
|
15572
|
+
case enums.publicKey.ed25519: {
|
|
15573
|
+
const { A } = publicKeyParams;
|
|
15574
|
+
const { seed } = privateKeyParams;
|
|
15575
|
+
return publicKey.elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed);
|
|
15198
15576
|
}
|
|
15199
15577
|
case enums.publicKey.hmac: {
|
|
15200
15578
|
const { cipher: algo } = publicKeyParams;
|
|
@@ -15210,34 +15588,31 @@ async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
|
|
|
15210
15588
|
var signature = /*#__PURE__*/Object.freeze({
|
|
15211
15589
|
__proto__: null,
|
|
15212
15590
|
parseSignatureParams: parseSignatureParams,
|
|
15213
|
-
verify: verify$
|
|
15214
|
-
sign: sign$
|
|
15591
|
+
verify: verify$5,
|
|
15592
|
+
sign: sign$5
|
|
15215
15593
|
});
|
|
15216
15594
|
|
|
15217
15595
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
15218
15596
|
|
|
15219
15597
|
class ECDHSymmetricKey {
|
|
15220
15598
|
constructor(data) {
|
|
15221
|
-
if (
|
|
15222
|
-
data =
|
|
15223
|
-
} else if (util.isString(data)) {
|
|
15224
|
-
data = util.stringToUint8Array(data);
|
|
15225
|
-
} else {
|
|
15226
|
-
data = new Uint8Array(data);
|
|
15599
|
+
if (data) {
|
|
15600
|
+
this.data = data;
|
|
15227
15601
|
}
|
|
15228
|
-
this.data = data;
|
|
15229
15602
|
}
|
|
15230
15603
|
|
|
15231
15604
|
/**
|
|
15232
|
-
* Read an ECDHSymmetricKey from an Uint8Array
|
|
15233
|
-
*
|
|
15605
|
+
* Read an ECDHSymmetricKey from an Uint8Array:
|
|
15606
|
+
* - 1 octect for the length `l`
|
|
15607
|
+
* - `l` octects of encoded session key data
|
|
15608
|
+
* @param {Uint8Array} bytes
|
|
15234
15609
|
* @returns {Number} Number of read bytes.
|
|
15235
15610
|
*/
|
|
15236
|
-
read(
|
|
15237
|
-
if (
|
|
15238
|
-
const length =
|
|
15239
|
-
if (
|
|
15240
|
-
this.data =
|
|
15611
|
+
read(bytes) {
|
|
15612
|
+
if (bytes.length >= 1) {
|
|
15613
|
+
const length = bytes[0];
|
|
15614
|
+
if (bytes.length >= 1 + length) {
|
|
15615
|
+
this.data = bytes.subarray(1, 1 + length);
|
|
15241
15616
|
return 1 + this.data.length;
|
|
15242
15617
|
}
|
|
15243
15618
|
}
|
|
@@ -15246,7 +15621,7 @@ class ECDHSymmetricKey {
|
|
|
15246
15621
|
|
|
15247
15622
|
/**
|
|
15248
15623
|
* Write an ECDHSymmetricKey as an Uint8Array
|
|
15249
|
-
* @returns {Uint8Array}
|
|
15624
|
+
* @returns {Uint8Array} Serialised data
|
|
15250
15625
|
*/
|
|
15251
15626
|
write() {
|
|
15252
15627
|
return util.concatUint8Array([new Uint8Array([this.data.length]), this.data]);
|
|
@@ -15286,6 +15661,9 @@ class KDFParams {
|
|
|
15286
15661
|
* @returns {Number} Number of read bytes.
|
|
15287
15662
|
*/
|
|
15288
15663
|
read(input) {
|
|
15664
|
+
if (input.length < 4 || (input[1] !== 1 && input[1] !== VERSION_FORWARDING)) {
|
|
15665
|
+
throw new UnsupportedError('Cannot read KDFParams');
|
|
15666
|
+
}
|
|
15289
15667
|
const totalBytes = input[0];
|
|
15290
15668
|
this.version = input[1];
|
|
15291
15669
|
this.hash = input[2];
|
|
@@ -15373,12 +15751,57 @@ const AEADEnum = type_enum(enums.aead);
|
|
|
15373
15751
|
const SymAlgoEnum = type_enum(enums.symmetric);
|
|
15374
15752
|
const HashEnum = type_enum(enums.hash);
|
|
15375
15753
|
|
|
15754
|
+
/**
|
|
15755
|
+
* Encoded symmetric key for x25519 and x448
|
|
15756
|
+
* The payload format varies for v3 and v6 PKESK:
|
|
15757
|
+
* the former includes an algorithm byte preceeding the encrypted session key.
|
|
15758
|
+
*
|
|
15759
|
+
* @module type/x25519x448_symkey
|
|
15760
|
+
*/
|
|
15761
|
+
|
|
15762
|
+
class ECDHXSymmetricKey {
|
|
15763
|
+
static fromObject({ wrappedKey, algorithm }) {
|
|
15764
|
+
const instance = new ECDHXSymmetricKey();
|
|
15765
|
+
instance.wrappedKey = wrappedKey;
|
|
15766
|
+
instance.algorithm = algorithm;
|
|
15767
|
+
return instance;
|
|
15768
|
+
}
|
|
15769
|
+
|
|
15770
|
+
/**
|
|
15771
|
+
* - 1 octect for the length `l`
|
|
15772
|
+
* - `l` octects of encoded session key data (with optional leading algorithm byte)
|
|
15773
|
+
* @param {Uint8Array} bytes
|
|
15774
|
+
* @returns {Number} Number of read bytes.
|
|
15775
|
+
*/
|
|
15776
|
+
read(bytes) {
|
|
15777
|
+
let read = 0;
|
|
15778
|
+
let followLength = bytes[read++];
|
|
15779
|
+
this.algorithm = followLength % 2 ? bytes[read++] : null; // session key size is always even
|
|
15780
|
+
followLength -= followLength % 2;
|
|
15781
|
+
this.wrappedKey = bytes.subarray(read, read + followLength); read += followLength;
|
|
15782
|
+
}
|
|
15783
|
+
|
|
15784
|
+
/**
|
|
15785
|
+
* Write an MontgomerySymmetricKey as an Uint8Array
|
|
15786
|
+
* @returns {Uint8Array} Serialised data
|
|
15787
|
+
*/
|
|
15788
|
+
write() {
|
|
15789
|
+
return util.concatUint8Array([
|
|
15790
|
+
this.algorithm ?
|
|
15791
|
+
new Uint8Array([this.wrappedKey.length + 1, this.algorithm]) :
|
|
15792
|
+
new Uint8Array([this.wrappedKey.length]),
|
|
15793
|
+
this.wrappedKey
|
|
15794
|
+
]);
|
|
15795
|
+
}
|
|
15796
|
+
}
|
|
15797
|
+
|
|
15376
15798
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
15377
15799
|
|
|
15378
15800
|
/**
|
|
15379
15801
|
* Encrypts data using specified algorithm and public key parameters.
|
|
15380
15802
|
* See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1} for public key algorithms.
|
|
15381
|
-
* @param {module:enums.publicKey}
|
|
15803
|
+
* @param {module:enums.publicKey} keyAlgo - Public key algorithm
|
|
15804
|
+
* @param {module:enums.symmetric} symmetricAlgo - Cipher algorithm
|
|
15382
15805
|
* @param {Object} publicParams - Algorithm-specific public key parameters
|
|
15383
15806
|
* @param {Object} privateParams - Algorithm-specific private key parameters
|
|
15384
15807
|
* @param {Uint8Array} data - Data to be encrypted
|
|
@@ -15386,8 +15809,8 @@ const HashEnum = type_enum(enums.hash);
|
|
|
15386
15809
|
* @returns {Promise<Object>} Encrypted session key parameters.
|
|
15387
15810
|
* @async
|
|
15388
15811
|
*/
|
|
15389
|
-
async function publicKeyEncrypt(
|
|
15390
|
-
switch (
|
|
15812
|
+
async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, privateParams, data, fingerprint) {
|
|
15813
|
+
switch (keyAlgo) {
|
|
15391
15814
|
case enums.publicKey.rsaEncrypt:
|
|
15392
15815
|
case enums.publicKey.rsaEncryptSign: {
|
|
15393
15816
|
const { n, e } = publicParams;
|
|
@@ -15404,6 +15827,17 @@ async function publicKeyEncrypt(algo, publicParams, privateParams, data, fingerp
|
|
|
15404
15827
|
oid, kdfParams, data, Q, fingerprint);
|
|
15405
15828
|
return { V, C: new ECDHSymmetricKey(C) };
|
|
15406
15829
|
}
|
|
15830
|
+
case enums.publicKey.x25519: {
|
|
15831
|
+
if (!util.isAES(symmetricAlgo)) {
|
|
15832
|
+
// see https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/276
|
|
15833
|
+
throw new Error('X25519 keys can only encrypt AES session keys');
|
|
15834
|
+
}
|
|
15835
|
+
const { A } = publicParams;
|
|
15836
|
+
const { ephemeralPublicKey, wrappedKey } = await publicKey.elliptic.ecdhX.encrypt(
|
|
15837
|
+
keyAlgo, data, A);
|
|
15838
|
+
const C = ECDHXSymmetricKey.fromObject({ algorithm: symmetricAlgo, wrappedKey });
|
|
15839
|
+
return { ephemeralPublicKey, C };
|
|
15840
|
+
}
|
|
15407
15841
|
case enums.publicKey.aead: {
|
|
15408
15842
|
if (!privateParams) {
|
|
15409
15843
|
throw new Error('Cannot encrypt with symmetric key missing private parameters');
|
|
@@ -15460,6 +15894,16 @@ async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, session
|
|
|
15460
15894
|
return publicKey.elliptic.ecdh.decrypt(
|
|
15461
15895
|
oid, kdfParams, V, C.data, Q, d, fingerprint);
|
|
15462
15896
|
}
|
|
15897
|
+
case enums.publicKey.x25519: {
|
|
15898
|
+
const { A } = publicKeyParams;
|
|
15899
|
+
const { k } = privateKeyParams;
|
|
15900
|
+
const { ephemeralPublicKey, C } = sessionKeyParams;
|
|
15901
|
+
if (!util.isAES(C.algorithm)) {
|
|
15902
|
+
throw new Error('AES session key expected');
|
|
15903
|
+
}
|
|
15904
|
+
return publicKey.elliptic.ecdhX.decrypt(
|
|
15905
|
+
algo, ephemeralPublicKey, C.wrappedKey, A, k);
|
|
15906
|
+
}
|
|
15463
15907
|
case enums.publicKey.aead: {
|
|
15464
15908
|
const { cipher: algo } = publicKeyParams;
|
|
15465
15909
|
const algoValue = algo.getValue();
|
|
@@ -15511,7 +15955,7 @@ function parsePublicKeyParams(algo, bytes) {
|
|
|
15511
15955
|
const Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
|
|
15512
15956
|
return { read: read, publicParams: { oid, Q } };
|
|
15513
15957
|
}
|
|
15514
|
-
case enums.publicKey.
|
|
15958
|
+
case enums.publicKey.eddsaLegacy: {
|
|
15515
15959
|
const oid = new OID(); read += oid.read(bytes);
|
|
15516
15960
|
checkSupportedCurve(oid);
|
|
15517
15961
|
let Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
|
|
@@ -15525,6 +15969,11 @@ function parsePublicKeyParams(algo, bytes) {
|
|
|
15525
15969
|
const kdfParams = new KDFParams(); read += kdfParams.read(bytes.subarray(read));
|
|
15526
15970
|
return { read: read, publicParams: { oid, Q, kdfParams } };
|
|
15527
15971
|
}
|
|
15972
|
+
case enums.publicKey.ed25519:
|
|
15973
|
+
case enums.publicKey.x25519: {
|
|
15974
|
+
const A = bytes.subarray(read, read + 32); read += A.length;
|
|
15975
|
+
return { read, publicParams: { A } };
|
|
15976
|
+
}
|
|
15528
15977
|
case enums.publicKey.hmac:
|
|
15529
15978
|
case enums.publicKey.aead: {
|
|
15530
15979
|
const algo = new SymAlgoEnum(); read += algo.read(bytes);
|
|
@@ -15563,17 +16012,25 @@ function parsePrivateKeyParams(algo, bytes, publicParams) {
|
|
|
15563
16012
|
}
|
|
15564
16013
|
case enums.publicKey.ecdsa:
|
|
15565
16014
|
case enums.publicKey.ecdh: {
|
|
15566
|
-
const curve = new
|
|
16015
|
+
const curve = new CurveWithOID(publicParams.oid);
|
|
15567
16016
|
let d = util.readMPI(bytes.subarray(read)); read += d.length + 2;
|
|
15568
16017
|
d = util.leftPad(d, curve.payloadSize);
|
|
15569
16018
|
return { read, privateParams: { d } };
|
|
15570
16019
|
}
|
|
15571
|
-
case enums.publicKey.
|
|
15572
|
-
const curve = new
|
|
16020
|
+
case enums.publicKey.eddsaLegacy: {
|
|
16021
|
+
const curve = new CurveWithOID(publicParams.oid);
|
|
15573
16022
|
let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2;
|
|
15574
16023
|
seed = util.leftPad(seed, curve.payloadSize);
|
|
15575
16024
|
return { read, privateParams: { seed } };
|
|
15576
16025
|
}
|
|
16026
|
+
case enums.publicKey.ed25519: {
|
|
16027
|
+
const seed = bytes.subarray(read, read + 32); read += seed.length;
|
|
16028
|
+
return { read, privateParams: { seed } };
|
|
16029
|
+
}
|
|
16030
|
+
case enums.publicKey.x25519: {
|
|
16031
|
+
const k = bytes.subarray(read, read + 32); read += k.length;
|
|
16032
|
+
return { read, privateParams: { k } };
|
|
16033
|
+
}
|
|
15577
16034
|
case enums.publicKey.hmac: {
|
|
15578
16035
|
const { cipher: algo } = publicParams;
|
|
15579
16036
|
const keySize = hash.getHashByteLength(algo.getValue());
|
|
@@ -15625,6 +16082,16 @@ function parseEncSessionKeyParams(algo, bytes) {
|
|
|
15625
16082
|
const C = new ECDHSymmetricKey(); C.read(bytes.subarray(read));
|
|
15626
16083
|
return { V, C };
|
|
15627
16084
|
}
|
|
16085
|
+
// Algorithm-Specific Fields for X25519 encrypted session keys:
|
|
16086
|
+
// - 32 octets representing an ephemeral X25519 public key.
|
|
16087
|
+
// - A one-octet size of the following fields.
|
|
16088
|
+
// - The one-octet algorithm identifier, if it was passed (in the case of a v3 PKESK packet).
|
|
16089
|
+
// - The encrypted session key.
|
|
16090
|
+
case enums.publicKey.x25519: {
|
|
16091
|
+
const ephemeralPublicKey = bytes.subarray(read, read + 32); read += ephemeralPublicKey.length;
|
|
16092
|
+
const C = new ECDHXSymmetricKey(); C.read(bytes.subarray(read));
|
|
16093
|
+
return { ephemeralPublicKey, C };
|
|
16094
|
+
}
|
|
15628
16095
|
// Algorithm-Specific Fields for symmetric AEAD encryption:
|
|
15629
16096
|
// - AEAD algorithm
|
|
15630
16097
|
// - Starting initialization vector
|
|
@@ -15651,22 +16118,13 @@ function parseEncSessionKeyParams(algo, bytes) {
|
|
|
15651
16118
|
* @returns {Uint8Array} The array containing the MPIs.
|
|
15652
16119
|
*/
|
|
15653
16120
|
function serializeParams(algo, params) {
|
|
15654
|
-
|
|
15655
|
-
|
|
15656
|
-
|
|
15657
|
-
|
|
15658
|
-
|
|
15659
|
-
|
|
15660
|
-
|
|
15661
|
-
});
|
|
15662
|
-
break;
|
|
15663
|
-
}
|
|
15664
|
-
default:
|
|
15665
|
-
orderedParams = Object.keys(params).map(name => {
|
|
15666
|
-
const param = params[name];
|
|
15667
|
-
return util.isUint8Array(param) ? util.uint8ArrayToMPI(param) : param.write();
|
|
15668
|
-
});
|
|
15669
|
-
}
|
|
16121
|
+
// Some algorithms do not rely on MPIs to store the binary params
|
|
16122
|
+
const algosWithNativeRepresentation = new Set([enums.publicKey.ed25519, enums.publicKey.x25519, enums.publicKey.aead, enums.publicKey.hmac]);
|
|
16123
|
+
const orderedParams = Object.keys(params).map(name => {
|
|
16124
|
+
const param = params[name];
|
|
16125
|
+
if (!util.isUint8Array(param)) return param.write();
|
|
16126
|
+
return algosWithNativeRepresentation.has(algo) ? param : util.uint8ArrayToMPI(param);
|
|
16127
|
+
});
|
|
15670
16128
|
return util.concatUint8Array(orderedParams);
|
|
15671
16129
|
}
|
|
15672
16130
|
|
|
@@ -15694,7 +16152,7 @@ function generateParams(algo, bits, oid, symmetric) {
|
|
|
15694
16152
|
privateParams: { d: secret },
|
|
15695
16153
|
publicParams: { oid: new OID(oid), Q }
|
|
15696
16154
|
}));
|
|
15697
|
-
case enums.publicKey.
|
|
16155
|
+
case enums.publicKey.eddsaLegacy:
|
|
15698
16156
|
return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
|
15699
16157
|
privateParams: { seed: secret },
|
|
15700
16158
|
publicParams: { oid: new OID(oid), Q }
|
|
@@ -15708,6 +16166,16 @@ function generateParams(algo, bits, oid, symmetric) {
|
|
|
15708
16166
|
kdfParams: new KDFParams({ hash, cipher })
|
|
15709
16167
|
}
|
|
15710
16168
|
}));
|
|
16169
|
+
case enums.publicKey.ed25519:
|
|
16170
|
+
return publicKey.elliptic.eddsa.generate(algo).then(({ A, seed }) => ({
|
|
16171
|
+
privateParams: { seed },
|
|
16172
|
+
publicParams: { A }
|
|
16173
|
+
}));
|
|
16174
|
+
case enums.publicKey.x25519:
|
|
16175
|
+
return publicKey.elliptic.ecdhX.generate(algo).then(({ A, k }) => ({
|
|
16176
|
+
privateParams: { k },
|
|
16177
|
+
publicParams: { A }
|
|
16178
|
+
}));
|
|
15711
16179
|
case enums.publicKey.hmac: {
|
|
15712
16180
|
const symAlgo = enums.write(enums.hash, symmetric);
|
|
15713
16181
|
const keyMaterial = getRandomBytes(hash.getHashByteLength(symAlgo));
|
|
@@ -15749,7 +16217,7 @@ async function createSymmetricParams(key, algo) {
|
|
|
15749
16217
|
* @returns {Promise<Boolean>} Whether the parameters are valid.
|
|
15750
16218
|
* @async
|
|
15751
16219
|
*/
|
|
15752
|
-
async function validateParams$
|
|
16220
|
+
async function validateParams$8(algo, publicParams, privateParams) {
|
|
15753
16221
|
if (!publicParams || !privateParams) {
|
|
15754
16222
|
throw new Error('Missing key parameters');
|
|
15755
16223
|
}
|
|
@@ -15778,10 +16246,20 @@ async function validateParams$6(algo, publicParams, privateParams) {
|
|
|
15778
16246
|
const { d } = privateParams;
|
|
15779
16247
|
return algoModule.validateParams(oid, Q, d);
|
|
15780
16248
|
}
|
|
15781
|
-
case enums.publicKey.
|
|
15782
|
-
const {
|
|
16249
|
+
case enums.publicKey.eddsaLegacy: {
|
|
16250
|
+
const { Q, oid } = publicParams;
|
|
16251
|
+
const { seed } = privateParams;
|
|
16252
|
+
return publicKey.elliptic.eddsaLegacy.validateParams(oid, Q, seed);
|
|
16253
|
+
}
|
|
16254
|
+
case enums.publicKey.ed25519: {
|
|
16255
|
+
const { A } = publicParams;
|
|
15783
16256
|
const { seed } = privateParams;
|
|
15784
|
-
return publicKey.elliptic.eddsa.validateParams(
|
|
16257
|
+
return publicKey.elliptic.eddsa.validateParams(algo, A, seed);
|
|
16258
|
+
}
|
|
16259
|
+
case enums.publicKey.x25519: {
|
|
16260
|
+
const { A } = publicParams;
|
|
16261
|
+
const { k } = privateParams;
|
|
16262
|
+
return publicKey.elliptic.ecdhX.validateParams(algo, A, k);
|
|
15785
16263
|
}
|
|
15786
16264
|
case enums.publicKey.hmac: {
|
|
15787
16265
|
const { cipher: algo, digest } = publicParams;
|
|
@@ -15851,6 +16329,23 @@ function checkSupportedCurve(oid) {
|
|
|
15851
16329
|
}
|
|
15852
16330
|
}
|
|
15853
16331
|
|
|
16332
|
+
/**
|
|
16333
|
+
* Get preferred hash algo for a given elliptic algo
|
|
16334
|
+
* @param {module:enums.publicKey} algo - alrogithm identifier
|
|
16335
|
+
* @param {module:type/oid} [oid] - curve OID if needed by algo
|
|
16336
|
+
*/
|
|
16337
|
+
function getPreferredCurveHashAlgo(algo, oid) {
|
|
16338
|
+
switch (algo) {
|
|
16339
|
+
case enums.publicKey.ecdsa:
|
|
16340
|
+
case enums.publicKey.eddsaLegacy:
|
|
16341
|
+
return publicKey.elliptic.getPreferredHashAlgo(oid);
|
|
16342
|
+
case enums.publicKey.ed25519:
|
|
16343
|
+
return publicKey.elliptic.eddsa.getPreferredHashAlgo(algo);
|
|
16344
|
+
default:
|
|
16345
|
+
throw new Error('Unknown elliptic signing algo');
|
|
16346
|
+
}
|
|
16347
|
+
}
|
|
16348
|
+
|
|
15854
16349
|
var crypto$1 = /*#__PURE__*/Object.freeze({
|
|
15855
16350
|
__proto__: null,
|
|
15856
16351
|
publicKeyEncrypt: publicKeyEncrypt,
|
|
@@ -15860,11 +16355,12 @@ var crypto$1 = /*#__PURE__*/Object.freeze({
|
|
|
15860
16355
|
parseEncSessionKeyParams: parseEncSessionKeyParams,
|
|
15861
16356
|
serializeParams: serializeParams,
|
|
15862
16357
|
generateParams: generateParams,
|
|
15863
|
-
validateParams: validateParams$
|
|
16358
|
+
validateParams: validateParams$8,
|
|
15864
16359
|
getPrefixRandom: getPrefixRandom,
|
|
15865
16360
|
generateSessionKey: generateSessionKey,
|
|
15866
16361
|
getAEADMode: getAEADMode,
|
|
15867
|
-
getCipher: getCipher
|
|
16362
|
+
getCipher: getCipher,
|
|
16363
|
+
getPreferredCurveHashAlgo: getPreferredCurveHashAlgo
|
|
15868
16364
|
});
|
|
15869
16365
|
|
|
15870
16366
|
/**
|
|
@@ -16107,15 +16603,15 @@ class GenericS2K {
|
|
|
16107
16603
|
this.type = 'gnu-dummy';
|
|
16108
16604
|
// GnuPG extension mode 1001 -- don't write secret key at all
|
|
16109
16605
|
} else {
|
|
16110
|
-
throw new
|
|
16606
|
+
throw new UnsupportedError('Unknown s2k gnu protection mode.');
|
|
16111
16607
|
}
|
|
16112
16608
|
} else {
|
|
16113
|
-
throw new
|
|
16609
|
+
throw new UnsupportedError('Unknown s2k type.');
|
|
16114
16610
|
}
|
|
16115
16611
|
break;
|
|
16116
16612
|
|
|
16117
16613
|
default:
|
|
16118
|
-
throw new
|
|
16614
|
+
throw new UnsupportedError('Unknown s2k type.'); // unreachable
|
|
16119
16615
|
}
|
|
16120
16616
|
|
|
16121
16617
|
return i;
|
|
@@ -16219,7 +16715,7 @@ function newS2KFromType(type, config$1 = config) {
|
|
|
16219
16715
|
case enums.s2k.simple:
|
|
16220
16716
|
return new GenericS2K(type, config$1);
|
|
16221
16717
|
default:
|
|
16222
|
-
throw new
|
|
16718
|
+
throw new UnsupportedError(`Unsupported S2K type ${type}`);
|
|
16223
16719
|
}
|
|
16224
16720
|
}
|
|
16225
16721
|
|
|
@@ -24973,13 +25469,17 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
24973
25469
|
* @param {Uint8Array} bytes - Payload of a tag 1 packet
|
|
24974
25470
|
*/
|
|
24975
25471
|
read(bytes) {
|
|
24976
|
-
|
|
25472
|
+
let i = 0;
|
|
25473
|
+
this.version = bytes[i++];
|
|
24977
25474
|
if (this.version !== VERSION$3) {
|
|
24978
25475
|
throw new UnsupportedError(`Version ${this.version} of the PKESK packet is unsupported.`);
|
|
24979
25476
|
}
|
|
24980
|
-
this.publicKeyID.read(bytes.subarray(
|
|
24981
|
-
this.publicKeyAlgorithm = bytes[
|
|
24982
|
-
this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(
|
|
25477
|
+
i += this.publicKeyID.read(bytes.subarray(i));
|
|
25478
|
+
this.publicKeyAlgorithm = bytes[i++];
|
|
25479
|
+
this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(i), this.version);
|
|
25480
|
+
if (this.publicKeyAlgorithm === enums.publicKey.x25519) {
|
|
25481
|
+
this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm);
|
|
25482
|
+
}
|
|
24983
25483
|
}
|
|
24984
25484
|
|
|
24985
25485
|
/**
|
|
@@ -25005,15 +25505,11 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
25005
25505
|
* @async
|
|
25006
25506
|
*/
|
|
25007
25507
|
async encrypt(key) {
|
|
25008
|
-
const data = util.concatUint8Array([
|
|
25009
|
-
new Uint8Array([enums.write(enums.symmetric, this.sessionKeyAlgorithm)]),
|
|
25010
|
-
this.sessionKey,
|
|
25011
|
-
util.writeChecksum(this.sessionKey)
|
|
25012
|
-
]);
|
|
25013
25508
|
const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
|
|
25509
|
+
const encoded = encodeSessionKey(this.version, algo, this.sessionKeyAlgorithm, this.sessionKey);
|
|
25014
25510
|
const privateParams = algo === enums.publicKey.aead ? key.privateParams : null;
|
|
25015
25511
|
this.encrypted = await mod.publicKeyEncrypt(
|
|
25016
|
-
algo, key.publicParams, privateParams,
|
|
25512
|
+
algo, this.sessionKeyAlgorithm, key.publicParams, privateParams, encoded, key.getFingerprintBytes());
|
|
25017
25513
|
}
|
|
25018
25514
|
|
|
25019
25515
|
/**
|
|
@@ -25030,34 +25526,86 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
25030
25526
|
throw new Error('Decryption error');
|
|
25031
25527
|
}
|
|
25032
25528
|
|
|
25033
|
-
const randomPayload = randomSessionKey ?
|
|
25034
|
-
|
|
25035
|
-
|
|
25036
|
-
|
|
25037
|
-
]) : null;
|
|
25038
|
-
const decoded = await mod.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes(), randomPayload);
|
|
25039
|
-
const symmetricAlgoByte = decoded[0];
|
|
25040
|
-
const sessionKey = decoded.subarray(1, decoded.length - 2);
|
|
25041
|
-
const checksum = decoded.subarray(decoded.length - 2);
|
|
25042
|
-
const computedChecksum = util.writeChecksum(sessionKey);
|
|
25043
|
-
const isValidChecksum = computedChecksum[0] === checksum[0] & computedChecksum[1] === checksum[1];
|
|
25044
|
-
|
|
25045
|
-
if (randomSessionKey) {
|
|
25046
|
-
// We must not leak info about the validity of the decrypted checksum or cipher algo.
|
|
25047
|
-
// The decrypted session key must be of the same algo and size as the random session key, otherwise we discard it and use the random data.
|
|
25048
|
-
const isValidPayload = isValidChecksum & symmetricAlgoByte === randomSessionKey.sessionKeyAlgorithm & sessionKey.length === randomSessionKey.sessionKey.length;
|
|
25049
|
-
this.sessionKeyAlgorithm = util.selectUint8(isValidPayload, symmetricAlgoByte, randomSessionKey.sessionKeyAlgorithm);
|
|
25050
|
-
this.sessionKey = util.selectUint8Array(isValidPayload, sessionKey, randomSessionKey.sessionKey);
|
|
25529
|
+
const randomPayload = randomSessionKey ?
|
|
25530
|
+
encodeSessionKey(this.version, this.publicKeyAlgorithm, randomSessionKey.sessionKeyAlgorithm, randomSessionKey.sessionKey) :
|
|
25531
|
+
null;
|
|
25532
|
+
const decryptedData = await mod.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes(), randomPayload);
|
|
25051
25533
|
|
|
25052
|
-
}
|
|
25053
|
-
|
|
25054
|
-
|
|
25055
|
-
|
|
25056
|
-
|
|
25534
|
+
const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey);
|
|
25535
|
+
|
|
25536
|
+
// v3 Montgomery curves have cleartext cipher algo
|
|
25537
|
+
if (this.publicKeyAlgorithm !== enums.publicKey.x25519) {
|
|
25538
|
+
this.sessionKeyAlgorithm = sessionKeyAlgorithm;
|
|
25539
|
+
}
|
|
25540
|
+
this.sessionKey = sessionKey;
|
|
25541
|
+
}
|
|
25542
|
+
}
|
|
25543
|
+
|
|
25544
|
+
|
|
25545
|
+
function encodeSessionKey(version, keyAlgo, cipherAlgo, sessionKeyData) {
|
|
25546
|
+
switch (keyAlgo) {
|
|
25547
|
+
case enums.publicKey.rsaEncrypt:
|
|
25548
|
+
case enums.publicKey.rsaEncryptSign:
|
|
25549
|
+
case enums.publicKey.elgamal:
|
|
25550
|
+
case enums.publicKey.ecdh:
|
|
25551
|
+
case enums.publicKey.aead: {
|
|
25552
|
+
// add checksum
|
|
25553
|
+
return util.concatUint8Array([
|
|
25554
|
+
new Uint8Array([cipherAlgo]),
|
|
25555
|
+
sessionKeyData,
|
|
25556
|
+
util.writeChecksum(sessionKeyData.subarray(sessionKeyData.length % 8))
|
|
25557
|
+
]);
|
|
25558
|
+
}
|
|
25559
|
+
case enums.publicKey.x25519:
|
|
25560
|
+
return sessionKeyData;
|
|
25561
|
+
default:
|
|
25562
|
+
throw new Error('Unsupported public key algorithm');
|
|
25563
|
+
}
|
|
25564
|
+
}
|
|
25565
|
+
|
|
25566
|
+
|
|
25567
|
+
function decodeSessionKey(version, keyAlgo, decryptedData, randomSessionKey) {
|
|
25568
|
+
switch (keyAlgo) {
|
|
25569
|
+
case enums.publicKey.rsaEncrypt:
|
|
25570
|
+
case enums.publicKey.rsaEncryptSign:
|
|
25571
|
+
case enums.publicKey.elgamal:
|
|
25572
|
+
case enums.publicKey.ecdh:
|
|
25573
|
+
case enums.publicKey.aead: {
|
|
25574
|
+
// verify checksum in constant time
|
|
25575
|
+
const result = decryptedData.subarray(0, decryptedData.length - 2);
|
|
25576
|
+
const checksum = decryptedData.subarray(decryptedData.length - 2);
|
|
25577
|
+
const computedChecksum = util.writeChecksum(result.subarray(result.length % 8));
|
|
25578
|
+
const isValidChecksum = computedChecksum[0] === checksum[0] & computedChecksum[1] === checksum[1];
|
|
25579
|
+
const decryptedSessionKey = { sessionKeyAlgorithm: result[0], sessionKey: result.subarray(1) };
|
|
25580
|
+
if (randomSessionKey) {
|
|
25581
|
+
// We must not leak info about the validity of the decrypted checksum or cipher algo.
|
|
25582
|
+
// The decrypted session key must be of the same algo and size as the random session key, otherwise we discard it and use the random data.
|
|
25583
|
+
const isValidPayload = isValidChecksum &
|
|
25584
|
+
decryptedSessionKey.sessionKeyAlgorithm === randomSessionKey.sessionKeyAlgorithm &
|
|
25585
|
+
decryptedSessionKey.sessionKey.length === randomSessionKey.sessionKey.length;
|
|
25586
|
+
return {
|
|
25587
|
+
sessionKey: util.selectUint8Array(isValidPayload, decryptedSessionKey.sessionKey, randomSessionKey.sessionKey),
|
|
25588
|
+
sessionKeyAlgorithm: util.selectUint8(
|
|
25589
|
+
isValidPayload,
|
|
25590
|
+
decryptedSessionKey.sessionKeyAlgorithm,
|
|
25591
|
+
randomSessionKey.sessionKeyAlgorithm
|
|
25592
|
+
)
|
|
25593
|
+
};
|
|
25057
25594
|
} else {
|
|
25058
|
-
|
|
25595
|
+
const isValidPayload = isValidChecksum && enums.read(enums.symmetric, decryptedSessionKey.sessionKeyAlgorithm);
|
|
25596
|
+
if (isValidPayload) {
|
|
25597
|
+
return decryptedSessionKey;
|
|
25598
|
+
} else {
|
|
25599
|
+
throw new Error('Decryption error');
|
|
25600
|
+
}
|
|
25059
25601
|
}
|
|
25060
25602
|
}
|
|
25603
|
+
case enums.publicKey.x25519:
|
|
25604
|
+
return {
|
|
25605
|
+
sessionKey: decryptedData
|
|
25606
|
+
};
|
|
25607
|
+
default:
|
|
25608
|
+
throw new Error('Unsupported public key algorithm');
|
|
25061
25609
|
}
|
|
25062
25610
|
}
|
|
25063
25611
|
|
|
@@ -25488,7 +26036,7 @@ class PublicKeyPacket {
|
|
|
25488
26036
|
result.bits = util.uint8ArrayBitLength(modulo);
|
|
25489
26037
|
} else if (this.publicParams.oid) {
|
|
25490
26038
|
result.curve = this.publicParams.oid.getName();
|
|
25491
|
-
} else {
|
|
26039
|
+
} else if (this.publicParams.cipher) {
|
|
25492
26040
|
result.symmetric = this.publicParams.cipher.getName();
|
|
25493
26041
|
}
|
|
25494
26042
|
return result;
|
|
@@ -25820,6 +26368,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25820
26368
|
async read(bytes) {
|
|
25821
26369
|
// - A Public-Key or Public-Subkey packet, as described above.
|
|
25822
26370
|
let i = await this.readPublicKey(bytes);
|
|
26371
|
+
const startOfSecretKeyData = i;
|
|
25823
26372
|
|
|
25824
26373
|
// - One octet indicating string-to-key usage conventions. Zero
|
|
25825
26374
|
// indicates that the secret-key data is not encrypted. 255 or 254
|
|
@@ -25833,41 +26382,48 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25833
26382
|
i++;
|
|
25834
26383
|
}
|
|
25835
26384
|
|
|
25836
|
-
|
|
25837
|
-
// one-octet symmetric encryption algorithm.
|
|
25838
|
-
if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
|
|
25839
|
-
this.symmetric = bytes[i++];
|
|
25840
|
-
|
|
25841
|
-
// - [Optional] If string-to-key usage octet was 253, a one-octet
|
|
25842
|
-
// AEAD algorithm.
|
|
25843
|
-
if (this.s2kUsage === 253) {
|
|
25844
|
-
this.aead = bytes[i++];
|
|
25845
|
-
}
|
|
25846
|
-
|
|
26385
|
+
try {
|
|
25847
26386
|
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
|
|
25848
|
-
//
|
|
25849
|
-
|
|
25850
|
-
|
|
25851
|
-
|
|
25852
|
-
|
|
26387
|
+
// one-octet symmetric encryption algorithm.
|
|
26388
|
+
if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
|
|
26389
|
+
this.symmetric = bytes[i++];
|
|
26390
|
+
|
|
26391
|
+
// - [Optional] If string-to-key usage octet was 253, a one-octet
|
|
26392
|
+
// AEAD algorithm.
|
|
26393
|
+
if (this.s2kUsage === 253) {
|
|
26394
|
+
this.aead = bytes[i++];
|
|
26395
|
+
}
|
|
25853
26396
|
|
|
25854
|
-
|
|
25855
|
-
|
|
26397
|
+
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
|
|
26398
|
+
// string-to-key specifier. The length of the string-to-key
|
|
26399
|
+
// specifier is implied by its type, as described above.
|
|
26400
|
+
const s2kType = bytes[i++];
|
|
26401
|
+
this.s2k = newS2KFromType(s2kType);
|
|
26402
|
+
i += this.s2k.read(bytes.subarray(i, bytes.length));
|
|
26403
|
+
|
|
26404
|
+
if (this.s2k.type === 'gnu-dummy') {
|
|
26405
|
+
return;
|
|
26406
|
+
}
|
|
26407
|
+
} else if (this.s2kUsage) {
|
|
26408
|
+
this.symmetric = this.s2kUsage;
|
|
25856
26409
|
}
|
|
25857
|
-
} else if (this.s2kUsage) {
|
|
25858
|
-
this.symmetric = this.s2kUsage;
|
|
25859
|
-
}
|
|
25860
26410
|
|
|
25861
|
-
|
|
25862
|
-
|
|
25863
|
-
|
|
25864
|
-
|
|
25865
|
-
|
|
25866
|
-
|
|
25867
|
-
|
|
25868
|
-
|
|
26411
|
+
// - [Optional] If secret data is encrypted (string-to-key usage octet
|
|
26412
|
+
// not zero), an Initial Vector (IV) of the same length as the
|
|
26413
|
+
// cipher's block size.
|
|
26414
|
+
if (this.s2kUsage) {
|
|
26415
|
+
this.iv = bytes.subarray(
|
|
26416
|
+
i,
|
|
26417
|
+
i + mod.getCipher(this.symmetric).blockSize
|
|
26418
|
+
);
|
|
25869
26419
|
|
|
25870
|
-
|
|
26420
|
+
i += this.iv.length;
|
|
26421
|
+
}
|
|
26422
|
+
} catch (e) {
|
|
26423
|
+
// if the s2k is unsupported, we still want to support encrypting and verifying with the given key
|
|
26424
|
+
if (!this.s2kUsage) throw e; // always throw for decrypted keys
|
|
26425
|
+
this.unparseableKeyMaterial = bytes.subarray(startOfSecretKeyData);
|
|
26426
|
+
this.isEncrypted = true;
|
|
25871
26427
|
}
|
|
25872
26428
|
|
|
25873
26429
|
// - Only for a version 5 packet, a four-octet scalar octet count for
|
|
@@ -25903,8 +26459,15 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25903
26459
|
* @returns {Uint8Array} A string of bytes containing the secret key OpenPGP packet.
|
|
25904
26460
|
*/
|
|
25905
26461
|
write() {
|
|
25906
|
-
const
|
|
26462
|
+
const serializedPublicKey = this.writePublicKey();
|
|
26463
|
+
if (this.unparseableKeyMaterial) {
|
|
26464
|
+
return util.concatUint8Array([
|
|
26465
|
+
serializedPublicKey,
|
|
26466
|
+
this.unparseableKeyMaterial
|
|
26467
|
+
]);
|
|
26468
|
+
}
|
|
25907
26469
|
|
|
26470
|
+
const arr = [serializedPublicKey];
|
|
25908
26471
|
arr.push(new Uint8Array([this.s2kUsage]));
|
|
25909
26472
|
|
|
25910
26473
|
const optionalFieldsArr = [];
|
|
@@ -25964,6 +26527,18 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25964
26527
|
return this.isEncrypted === false;
|
|
25965
26528
|
}
|
|
25966
26529
|
|
|
26530
|
+
/**
|
|
26531
|
+
* Check whether the key includes secret key material.
|
|
26532
|
+
* Some secret keys do not include it, and can thus only be used
|
|
26533
|
+
* for public-key operations (encryption and verification).
|
|
26534
|
+
* Such keys are:
|
|
26535
|
+
* - GNU-dummy keys, where the secret material has been stripped away
|
|
26536
|
+
* - encrypted keys with unsupported S2K or cipher
|
|
26537
|
+
*/
|
|
26538
|
+
isMissingSecretKeyMaterial() {
|
|
26539
|
+
return this.unparseableKeyMaterial !== undefined || this.isDummy();
|
|
26540
|
+
}
|
|
26541
|
+
|
|
25967
26542
|
/**
|
|
25968
26543
|
* Check whether this is a gnu-dummy key
|
|
25969
26544
|
* @returns {Boolean}
|
|
@@ -25984,6 +26559,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25984
26559
|
if (this.isDecrypted()) {
|
|
25985
26560
|
this.clearPrivateParams();
|
|
25986
26561
|
}
|
|
26562
|
+
delete this.unparseableKeyMaterial;
|
|
25987
26563
|
this.isEncrypted = null;
|
|
25988
26564
|
this.keyMaterial = null;
|
|
25989
26565
|
this.s2k = newS2KFromType(enums.s2k.gnu, config$1);
|
|
@@ -26055,6 +26631,10 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
26055
26631
|
return false;
|
|
26056
26632
|
}
|
|
26057
26633
|
|
|
26634
|
+
if (this.unparseableKeyMaterial) {
|
|
26635
|
+
throw new Error('Key packet cannot be decrypted: unsupported S2K or cipher algo');
|
|
26636
|
+
}
|
|
26637
|
+
|
|
26058
26638
|
if (this.isDecrypted()) {
|
|
26059
26639
|
throw new Error('Key packet is already decrypted.');
|
|
26060
26640
|
}
|
|
@@ -26139,7 +26719,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
26139
26719
|
* Clear private key parameters
|
|
26140
26720
|
*/
|
|
26141
26721
|
clearPrivateParams() {
|
|
26142
|
-
if (this.
|
|
26722
|
+
if (this.isMissingSecretKeyMaterial()) {
|
|
26143
26723
|
return;
|
|
26144
26724
|
}
|
|
26145
26725
|
|
|
@@ -27538,25 +28118,22 @@ async function createBindingSignature(subkey, primaryKey, options, config) {
|
|
|
27538
28118
|
const dataToSign = {};
|
|
27539
28119
|
dataToSign.key = primaryKey;
|
|
27540
28120
|
dataToSign.bind = subkey;
|
|
27541
|
-
const
|
|
27542
|
-
subkeySignaturePacket.signatureType = enums.signature.subkeyBinding;
|
|
27543
|
-
subkeySignaturePacket.publicKeyAlgorithm = primaryKey.algorithm;
|
|
27544
|
-
subkeySignaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(null, subkey, undefined, undefined, config);
|
|
28121
|
+
const signatureProperties = { signatureType: enums.signature.subkeyBinding };
|
|
27545
28122
|
if (options.sign) {
|
|
27546
|
-
|
|
27547
|
-
|
|
28123
|
+
signatureProperties.keyFlags = [enums.keyFlags.signData];
|
|
28124
|
+
signatureProperties.embeddedSignature = await createSignaturePacket(dataToSign, null, subkey, {
|
|
27548
28125
|
signatureType: enums.signature.keyBinding
|
|
27549
28126
|
}, options.date, undefined, undefined, undefined, config);
|
|
27550
28127
|
} else {
|
|
27551
|
-
|
|
28128
|
+
signatureProperties.keyFlags = options.forwarding ?
|
|
27552
28129
|
[enums.keyFlags.forwardedCommunication] :
|
|
27553
28130
|
[enums.keyFlags.encryptCommunication | enums.keyFlags.encryptStorage];
|
|
27554
28131
|
}
|
|
27555
28132
|
if (options.keyExpirationTime > 0) {
|
|
27556
|
-
|
|
27557
|
-
|
|
28133
|
+
signatureProperties.keyExpirationTime = options.keyExpirationTime;
|
|
28134
|
+
signatureProperties.keyNeverExpires = false;
|
|
27558
28135
|
}
|
|
27559
|
-
await
|
|
28136
|
+
const subkeySignaturePacket = await createSignaturePacket(dataToSign, null, primaryKey, signatureProperties, options.date, undefined, undefined, undefined, config);
|
|
27560
28137
|
return subkeySignaturePacket;
|
|
27561
28138
|
}
|
|
27562
28139
|
|
|
@@ -27570,7 +28147,7 @@ async function createBindingSignature(subkey, primaryKey, options, config) {
|
|
|
27570
28147
|
* @returns {Promise<enums.hash>}
|
|
27571
28148
|
* @async
|
|
27572
28149
|
*/
|
|
27573
|
-
async function getPreferredHashAlgo$
|
|
28150
|
+
async function getPreferredHashAlgo$2(key, keyPacket, date = new Date(), userID = {}, config) {
|
|
27574
28151
|
let hashAlgo = config.preferredHashAlgorithm;
|
|
27575
28152
|
let prefAlgo = hashAlgo;
|
|
27576
28153
|
if (key) {
|
|
@@ -27581,17 +28158,11 @@ async function getPreferredHashAlgo$1(key, keyPacket, date = new Date(), userID
|
|
|
27581
28158
|
prefAlgo : hashAlgo;
|
|
27582
28159
|
}
|
|
27583
28160
|
}
|
|
27584
|
-
switch (
|
|
27585
|
-
case
|
|
27586
|
-
case
|
|
27587
|
-
case
|
|
27588
|
-
|
|
27589
|
-
switch (keyPacket.algorithm) {
|
|
27590
|
-
case enums.publicKey.ecdh:
|
|
27591
|
-
case enums.publicKey.ecdsa:
|
|
27592
|
-
case enums.publicKey.eddsa:
|
|
27593
|
-
prefAlgo = mod.publicKey.elliptic.getPreferredHashAlgo(keyPacket.publicParams.oid);
|
|
27594
|
-
}
|
|
28161
|
+
switch (keyPacket.algorithm) {
|
|
28162
|
+
case enums.publicKey.ecdsa:
|
|
28163
|
+
case enums.publicKey.eddsaLegacy:
|
|
28164
|
+
case enums.publicKey.ed25519:
|
|
28165
|
+
prefAlgo = mod.getPreferredCurveHashAlgo(keyPacket.algorithm, keyPacket.publicParams.oid);
|
|
27595
28166
|
}
|
|
27596
28167
|
return mod.hash.getHashByteLength(hashAlgo) <= mod.hash.getHashByteLength(prefAlgo) ?
|
|
27597
28168
|
prefAlgo : hashAlgo;
|
|
@@ -27659,7 +28230,7 @@ async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, s
|
|
|
27659
28230
|
const signaturePacket = new SignaturePacket();
|
|
27660
28231
|
Object.assign(signaturePacket, signatureProperties);
|
|
27661
28232
|
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
|
27662
|
-
signaturePacket.hashAlgorithm = await getPreferredHashAlgo$
|
|
28233
|
+
signaturePacket.hashAlgorithm = await getPreferredHashAlgo$2(privateKey, signingKeyPacket, date, userID, config);
|
|
27663
28234
|
signaturePacket.rawNotations = notations;
|
|
27664
28235
|
await signaturePacket.sign(signingKeyPacket, dataToSign, date, detached);
|
|
27665
28236
|
return signaturePacket;
|
|
@@ -27800,11 +28371,11 @@ function sanitizeKeyOptions(options, subkeyDefaults = {}) {
|
|
|
27800
28371
|
} catch (e) {
|
|
27801
28372
|
throw new Error('Unknown curve');
|
|
27802
28373
|
}
|
|
27803
|
-
if (options.curve === enums.curve.
|
|
27804
|
-
options.curve = options.sign ? enums.curve.
|
|
28374
|
+
if (options.curve === enums.curve.ed25519Legacy || options.curve === enums.curve.curve25519Legacy) {
|
|
28375
|
+
options.curve = options.sign ? enums.curve.ed25519Legacy : enums.curve.curve25519Legacy;
|
|
27805
28376
|
}
|
|
27806
28377
|
if (options.sign) {
|
|
27807
|
-
options.algorithm = options.curve === enums.curve.
|
|
28378
|
+
options.algorithm = options.curve === enums.curve.ed25519Legacy ? enums.publicKey.eddsaLegacy : enums.publicKey.ecdsa;
|
|
27808
28379
|
} else {
|
|
27809
28380
|
options.algorithm = enums.publicKey.ecdh;
|
|
27810
28381
|
}
|
|
@@ -27832,6 +28403,7 @@ function isValidSigningKeyPacket(keyPacket, signature) {
|
|
|
27832
28403
|
return keyAlgo !== enums.publicKey.rsaEncrypt &&
|
|
27833
28404
|
keyAlgo !== enums.publicKey.elgamal &&
|
|
27834
28405
|
keyAlgo !== enums.publicKey.ecdh &&
|
|
28406
|
+
keyAlgo !== enums.publicKey.x25519 &&
|
|
27835
28407
|
(!signature.keyFlags ||
|
|
27836
28408
|
(signature.keyFlags[0] & enums.keyFlags.signData) !== 0);
|
|
27837
28409
|
}
|
|
@@ -27841,7 +28413,8 @@ function isValidEncryptionKeyPacket(keyPacket, signature) {
|
|
|
27841
28413
|
return keyAlgo !== enums.publicKey.dsa &&
|
|
27842
28414
|
keyAlgo !== enums.publicKey.rsaSign &&
|
|
27843
28415
|
keyAlgo !== enums.publicKey.ecdsa &&
|
|
27844
|
-
keyAlgo !== enums.publicKey.
|
|
28416
|
+
keyAlgo !== enums.publicKey.eddsaLegacy &&
|
|
28417
|
+
keyAlgo !== enums.publicKey.ed25519 &&
|
|
27845
28418
|
(!signature.keyFlags ||
|
|
27846
28419
|
(signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 ||
|
|
27847
28420
|
(signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0);
|
|
@@ -27886,7 +28459,7 @@ function checkKeyRequirements(keyPacket, config) {
|
|
|
27886
28459
|
}
|
|
27887
28460
|
break;
|
|
27888
28461
|
case enums.publicKey.ecdsa:
|
|
27889
|
-
case enums.publicKey.
|
|
28462
|
+
case enums.publicKey.eddsaLegacy:
|
|
27890
28463
|
case enums.publicKey.ecdh:
|
|
27891
28464
|
if (config.rejectCurves.has(algoInfo.curve)) {
|
|
27892
28465
|
throw new Error(`Support for ${algoInfo.algorithm} keys using curve ${algoInfo.curve} is disabled.`);
|
|
@@ -29396,7 +29969,7 @@ function createKey(packetlist) {
|
|
|
29396
29969
|
* @static
|
|
29397
29970
|
* @private
|
|
29398
29971
|
*/
|
|
29399
|
-
async function generate$
|
|
29972
|
+
async function generate$4(options, config) {
|
|
29400
29973
|
options.sign = true; // primary key is always a signing key
|
|
29401
29974
|
options = sanitizeKeyOptions(options);
|
|
29402
29975
|
options.subkeys = options.subkeys.map((subkey, index) => sanitizeKeyOptions(options.subkeys[index], options));
|
|
@@ -29513,50 +30086,50 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
|
|
|
29513
30086
|
const dataToSign = {};
|
|
29514
30087
|
dataToSign.userID = userIDPacket;
|
|
29515
30088
|
dataToSign.key = secretKeyPacket;
|
|
29516
|
-
|
|
29517
|
-
|
|
29518
|
-
|
|
29519
|
-
|
|
29520
|
-
|
|
29521
|
-
signaturePacket.preferredSymmetricAlgorithms = createPreferredAlgos([
|
|
30089
|
+
|
|
30090
|
+
const signatureProperties = {};
|
|
30091
|
+
signatureProperties.signatureType = enums.signature.certGeneric;
|
|
30092
|
+
signatureProperties.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData];
|
|
30093
|
+
signatureProperties.preferredSymmetricAlgorithms = createPreferredAlgos([
|
|
29522
30094
|
// prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support)
|
|
29523
30095
|
enums.symmetric.aes256,
|
|
29524
30096
|
enums.symmetric.aes128,
|
|
29525
30097
|
enums.symmetric.aes192
|
|
29526
30098
|
], config.preferredSymmetricAlgorithm);
|
|
29527
30099
|
if (config.aeadProtect) {
|
|
29528
|
-
|
|
30100
|
+
signatureProperties.preferredAEADAlgorithms = createPreferredAlgos([
|
|
29529
30101
|
enums.aead.eax,
|
|
29530
30102
|
enums.aead.ocb
|
|
29531
30103
|
], config.preferredAEADAlgorithm);
|
|
29532
30104
|
}
|
|
29533
|
-
|
|
30105
|
+
signatureProperties.preferredHashAlgorithms = createPreferredAlgos([
|
|
29534
30106
|
// prefer fast asm.js implementations (SHA-256)
|
|
29535
30107
|
enums.hash.sha256,
|
|
29536
30108
|
enums.hash.sha512
|
|
29537
30109
|
], config.preferredHashAlgorithm);
|
|
29538
|
-
|
|
30110
|
+
signatureProperties.preferredCompressionAlgorithms = createPreferredAlgos([
|
|
29539
30111
|
enums.compression.zlib,
|
|
29540
30112
|
enums.compression.zip,
|
|
29541
30113
|
enums.compression.uncompressed
|
|
29542
30114
|
], config.preferredCompressionAlgorithm);
|
|
29543
30115
|
if (index === 0) {
|
|
29544
|
-
|
|
30116
|
+
signatureProperties.isPrimaryUserID = true;
|
|
29545
30117
|
}
|
|
29546
30118
|
// integrity protection always enabled
|
|
29547
|
-
|
|
29548
|
-
|
|
30119
|
+
signatureProperties.features = [0];
|
|
30120
|
+
signatureProperties.features[0] |= enums.features.modificationDetection;
|
|
29549
30121
|
if (config.aeadProtect) {
|
|
29550
|
-
|
|
30122
|
+
signatureProperties.features[0] |= enums.features.aead;
|
|
29551
30123
|
}
|
|
29552
30124
|
if (config.v5Keys) {
|
|
29553
|
-
|
|
30125
|
+
signatureProperties.features[0] |= enums.features.v5Keys;
|
|
29554
30126
|
}
|
|
29555
30127
|
if (options.keyExpirationTime > 0) {
|
|
29556
|
-
|
|
29557
|
-
|
|
30128
|
+
signatureProperties.keyExpirationTime = options.keyExpirationTime;
|
|
30129
|
+
signatureProperties.keyNeverExpires = false;
|
|
29558
30130
|
}
|
|
29559
|
-
|
|
30131
|
+
|
|
30132
|
+
const signaturePacket = await createSignaturePacket(dataToSign, null, secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config);
|
|
29560
30133
|
|
|
29561
30134
|
return { userIDPacket, signaturePacket };
|
|
29562
30135
|
})).then(list => {
|
|
@@ -30075,6 +30648,15 @@ class Message {
|
|
|
30075
30648
|
enums.read(enums.aead, await getPreferredAlgo('aead', encryptionKeys, date, userIDs, config$1)) :
|
|
30076
30649
|
undefined;
|
|
30077
30650
|
|
|
30651
|
+
await Promise.all(encryptionKeys.map(key => key.getEncryptionKey()
|
|
30652
|
+
.catch(() => null) // ignore key strength requirements
|
|
30653
|
+
.then(maybeKey => {
|
|
30654
|
+
if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519) && !util.isAES(algo)) {
|
|
30655
|
+
throw new Error('Could not generate a session key compatible with the given `encryptionKeys`: X22519 keys can only be used to encrypt AES session keys; change `config.preferredSymmetricAlgorithm` accordingly.');
|
|
30656
|
+
}
|
|
30657
|
+
})
|
|
30658
|
+
));
|
|
30659
|
+
|
|
30078
30660
|
const sessionKeyData = mod.generateSessionKey(algo);
|
|
30079
30661
|
return { data: sessionKeyData, algorithm: algorithmName, aeadAlgorithm: aeadAlgorithmName };
|
|
30080
30662
|
}
|
|
@@ -30249,7 +30831,7 @@ class Message {
|
|
|
30249
30831
|
const signingKey = await primaryKey.getSigningKey(signingKeyID, date, userIDs, config$1);
|
|
30250
30832
|
const onePassSig = new OnePassSignaturePacket();
|
|
30251
30833
|
onePassSig.signatureType = signatureType;
|
|
30252
|
-
onePassSig.hashAlgorithm = await getPreferredHashAlgo$
|
|
30834
|
+
onePassSig.hashAlgorithm = await getPreferredHashAlgo$2(primaryKey, signingKey.keyPacket, date, userIDs, config$1);
|
|
30253
30835
|
onePassSig.publicKeyAlgorithm = signingKey.keyPacket.algorithm;
|
|
30254
30836
|
onePassSig.issuerKeyID = signingKey.getKeyID();
|
|
30255
30837
|
if (i === signingKeys.length - 1) {
|
|
@@ -30382,7 +30964,7 @@ class Message {
|
|
|
30382
30964
|
if (literalDataList.length !== 1) {
|
|
30383
30965
|
throw new Error('Can only verify message with one literal data packet.');
|
|
30384
30966
|
}
|
|
30385
|
-
const signatureList = signature.packets;
|
|
30967
|
+
const signatureList = signature.packets.filterByTag(enums.packet.signature); // drop UnparsablePackets
|
|
30386
30968
|
return createVerificationObjects(signatureList, literalDataList, verificationKeys, date, true, config$1);
|
|
30387
30969
|
}
|
|
30388
30970
|
|
|
@@ -30729,7 +31311,7 @@ class CleartextMessage {
|
|
|
30729
31311
|
* @async
|
|
30730
31312
|
*/
|
|
30731
31313
|
verify(keys, date = new Date(), config$1 = config) {
|
|
30732
|
-
const signatureList = this.signature.packets;
|
|
31314
|
+
const signatureList = this.signature.packets.filterByTag(enums.packet.signature); // drop UnparsablePackets
|
|
30733
31315
|
const literalDataPacket = new LiteralDataPacket();
|
|
30734
31316
|
// we assume that cleartext signature is generated based on UTF8 cleartext
|
|
30735
31317
|
literalDataPacket.setText(this.text);
|
|
@@ -30814,7 +31396,7 @@ function verifyHeaders$1(headers, packetlist) {
|
|
|
30814
31396
|
let oneHeader = null;
|
|
30815
31397
|
let hashAlgos = [];
|
|
30816
31398
|
headers.forEach(function(header) {
|
|
30817
|
-
oneHeader = header.match(
|
|
31399
|
+
oneHeader = header.match(/^Hash: (.+)$/); // get header value
|
|
30818
31400
|
if (oneHeader) {
|
|
30819
31401
|
oneHeader = oneHeader[1].replace(/\s/g, ''); // remove whitespace
|
|
30820
31402
|
oneHeader = oneHeader.split(',');
|
|
@@ -30906,7 +31488,7 @@ async function generateKey({ userIDs = [], passphrase, type = 'ecc', rsaBits = 4
|
|
|
30906
31488
|
const options = { userIDs, passphrase, type, rsaBits, curve, keyExpirationTime, date, subkeys, symmetricHash, symmetricCipher };
|
|
30907
31489
|
|
|
30908
31490
|
try {
|
|
30909
|
-
const { key, revocationCertificate } = await generate$
|
|
31491
|
+
const { key, revocationCertificate } = await generate$4(options, config$1);
|
|
30910
31492
|
key.getKeys().forEach(({ keyPacket }) => checkKeyRequirements(keyPacket, config$1));
|
|
30911
31493
|
|
|
30912
31494
|
return {
|
|
@@ -31100,7 +31682,7 @@ async function encryptKey({ privateKey, passphrase, config: config$1, ...rest })
|
|
|
31100
31682
|
* @async
|
|
31101
31683
|
* @static
|
|
31102
31684
|
*/
|
|
31103
|
-
async function encrypt$
|
|
31685
|
+
async function encrypt$5({ message, encryptionKeys, signingKeys, passwords, sessionKey, format = 'armored', signature = null, wildcard = false, signingKeyIDs = [], encryptionKeyIDs = [], date = new Date(), signingUserIDs = [], encryptionUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
|
|
31104
31686
|
config$1 = { ...config, ...config$1 }; checkConfig(config$1);
|
|
31105
31687
|
checkMessage(message); checkOutputMessageFormat(format);
|
|
31106
31688
|
encryptionKeys = toArray$1(encryptionKeys); signingKeys = toArray$1(signingKeys); passwords = toArray$1(passwords);
|
|
@@ -31169,7 +31751,7 @@ async function encrypt$4({ message, encryptionKeys, signingKeys, passwords, sess
|
|
|
31169
31751
|
* @async
|
|
31170
31752
|
* @static
|
|
31171
31753
|
*/
|
|
31172
|
-
async function decrypt$
|
|
31754
|
+
async function decrypt$5({ message, decryptionKeys, passwords, sessionKeys, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
|
|
31173
31755
|
config$1 = { ...config, ...config$1 }; checkConfig(config$1);
|
|
31174
31756
|
checkMessage(message); verificationKeys = toArray$1(verificationKeys); decryptionKeys = toArray$1(decryptionKeys); passwords = toArray$1(passwords); sessionKeys = toArray$1(sessionKeys);
|
|
31175
31757
|
if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.decrypt, pass `decryptionKeys` instead');
|
|
@@ -31232,7 +31814,7 @@ async function decrypt$4({ message, decryptionKeys, passwords, sessionKeys, veri
|
|
|
31232
31814
|
* @async
|
|
31233
31815
|
* @static
|
|
31234
31816
|
*/
|
|
31235
|
-
async function sign$
|
|
31817
|
+
async function sign$6({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
|
|
31236
31818
|
config$1 = { ...config, ...config$1 }; checkConfig(config$1);
|
|
31237
31819
|
checkCleartextOrMessage(message); checkOutputMessageFormat(format);
|
|
31238
31820
|
signingKeys = toArray$1(signingKeys); signingKeyIDs = toArray$1(signingKeyIDs); signingUserIDs = toArray$1(signingUserIDs); signatureNotations = toArray$1(signatureNotations);
|
|
@@ -31301,7 +31883,7 @@ async function sign$5({ message, signingKeys, format = 'armored', detached = fal
|
|
|
31301
31883
|
* @async
|
|
31302
31884
|
* @static
|
|
31303
31885
|
*/
|
|
31304
|
-
async function verify$
|
|
31886
|
+
async function verify$6({ message, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
|
|
31305
31887
|
config$1 = { ...config, ...config$1 }; checkConfig(config$1);
|
|
31306
31888
|
checkCleartextOrMessage(message); verificationKeys = toArray$1(verificationKeys);
|
|
31307
31889
|
if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.verify, pass `verificationKeys` instead');
|
|
@@ -31567,4 +32149,4 @@ function formatObject(object, format, config) {
|
|
|
31567
32149
|
}
|
|
31568
32150
|
}
|
|
31569
32151
|
|
|
31570
|
-
export { AEADEncryptedDataPacket, CleartextMessage, CompressedDataPacket, KDFParams, LiteralDataPacket, MarkerPacket, Message, OnePassSignaturePacket, PacketList, PrivateKey, PublicKey, PublicKeyEncryptedSessionKeyPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, Signature, SignaturePacket, Subkey, SymEncryptedIntegrityProtectedDataPacket, SymEncryptedSessionKeyPacket, SymmetricallyEncryptedDataPacket, TrustPacket, UnparseablePacket, UserAttributePacket, UserIDPacket, _224 as _, commonjsGlobal as a, armor, common$1 as b, createCommonjsModule as c, config, createCleartextMessage, createMessage, common as d, decrypt$
|
|
32152
|
+
export { AEADEncryptedDataPacket, CleartextMessage, CompressedDataPacket, KDFParams, LiteralDataPacket, MarkerPacket, Message, OnePassSignaturePacket, PacketList, PrivateKey, PublicKey, PublicKeyEncryptedSessionKeyPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, Signature, SignaturePacket, Subkey, SymEncryptedIntegrityProtectedDataPacket, SymEncryptedSessionKeyPacket, SymmetricallyEncryptedDataPacket, TrustPacket, UnparseablePacket, UserAttributePacket, UserIDPacket, _224 as _, commonjsGlobal as a, armor, common$1 as b, createCommonjsModule as c, config, createCleartextMessage, createMessage, common as d, decrypt$5 as decrypt, decryptKey, decryptSessionKeys, _256 as e, encrypt$5 as encrypt, encryptKey, encryptSessionKey, enums, _384 as f, _512 as g, generateKey, generateSessionKey$1 as generateSessionKey, inherits_browser as i, minimalisticAssert as m, ripemd as r, readCleartextMessage, readKey, readKeys, readMessage, readPrivateKey, readPrivateKeys, readSignature, reformatKey, revokeKey, sign$6 as sign, utils as u, unarmor, verify$6 as verify };
|