@protontech/openpgp 5.9.1-1 → 5.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +1734 -1208
- 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 +1210 -684
- 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 +1207 -681
- package/dist/openpgp.js +1210 -684
- 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 +1207 -681
- package/openpgp.d.ts +1 -0
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! OpenPGP.js v5.
|
|
1
|
+
/*! OpenPGP.js v5.10.2 - 2023-09-18 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
|
|
2
2
|
const globalThis = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
3
3
|
|
|
4
4
|
const doneWritingPromise = Symbol('doneWritingPromise');
|
|
@@ -1507,1211 +1507,1226 @@ async function getBigInteger() {
|
|
|
1507
1507
|
}
|
|
1508
1508
|
}
|
|
1509
1509
|
|
|
1510
|
-
|
|
1510
|
+
/**
|
|
1511
|
+
* @module enums
|
|
1512
|
+
*/
|
|
1511
1513
|
|
|
1512
|
-
const
|
|
1513
|
-
try {
|
|
1514
|
-
return process.env.NODE_ENV === 'development'; // eslint-disable-line no-process-env
|
|
1515
|
-
} catch (e) {}
|
|
1516
|
-
return false;
|
|
1517
|
-
})();
|
|
1514
|
+
const byValue = Symbol('byValue');
|
|
1518
1515
|
|
|
1519
|
-
|
|
1520
|
-
isString: function(data) {
|
|
1521
|
-
return typeof data === 'string' || data instanceof String;
|
|
1522
|
-
},
|
|
1516
|
+
var enums = {
|
|
1523
1517
|
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1518
|
+
/** Maps curve names under various standards to one
|
|
1519
|
+
* @see {@link https://wiki.gnupg.org/ECC|ECC - GnuPG wiki}
|
|
1520
|
+
* @enum {String}
|
|
1521
|
+
* @readonly
|
|
1522
|
+
*/
|
|
1523
|
+
curve: {
|
|
1524
|
+
/** NIST P-256 Curve */
|
|
1525
|
+
'p256': 'p256',
|
|
1526
|
+
'P-256': 'p256',
|
|
1527
|
+
'secp256r1': 'p256',
|
|
1528
|
+
'prime256v1': 'p256',
|
|
1529
|
+
'1.2.840.10045.3.1.7': 'p256',
|
|
1530
|
+
'2a8648ce3d030107': 'p256',
|
|
1531
|
+
'2A8648CE3D030107': 'p256',
|
|
1527
1532
|
|
|
1528
|
-
|
|
1533
|
+
/** NIST P-384 Curve */
|
|
1534
|
+
'p384': 'p384',
|
|
1535
|
+
'P-384': 'p384',
|
|
1536
|
+
'secp384r1': 'p384',
|
|
1537
|
+
'1.3.132.0.34': 'p384',
|
|
1538
|
+
'2b81040022': 'p384',
|
|
1539
|
+
'2B81040022': 'p384',
|
|
1529
1540
|
|
|
1530
|
-
|
|
1541
|
+
/** NIST P-521 Curve */
|
|
1542
|
+
'p521': 'p521',
|
|
1543
|
+
'P-521': 'p521',
|
|
1544
|
+
'secp521r1': 'p521',
|
|
1545
|
+
'1.3.132.0.35': 'p521',
|
|
1546
|
+
'2b81040023': 'p521',
|
|
1547
|
+
'2B81040023': 'p521',
|
|
1531
1548
|
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
return n;
|
|
1538
|
-
},
|
|
1549
|
+
/** SECG SECP256k1 Curve */
|
|
1550
|
+
'secp256k1': 'secp256k1',
|
|
1551
|
+
'1.3.132.0.10': 'secp256k1',
|
|
1552
|
+
'2b8104000a': 'secp256k1',
|
|
1553
|
+
'2B8104000A': 'secp256k1',
|
|
1539
1554
|
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1555
|
+
/** Ed25519 */
|
|
1556
|
+
'ED25519': 'ed25519',
|
|
1557
|
+
'ed25519': 'ed25519',
|
|
1558
|
+
'Ed25519': 'ed25519',
|
|
1559
|
+
'1.3.6.1.4.1.11591.15.1': 'ed25519',
|
|
1560
|
+
'2b06010401da470f01': 'ed25519',
|
|
1561
|
+
'2B06010401DA470F01': 'ed25519',
|
|
1545
1562
|
|
|
1546
|
-
|
|
1547
|
-
|
|
1563
|
+
/** Curve25519 */
|
|
1564
|
+
'X25519': 'curve25519',
|
|
1565
|
+
'cv25519': 'curve25519',
|
|
1566
|
+
'curve25519': 'curve25519',
|
|
1567
|
+
'Curve25519': 'curve25519',
|
|
1568
|
+
'1.3.6.1.4.1.3029.1.5.1': 'curve25519',
|
|
1569
|
+
'2b060104019755010501': 'curve25519',
|
|
1570
|
+
'2B060104019755010501': 'curve25519',
|
|
1548
1571
|
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1572
|
+
/** BrainpoolP256r1 Curve */
|
|
1573
|
+
'brainpoolP256r1': 'brainpoolP256r1',
|
|
1574
|
+
'1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1',
|
|
1575
|
+
'2b2403030208010107': 'brainpoolP256r1',
|
|
1576
|
+
'2B2403030208010107': 'brainpoolP256r1',
|
|
1554
1577
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1578
|
+
/** BrainpoolP384r1 Curve */
|
|
1579
|
+
'brainpoolP384r1': 'brainpoolP384r1',
|
|
1580
|
+
'1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1',
|
|
1581
|
+
'2b240303020801010b': 'brainpoolP384r1',
|
|
1582
|
+
'2B240303020801010B': 'brainpoolP384r1',
|
|
1557
1583
|
|
|
1558
|
-
|
|
1584
|
+
/** BrainpoolP512r1 Curve */
|
|
1585
|
+
'brainpoolP512r1': 'brainpoolP512r1',
|
|
1586
|
+
'1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1',
|
|
1587
|
+
'2b240303020801010d': 'brainpoolP512r1',
|
|
1588
|
+
'2B240303020801010D': 'brainpoolP512r1'
|
|
1559
1589
|
},
|
|
1560
1590
|
|
|
1561
|
-
|
|
1562
|
-
|
|
1591
|
+
/** KDF parameters flags
|
|
1592
|
+
* Non-standard extensions (for now) to allow email forwarding
|
|
1593
|
+
* @enum {Integer}
|
|
1594
|
+
* @readonly
|
|
1595
|
+
*/
|
|
1596
|
+
kdfFlags: {
|
|
1597
|
+
/** Specify fingerprint to use instead of the recipient's */
|
|
1598
|
+
replace_fingerprint: 0x01,
|
|
1599
|
+
/** Specify custom parameters to use in the KDF digest computation */
|
|
1600
|
+
replace_kdf_params: 0x02
|
|
1563
1601
|
},
|
|
1564
1602
|
|
|
1565
|
-
/**
|
|
1566
|
-
*
|
|
1567
|
-
* @
|
|
1568
|
-
* @returns {Uint8Array} Parsed MPI.
|
|
1603
|
+
/** A string to key specifier type
|
|
1604
|
+
* @enum {Integer}
|
|
1605
|
+
* @readonly
|
|
1569
1606
|
*/
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1607
|
+
s2k: {
|
|
1608
|
+
simple: 0,
|
|
1609
|
+
salted: 1,
|
|
1610
|
+
iterated: 3,
|
|
1611
|
+
argon2: 4,
|
|
1612
|
+
gnu: 101
|
|
1574
1613
|
},
|
|
1575
1614
|
|
|
1576
|
-
/**
|
|
1577
|
-
*
|
|
1578
|
-
* @
|
|
1579
|
-
* @param {Number} length - Padded length
|
|
1580
|
-
* @returns {Uint8Array} Padded bytes.
|
|
1615
|
+
/** {@link https://tools.ietf.org/html/draft-ietf-openpgp-crypto-refresh-08.html#section-9.1|crypto-refresh RFC, section 9.1}
|
|
1616
|
+
* @enum {Integer}
|
|
1617
|
+
* @readonly
|
|
1581
1618
|
*/
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1619
|
+
publicKey: {
|
|
1620
|
+
/** RSA (Encrypt or Sign) [HAC] */
|
|
1621
|
+
rsaEncryptSign: 1,
|
|
1622
|
+
/** RSA (Encrypt only) [HAC] */
|
|
1623
|
+
rsaEncrypt: 2,
|
|
1624
|
+
/** RSA (Sign only) [HAC] */
|
|
1625
|
+
rsaSign: 3,
|
|
1626
|
+
/** Elgamal (Encrypt only) [ELGAMAL] [HAC] */
|
|
1627
|
+
elgamal: 16,
|
|
1628
|
+
/** DSA (Sign only) [FIPS186] [HAC] */
|
|
1629
|
+
dsa: 17,
|
|
1630
|
+
/** ECDH (Encrypt only) [RFC6637] */
|
|
1631
|
+
ecdh: 18,
|
|
1632
|
+
/** ECDSA (Sign only) [RFC6637] */
|
|
1633
|
+
ecdsa: 19,
|
|
1634
|
+
/** EdDSA (Sign only) - deprecated by crypto-refresh (replaced by `ed25519` identifier below)
|
|
1635
|
+
* [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */
|
|
1636
|
+
ed25519Legacy: 22, // NB: this is declared before `eddsa` to translate 22 to 'eddsa' for backwards compatibility
|
|
1637
|
+
eddsa: 22, // to be deprecated in v6
|
|
1638
|
+
/** Reserved for AEDH */
|
|
1639
|
+
aedh: 23,
|
|
1640
|
+
/** Reserved for AEDSA */
|
|
1641
|
+
aedsa: 24,
|
|
1642
|
+
/** X25519 (Encrypt only) */
|
|
1643
|
+
x25519: 25,
|
|
1644
|
+
/** X448 (Encrypt only) */
|
|
1645
|
+
x448: 26,
|
|
1646
|
+
/** Ed25519 (Sign only) */
|
|
1647
|
+
ed25519: 27,
|
|
1648
|
+
/** Ed448 (Sign only) */
|
|
1649
|
+
ed448: 28,
|
|
1650
|
+
/** Symmetric authenticated encryption algorithms */
|
|
1651
|
+
aead: 100,
|
|
1652
|
+
/** Authentication using CMAC */
|
|
1653
|
+
hmac: 101
|
|
1587
1654
|
},
|
|
1588
1655
|
|
|
1589
|
-
/**
|
|
1590
|
-
*
|
|
1591
|
-
* @
|
|
1592
|
-
* @returns {Uint8Array} MPI-formatted Uint8Array.
|
|
1656
|
+
/** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
|
|
1657
|
+
* @enum {Integer}
|
|
1658
|
+
* @readonly
|
|
1593
1659
|
*/
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1660
|
+
symmetric: {
|
|
1661
|
+
plaintext: 0,
|
|
1662
|
+
/** Not implemented! */
|
|
1663
|
+
idea: 1,
|
|
1664
|
+
tripledes: 2,
|
|
1665
|
+
cast5: 3,
|
|
1666
|
+
blowfish: 4,
|
|
1667
|
+
aes128: 7,
|
|
1668
|
+
aes192: 8,
|
|
1669
|
+
aes256: 9,
|
|
1670
|
+
twofish: 10
|
|
1602
1671
|
},
|
|
1603
1672
|
|
|
1604
|
-
/**
|
|
1605
|
-
*
|
|
1606
|
-
* @
|
|
1607
|
-
* @returns bit length
|
|
1673
|
+
/** {@link https://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
|
|
1674
|
+
* @enum {Integer}
|
|
1675
|
+
* @readonly
|
|
1608
1676
|
*/
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
return (stripped.length - 1) * 8 + util.nbits(stripped[0]);
|
|
1677
|
+
compression: {
|
|
1678
|
+
uncompressed: 0,
|
|
1679
|
+
/** RFC1951 */
|
|
1680
|
+
zip: 1,
|
|
1681
|
+
/** RFC1950 */
|
|
1682
|
+
zlib: 2,
|
|
1683
|
+
bzip2: 3
|
|
1617
1684
|
},
|
|
1618
1685
|
|
|
1619
|
-
/**
|
|
1620
|
-
*
|
|
1621
|
-
* @
|
|
1622
|
-
* @returns {Uint8Array} An array of 8-bit integers.
|
|
1686
|
+
/** {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
|
|
1687
|
+
* @enum {Integer}
|
|
1688
|
+
* @readonly
|
|
1623
1689
|
*/
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1690
|
+
hash: {
|
|
1691
|
+
md5: 1,
|
|
1692
|
+
sha1: 2,
|
|
1693
|
+
ripemd: 3,
|
|
1694
|
+
sha256: 8,
|
|
1695
|
+
sha384: 9,
|
|
1696
|
+
sha512: 10,
|
|
1697
|
+
sha224: 11
|
|
1630
1698
|
},
|
|
1631
1699
|
|
|
1632
|
-
/**
|
|
1633
|
-
*
|
|
1634
|
-
* @
|
|
1635
|
-
* @returns {String} Hexadecimal representation of the array.
|
|
1700
|
+
/** A list of hash names as accepted by webCrypto functions.
|
|
1701
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest|Parameters, algo}
|
|
1702
|
+
* @enum {String}
|
|
1636
1703
|
*/
|
|
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
|
-
});
|
|
1704
|
+
webHash: {
|
|
1705
|
+
'SHA-1': 2,
|
|
1706
|
+
'SHA-256': 8,
|
|
1707
|
+
'SHA-384': 9,
|
|
1708
|
+
'SHA-512': 10
|
|
1669
1709
|
},
|
|
1670
1710
|
|
|
1671
|
-
/**
|
|
1672
|
-
*
|
|
1673
|
-
* @
|
|
1674
|
-
* @returns {String} String representation of the array.
|
|
1711
|
+
/** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.6|RFC4880bis-04, section 9.6}
|
|
1712
|
+
* @enum {Integer}
|
|
1713
|
+
* @readonly
|
|
1675
1714
|
*/
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
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('');
|
|
1715
|
+
aead: {
|
|
1716
|
+
eax: 1,
|
|
1717
|
+
ocb: 2,
|
|
1718
|
+
experimentalGCM: 100 // Private algorithm
|
|
1686
1719
|
},
|
|
1687
1720
|
|
|
1688
|
-
/**
|
|
1689
|
-
*
|
|
1690
|
-
* @
|
|
1691
|
-
* @returns {Uint8Array|ReadableStream} A valid squence of utf8 bytes.
|
|
1721
|
+
/** A list of packet types and numeric tags associated with them.
|
|
1722
|
+
* @enum {Integer}
|
|
1723
|
+
* @readonly
|
|
1692
1724
|
*/
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1725
|
+
packet: {
|
|
1726
|
+
publicKeyEncryptedSessionKey: 1,
|
|
1727
|
+
signature: 2,
|
|
1728
|
+
symEncryptedSessionKey: 3,
|
|
1729
|
+
onePassSignature: 4,
|
|
1730
|
+
secretKey: 5,
|
|
1731
|
+
publicKey: 6,
|
|
1732
|
+
secretSubkey: 7,
|
|
1733
|
+
compressedData: 8,
|
|
1734
|
+
symmetricallyEncryptedData: 9,
|
|
1735
|
+
marker: 10,
|
|
1736
|
+
literalData: 11,
|
|
1737
|
+
trust: 12,
|
|
1738
|
+
userID: 13,
|
|
1739
|
+
publicSubkey: 14,
|
|
1740
|
+
userAttribute: 17,
|
|
1741
|
+
symEncryptedIntegrityProtectedData: 18,
|
|
1742
|
+
modificationDetectionCode: 19,
|
|
1743
|
+
aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
|
|
1700
1744
|
},
|
|
1701
1745
|
|
|
1702
|
-
/**
|
|
1703
|
-
*
|
|
1704
|
-
* @
|
|
1705
|
-
* @returns {String|ReadableStream} A native javascript string.
|
|
1746
|
+
/** Data types in the literal packet
|
|
1747
|
+
* @enum {Integer}
|
|
1748
|
+
* @readonly
|
|
1706
1749
|
*/
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1750
|
+
literal: {
|
|
1751
|
+
/** Binary data 'b' */
|
|
1752
|
+
binary: 'b'.charCodeAt(),
|
|
1753
|
+
/** Text data 't' */
|
|
1754
|
+
text: 't'.charCodeAt(),
|
|
1755
|
+
/** Utf8 data 'u' */
|
|
1756
|
+
utf8: 'u'.charCodeAt(),
|
|
1757
|
+
/** MIME message body part 'm' */
|
|
1758
|
+
mime: 'm'.charCodeAt()
|
|
1714
1759
|
},
|
|
1715
1760
|
|
|
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
1761
|
|
|
1724
|
-
/**
|
|
1725
|
-
*
|
|
1726
|
-
* @
|
|
1727
|
-
* @returns {Uint8Array} Concatenated array.
|
|
1762
|
+
/** One pass signature packet type
|
|
1763
|
+
* @enum {Integer}
|
|
1764
|
+
* @readonly
|
|
1728
1765
|
*/
|
|
1729
|
-
|
|
1766
|
+
signature: {
|
|
1767
|
+
/** 0x00: Signature of a binary document. */
|
|
1768
|
+
binary: 0,
|
|
1769
|
+
/** 0x01: Signature of a canonical text document.
|
|
1770
|
+
*
|
|
1771
|
+
* Canonicalyzing the document by converting line endings. */
|
|
1772
|
+
text: 1,
|
|
1773
|
+
/** 0x02: Standalone signature.
|
|
1774
|
+
*
|
|
1775
|
+
* This signature is a signature of only its own subpacket contents.
|
|
1776
|
+
* It is calculated identically to a signature over a zero-lengh
|
|
1777
|
+
* binary document. Note that it doesn't make sense to have a V3
|
|
1778
|
+
* standalone signature. */
|
|
1779
|
+
standalone: 2,
|
|
1780
|
+
/** 0x10: Generic certification of a User ID and Public-Key packet.
|
|
1781
|
+
*
|
|
1782
|
+
* The issuer of this certification does not make any particular
|
|
1783
|
+
* assertion as to how well the certifier has checked that the owner
|
|
1784
|
+
* of the key is in fact the person described by the User ID. */
|
|
1785
|
+
certGeneric: 16,
|
|
1786
|
+
/** 0x11: Persona certification of a User ID and Public-Key packet.
|
|
1787
|
+
*
|
|
1788
|
+
* The issuer of this certification has not done any verification of
|
|
1789
|
+
* the claim that the owner of this key is the User ID specified. */
|
|
1790
|
+
certPersona: 17,
|
|
1791
|
+
/** 0x12: Casual certification of a User ID and Public-Key packet.
|
|
1792
|
+
*
|
|
1793
|
+
* The issuer of this certification has done some casual
|
|
1794
|
+
* verification of the claim of identity. */
|
|
1795
|
+
certCasual: 18,
|
|
1796
|
+
/** 0x13: Positive certification of a User ID and Public-Key packet.
|
|
1797
|
+
*
|
|
1798
|
+
* The issuer of this certification has done substantial
|
|
1799
|
+
* verification of the claim of identity.
|
|
1800
|
+
*
|
|
1801
|
+
* Most OpenPGP implementations make their "key signatures" as 0x10
|
|
1802
|
+
* certifications. Some implementations can issue 0x11-0x13
|
|
1803
|
+
* certifications, but few differentiate between the types. */
|
|
1804
|
+
certPositive: 19,
|
|
1805
|
+
/** 0x30: Certification revocation signature
|
|
1806
|
+
*
|
|
1807
|
+
* This signature revokes an earlier User ID certification signature
|
|
1808
|
+
* (signature class 0x10 through 0x13) or direct-key signature
|
|
1809
|
+
* (0x1F). It should be issued by the same key that issued the
|
|
1810
|
+
* revoked signature or an authorized revocation key. The signature
|
|
1811
|
+
* is computed over the same data as the certificate that it
|
|
1812
|
+
* revokes, and should have a later creation date than that
|
|
1813
|
+
* certificate. */
|
|
1814
|
+
certRevocation: 48,
|
|
1815
|
+
/** 0x18: Subkey Binding Signature
|
|
1816
|
+
*
|
|
1817
|
+
* This signature is a statement by the top-level signing key that
|
|
1818
|
+
* indicates that it owns the subkey. This signature is calculated
|
|
1819
|
+
* directly on the primary key and subkey, and not on any User ID or
|
|
1820
|
+
* other packets. A signature that binds a signing subkey MUST have
|
|
1821
|
+
* an Embedded Signature subpacket in this binding signature that
|
|
1822
|
+
* contains a 0x19 signature made by the signing subkey on the
|
|
1823
|
+
* primary key and subkey. */
|
|
1824
|
+
subkeyBinding: 24,
|
|
1825
|
+
/** 0x19: Primary Key Binding Signature
|
|
1826
|
+
*
|
|
1827
|
+
* This signature is a statement by a signing subkey, indicating
|
|
1828
|
+
* that it is owned by the primary key and subkey. This signature
|
|
1829
|
+
* is calculated the same way as a 0x18 signature: directly on the
|
|
1830
|
+
* primary key and subkey, and not on any User ID or other packets.
|
|
1831
|
+
*
|
|
1832
|
+
* When a signature is made over a key, the hash data starts with the
|
|
1833
|
+
* octet 0x99, followed by a two-octet length of the key, and then body
|
|
1834
|
+
* of the key packet. (Note that this is an old-style packet header for
|
|
1835
|
+
* a key packet with two-octet length.) A subkey binding signature
|
|
1836
|
+
* (type 0x18) or primary key binding signature (type 0x19) then hashes
|
|
1837
|
+
* the subkey using the same format as the main key (also using 0x99 as
|
|
1838
|
+
* the first octet). */
|
|
1839
|
+
keyBinding: 25,
|
|
1840
|
+
/** 0x1F: Signature directly on a key
|
|
1841
|
+
*
|
|
1842
|
+
* This signature is calculated directly on a key. It binds the
|
|
1843
|
+
* information in the Signature subpackets to the key, and is
|
|
1844
|
+
* appropriate to be used for subpackets that provide information
|
|
1845
|
+
* about the key, such as the Revocation Key subpacket. It is also
|
|
1846
|
+
* appropriate for statements that non-self certifiers want to make
|
|
1847
|
+
* about the key itself, rather than the binding between a key and a
|
|
1848
|
+
* name. */
|
|
1849
|
+
key: 31,
|
|
1850
|
+
/** 0x20: Key revocation signature
|
|
1851
|
+
*
|
|
1852
|
+
* The signature is calculated directly on the key being revoked. A
|
|
1853
|
+
* revoked key is not to be used. Only revocation signatures by the
|
|
1854
|
+
* key being revoked, or by an authorized revocation key, should be
|
|
1855
|
+
* considered valid revocation signatures.a */
|
|
1856
|
+
keyRevocation: 32,
|
|
1857
|
+
/** 0x28: Subkey revocation signature
|
|
1858
|
+
*
|
|
1859
|
+
* The signature is calculated directly on the subkey being revoked.
|
|
1860
|
+
* A revoked subkey is not to be used. Only revocation signatures
|
|
1861
|
+
* by the top-level signature key that is bound to this subkey, or
|
|
1862
|
+
* by an authorized revocation key, should be considered valid
|
|
1863
|
+
* revocation signatures.
|
|
1864
|
+
*
|
|
1865
|
+
* Key revocation signatures (types 0x20 and 0x28)
|
|
1866
|
+
* hash only the key being revoked. */
|
|
1867
|
+
subkeyRevocation: 40,
|
|
1868
|
+
/** 0x40: Timestamp signature.
|
|
1869
|
+
* This signature is only meaningful for the timestamp contained in
|
|
1870
|
+
* it. */
|
|
1871
|
+
timestamp: 64,
|
|
1872
|
+
/** 0x50: Third-Party Confirmation signature.
|
|
1873
|
+
*
|
|
1874
|
+
* This signature is a signature over some other OpenPGP Signature
|
|
1875
|
+
* packet(s). It is analogous to a notary seal on the signed data.
|
|
1876
|
+
* A third-party signature SHOULD include Signature Target
|
|
1877
|
+
* subpacket(s) to give easy identification. Note that we really do
|
|
1878
|
+
* mean SHOULD. There are plausible uses for this (such as a blind
|
|
1879
|
+
* party that only sees the signature, not the key or source
|
|
1880
|
+
* document) that cannot include a target subpacket. */
|
|
1881
|
+
thirdParty: 80
|
|
1882
|
+
},
|
|
1730
1883
|
|
|
1731
|
-
/**
|
|
1732
|
-
*
|
|
1733
|
-
* @
|
|
1734
|
-
* @param {Uint8Array} array2 - Second array
|
|
1735
|
-
* @returns {Boolean} Equality.
|
|
1884
|
+
/** Signature subpacket type
|
|
1885
|
+
* @enum {Integer}
|
|
1886
|
+
* @readonly
|
|
1736
1887
|
*/
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1888
|
+
signatureSubpacket: {
|
|
1889
|
+
signatureCreationTime: 2,
|
|
1890
|
+
signatureExpirationTime: 3,
|
|
1891
|
+
exportableCertification: 4,
|
|
1892
|
+
trustSignature: 5,
|
|
1893
|
+
regularExpression: 6,
|
|
1894
|
+
revocable: 7,
|
|
1895
|
+
keyExpirationTime: 9,
|
|
1896
|
+
placeholderBackwardsCompatibility: 10,
|
|
1897
|
+
preferredSymmetricAlgorithms: 11,
|
|
1898
|
+
revocationKey: 12,
|
|
1899
|
+
issuer: 16,
|
|
1900
|
+
notationData: 20,
|
|
1901
|
+
preferredHashAlgorithms: 21,
|
|
1902
|
+
preferredCompressionAlgorithms: 22,
|
|
1903
|
+
keyServerPreferences: 23,
|
|
1904
|
+
preferredKeyServer: 24,
|
|
1905
|
+
primaryUserID: 25,
|
|
1906
|
+
policyURI: 26,
|
|
1907
|
+
keyFlags: 27,
|
|
1908
|
+
signersUserID: 28,
|
|
1909
|
+
reasonForRevocation: 29,
|
|
1910
|
+
features: 30,
|
|
1911
|
+
signatureTarget: 31,
|
|
1912
|
+
embeddedSignature: 32,
|
|
1913
|
+
issuerFingerprint: 33,
|
|
1914
|
+
preferredAEADAlgorithms: 34
|
|
1752
1915
|
},
|
|
1753
1916
|
|
|
1754
|
-
/**
|
|
1755
|
-
*
|
|
1756
|
-
*
|
|
1757
|
-
* @param {Uint8Array} Uint8Array - To create a sum of
|
|
1758
|
-
* @returns {Uint8Array} 2 bytes containing the sum of all charcodes % 65535.
|
|
1917
|
+
/** Key flags
|
|
1918
|
+
* @enum {Integer}
|
|
1919
|
+
* @readonly
|
|
1759
1920
|
*/
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1921
|
+
keyFlags: {
|
|
1922
|
+
/** 0x01 - This key may be used to certify other keys. */
|
|
1923
|
+
certifyKeys: 1,
|
|
1924
|
+
/** 0x02 - This key may be used to sign data. */
|
|
1925
|
+
signData: 2,
|
|
1926
|
+
/** 0x04 - This key may be used to encrypt communications. */
|
|
1927
|
+
encryptCommunication: 4,
|
|
1928
|
+
/** 0x08 - This key may be used to encrypt storage. */
|
|
1929
|
+
encryptStorage: 8,
|
|
1930
|
+
/** 0x10 - The private component of this key may have been split
|
|
1931
|
+
* by a secret-sharing mechanism. */
|
|
1932
|
+
splitPrivateKey: 16,
|
|
1933
|
+
/** 0x20 - This key may be used for authentication. */
|
|
1934
|
+
authentication: 32,
|
|
1935
|
+
/** This key may be used for forwarded communications */
|
|
1936
|
+
forwardedCommunication: 64,
|
|
1937
|
+
/** 0x80 - The private component of this key may be in the
|
|
1938
|
+
* possession of more than one person. */
|
|
1939
|
+
sharedPrivateKey: 128
|
|
1766
1940
|
},
|
|
1767
1941
|
|
|
1768
|
-
/**
|
|
1769
|
-
*
|
|
1770
|
-
*
|
|
1771
|
-
* @param {String} str - String of the debug message
|
|
1942
|
+
/** Armor type
|
|
1943
|
+
* @enum {Integer}
|
|
1944
|
+
* @readonly
|
|
1772
1945
|
*/
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1946
|
+
armor: {
|
|
1947
|
+
multipartSection: 0,
|
|
1948
|
+
multipartLast: 1,
|
|
1949
|
+
signed: 2,
|
|
1950
|
+
message: 3,
|
|
1951
|
+
publicKey: 4,
|
|
1952
|
+
privateKey: 5,
|
|
1953
|
+
signature: 6
|
|
1777
1954
|
},
|
|
1778
1955
|
|
|
1779
|
-
/**
|
|
1780
|
-
*
|
|
1781
|
-
*
|
|
1782
|
-
* @param {String} str - String of the debug message
|
|
1956
|
+
/** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
|
|
1957
|
+
* @enum {Integer}
|
|
1958
|
+
* @readonly
|
|
1783
1959
|
*/
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1960
|
+
reasonForRevocation: {
|
|
1961
|
+
/** No reason specified (key revocations or cert revocations) */
|
|
1962
|
+
noReason: 0,
|
|
1963
|
+
/** Key is superseded (key revocations) */
|
|
1964
|
+
keySuperseded: 1,
|
|
1965
|
+
/** Key material has been compromised (key revocations) */
|
|
1966
|
+
keyCompromised: 2,
|
|
1967
|
+
/** Key is retired and no longer used (key revocations) */
|
|
1968
|
+
keyRetired: 3,
|
|
1969
|
+
/** User ID information is no longer valid (cert revocations) */
|
|
1970
|
+
userIDInvalid: 32
|
|
1788
1971
|
},
|
|
1789
1972
|
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
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;
|
|
1973
|
+
/** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
|
|
1974
|
+
* @enum {Integer}
|
|
1975
|
+
* @readonly
|
|
1976
|
+
*/
|
|
1977
|
+
features: {
|
|
1978
|
+
/** 0x01 - Modification Detection (packets 18 and 19) */
|
|
1979
|
+
modificationDetection: 1,
|
|
1980
|
+
/** 0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
|
|
1981
|
+
* Symmetric-Key Encrypted Session Key Packets (packet 3) */
|
|
1982
|
+
aead: 2,
|
|
1983
|
+
/** 0x04 - Version 5 Public-Key Packet format and corresponding new
|
|
1984
|
+
* fingerprint format */
|
|
1985
|
+
v5Keys: 4
|
|
1819
1986
|
},
|
|
1820
1987
|
|
|
1821
1988
|
/**
|
|
1822
|
-
*
|
|
1823
|
-
*
|
|
1824
|
-
*
|
|
1825
|
-
*
|
|
1826
|
-
*
|
|
1827
|
-
*
|
|
1828
|
-
* @param {Uint8Array} data
|
|
1989
|
+
* Asserts validity of given value and converts from string/integer to integer.
|
|
1990
|
+
* @param {Object} type target enum type
|
|
1991
|
+
* @param {String|Integer} e value to check and/or convert
|
|
1992
|
+
* @returns {Integer} enum value if it exists
|
|
1993
|
+
* @throws {Error} if the value is invalid
|
|
1829
1994
|
*/
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
for (let i = 0; i < last; i++) {
|
|
1834
|
-
doubleVar[i] = (data[i] << 1) ^ (data[i + 1] >> 7);
|
|
1995
|
+
write: function(type, e) {
|
|
1996
|
+
if (typeof e === 'number') {
|
|
1997
|
+
e = this.read(type, e);
|
|
1835
1998
|
}
|
|
1836
|
-
doubleVar[last] = (data[last] << 1) ^ ((data[0] >> 7) * 0x87);
|
|
1837
|
-
return doubleVar;
|
|
1838
|
-
},
|
|
1839
1999
|
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
* @param {Uint8Array} array - The array to shift
|
|
1843
|
-
* @param {Integer} bits - Amount of bits to shift (MUST be smaller
|
|
1844
|
-
* than 8)
|
|
1845
|
-
* @returns {String} Resulting array.
|
|
1846
|
-
*/
|
|
1847
|
-
shiftRight: function (array, bits) {
|
|
1848
|
-
if (bits) {
|
|
1849
|
-
for (let i = array.length - 1; i >= 0; i--) {
|
|
1850
|
-
array[i] >>= bits;
|
|
1851
|
-
if (i > 0) {
|
|
1852
|
-
array[i] |= (array[i - 1] << (8 - bits));
|
|
1853
|
-
}
|
|
1854
|
-
}
|
|
2000
|
+
if (type[e] !== undefined) {
|
|
2001
|
+
return type[e];
|
|
1855
2002
|
}
|
|
1856
|
-
return array;
|
|
1857
|
-
},
|
|
1858
2003
|
|
|
1859
|
-
|
|
1860
|
-
* Get native Web Cryptography api, only the current version of the spec.
|
|
1861
|
-
* @returns {Object} The SubtleCrypto api or 'undefined'.
|
|
1862
|
-
*/
|
|
1863
|
-
getWebCrypto: function() {
|
|
1864
|
-
return typeof globalThis !== 'undefined' && globalThis.crypto && globalThis.crypto.subtle;
|
|
2004
|
+
throw new Error('Invalid enum value.');
|
|
1865
2005
|
},
|
|
1866
2006
|
|
|
1867
2007
|
/**
|
|
1868
|
-
*
|
|
1869
|
-
*
|
|
1870
|
-
*
|
|
1871
|
-
* @returns {
|
|
1872
|
-
* @
|
|
2008
|
+
* Converts enum integer value to the corresponding string, if it exists.
|
|
2009
|
+
* @param {Object} type target enum type
|
|
2010
|
+
* @param {Integer} e value to convert
|
|
2011
|
+
* @returns {String} name of enum value if it exists
|
|
2012
|
+
* @throws {Error} if the value is invalid
|
|
1873
2013
|
*/
|
|
1874
|
-
|
|
2014
|
+
read: function(type, e) {
|
|
2015
|
+
if (!type[byValue]) {
|
|
2016
|
+
type[byValue] = [];
|
|
2017
|
+
Object.entries(type).forEach(([key, value]) => {
|
|
2018
|
+
type[byValue][value] = key;
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
1875
2021
|
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
*/
|
|
1880
|
-
getNodeCrypto: function() {
|
|
1881
|
-
return void('crypto');
|
|
1882
|
-
},
|
|
2022
|
+
if (type[byValue][e] !== undefined) {
|
|
2023
|
+
return type[byValue][e];
|
|
2024
|
+
}
|
|
1883
2025
|
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
2026
|
+
throw new Error('Invalid enum value.');
|
|
2027
|
+
}
|
|
2028
|
+
};
|
|
1887
2029
|
|
|
1888
|
-
|
|
1889
|
-
* Get native Node.js Buffer constructor. This should be used since
|
|
1890
|
-
* Buffer is not available under browserify.
|
|
1891
|
-
* @returns {Function} The Buffer constructor or 'undefined'.
|
|
1892
|
-
*/
|
|
1893
|
-
getNodeBuffer: function() {
|
|
1894
|
-
return ({}).Buffer;
|
|
1895
|
-
},
|
|
2030
|
+
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
1896
2031
|
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
2032
|
+
const debugMode = (() => {
|
|
2033
|
+
try {
|
|
2034
|
+
return process.env.NODE_ENV === 'development'; // eslint-disable-line no-process-env
|
|
2035
|
+
} catch (e) {}
|
|
2036
|
+
return false;
|
|
2037
|
+
})();
|
|
1901
2038
|
|
|
1902
|
-
|
|
1903
|
-
|
|
2039
|
+
const util = {
|
|
2040
|
+
isString: function(data) {
|
|
2041
|
+
return typeof data === 'string' || data instanceof String;
|
|
1904
2042
|
},
|
|
1905
2043
|
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
return false;
|
|
1909
|
-
}
|
|
1910
|
-
const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+([a-zA-Z]{2,}[0-9]*|xn--[a-zA-Z\-0-9]+)))$/;
|
|
1911
|
-
return re.test(data);
|
|
2044
|
+
isArray: function(data) {
|
|
2045
|
+
return data instanceof Array;
|
|
1912
2046
|
},
|
|
1913
2047
|
|
|
1914
|
-
|
|
1915
|
-
* Normalize line endings to <CR><LF>
|
|
1916
|
-
* Support any encoding where CR=0x0D, LF=0x0A
|
|
1917
|
-
*/
|
|
1918
|
-
canonicalizeEOL: function(data) {
|
|
1919
|
-
const CR = 13;
|
|
1920
|
-
const LF = 10;
|
|
1921
|
-
let carryOverCR = false;
|
|
2048
|
+
isUint8Array: isUint8Array,
|
|
1922
2049
|
|
|
1923
|
-
|
|
1924
|
-
if (carryOverCR) {
|
|
1925
|
-
bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
|
|
1926
|
-
}
|
|
2050
|
+
isStream: isStream,
|
|
1927
2051
|
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
2052
|
+
readNumber: function (bytes) {
|
|
2053
|
+
let n = 0;
|
|
2054
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
2055
|
+
n += (256 ** i) * bytes[bytes.length - 1 - i];
|
|
2056
|
+
}
|
|
2057
|
+
return n;
|
|
2058
|
+
},
|
|
1934
2059
|
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
if (bytes[index - 2] !== CR) indices.push(index);
|
|
1941
|
-
} else {
|
|
1942
|
-
break;
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
if (!indices.length) {
|
|
1946
|
-
return bytes;
|
|
1947
|
-
}
|
|
2060
|
+
writeNumber: function (n, bytes) {
|
|
2061
|
+
const b = new Uint8Array(bytes);
|
|
2062
|
+
for (let i = 0; i < bytes; i++) {
|
|
2063
|
+
b[i] = (n >> (8 * (bytes - i - 1))) & 0xFF;
|
|
2064
|
+
}
|
|
1948
2065
|
|
|
1949
|
-
|
|
1950
|
-
let j = 0;
|
|
1951
|
-
for (let i = 0; i < indices.length; i++) {
|
|
1952
|
-
const sub = bytes.subarray(indices[i - 1] || 0, indices[i]);
|
|
1953
|
-
normalized.set(sub, j);
|
|
1954
|
-
j += sub.length;
|
|
1955
|
-
normalized[j - 1] = CR;
|
|
1956
|
-
normalized[j] = LF;
|
|
1957
|
-
j++;
|
|
1958
|
-
}
|
|
1959
|
-
normalized.set(bytes.subarray(indices[indices.length - 1] || 0), j);
|
|
1960
|
-
return normalized;
|
|
1961
|
-
}, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
|
|
2066
|
+
return b;
|
|
1962
2067
|
},
|
|
1963
2068
|
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
const CR = 13;
|
|
1970
|
-
const LF = 10;
|
|
1971
|
-
let carryOverCR = false;
|
|
2069
|
+
readDate: function (bytes) {
|
|
2070
|
+
const n = util.readNumber(bytes);
|
|
2071
|
+
const d = new Date(n * 1000);
|
|
2072
|
+
return d;
|
|
2073
|
+
},
|
|
1972
2074
|
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
|
|
1976
|
-
} else {
|
|
1977
|
-
bytes = new Uint8Array(bytes); // Don't mutate passed bytes
|
|
1978
|
-
}
|
|
2075
|
+
writeDate: function (time) {
|
|
2076
|
+
const numeric = Math.floor(time.getTime() / 1000);
|
|
1979
2077
|
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
bytes = bytes.subarray(0, -1);
|
|
1983
|
-
} else {
|
|
1984
|
-
carryOverCR = false;
|
|
1985
|
-
}
|
|
2078
|
+
return util.writeNumber(numeric, 4);
|
|
2079
|
+
},
|
|
1986
2080
|
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
for (let i = 0; i !== bytes.length; i = index) {
|
|
1990
|
-
index = bytes.indexOf(CR, i) + 1;
|
|
1991
|
-
if (!index) index = bytes.length;
|
|
1992
|
-
const last = index - (bytes[index] === LF ? 1 : 0);
|
|
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));
|
|
2081
|
+
normalizeDate: function (time = Date.now()) {
|
|
2082
|
+
return time === null || time === Infinity ? time : new Date(Math.floor(+time / 1000) * 1000);
|
|
1998
2083
|
},
|
|
1999
2084
|
|
|
2000
2085
|
/**
|
|
2001
|
-
*
|
|
2086
|
+
* Read one MPI from bytes in input
|
|
2087
|
+
* @param {Uint8Array} bytes - Input data to parse
|
|
2088
|
+
* @returns {Uint8Array} Parsed MPI.
|
|
2002
2089
|
*/
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
return line.substr(0, i + 1);
|
|
2008
|
-
}).join('\n');
|
|
2090
|
+
readMPI: function (bytes) {
|
|
2091
|
+
const bits = (bytes[0] << 8) | bytes[1];
|
|
2092
|
+
const bytelen = (bits + 7) >>> 3;
|
|
2093
|
+
return bytes.subarray(2, 2 + bytelen);
|
|
2009
2094
|
},
|
|
2010
2095
|
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2096
|
+
/**
|
|
2097
|
+
* Left-pad Uint8Array to length by adding 0x0 bytes
|
|
2098
|
+
* @param {Uint8Array} bytes - Data to pad
|
|
2099
|
+
* @param {Number} length - Padded length
|
|
2100
|
+
* @returns {Uint8Array} Padded bytes.
|
|
2101
|
+
*/
|
|
2102
|
+
leftPad(bytes, length) {
|
|
2103
|
+
const padded = new Uint8Array(length);
|
|
2104
|
+
const offset = length - bytes.length;
|
|
2105
|
+
padded.set(bytes, offset);
|
|
2106
|
+
return padded;
|
|
2107
|
+
},
|
|
2020
2108
|
|
|
2021
|
-
|
|
2109
|
+
/**
|
|
2110
|
+
* Convert a Uint8Array to an MPI-formatted Uint8Array.
|
|
2111
|
+
* @param {Uint8Array} bin - An array of 8-bit integers to convert
|
|
2112
|
+
* @returns {Uint8Array} MPI-formatted Uint8Array.
|
|
2113
|
+
*/
|
|
2114
|
+
uint8ArrayToMPI: function (bin) {
|
|
2115
|
+
const bitSize = util.uint8ArrayBitLength(bin);
|
|
2116
|
+
if (bitSize === 0) {
|
|
2117
|
+
throw new Error('Zero MPI');
|
|
2118
|
+
}
|
|
2119
|
+
const stripped = bin.subarray(bin.length - Math.ceil(bitSize / 8));
|
|
2120
|
+
const prefix = new Uint8Array([(bitSize & 0xFF00) >> 8, bitSize & 0xFF]);
|
|
2121
|
+
return util.concatUint8Array([prefix, stripped]);
|
|
2022
2122
|
},
|
|
2023
2123
|
|
|
2024
2124
|
/**
|
|
2025
|
-
*
|
|
2026
|
-
*
|
|
2027
|
-
* @
|
|
2028
|
-
* @returns {Object} map from enum.packet to corresponding *Packet class
|
|
2125
|
+
* Return bit length of the input data
|
|
2126
|
+
* @param {Uint8Array} bin input data (big endian)
|
|
2127
|
+
* @returns bit length
|
|
2029
2128
|
*/
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
return map;
|
|
2129
|
+
uint8ArrayBitLength: function (bin) {
|
|
2130
|
+
let i; // index of leading non-zero byte
|
|
2131
|
+
for (i = 0; i < bin.length; i++) if (bin[i] !== 0) break;
|
|
2132
|
+
if (i === bin.length) {
|
|
2133
|
+
return 0;
|
|
2134
|
+
}
|
|
2135
|
+
const stripped = bin.subarray(i);
|
|
2136
|
+
return (stripped.length - 1) * 8 + util.nbits(stripped[0]);
|
|
2039
2137
|
},
|
|
2040
2138
|
|
|
2041
2139
|
/**
|
|
2042
|
-
*
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
* @param {Array<Promise>} promises
|
|
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)
|
|
2140
|
+
* Convert a hex string to an array of 8-bit integers
|
|
2141
|
+
* @param {String} hex - A hex string to convert
|
|
2142
|
+
* @returns {Uint8Array} An array of 8-bit integers.
|
|
2048
2143
|
*/
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
resolve(await promise);
|
|
2056
|
-
} catch (e) {
|
|
2057
|
-
exception = e;
|
|
2058
|
-
}
|
|
2059
|
-
}));
|
|
2060
|
-
reject(exception);
|
|
2061
|
-
});
|
|
2144
|
+
hexToUint8Array: function (hex) {
|
|
2145
|
+
const result = new Uint8Array(hex.length >> 1);
|
|
2146
|
+
for (let k = 0; k < hex.length >> 1; k++) {
|
|
2147
|
+
result[k] = parseInt(hex.substr(k << 1, 2), 16);
|
|
2148
|
+
}
|
|
2149
|
+
return result;
|
|
2062
2150
|
},
|
|
2063
2151
|
|
|
2064
2152
|
/**
|
|
2065
|
-
*
|
|
2066
|
-
* @param {
|
|
2067
|
-
* @
|
|
2068
|
-
* @param {Uint8Array} b
|
|
2069
|
-
* @returns `a` if `cond` is true, `b` otherwise
|
|
2153
|
+
* Convert an array of 8-bit integers to a hex string
|
|
2154
|
+
* @param {Uint8Array} bytes - Array of 8-bit integers to convert
|
|
2155
|
+
* @returns {String} Hexadecimal representation of the array.
|
|
2070
2156
|
*/
|
|
2071
|
-
|
|
2072
|
-
const
|
|
2073
|
-
const
|
|
2074
|
-
let
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2157
|
+
uint8ArrayToHex: function (bytes) {
|
|
2158
|
+
const r = [];
|
|
2159
|
+
const e = bytes.length;
|
|
2160
|
+
let c = 0;
|
|
2161
|
+
let h;
|
|
2162
|
+
while (c < e) {
|
|
2163
|
+
h = bytes[c++].toString(16);
|
|
2164
|
+
while (h.length < 2) {
|
|
2165
|
+
h = '0' + h;
|
|
2166
|
+
}
|
|
2167
|
+
r.push('' + h);
|
|
2078
2168
|
}
|
|
2079
|
-
return
|
|
2169
|
+
return r.join('');
|
|
2080
2170
|
},
|
|
2171
|
+
|
|
2081
2172
|
/**
|
|
2082
|
-
*
|
|
2083
|
-
*
|
|
2084
|
-
* @
|
|
2085
|
-
* @param {Uint8} a
|
|
2086
|
-
* @param {Uint8} b
|
|
2087
|
-
* @returns `a` if `cond` is true, `b` otherwise
|
|
2173
|
+
* Convert a string to an array of 8-bit integers
|
|
2174
|
+
* @param {String} str - String to convert
|
|
2175
|
+
* @returns {Uint8Array} An array of 8-bit integers.
|
|
2088
2176
|
*/
|
|
2089
|
-
|
|
2090
|
-
return (
|
|
2091
|
-
|
|
2092
|
-
|
|
2177
|
+
stringToUint8Array: function (str) {
|
|
2178
|
+
return transform(str, str => {
|
|
2179
|
+
if (!util.isString(str)) {
|
|
2180
|
+
throw new Error('stringToUint8Array: Data must be in the form of a string');
|
|
2181
|
+
}
|
|
2093
2182
|
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
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();
|
|
2183
|
+
const result = new Uint8Array(str.length);
|
|
2184
|
+
for (let i = 0; i < str.length; i++) {
|
|
2185
|
+
result[i] = str.charCodeAt(i);
|
|
2186
|
+
}
|
|
2187
|
+
return result;
|
|
2188
|
+
});
|
|
2189
|
+
},
|
|
2108
2190
|
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
decodeChunk = str => util.stringToUint8Array(atob(str));
|
|
2120
|
-
}
|
|
2191
|
+
/**
|
|
2192
|
+
* Convert an array of 8-bit integers to a string
|
|
2193
|
+
* @param {Uint8Array} bytes - An array of 8-bit integers to convert
|
|
2194
|
+
* @returns {String} String representation of the array.
|
|
2195
|
+
*/
|
|
2196
|
+
uint8ArrayToString: function (bytes) {
|
|
2197
|
+
bytes = new Uint8Array(bytes);
|
|
2198
|
+
const result = [];
|
|
2199
|
+
const bs = 1 << 14;
|
|
2200
|
+
const j = bytes.length;
|
|
2121
2201
|
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
* @param {Uint8Array | ReadableStream<Uint8Array>} data - Uint8Array to convert
|
|
2125
|
-
* @returns {String | ReadableStream<String>} Radix-64 version of input string.
|
|
2126
|
-
* @static
|
|
2127
|
-
*/
|
|
2128
|
-
function encode(data) {
|
|
2129
|
-
let buf = new Uint8Array();
|
|
2130
|
-
return transform(data, value => {
|
|
2131
|
-
buf = util.concatUint8Array([buf, value]);
|
|
2132
|
-
const r = [];
|
|
2133
|
-
const bytesPerLine = 45; // 60 chars per line * (3 bytes / 4 chars of base64).
|
|
2134
|
-
const lines = Math.floor(buf.length / bytesPerLine);
|
|
2135
|
-
const bytes = lines * bytesPerLine;
|
|
2136
|
-
const encoded = encodeChunk(buf.subarray(0, bytes));
|
|
2137
|
-
for (let i = 0; i < lines; i++) {
|
|
2138
|
-
r.push(encoded.substr(i * 60, 60));
|
|
2139
|
-
r.push('\n');
|
|
2202
|
+
for (let i = 0; i < j; i += bs) {
|
|
2203
|
+
result.push(String.fromCharCode.apply(String, bytes.subarray(i, i + bs < j ? i + bs : j)));
|
|
2140
2204
|
}
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
}, () => (buf.length ? encodeChunk(buf) + '\n' : ''));
|
|
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;
|
|
2205
|
+
return result.join('');
|
|
2206
|
+
},
|
|
2156
2207
|
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2208
|
+
/**
|
|
2209
|
+
* Convert a native javascript string to a Uint8Array of utf8 bytes
|
|
2210
|
+
* @param {String|ReadableStream} str - The string to convert
|
|
2211
|
+
* @returns {Uint8Array|ReadableStream} A valid squence of utf8 bytes.
|
|
2212
|
+
*/
|
|
2213
|
+
encodeUTF8: function (str) {
|
|
2214
|
+
const encoder = new TextEncoder('utf-8');
|
|
2215
|
+
// eslint-disable-next-line no-inner-declarations
|
|
2216
|
+
function process(value, lastChunk = false) {
|
|
2217
|
+
return encoder.encode(value, { stream: !lastChunk });
|
|
2165
2218
|
}
|
|
2219
|
+
return transform(str, process, () => process('', true));
|
|
2220
|
+
},
|
|
2166
2221
|
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2222
|
+
/**
|
|
2223
|
+
* Convert a Uint8Array of utf8 bytes to a native javascript string
|
|
2224
|
+
* @param {Uint8Array|ReadableStream} utf8 - A valid squence of utf8 bytes
|
|
2225
|
+
* @returns {String|ReadableStream} A native javascript string.
|
|
2226
|
+
*/
|
|
2227
|
+
decodeUTF8: function (utf8) {
|
|
2228
|
+
const decoder = new TextDecoder('utf-8');
|
|
2229
|
+
// eslint-disable-next-line no-inner-declarations
|
|
2230
|
+
function process(value, lastChunk = false) {
|
|
2231
|
+
return decoder.decode(value, { stream: !lastChunk });
|
|
2172
2232
|
}
|
|
2233
|
+
return transform(utf8, process, () => process(new Uint8Array(), true));
|
|
2234
|
+
},
|
|
2173
2235
|
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
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
|
-
}
|
|
2236
|
+
/**
|
|
2237
|
+
* Concat a list of Uint8Arrays, Strings or Streams
|
|
2238
|
+
* The caller must not mix Uint8Arrays with Strings, but may mix Streams with non-Streams.
|
|
2239
|
+
* @param {Array<Uint8Array|String|ReadableStream>} Array - Of Uint8Arrays/Strings/Streams to concatenate
|
|
2240
|
+
* @returns {Uint8Array|String|ReadableStream} Concatenated array.
|
|
2241
|
+
*/
|
|
2242
|
+
concat: concat,
|
|
2190
2243
|
|
|
2191
|
-
/**
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
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
|
-
}
|
|
2244
|
+
/**
|
|
2245
|
+
* Concat Uint8Arrays
|
|
2246
|
+
* @param {Array<Uint8Array>} Array - Of Uint8Arrays to concatenate
|
|
2247
|
+
* @returns {Uint8Array} Concatenated array.
|
|
2248
|
+
*/
|
|
2249
|
+
concatUint8Array: concatUint8Array,
|
|
2204
2250
|
|
|
2205
|
-
/**
|
|
2206
|
-
|
|
2207
|
-
|
|
2251
|
+
/**
|
|
2252
|
+
* Check Uint8Array equality
|
|
2253
|
+
* @param {Uint8Array} array1 - First array
|
|
2254
|
+
* @param {Uint8Array} array2 - Second array
|
|
2255
|
+
* @returns {Boolean} Equality.
|
|
2256
|
+
*/
|
|
2257
|
+
equalsUint8Array: function (array1, array2) {
|
|
2258
|
+
if (!util.isUint8Array(array1) || !util.isUint8Array(array2)) {
|
|
2259
|
+
throw new Error('Data must be in the form of a Uint8Array');
|
|
2260
|
+
}
|
|
2208
2261
|
|
|
2209
|
-
|
|
2262
|
+
if (array1.length !== array2.length) {
|
|
2263
|
+
return false;
|
|
2264
|
+
}
|
|
2210
2265
|
|
|
2211
|
-
|
|
2266
|
+
for (let i = 0; i < array1.length; i++) {
|
|
2267
|
+
if (array1[i] !== array2[i]) {
|
|
2268
|
+
return false;
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
return true;
|
|
2272
|
+
},
|
|
2212
2273
|
|
|
2213
|
-
/**
|
|
2214
|
-
*
|
|
2215
|
-
*
|
|
2216
|
-
* @
|
|
2274
|
+
/**
|
|
2275
|
+
* Calculates a 16bit sum of a Uint8Array by adding each character
|
|
2276
|
+
* codes modulus 65535
|
|
2277
|
+
* @param {Uint8Array} Uint8Array - To create a sum of
|
|
2278
|
+
* @returns {Uint8Array} 2 bytes containing the sum of all charcodes % 65535.
|
|
2217
2279
|
*/
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
'2a8648ce3d030107': 'p256',
|
|
2226
|
-
'2A8648CE3D030107': 'p256',
|
|
2227
|
-
|
|
2228
|
-
/** NIST P-384 Curve */
|
|
2229
|
-
'p384': 'p384',
|
|
2230
|
-
'P-384': 'p384',
|
|
2231
|
-
'secp384r1': 'p384',
|
|
2232
|
-
'1.3.132.0.34': 'p384',
|
|
2233
|
-
'2b81040022': 'p384',
|
|
2234
|
-
'2B81040022': 'p384',
|
|
2235
|
-
|
|
2236
|
-
/** NIST P-521 Curve */
|
|
2237
|
-
'p521': 'p521',
|
|
2238
|
-
'P-521': 'p521',
|
|
2239
|
-
'secp521r1': 'p521',
|
|
2240
|
-
'1.3.132.0.35': 'p521',
|
|
2241
|
-
'2b81040023': 'p521',
|
|
2242
|
-
'2B81040023': 'p521',
|
|
2280
|
+
writeChecksum: function (text) {
|
|
2281
|
+
let s = 0;
|
|
2282
|
+
for (let i = 0; i < text.length; i++) {
|
|
2283
|
+
s = (s + text[i]) & 0xFFFF;
|
|
2284
|
+
}
|
|
2285
|
+
return util.writeNumber(s, 2);
|
|
2286
|
+
},
|
|
2243
2287
|
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2288
|
+
/**
|
|
2289
|
+
* Helper function to print a debug message. Debug
|
|
2290
|
+
* messages are only printed if
|
|
2291
|
+
* @param {String} str - String of the debug message
|
|
2292
|
+
*/
|
|
2293
|
+
printDebug: function (str) {
|
|
2294
|
+
if (debugMode) {
|
|
2295
|
+
console.log('[OpenPGP.js debug]', str);
|
|
2296
|
+
}
|
|
2297
|
+
},
|
|
2249
2298
|
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2299
|
+
/**
|
|
2300
|
+
* Helper function to print a debug error. Debug
|
|
2301
|
+
* messages are only printed if
|
|
2302
|
+
* @param {String} str - String of the debug message
|
|
2303
|
+
*/
|
|
2304
|
+
printDebugError: function (error) {
|
|
2305
|
+
if (debugMode) {
|
|
2306
|
+
console.error('[OpenPGP.js debug]', error);
|
|
2307
|
+
}
|
|
2308
|
+
},
|
|
2257
2309
|
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2310
|
+
// returns bit length of the integer x
|
|
2311
|
+
nbits: function (x) {
|
|
2312
|
+
let r = 1;
|
|
2313
|
+
let t = x >>> 16;
|
|
2314
|
+
if (t !== 0) {
|
|
2315
|
+
x = t;
|
|
2316
|
+
r += 16;
|
|
2317
|
+
}
|
|
2318
|
+
t = x >> 8;
|
|
2319
|
+
if (t !== 0) {
|
|
2320
|
+
x = t;
|
|
2321
|
+
r += 8;
|
|
2322
|
+
}
|
|
2323
|
+
t = x >> 4;
|
|
2324
|
+
if (t !== 0) {
|
|
2325
|
+
x = t;
|
|
2326
|
+
r += 4;
|
|
2327
|
+
}
|
|
2328
|
+
t = x >> 2;
|
|
2329
|
+
if (t !== 0) {
|
|
2330
|
+
x = t;
|
|
2331
|
+
r += 2;
|
|
2332
|
+
}
|
|
2333
|
+
t = x >> 1;
|
|
2334
|
+
if (t !== 0) {
|
|
2335
|
+
x = t;
|
|
2336
|
+
r += 1;
|
|
2337
|
+
}
|
|
2338
|
+
return r;
|
|
2284
2339
|
},
|
|
2285
2340
|
|
|
2286
|
-
/**
|
|
2287
|
-
*
|
|
2288
|
-
*
|
|
2289
|
-
*
|
|
2341
|
+
/**
|
|
2342
|
+
* If S[1] == 0, then double(S) == (S[2..128] || 0);
|
|
2343
|
+
* otherwise, double(S) == (S[2..128] || 0) xor
|
|
2344
|
+
* (zeros(120) || 10000111).
|
|
2345
|
+
*
|
|
2346
|
+
* Both OCB and EAX (through CMAC) require this function to be constant-time.
|
|
2347
|
+
*
|
|
2348
|
+
* @param {Uint8Array} data
|
|
2290
2349
|
*/
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2350
|
+
double: function(data) {
|
|
2351
|
+
const doubleVar = new Uint8Array(data.length);
|
|
2352
|
+
const last = data.length - 1;
|
|
2353
|
+
for (let i = 0; i < last; i++) {
|
|
2354
|
+
doubleVar[i] = (data[i] << 1) ^ (data[i + 1] >> 7);
|
|
2355
|
+
}
|
|
2356
|
+
doubleVar[last] = (data[last] << 1) ^ ((data[0] >> 7) * 0x87);
|
|
2357
|
+
return doubleVar;
|
|
2296
2358
|
},
|
|
2297
2359
|
|
|
2298
|
-
/**
|
|
2299
|
-
*
|
|
2300
|
-
* @
|
|
2360
|
+
/**
|
|
2361
|
+
* Shift a Uint8Array to the right by n bits
|
|
2362
|
+
* @param {Uint8Array} array - The array to shift
|
|
2363
|
+
* @param {Integer} bits - Amount of bits to shift (MUST be smaller
|
|
2364
|
+
* than 8)
|
|
2365
|
+
* @returns {String} Resulting array.
|
|
2301
2366
|
*/
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2367
|
+
shiftRight: function (array, bits) {
|
|
2368
|
+
if (bits) {
|
|
2369
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
2370
|
+
array[i] >>= bits;
|
|
2371
|
+
if (i > 0) {
|
|
2372
|
+
array[i] |= (array[i - 1] << (8 - bits));
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
return array;
|
|
2308
2377
|
},
|
|
2309
2378
|
|
|
2310
|
-
/**
|
|
2311
|
-
*
|
|
2312
|
-
* @
|
|
2379
|
+
/**
|
|
2380
|
+
* Get native Web Cryptography api, only the current version of the spec.
|
|
2381
|
+
* @returns {Object} The SubtleCrypto api or 'undefined'.
|
|
2313
2382
|
*/
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
rsaEncryptSign: 1,
|
|
2317
|
-
/** RSA (Encrypt only) [HAC] */
|
|
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
|
|
2383
|
+
getWebCrypto: function() {
|
|
2384
|
+
return typeof globalThis !== 'undefined' && globalThis.crypto && globalThis.crypto.subtle;
|
|
2340
2385
|
},
|
|
2341
2386
|
|
|
2342
|
-
/**
|
|
2343
|
-
*
|
|
2344
|
-
*
|
|
2387
|
+
/**
|
|
2388
|
+
* Get BigInteger class
|
|
2389
|
+
* It wraps the native BigInt type if it's available
|
|
2390
|
+
* Otherwise it relies on bn.js
|
|
2391
|
+
* @returns {BigInteger}
|
|
2392
|
+
* @async
|
|
2345
2393
|
*/
|
|
2346
|
-
|
|
2347
|
-
plaintext: 0,
|
|
2348
|
-
/** Not implemented! */
|
|
2349
|
-
idea: 1,
|
|
2350
|
-
tripledes: 2,
|
|
2351
|
-
cast5: 3,
|
|
2352
|
-
blowfish: 4,
|
|
2353
|
-
aes128: 7,
|
|
2354
|
-
aes192: 8,
|
|
2355
|
-
aes256: 9,
|
|
2356
|
-
twofish: 10
|
|
2357
|
-
},
|
|
2394
|
+
getBigInteger,
|
|
2358
2395
|
|
|
2359
|
-
/**
|
|
2360
|
-
*
|
|
2361
|
-
* @
|
|
2396
|
+
/**
|
|
2397
|
+
* Get native Node.js crypto api.
|
|
2398
|
+
* @returns {Object} The crypto module or 'undefined'.
|
|
2362
2399
|
*/
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
/** RFC1951 */
|
|
2366
|
-
zip: 1,
|
|
2367
|
-
/** RFC1950 */
|
|
2368
|
-
zlib: 2,
|
|
2369
|
-
bzip2: 3
|
|
2400
|
+
getNodeCrypto: function() {
|
|
2401
|
+
return void('crypto');
|
|
2370
2402
|
},
|
|
2371
2403
|
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
* @readonly
|
|
2375
|
-
*/
|
|
2376
|
-
hash: {
|
|
2377
|
-
md5: 1,
|
|
2378
|
-
sha1: 2,
|
|
2379
|
-
ripemd: 3,
|
|
2380
|
-
sha256: 8,
|
|
2381
|
-
sha384: 9,
|
|
2382
|
-
sha512: 10,
|
|
2383
|
-
sha224: 11
|
|
2404
|
+
getNodeZlib: function() {
|
|
2405
|
+
return void('zlib');
|
|
2384
2406
|
},
|
|
2385
2407
|
|
|
2386
|
-
/**
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2408
|
+
/**
|
|
2409
|
+
* Get native Node.js Buffer constructor. This should be used since
|
|
2410
|
+
* Buffer is not available under browserify.
|
|
2411
|
+
* @returns {Function} The Buffer constructor or 'undefined'.
|
|
2389
2412
|
*/
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
'SHA-256': 8,
|
|
2393
|
-
'SHA-384': 9,
|
|
2394
|
-
'SHA-512': 10
|
|
2413
|
+
getNodeBuffer: function() {
|
|
2414
|
+
return ({}).Buffer;
|
|
2395
2415
|
},
|
|
2396
2416
|
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
experimentalGCM: 100 // Private algorithm
|
|
2417
|
+
getHardwareConcurrency: function() {
|
|
2418
|
+
if (typeof navigator !== 'undefined') {
|
|
2419
|
+
return navigator.hardwareConcurrency || 1;
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
const os = void('os'); // Assume we're on Node.js.
|
|
2423
|
+
return os.cpus().length;
|
|
2405
2424
|
},
|
|
2406
2425
|
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
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
|
|
2426
|
+
isEmailAddress: function(data) {
|
|
2427
|
+
if (!util.isString(data)) {
|
|
2428
|
+
return false;
|
|
2429
|
+
}
|
|
2430
|
+
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]+)))$/;
|
|
2431
|
+
return re.test(data);
|
|
2430
2432
|
},
|
|
2431
2433
|
|
|
2432
|
-
/**
|
|
2433
|
-
*
|
|
2434
|
-
*
|
|
2434
|
+
/**
|
|
2435
|
+
* Normalize line endings to <CR><LF>
|
|
2436
|
+
* Support any encoding where CR=0x0D, LF=0x0A
|
|
2435
2437
|
*/
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
text: 't'.charCodeAt(),
|
|
2441
|
-
/** Utf8 data 'u' */
|
|
2442
|
-
utf8: 'u'.charCodeAt(),
|
|
2443
|
-
/** MIME message body part 'm' */
|
|
2444
|
-
mime: 'm'.charCodeAt()
|
|
2445
|
-
},
|
|
2438
|
+
canonicalizeEOL: function(data) {
|
|
2439
|
+
const CR = 13;
|
|
2440
|
+
const LF = 10;
|
|
2441
|
+
let carryOverCR = false;
|
|
2446
2442
|
|
|
2443
|
+
return transform(data, bytes => {
|
|
2444
|
+
if (carryOverCR) {
|
|
2445
|
+
bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
|
|
2446
|
+
}
|
|
2447
2447
|
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
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
|
|
2448
|
+
if (bytes[bytes.length - 1] === CR) {
|
|
2449
|
+
carryOverCR = true;
|
|
2450
|
+
bytes = bytes.subarray(0, -1);
|
|
2451
|
+
} else {
|
|
2452
|
+
carryOverCR = false;
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
let index;
|
|
2456
|
+
const indices = [];
|
|
2457
|
+
for (let i = 0; ; i = index) {
|
|
2458
|
+
index = bytes.indexOf(LF, i) + 1;
|
|
2459
|
+
if (index) {
|
|
2460
|
+
if (bytes[index - 2] !== CR) indices.push(index);
|
|
2461
|
+
} else {
|
|
2462
|
+
break;
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
if (!indices.length) {
|
|
2466
|
+
return bytes;
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
const normalized = new Uint8Array(bytes.length + indices.length);
|
|
2470
|
+
let j = 0;
|
|
2471
|
+
for (let i = 0; i < indices.length; i++) {
|
|
2472
|
+
const sub = bytes.subarray(indices[i - 1] || 0, indices[i]);
|
|
2473
|
+
normalized.set(sub, j);
|
|
2474
|
+
j += sub.length;
|
|
2475
|
+
normalized[j - 1] = CR;
|
|
2476
|
+
normalized[j] = LF;
|
|
2477
|
+
j++;
|
|
2478
|
+
}
|
|
2479
|
+
normalized.set(bytes.subarray(indices[indices.length - 1] || 0), j);
|
|
2480
|
+
return normalized;
|
|
2481
|
+
}, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
|
|
2568
2482
|
},
|
|
2569
2483
|
|
|
2570
|
-
/**
|
|
2571
|
-
*
|
|
2572
|
-
*
|
|
2484
|
+
/**
|
|
2485
|
+
* Convert line endings from canonicalized <CR><LF> to native <LF>
|
|
2486
|
+
* Support any encoding where CR=0x0D, LF=0x0A
|
|
2573
2487
|
*/
|
|
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
|
-
|
|
2488
|
+
nativeEOL: function(data) {
|
|
2489
|
+
const CR = 13;
|
|
2490
|
+
const LF = 10;
|
|
2491
|
+
let carryOverCR = false;
|
|
2492
|
+
|
|
2493
|
+
return transform(data, bytes => {
|
|
2494
|
+
if (carryOverCR && bytes[0] !== LF) {
|
|
2495
|
+
bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
|
|
2496
|
+
} else {
|
|
2497
|
+
bytes = new Uint8Array(bytes); // Don't mutate passed bytes
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2500
|
+
if (bytes[bytes.length - 1] === CR) {
|
|
2501
|
+
carryOverCR = true;
|
|
2502
|
+
bytes = bytes.subarray(0, -1);
|
|
2503
|
+
} else {
|
|
2504
|
+
carryOverCR = false;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
let index;
|
|
2508
|
+
let j = 0;
|
|
2509
|
+
for (let i = 0; i !== bytes.length; i = index) {
|
|
2510
|
+
index = bytes.indexOf(CR, i) + 1;
|
|
2511
|
+
if (!index) index = bytes.length;
|
|
2512
|
+
const last = index - (bytes[index] === LF ? 1 : 0);
|
|
2513
|
+
if (i) bytes.copyWithin(j, i, last);
|
|
2514
|
+
j += last - i;
|
|
2515
|
+
}
|
|
2516
|
+
return bytes.subarray(0, j);
|
|
2517
|
+
}, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
|
|
2601
2518
|
},
|
|
2602
2519
|
|
|
2603
|
-
/**
|
|
2604
|
-
*
|
|
2605
|
-
* @readonly
|
|
2520
|
+
/**
|
|
2521
|
+
* Remove trailing spaces, carriage returns and tabs from each line
|
|
2606
2522
|
*/
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
encryptCommunication: 4,
|
|
2614
|
-
/** 0x08 - This key may be used to encrypt storage. */
|
|
2615
|
-
encryptStorage: 8,
|
|
2616
|
-
/** 0x10 - The private component of this key may have been split
|
|
2617
|
-
* by a secret-sharing mechanism. */
|
|
2618
|
-
splitPrivateKey: 16,
|
|
2619
|
-
/** 0x20 - This key may be used for authentication. */
|
|
2620
|
-
authentication: 32,
|
|
2621
|
-
/** This key may be used for forwarded communications */
|
|
2622
|
-
forwardedCommunication: 64,
|
|
2623
|
-
/** 0x80 - The private component of this key may be in the
|
|
2624
|
-
* possession of more than one person. */
|
|
2625
|
-
sharedPrivateKey: 128
|
|
2523
|
+
removeTrailingSpaces: function(text) {
|
|
2524
|
+
return text.split('\n').map(line => {
|
|
2525
|
+
let i = line.length - 1;
|
|
2526
|
+
for (; i >= 0 && (line[i] === ' ' || line[i] === '\t' || line[i] === '\r'); i--);
|
|
2527
|
+
return line.substr(0, i + 1);
|
|
2528
|
+
}).join('\n');
|
|
2626
2529
|
},
|
|
2627
2530
|
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2531
|
+
wrapError: function(message, error) {
|
|
2532
|
+
if (!error) {
|
|
2533
|
+
return new Error(message);
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// update error message
|
|
2537
|
+
try {
|
|
2538
|
+
error.message = message + ': ' + error.message;
|
|
2539
|
+
} catch (e) {}
|
|
2540
|
+
|
|
2541
|
+
return error;
|
|
2542
|
+
},
|
|
2543
|
+
|
|
2544
|
+
/**
|
|
2545
|
+
* Map allowed packet tags to corresponding classes
|
|
2546
|
+
* Meant to be used to format `allowedPacket` for Packetlist.read
|
|
2547
|
+
* @param {Array<Object>} allowedClasses
|
|
2548
|
+
* @returns {Object} map from enum.packet to corresponding *Packet class
|
|
2631
2549
|
*/
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2550
|
+
constructAllowedPackets: function(allowedClasses) {
|
|
2551
|
+
const map = {};
|
|
2552
|
+
allowedClasses.forEach(PacketClass => {
|
|
2553
|
+
if (!PacketClass.tag) {
|
|
2554
|
+
throw new Error('Invalid input: expected a packet class');
|
|
2555
|
+
}
|
|
2556
|
+
map[PacketClass.tag] = PacketClass;
|
|
2557
|
+
});
|
|
2558
|
+
return map;
|
|
2640
2559
|
},
|
|
2641
2560
|
|
|
2642
|
-
/**
|
|
2643
|
-
*
|
|
2644
|
-
*
|
|
2561
|
+
/**
|
|
2562
|
+
* Return a Promise that will resolve as soon as one of the promises in input resolves
|
|
2563
|
+
* or will reject if all input promises all rejected
|
|
2564
|
+
* (similar to Promise.any, but with slightly different error handling)
|
|
2565
|
+
* @param {Array<Promise>} promises
|
|
2566
|
+
* @return {Promise<Any>} Promise resolving to the result of the fastest fulfilled promise
|
|
2567
|
+
* or rejected with the Error of the last resolved Promise (if all promises are rejected)
|
|
2645
2568
|
*/
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2569
|
+
anyPromise: function(promises) {
|
|
2570
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
2571
|
+
return new Promise(async (resolve, reject) => {
|
|
2572
|
+
let exception;
|
|
2573
|
+
await Promise.all(promises.map(async promise => {
|
|
2574
|
+
try {
|
|
2575
|
+
resolve(await promise);
|
|
2576
|
+
} catch (e) {
|
|
2577
|
+
exception = e;
|
|
2578
|
+
}
|
|
2579
|
+
}));
|
|
2580
|
+
reject(exception);
|
|
2581
|
+
});
|
|
2657
2582
|
},
|
|
2658
2583
|
|
|
2659
|
-
/**
|
|
2660
|
-
*
|
|
2661
|
-
* @
|
|
2584
|
+
/**
|
|
2585
|
+
* Return either `a` or `b` based on `cond`, in algorithmic constant time.
|
|
2586
|
+
* @param {Boolean} cond
|
|
2587
|
+
* @param {Uint8Array} a
|
|
2588
|
+
* @param {Uint8Array} b
|
|
2589
|
+
* @returns `a` if `cond` is true, `b` otherwise
|
|
2662
2590
|
*/
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2591
|
+
selectUint8Array: function(cond, a, b) {
|
|
2592
|
+
const length = Math.max(a.length, b.length);
|
|
2593
|
+
const result = new Uint8Array(length);
|
|
2594
|
+
let end = 0;
|
|
2595
|
+
for (let i = 0; i < result.length; i++) {
|
|
2596
|
+
result[i] = (a[i] & (256 - cond)) | (b[i] & (255 + cond));
|
|
2597
|
+
end += (cond & i < a.length) | ((1 - cond) & i < b.length);
|
|
2598
|
+
}
|
|
2599
|
+
return result.subarray(0, end);
|
|
2672
2600
|
},
|
|
2673
|
-
|
|
2674
2601
|
/**
|
|
2675
|
-
*
|
|
2676
|
-
*
|
|
2677
|
-
* @param {
|
|
2678
|
-
* @
|
|
2679
|
-
* @
|
|
2602
|
+
* Return either `a` or `b` based on `cond`, in algorithmic constant time.
|
|
2603
|
+
* NB: it only supports `a, b` with values between 0-255.
|
|
2604
|
+
* @param {Boolean} cond
|
|
2605
|
+
* @param {Uint8} a
|
|
2606
|
+
* @param {Uint8} b
|
|
2607
|
+
* @returns `a` if `cond` is true, `b` otherwise
|
|
2680
2608
|
*/
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2609
|
+
selectUint8: function(cond, a, b) {
|
|
2610
|
+
return (a & (256 - cond)) | (b & (255 + cond));
|
|
2611
|
+
},
|
|
2612
|
+
/**
|
|
2613
|
+
* @param {module:enums.symmetric} cipherAlgo
|
|
2614
|
+
*/
|
|
2615
|
+
isAES: function(cipherAlgo) {
|
|
2616
|
+
return cipherAlgo === enums.symmetric.aes128 || cipherAlgo === enums.symmetric.aes192 || cipherAlgo === enums.symmetric.aes256;
|
|
2617
|
+
}
|
|
2618
|
+
};
|
|
2685
2619
|
|
|
2686
|
-
|
|
2687
|
-
|
|
2620
|
+
/* OpenPGP radix-64/base64 string encoding/decoding
|
|
2621
|
+
* Copyright 2005 Herbert Hanewinkel, www.haneWIN.de
|
|
2622
|
+
* version 1.0, check www.haneWIN.de for the latest version
|
|
2623
|
+
*
|
|
2624
|
+
* This software is provided as-is, without express or implied warranty.
|
|
2625
|
+
* Permission to use, copy, modify, distribute or sell this software, with or
|
|
2626
|
+
* without fee, for any purpose and by any individual or organization, is hereby
|
|
2627
|
+
* granted, provided that the above copyright notice and this paragraph appear
|
|
2628
|
+
* in all copies. Distribution as a part of an application or binary must
|
|
2629
|
+
* include the above copyright notice in the documentation and/or other materials
|
|
2630
|
+
* provided with the application or distribution.
|
|
2631
|
+
*/
|
|
2632
|
+
|
|
2633
|
+
const Buffer = util.getNodeBuffer();
|
|
2634
|
+
|
|
2635
|
+
let encodeChunk;
|
|
2636
|
+
let decodeChunk;
|
|
2637
|
+
if (Buffer) {
|
|
2638
|
+
encodeChunk = buf => Buffer.from(buf).toString('base64');
|
|
2639
|
+
decodeChunk = str => {
|
|
2640
|
+
const b = Buffer.from(str, 'base64');
|
|
2641
|
+
return new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
|
|
2642
|
+
};
|
|
2643
|
+
} else {
|
|
2644
|
+
encodeChunk = buf => btoa(util.uint8ArrayToString(buf));
|
|
2645
|
+
decodeChunk = str => util.stringToUint8Array(atob(str));
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2648
|
+
/**
|
|
2649
|
+
* Convert binary array to radix-64
|
|
2650
|
+
* @param {Uint8Array | ReadableStream<Uint8Array>} data - Uint8Array to convert
|
|
2651
|
+
* @returns {String | ReadableStream<String>} Radix-64 version of input string.
|
|
2652
|
+
* @static
|
|
2653
|
+
*/
|
|
2654
|
+
function encode(data) {
|
|
2655
|
+
let buf = new Uint8Array();
|
|
2656
|
+
return transform(data, value => {
|
|
2657
|
+
buf = util.concatUint8Array([buf, value]);
|
|
2658
|
+
const r = [];
|
|
2659
|
+
const bytesPerLine = 45; // 60 chars per line * (3 bytes / 4 chars of base64).
|
|
2660
|
+
const lines = Math.floor(buf.length / bytesPerLine);
|
|
2661
|
+
const bytes = lines * bytesPerLine;
|
|
2662
|
+
const encoded = encodeChunk(buf.subarray(0, bytes));
|
|
2663
|
+
for (let i = 0; i < lines; i++) {
|
|
2664
|
+
r.push(encoded.substr(i * 60, 60));
|
|
2665
|
+
r.push('\n');
|
|
2688
2666
|
}
|
|
2667
|
+
buf = buf.subarray(bytes);
|
|
2668
|
+
return r.join('');
|
|
2669
|
+
}, () => (buf.length ? encodeChunk(buf) + '\n' : ''));
|
|
2670
|
+
}
|
|
2689
2671
|
|
|
2690
|
-
|
|
2691
|
-
|
|
2672
|
+
/**
|
|
2673
|
+
* Convert radix-64 to binary array
|
|
2674
|
+
* @param {String | ReadableStream<String>} data - Radix-64 string to convert
|
|
2675
|
+
* @returns {Uint8Array | ReadableStream<Uint8Array>} Binary array version of input string.
|
|
2676
|
+
* @static
|
|
2677
|
+
*/
|
|
2678
|
+
function decode(data) {
|
|
2679
|
+
let buf = '';
|
|
2680
|
+
return transform(data, value => {
|
|
2681
|
+
buf += value;
|
|
2692
2682
|
|
|
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
|
-
});
|
|
2683
|
+
// Count how many whitespace characters there are in buf
|
|
2684
|
+
let spaces = 0;
|
|
2685
|
+
const spacechars = [' ', '\t', '\r', '\n'];
|
|
2686
|
+
for (let i = 0; i < spacechars.length; i++) {
|
|
2687
|
+
const spacechar = spacechars[i];
|
|
2688
|
+
for (let pos = buf.indexOf(spacechar); pos !== -1; pos = buf.indexOf(spacechar, pos + 1)) {
|
|
2689
|
+
spaces++;
|
|
2690
|
+
}
|
|
2706
2691
|
}
|
|
2707
2692
|
|
|
2708
|
-
|
|
2709
|
-
|
|
2693
|
+
// Backtrack until we have 4n non-whitespace characters
|
|
2694
|
+
// that we can safely base64-decode
|
|
2695
|
+
let length = buf.length;
|
|
2696
|
+
for (; length > 0 && (length - spaces) % 4 !== 0; length--) {
|
|
2697
|
+
if (spacechars.includes(buf[length])) spaces--;
|
|
2710
2698
|
}
|
|
2711
2699
|
|
|
2712
|
-
|
|
2700
|
+
const decoded = decodeChunk(buf.substr(0, length));
|
|
2701
|
+
buf = buf.substr(length);
|
|
2702
|
+
return decoded;
|
|
2703
|
+
}, () => decodeChunk(buf));
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
/**
|
|
2707
|
+
* Convert a Base-64 encoded string an array of 8-bit integer
|
|
2708
|
+
*
|
|
2709
|
+
* Note: accepts both Radix-64 and URL-safe strings
|
|
2710
|
+
* @param {String} base64 - Base-64 encoded string to convert
|
|
2711
|
+
* @returns {Uint8Array} An array of 8-bit integers.
|
|
2712
|
+
*/
|
|
2713
|
+
function b64ToUint8Array(base64) {
|
|
2714
|
+
return decode(base64.replace(/-/g, '+').replace(/_/g, '/'));
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
/**
|
|
2718
|
+
* Convert an array of 8-bit integer to a Base-64 encoded string
|
|
2719
|
+
* @param {Uint8Array} bytes - An array of 8-bit integers to convert
|
|
2720
|
+
* @param {bool} url - If true, output is URL-safe
|
|
2721
|
+
* @returns {String} Base-64 encoded string.
|
|
2722
|
+
*/
|
|
2723
|
+
function uint8ArrayToB64(bytes, url) {
|
|
2724
|
+
let encoded = encode(bytes).replace(/[\r\n]/g, '');
|
|
2725
|
+
if (url) {
|
|
2726
|
+
encoded = encoded.replace(/[+]/g, '-').replace(/[/]/g, '_').replace(/[=]/g, '');
|
|
2713
2727
|
}
|
|
2714
|
-
|
|
2728
|
+
return encoded;
|
|
2729
|
+
}
|
|
2715
2730
|
|
|
2716
2731
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
2717
2732
|
|
|
@@ -2929,7 +2944,7 @@ var config = {
|
|
|
2929
2944
|
* @memberof module:config
|
|
2930
2945
|
* @property {String} versionString A version string to be included in armored messages
|
|
2931
2946
|
*/
|
|
2932
|
-
versionString: 'OpenPGP.js 5.
|
|
2947
|
+
versionString: 'OpenPGP.js 5.10.2',
|
|
2933
2948
|
/**
|
|
2934
2949
|
* @memberof module:config
|
|
2935
2950
|
* @property {String} commentString A comment string to be included in armored messages
|
|
@@ -3415,6 +3430,7 @@ class KeyID {
|
|
|
3415
3430
|
*/
|
|
3416
3431
|
read(bytes) {
|
|
3417
3432
|
this.bytes = util.uint8ArrayToString(bytes.subarray(0, 8));
|
|
3433
|
+
return this.bytes.length;
|
|
3418
3434
|
}
|
|
3419
3435
|
|
|
3420
3436
|
/**
|
|
@@ -9961,7 +9977,7 @@ async function encrypt(algo, key, plaintext, iv, config) {
|
|
|
9961
9977
|
if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
|
|
9962
9978
|
return nodeEncrypt(algo, key, plaintext, iv);
|
|
9963
9979
|
}
|
|
9964
|
-
if (
|
|
9980
|
+
if (util.isAES(algo)) {
|
|
9965
9981
|
return aesEncrypt(algo, key, plaintext, iv, config);
|
|
9966
9982
|
}
|
|
9967
9983
|
|
|
@@ -10004,7 +10020,7 @@ async function decrypt(algo, key, ciphertext, iv) {
|
|
|
10004
10020
|
if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
|
|
10005
10021
|
return nodeDecrypt(algo, key, ciphertext, iv);
|
|
10006
10022
|
}
|
|
10007
|
-
if (
|
|
10023
|
+
if (util.isAES(algo)) {
|
|
10008
10024
|
return aesDecrypt(algo, key, ciphertext, iv);
|
|
10009
10025
|
}
|
|
10010
10026
|
|
|
@@ -10023,7 +10039,7 @@ async function decrypt(algo, key, ciphertext, iv) {
|
|
|
10023
10039
|
let j = 0;
|
|
10024
10040
|
while (chunk ? ct.length >= block_size : ct.length) {
|
|
10025
10041
|
const decblock = cipherfn.encrypt(blockp);
|
|
10026
|
-
blockp = ct;
|
|
10042
|
+
blockp = ct.subarray(0, block_size);
|
|
10027
10043
|
for (i = 0; i < block_size; i++) {
|
|
10028
10044
|
plaintext[j++] = blockp[i] ^ decblock[i];
|
|
10029
10045
|
}
|
|
@@ -13592,7 +13608,7 @@ const curves = {
|
|
|
13592
13608
|
}
|
|
13593
13609
|
};
|
|
13594
13610
|
|
|
13595
|
-
class
|
|
13611
|
+
class CurveWithOID {
|
|
13596
13612
|
constructor(oidOrName, params) {
|
|
13597
13613
|
try {
|
|
13598
13614
|
if (util.isArray(oidOrName) ||
|
|
@@ -13669,7 +13685,7 @@ class Curve {
|
|
|
13669
13685
|
async function generate$1(curve) {
|
|
13670
13686
|
const BigInteger = await util.getBigInteger();
|
|
13671
13687
|
|
|
13672
|
-
curve = new
|
|
13688
|
+
curve = new CurveWithOID(curve);
|
|
13673
13689
|
const keyPair = await curve.genKeyPair();
|
|
13674
13690
|
const Q = new BigInteger(keyPair.publicKey).toUint8Array();
|
|
13675
13691
|
const secret = new BigInteger(keyPair.privateKey).toUint8Array('be', curve.payloadSize);
|
|
@@ -13860,7 +13876,7 @@ const nodeCrypto$8 = util.getNodeCrypto();
|
|
|
13860
13876
|
* @async
|
|
13861
13877
|
*/
|
|
13862
13878
|
async function sign$1(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
13863
|
-
const curve = new
|
|
13879
|
+
const curve = new CurveWithOID(oid);
|
|
13864
13880
|
if (message && !util.isStream(message)) {
|
|
13865
13881
|
const keyPair = { publicKey, privateKey };
|
|
13866
13882
|
switch (curve.type) {
|
|
@@ -13905,7 +13921,7 @@ async function sign$1(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
13905
13921
|
* @async
|
|
13906
13922
|
*/
|
|
13907
13923
|
async function verify$1(oid, hashAlgo, signature, message, publicKey, hashed) {
|
|
13908
|
-
const curve = new
|
|
13924
|
+
const curve = new CurveWithOID(oid);
|
|
13909
13925
|
if (message && !util.isStream(message)) {
|
|
13910
13926
|
switch (curve.type) {
|
|
13911
13927
|
case 'web':
|
|
@@ -13939,7 +13955,7 @@ async function verify$1(oid, hashAlgo, signature, message, publicKey, hashed) {
|
|
|
13939
13955
|
* @async
|
|
13940
13956
|
*/
|
|
13941
13957
|
async function validateParams$2(oid, Q, d) {
|
|
13942
|
-
const curve = new
|
|
13958
|
+
const curve = new CurveWithOID(oid);
|
|
13943
13959
|
// Reject curves x25519 and ed25519
|
|
13944
13960
|
if (curve.keyType !== enums.publicKey.ecdsa) {
|
|
13945
13961
|
return false;
|
|
@@ -14142,7 +14158,7 @@ var ecdsa = /*#__PURE__*/Object.freeze({
|
|
|
14142
14158
|
naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
|
|
14143
14159
|
|
|
14144
14160
|
/**
|
|
14145
|
-
* Sign a message using the provided key
|
|
14161
|
+
* Sign a message using the provided legacy EdDSA key
|
|
14146
14162
|
* @param {module:type/oid} oid - Elliptic curve object identifier
|
|
14147
14163
|
* @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
|
|
14148
14164
|
* @param {Uint8Array} message - Message to sign
|
|
@@ -14170,7 +14186,7 @@ async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
|
14170
14186
|
}
|
|
14171
14187
|
|
|
14172
14188
|
/**
|
|
14173
|
-
* Verifies if a signature is valid for a message
|
|
14189
|
+
* Verifies if a legacy EdDSA signature is valid for a message
|
|
14174
14190
|
* @param {module:type/oid} oid - Elliptic curve object identifier
|
|
14175
14191
|
* @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
|
|
14176
14192
|
* @param {{r: Uint8Array,
|
|
@@ -14186,33 +14202,141 @@ async function verify$2(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
|
|
14186
14202
|
return naclFastLight.sign.detached.verify(hashed, signature, publicKey.subarray(1));
|
|
14187
14203
|
}
|
|
14188
14204
|
/**
|
|
14189
|
-
* Validate EdDSA parameters
|
|
14190
|
-
* @param {module:type/oid} oid - Elliptic curve object identifier
|
|
14191
|
-
* @param {Uint8Array} Q - EdDSA public point
|
|
14192
|
-
* @param {Uint8Array} k - EdDSA secret seed
|
|
14205
|
+
* Validate legacy EdDSA parameters
|
|
14206
|
+
* @param {module:type/oid} oid - Elliptic curve object identifier
|
|
14207
|
+
* @param {Uint8Array} Q - EdDSA public point
|
|
14208
|
+
* @param {Uint8Array} k - EdDSA secret seed
|
|
14209
|
+
* @returns {Promise<Boolean>} Whether params are valid.
|
|
14210
|
+
* @async
|
|
14211
|
+
*/
|
|
14212
|
+
async function validateParams$3(oid, Q, k) {
|
|
14213
|
+
// Check whether the given curve is supported
|
|
14214
|
+
if (oid.getName() !== 'ed25519') {
|
|
14215
|
+
return false;
|
|
14216
|
+
}
|
|
14217
|
+
|
|
14218
|
+
/**
|
|
14219
|
+
* Derive public point Q' = dG from private key
|
|
14220
|
+
* and expect Q == Q'
|
|
14221
|
+
*/
|
|
14222
|
+
const { publicKey } = naclFastLight.sign.keyPair.fromSeed(k);
|
|
14223
|
+
const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
|
|
14224
|
+
return util.equalsUint8Array(Q, dG);
|
|
14225
|
+
|
|
14226
|
+
}
|
|
14227
|
+
|
|
14228
|
+
var eddsa_legacy = /*#__PURE__*/Object.freeze({
|
|
14229
|
+
__proto__: null,
|
|
14230
|
+
sign: sign$2,
|
|
14231
|
+
verify: verify$2,
|
|
14232
|
+
validateParams: validateParams$3
|
|
14233
|
+
});
|
|
14234
|
+
|
|
14235
|
+
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
14236
|
+
|
|
14237
|
+
naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
|
|
14238
|
+
|
|
14239
|
+
/**
|
|
14240
|
+
* Generate (non-legacy) EdDSA key
|
|
14241
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14242
|
+
* @returns {Promise<{ A: Uint8Array, seed: Uint8Array }>}
|
|
14243
|
+
*/
|
|
14244
|
+
async function generate$2(algo) {
|
|
14245
|
+
switch (algo) {
|
|
14246
|
+
case enums.publicKey.ed25519: {
|
|
14247
|
+
const seed = getRandomBytes(32);
|
|
14248
|
+
const { publicKey: A } = naclFastLight.sign.keyPair.fromSeed(seed);
|
|
14249
|
+
return { A, seed };
|
|
14250
|
+
}
|
|
14251
|
+
default:
|
|
14252
|
+
throw new Error('Unsupported EdDSA algorithm');
|
|
14253
|
+
}
|
|
14254
|
+
}
|
|
14255
|
+
|
|
14256
|
+
/**
|
|
14257
|
+
* Sign a message using the provided key
|
|
14258
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14259
|
+
* @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
|
|
14260
|
+
* @param {Uint8Array} message - Message to sign
|
|
14261
|
+
* @param {Uint8Array} publicKey - Public key
|
|
14262
|
+
* @param {Uint8Array} privateKey - Private key used to sign the message
|
|
14263
|
+
* @param {Uint8Array} hashed - The hashed message
|
|
14264
|
+
* @returns {Promise<{
|
|
14265
|
+
* RS: Uint8Array
|
|
14266
|
+
* }>} Signature of the message
|
|
14267
|
+
* @async
|
|
14268
|
+
*/
|
|
14269
|
+
async function sign$3(algo, hashAlgo, message, publicKey, privateKey, hashed) {
|
|
14270
|
+
if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
|
|
14271
|
+
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
|
|
14272
|
+
throw new Error('Hash algorithm too weak: sha256 or stronger is required for EdDSA.');
|
|
14273
|
+
}
|
|
14274
|
+
switch (algo) {
|
|
14275
|
+
case enums.publicKey.ed25519: {
|
|
14276
|
+
const secretKey = util.concatUint8Array([privateKey, publicKey]);
|
|
14277
|
+
const signature = naclFastLight.sign.detached(hashed, secretKey);
|
|
14278
|
+
return { RS: signature };
|
|
14279
|
+
}
|
|
14280
|
+
case enums.publicKey.ed448:
|
|
14281
|
+
default:
|
|
14282
|
+
throw new Error('Unsupported EdDSA algorithm');
|
|
14283
|
+
}
|
|
14284
|
+
|
|
14285
|
+
}
|
|
14286
|
+
|
|
14287
|
+
/**
|
|
14288
|
+
* Verifies if a signature is valid for a message
|
|
14289
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14290
|
+
* @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
|
|
14291
|
+
* @param {{ RS: Uint8Array }} signature Signature to verify the message
|
|
14292
|
+
* @param {Uint8Array} m - Message to verify
|
|
14293
|
+
* @param {Uint8Array} publicKey - Public key used to verify the message
|
|
14294
|
+
* @param {Uint8Array} hashed - The hashed message
|
|
14295
|
+
* @returns {Boolean}
|
|
14296
|
+
* @async
|
|
14297
|
+
*/
|
|
14298
|
+
async function verify$3(algo, hashAlgo, { RS }, m, publicKey, hashed) {
|
|
14299
|
+
switch (algo) {
|
|
14300
|
+
case enums.publicKey.ed25519: {
|
|
14301
|
+
return naclFastLight.sign.detached.verify(hashed, RS, publicKey);
|
|
14302
|
+
}
|
|
14303
|
+
case enums.publicKey.ed448:
|
|
14304
|
+
default:
|
|
14305
|
+
throw new Error('Unsupported EdDSA algorithm');
|
|
14306
|
+
}
|
|
14307
|
+
}
|
|
14308
|
+
/**
|
|
14309
|
+
* Validate (non-legacy) EdDSA parameters
|
|
14310
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14311
|
+
* @param {Uint8Array} A - EdDSA public point
|
|
14312
|
+
* @param {Uint8Array} seed - EdDSA secret seed
|
|
14313
|
+
* @param {Uint8Array} oid - (legacy only) EdDSA OID
|
|
14193
14314
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
14194
14315
|
* @async
|
|
14195
14316
|
*/
|
|
14196
|
-
async function validateParams$
|
|
14197
|
-
|
|
14198
|
-
|
|
14199
|
-
|
|
14200
|
-
|
|
14317
|
+
async function validateParams$4(algo, A, seed) {
|
|
14318
|
+
switch (algo) {
|
|
14319
|
+
case enums.publicKey.ed25519: {
|
|
14320
|
+
/**
|
|
14321
|
+
* Derive public point A' from private key
|
|
14322
|
+
* and expect A == A'
|
|
14323
|
+
*/
|
|
14324
|
+
const { publicKey } = naclFastLight.sign.keyPair.fromSeed(seed);
|
|
14325
|
+
return util.equalsUint8Array(A, publicKey);
|
|
14326
|
+
}
|
|
14201
14327
|
|
|
14202
|
-
|
|
14203
|
-
|
|
14204
|
-
|
|
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);
|
|
14328
|
+
case enums.publicKey.ed448: // unsupported
|
|
14329
|
+
default:
|
|
14330
|
+
return false;
|
|
14331
|
+
}
|
|
14209
14332
|
}
|
|
14210
14333
|
|
|
14211
14334
|
var eddsa = /*#__PURE__*/Object.freeze({
|
|
14212
14335
|
__proto__: null,
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14336
|
+
generate: generate$2,
|
|
14337
|
+
sign: sign$3,
|
|
14338
|
+
verify: verify$3,
|
|
14339
|
+
validateParams: validateParams$4
|
|
14216
14340
|
});
|
|
14217
14341
|
|
|
14218
14342
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
@@ -14404,7 +14528,7 @@ const nodeCrypto$9 = util.getNodeCrypto();
|
|
|
14404
14528
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
14405
14529
|
* @async
|
|
14406
14530
|
*/
|
|
14407
|
-
async function validateParams$
|
|
14531
|
+
async function validateParams$5(oid, Q, d) {
|
|
14408
14532
|
return validateStandardParams(enums.publicKey.ecdh, oid, Q, d);
|
|
14409
14533
|
}
|
|
14410
14534
|
|
|
@@ -14446,7 +14570,7 @@ async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTraili
|
|
|
14446
14570
|
/**
|
|
14447
14571
|
* Generate ECDHE ephemeral key and secret from public key
|
|
14448
14572
|
*
|
|
14449
|
-
* @param {
|
|
14573
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14450
14574
|
* @param {Uint8Array} Q - Recipient public key
|
|
14451
14575
|
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
14452
14576
|
* @async
|
|
@@ -14489,7 +14613,7 @@ async function genPublicEphemeralKey(curve, Q) {
|
|
|
14489
14613
|
async function encrypt$3(oid, kdfParams, data, Q, fingerprint) {
|
|
14490
14614
|
const m = encode$1(data);
|
|
14491
14615
|
|
|
14492
|
-
const curve = new
|
|
14616
|
+
const curve = new CurveWithOID(oid);
|
|
14493
14617
|
const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
|
|
14494
14618
|
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
|
|
14495
14619
|
const { keySize } = getCipher(kdfParams.cipher);
|
|
@@ -14501,7 +14625,7 @@ async function encrypt$3(oid, kdfParams, data, Q, fingerprint) {
|
|
|
14501
14625
|
/**
|
|
14502
14626
|
* Generate ECDHE secret from private key and public part of ephemeral key
|
|
14503
14627
|
*
|
|
14504
|
-
* @param {
|
|
14628
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14505
14629
|
* @param {Uint8Array} V - Public part of ephemeral key
|
|
14506
14630
|
* @param {Uint8Array} Q - Recipient public key
|
|
14507
14631
|
* @param {Uint8Array} d - Recipient private key
|
|
@@ -14549,7 +14673,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) {
|
|
|
14549
14673
|
* @async
|
|
14550
14674
|
*/
|
|
14551
14675
|
async function decrypt$3(oid, kdfParams, V, C, Q, d, fingerprint) {
|
|
14552
|
-
const curve = new
|
|
14676
|
+
const curve = new CurveWithOID(oid);
|
|
14553
14677
|
const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
|
|
14554
14678
|
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
|
|
14555
14679
|
const { keySize } = getCipher(kdfParams.cipher);
|
|
@@ -14569,7 +14693,7 @@ async function decrypt$3(oid, kdfParams, V, C, Q, d, fingerprint) {
|
|
|
14569
14693
|
/**
|
|
14570
14694
|
* Generate ECDHE secret from private key and public part of ephemeral key using webCrypto
|
|
14571
14695
|
*
|
|
14572
|
-
* @param {
|
|
14696
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14573
14697
|
* @param {Uint8Array} V - Public part of ephemeral key
|
|
14574
14698
|
* @param {Uint8Array} Q - Recipient public key
|
|
14575
14699
|
* @param {Uint8Array} d - Recipient private key
|
|
@@ -14622,7 +14746,7 @@ async function webPrivateEphemeralKey(curve, V, Q, d) {
|
|
|
14622
14746
|
/**
|
|
14623
14747
|
* Generate ECDHE ephemeral key and secret from public key using webCrypto
|
|
14624
14748
|
*
|
|
14625
|
-
* @param {
|
|
14749
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14626
14750
|
* @param {Uint8Array} Q - Recipient public key
|
|
14627
14751
|
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
14628
14752
|
* @async
|
|
@@ -14670,7 +14794,7 @@ async function webPublicEphemeralKey(curve, Q) {
|
|
|
14670
14794
|
/**
|
|
14671
14795
|
* Generate ECDHE secret from private key and public part of ephemeral key using indutny/elliptic
|
|
14672
14796
|
*
|
|
14673
|
-
* @param {
|
|
14797
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14674
14798
|
* @param {Uint8Array} V - Public part of ephemeral key
|
|
14675
14799
|
* @param {Uint8Array} d - Recipient private key
|
|
14676
14800
|
* @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
@@ -14690,7 +14814,7 @@ async function ellipticPrivateEphemeralKey(curve, V, d) {
|
|
|
14690
14814
|
/**
|
|
14691
14815
|
* Generate ECDHE ephemeral key and secret from public key using indutny/elliptic
|
|
14692
14816
|
*
|
|
14693
|
-
* @param {
|
|
14817
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14694
14818
|
* @param {Uint8Array} Q - Recipient public key
|
|
14695
14819
|
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
14696
14820
|
* @async
|
|
@@ -14710,7 +14834,7 @@ async function ellipticPublicEphemeralKey(curve, Q) {
|
|
|
14710
14834
|
/**
|
|
14711
14835
|
* Generate ECDHE secret from private key and public part of ephemeral key using nodeCrypto
|
|
14712
14836
|
*
|
|
14713
|
-
* @param {
|
|
14837
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14714
14838
|
* @param {Uint8Array} V - Public part of ephemeral key
|
|
14715
14839
|
* @param {Uint8Array} d - Recipient private key
|
|
14716
14840
|
* @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
@@ -14727,7 +14851,7 @@ async function nodePrivateEphemeralKey(curve, V, d) {
|
|
|
14727
14851
|
/**
|
|
14728
14852
|
* Generate ECDHE ephemeral key and secret from public key using nodeCrypto
|
|
14729
14853
|
*
|
|
14730
|
-
* @param {
|
|
14854
|
+
* @param {CurveWithOID} curve - Elliptic curve object
|
|
14731
14855
|
* @param {Uint8Array} Q - Recipient public key
|
|
14732
14856
|
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
|
|
14733
14857
|
* @async
|
|
@@ -14742,18 +14866,204 @@ async function nodePublicEphemeralKey(curve, Q) {
|
|
|
14742
14866
|
|
|
14743
14867
|
var ecdh = /*#__PURE__*/Object.freeze({
|
|
14744
14868
|
__proto__: null,
|
|
14745
|
-
validateParams: validateParams$
|
|
14869
|
+
validateParams: validateParams$5,
|
|
14746
14870
|
encrypt: encrypt$3,
|
|
14747
14871
|
decrypt: decrypt$3
|
|
14748
14872
|
});
|
|
14749
14873
|
|
|
14874
|
+
/**
|
|
14875
|
+
* @fileoverview This module implements HKDF using either the WebCrypto API or Node.js' crypto API.
|
|
14876
|
+
* @module crypto/hkdf
|
|
14877
|
+
* @private
|
|
14878
|
+
*/
|
|
14879
|
+
|
|
14880
|
+
const webCrypto$9 = util.getWebCrypto();
|
|
14881
|
+
const nodeCrypto$a = util.getNodeCrypto();
|
|
14882
|
+
const nodeSubtleCrypto = nodeCrypto$a && nodeCrypto$a.webcrypto && nodeCrypto$a.webcrypto.subtle;
|
|
14883
|
+
|
|
14884
|
+
async function HKDF(hashAlgo, inputKey, salt, info, outLen) {
|
|
14885
|
+
const hash = enums.read(enums.webHash, hashAlgo);
|
|
14886
|
+
if (!hash) throw new Error('Hash algo not supported with HKDF');
|
|
14887
|
+
|
|
14888
|
+
if (webCrypto$9 || nodeSubtleCrypto) {
|
|
14889
|
+
const crypto = webCrypto$9 || nodeSubtleCrypto;
|
|
14890
|
+
const importedKey = await crypto.importKey('raw', inputKey, 'HKDF', false, ['deriveBits']);
|
|
14891
|
+
const bits = await crypto.deriveBits({ name: 'HKDF', hash, salt, info }, importedKey, outLen * 8);
|
|
14892
|
+
return new Uint8Array(bits);
|
|
14893
|
+
}
|
|
14894
|
+
|
|
14895
|
+
if (nodeCrypto$a) {
|
|
14896
|
+
const hashAlgoName = enums.read(enums.hash, hashAlgo);
|
|
14897
|
+
// Node-only HKDF implementation based on https://www.rfc-editor.org/rfc/rfc5869
|
|
14898
|
+
|
|
14899
|
+
const computeHMAC = (hmacKey, hmacMessage) => nodeCrypto$a.createHmac(hashAlgoName, hmacKey).update(hmacMessage).digest();
|
|
14900
|
+
// Step 1: Extract
|
|
14901
|
+
// PRK = HMAC-Hash(salt, IKM)
|
|
14902
|
+
const pseudoRandomKey = computeHMAC(salt, inputKey);
|
|
14903
|
+
|
|
14904
|
+
const hashLen = pseudoRandomKey.length;
|
|
14905
|
+
|
|
14906
|
+
// Step 2: Expand
|
|
14907
|
+
// HKDF-Expand(PRK, info, L) -> OKM
|
|
14908
|
+
const n = Math.ceil(outLen / hashLen);
|
|
14909
|
+
const outputKeyingMaterial = new Uint8Array(n * hashLen);
|
|
14910
|
+
|
|
14911
|
+
// HMAC input buffer updated at each iteration
|
|
14912
|
+
const roundInput = new Uint8Array(hashLen + info.length + 1);
|
|
14913
|
+
// T_i and last byte are updated at each iteration, but `info` remains constant
|
|
14914
|
+
roundInput.set(info, hashLen);
|
|
14915
|
+
|
|
14916
|
+
for (let i = 0; i < n; i++) {
|
|
14917
|
+
// T(0) = empty string (zero length)
|
|
14918
|
+
// T(i) = HMAC-Hash(PRK, T(i-1) | info | i)
|
|
14919
|
+
roundInput[roundInput.length - 1] = i + 1;
|
|
14920
|
+
// t = T(i+1)
|
|
14921
|
+
const t = computeHMAC(pseudoRandomKey, i > 0 ? roundInput : roundInput.subarray(hashLen));
|
|
14922
|
+
roundInput.set(t, 0);
|
|
14923
|
+
|
|
14924
|
+
outputKeyingMaterial.set(t, i * hashLen);
|
|
14925
|
+
}
|
|
14926
|
+
|
|
14927
|
+
return outputKeyingMaterial.subarray(0, outLen);
|
|
14928
|
+
}
|
|
14929
|
+
|
|
14930
|
+
throw new Error('No HKDF implementation available');
|
|
14931
|
+
}
|
|
14932
|
+
|
|
14933
|
+
/**
|
|
14934
|
+
* @fileoverview Key encryption and decryption for RFC 6637 ECDH
|
|
14935
|
+
* @module crypto/public_key/elliptic/ecdh
|
|
14936
|
+
* @private
|
|
14937
|
+
*/
|
|
14938
|
+
|
|
14939
|
+
const HKDF_INFO = {
|
|
14940
|
+
x25519: util.encodeUTF8('OpenPGP X25519')
|
|
14941
|
+
};
|
|
14942
|
+
|
|
14943
|
+
/**
|
|
14944
|
+
* Generate ECDH key for Montgomery curves
|
|
14945
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14946
|
+
* @returns {Promise<{ A: Uint8Array, k: Uint8Array }>}
|
|
14947
|
+
*/
|
|
14948
|
+
async function generate$3(algo) {
|
|
14949
|
+
switch (algo) {
|
|
14950
|
+
case enums.publicKey.x25519: {
|
|
14951
|
+
// k stays in little-endian, unlike legacy ECDH over curve25519
|
|
14952
|
+
const k = getRandomBytes(32);
|
|
14953
|
+
k[0] &= 248;
|
|
14954
|
+
k[31] = (k[31] & 127) | 64;
|
|
14955
|
+
const { publicKey: A } = naclFastLight.box.keyPair.fromSecretKey(k);
|
|
14956
|
+
return { A, k };
|
|
14957
|
+
}
|
|
14958
|
+
default:
|
|
14959
|
+
throw new Error('Unsupported ECDH algorithm');
|
|
14960
|
+
}
|
|
14961
|
+
}
|
|
14962
|
+
|
|
14963
|
+
/**
|
|
14964
|
+
* Validate ECDH parameters
|
|
14965
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14966
|
+
* @param {Uint8Array} A - ECDH public point
|
|
14967
|
+
* @param {Uint8Array} k - ECDH secret scalar
|
|
14968
|
+
* @returns {Promise<Boolean>} Whether params are valid.
|
|
14969
|
+
* @async
|
|
14970
|
+
*/
|
|
14971
|
+
async function validateParams$6(algo, A, k) {
|
|
14972
|
+
switch (algo) {
|
|
14973
|
+
case enums.publicKey.x25519: {
|
|
14974
|
+
/**
|
|
14975
|
+
* Derive public point A' from private key
|
|
14976
|
+
* and expect A == A'
|
|
14977
|
+
*/
|
|
14978
|
+
const { publicKey } = naclFastLight.box.keyPair.fromSecretKey(k);
|
|
14979
|
+
return util.equalsUint8Array(A, publicKey);
|
|
14980
|
+
}
|
|
14981
|
+
|
|
14982
|
+
default:
|
|
14983
|
+
return false;
|
|
14984
|
+
}
|
|
14985
|
+
}
|
|
14986
|
+
|
|
14987
|
+
/**
|
|
14988
|
+
* Wrap and encrypt a session key
|
|
14989
|
+
*
|
|
14990
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
14991
|
+
* @param {Uint8Array} data - session key data to be encrypted
|
|
14992
|
+
* @param {Uint8Array} recipientA - Recipient public key (K_B)
|
|
14993
|
+
* @returns {Promise<{
|
|
14994
|
+
* ephemeralPublicKey: Uint8Array,
|
|
14995
|
+
* wrappedKey: Uint8Array
|
|
14996
|
+
* }>} ephemeral public key (K_A) and encrypted key
|
|
14997
|
+
* @async
|
|
14998
|
+
*/
|
|
14999
|
+
async function encrypt$4(algo, data, recipientA) {
|
|
15000
|
+
switch (algo) {
|
|
15001
|
+
case enums.publicKey.x25519: {
|
|
15002
|
+
const ephemeralSecretKey = getRandomBytes(32);
|
|
15003
|
+
const sharedSecret = naclFastLight.scalarMult(ephemeralSecretKey, recipientA);
|
|
15004
|
+
const { publicKey: ephemeralPublicKey } = naclFastLight.box.keyPair.fromSecretKey(ephemeralSecretKey);
|
|
15005
|
+
const hkdfInput = util.concatUint8Array([
|
|
15006
|
+
ephemeralPublicKey,
|
|
15007
|
+
recipientA,
|
|
15008
|
+
sharedSecret
|
|
15009
|
+
]);
|
|
15010
|
+
const { keySize } = getCipher(enums.symmetric.aes128);
|
|
15011
|
+
const encryptionKey = await HKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
|
|
15012
|
+
const wrappedKey = wrap(encryptionKey, data);
|
|
15013
|
+
return { ephemeralPublicKey, wrappedKey };
|
|
15014
|
+
}
|
|
15015
|
+
|
|
15016
|
+
default:
|
|
15017
|
+
throw new Error('Unsupported ECDH algorithm');
|
|
15018
|
+
}
|
|
15019
|
+
}
|
|
15020
|
+
|
|
15021
|
+
/**
|
|
15022
|
+
* Decrypt and unwrap the session key
|
|
15023
|
+
*
|
|
15024
|
+
* @param {module:enums.publicKey} algo - Algorithm identifier
|
|
15025
|
+
* @param {Uint8Array} ephemeralPublicKey - (K_A)
|
|
15026
|
+
* @param {Uint8Array} wrappedKey,
|
|
15027
|
+
* @param {Uint8Array} A - Recipient public key (K_b), needed for KDF
|
|
15028
|
+
* @param {Uint8Array} k - Recipient secret key (b)
|
|
15029
|
+
* @returns {Promise<Uint8Array>} decrypted session key data
|
|
15030
|
+
* @async
|
|
15031
|
+
*/
|
|
15032
|
+
async function decrypt$4(algo, ephemeralPublicKey, wrappedKey, A, k) {
|
|
15033
|
+
switch (algo) {
|
|
15034
|
+
case enums.publicKey.x25519: {
|
|
15035
|
+
const sharedSecret = naclFastLight.scalarMult(k, ephemeralPublicKey);
|
|
15036
|
+
const hkdfInput = util.concatUint8Array([
|
|
15037
|
+
ephemeralPublicKey,
|
|
15038
|
+
A,
|
|
15039
|
+
sharedSecret
|
|
15040
|
+
]);
|
|
15041
|
+
const { keySize } = getCipher(enums.symmetric.aes128);
|
|
15042
|
+
const encryptionKey = await HKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
|
|
15043
|
+
return unwrap(encryptionKey, wrappedKey);
|
|
15044
|
+
}
|
|
15045
|
+
default:
|
|
15046
|
+
throw new Error('Unsupported ECDH algorithm');
|
|
15047
|
+
}
|
|
15048
|
+
}
|
|
15049
|
+
|
|
15050
|
+
var ecdh_x = /*#__PURE__*/Object.freeze({
|
|
15051
|
+
__proto__: null,
|
|
15052
|
+
generate: generate$3,
|
|
15053
|
+
validateParams: validateParams$6,
|
|
15054
|
+
encrypt: encrypt$4,
|
|
15055
|
+
decrypt: decrypt$4
|
|
15056
|
+
});
|
|
15057
|
+
|
|
14750
15058
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
14751
15059
|
|
|
14752
15060
|
var elliptic = /*#__PURE__*/Object.freeze({
|
|
14753
15061
|
__proto__: null,
|
|
14754
|
-
|
|
15062
|
+
CurveWithOID: CurveWithOID,
|
|
14755
15063
|
ecdh: ecdh,
|
|
15064
|
+
ecdhX: ecdh_x,
|
|
14756
15065
|
ecdsa: ecdsa,
|
|
15066
|
+
eddsaLegacy: eddsa_legacy,
|
|
14757
15067
|
eddsa: eddsa,
|
|
14758
15068
|
generate: generate$1,
|
|
14759
15069
|
getPreferredHashAlgo: getPreferredHashAlgo
|
|
@@ -14778,7 +15088,7 @@ var elliptic = /*#__PURE__*/Object.freeze({
|
|
|
14778
15088
|
* @returns {Promise<{ r: Uint8Array, s: Uint8Array }>}
|
|
14779
15089
|
* @async
|
|
14780
15090
|
*/
|
|
14781
|
-
async function sign$
|
|
15091
|
+
async function sign$4(hashAlgo, hashed, g, p, q, x) {
|
|
14782
15092
|
const BigInteger = await util.getBigInteger();
|
|
14783
15093
|
const one = new BigInteger(1);
|
|
14784
15094
|
p = new BigInteger(p);
|
|
@@ -14837,7 +15147,7 @@ async function sign$3(hashAlgo, hashed, g, p, q, x) {
|
|
|
14837
15147
|
* @returns {boolean}
|
|
14838
15148
|
* @async
|
|
14839
15149
|
*/
|
|
14840
|
-
async function verify$
|
|
15150
|
+
async function verify$4(hashAlgo, r, s, hashed, g, p, q, y) {
|
|
14841
15151
|
const BigInteger = await util.getBigInteger();
|
|
14842
15152
|
const zero = new BigInteger(0);
|
|
14843
15153
|
r = new BigInteger(r);
|
|
@@ -14880,7 +15190,7 @@ async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
|
|
|
14880
15190
|
* @returns {Promise<Boolean>} Whether params are valid.
|
|
14881
15191
|
* @async
|
|
14882
15192
|
*/
|
|
14883
|
-
async function validateParams$
|
|
15193
|
+
async function validateParams$7(p, q, g, y, x) {
|
|
14884
15194
|
const BigInteger = await util.getBigInteger();
|
|
14885
15195
|
p = new BigInteger(p);
|
|
14886
15196
|
q = new BigInteger(q);
|
|
@@ -14935,9 +15245,9 @@ async function validateParams$5(p, q, g, y, x) {
|
|
|
14935
15245
|
|
|
14936
15246
|
var dsa = /*#__PURE__*/Object.freeze({
|
|
14937
15247
|
__proto__: null,
|
|
14938
|
-
sign: sign$
|
|
14939
|
-
verify: verify$
|
|
14940
|
-
validateParams: validateParams$
|
|
15248
|
+
sign: sign$4,
|
|
15249
|
+
verify: verify$4,
|
|
15250
|
+
validateParams: validateParams$7
|
|
14941
15251
|
});
|
|
14942
15252
|
|
|
14943
15253
|
/**
|
|
@@ -15073,10 +15383,11 @@ function parseSignatureParams(algo, signature) {
|
|
|
15073
15383
|
const s = util.readMPI(signature.subarray(read));
|
|
15074
15384
|
return { r, s };
|
|
15075
15385
|
}
|
|
15076
|
-
// Algorithm-Specific Fields for EdDSA signatures:
|
|
15386
|
+
// Algorithm-Specific Fields for legacy EdDSA signatures:
|
|
15077
15387
|
// - MPI of an EC point r.
|
|
15078
15388
|
// - EdDSA value s, in MPI, in the little endian representation
|
|
15079
|
-
case enums.publicKey.eddsa:
|
|
15389
|
+
case enums.publicKey.eddsa:
|
|
15390
|
+
case enums.publicKey.ed25519Legacy: {
|
|
15080
15391
|
// When parsing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
|
|
15081
15392
|
// https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
|
|
15082
15393
|
let r = util.readMPI(signature.subarray(read)); read += r.length + 2;
|
|
@@ -15085,7 +15396,12 @@ function parseSignatureParams(algo, signature) {
|
|
|
15085
15396
|
s = util.leftPad(s, 32);
|
|
15086
15397
|
return { r, s };
|
|
15087
15398
|
}
|
|
15088
|
-
|
|
15399
|
+
// Algorithm-Specific Fields for Ed25519 signatures:
|
|
15400
|
+
// - 64 octets of the native signature
|
|
15401
|
+
case enums.publicKey.ed25519: {
|
|
15402
|
+
const RS = signature.subarray(read, read + 64); read += RS.length;
|
|
15403
|
+
return { RS };
|
|
15404
|
+
}
|
|
15089
15405
|
case enums.publicKey.hmac: {
|
|
15090
15406
|
const mac = new ShortByteString(); mac.read(signature.subarray(read));
|
|
15091
15407
|
return { mac };
|
|
@@ -15110,7 +15426,7 @@ function parseSignatureParams(algo, signature) {
|
|
|
15110
15426
|
* @returns {Promise<Boolean>} True if signature is valid.
|
|
15111
15427
|
* @async
|
|
15112
15428
|
*/
|
|
15113
|
-
async function verify$
|
|
15429
|
+
async function verify$5(algo, hashAlgo, signature, publicParams, privateParams, data, hashed) {
|
|
15114
15430
|
switch (algo) {
|
|
15115
15431
|
case enums.publicKey.rsaEncryptSign:
|
|
15116
15432
|
case enums.publicKey.rsaEncrypt:
|
|
@@ -15126,16 +15442,21 @@ async function verify$4(algo, hashAlgo, signature, publicParams, privateParams,
|
|
|
15126
15442
|
}
|
|
15127
15443
|
case enums.publicKey.ecdsa: {
|
|
15128
15444
|
const { oid, Q } = publicParams;
|
|
15129
|
-
const curveSize = new publicKey.elliptic.
|
|
15445
|
+
const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize;
|
|
15130
15446
|
// padding needed for webcrypto
|
|
15131
15447
|
const r = util.leftPad(signature.r, curveSize);
|
|
15132
15448
|
const s = util.leftPad(signature.s, curveSize);
|
|
15133
15449
|
return publicKey.elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
|
|
15134
15450
|
}
|
|
15135
|
-
case enums.publicKey.eddsa:
|
|
15451
|
+
case enums.publicKey.eddsa:
|
|
15452
|
+
case enums.publicKey.ed25519Legacy: {
|
|
15136
15453
|
const { oid, Q } = publicParams;
|
|
15137
15454
|
// signature already padded on parsing
|
|
15138
|
-
return publicKey.elliptic.
|
|
15455
|
+
return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, signature, data, Q, hashed);
|
|
15456
|
+
}
|
|
15457
|
+
case enums.publicKey.ed25519: {
|
|
15458
|
+
const { A } = publicParams;
|
|
15459
|
+
return publicKey.elliptic.eddsa.verify(algo, hashAlgo, signature, data, A, hashed);
|
|
15139
15460
|
}
|
|
15140
15461
|
case enums.publicKey.hmac: {
|
|
15141
15462
|
if (!privateParams) {
|
|
@@ -15165,7 +15486,7 @@ async function verify$4(algo, hashAlgo, signature, publicParams, privateParams,
|
|
|
15165
15486
|
* @returns {Promise<Object>} Signature Object containing named signature parameters.
|
|
15166
15487
|
* @async
|
|
15167
15488
|
*/
|
|
15168
|
-
async function sign$
|
|
15489
|
+
async function sign$5(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) {
|
|
15169
15490
|
if (!publicKeyParams || !privateKeyParams) {
|
|
15170
15491
|
throw new Error('Missing key parameters');
|
|
15171
15492
|
}
|
|
@@ -15191,10 +15512,16 @@ async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
|
|
|
15191
15512
|
const { d } = privateKeyParams;
|
|
15192
15513
|
return publicKey.elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
|
|
15193
15514
|
}
|
|
15194
|
-
case enums.publicKey.eddsa:
|
|
15515
|
+
case enums.publicKey.eddsa:
|
|
15516
|
+
case enums.publicKey.ed25519Legacy: {
|
|
15195
15517
|
const { oid, Q } = publicKeyParams;
|
|
15196
15518
|
const { seed } = privateKeyParams;
|
|
15197
|
-
return publicKey.elliptic.
|
|
15519
|
+
return publicKey.elliptic.eddsaLegacy.sign(oid, hashAlgo, data, Q, seed, hashed);
|
|
15520
|
+
}
|
|
15521
|
+
case enums.publicKey.ed25519: {
|
|
15522
|
+
const { A } = publicKeyParams;
|
|
15523
|
+
const { seed } = privateKeyParams;
|
|
15524
|
+
return publicKey.elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed);
|
|
15198
15525
|
}
|
|
15199
15526
|
case enums.publicKey.hmac: {
|
|
15200
15527
|
const { cipher: algo } = publicKeyParams;
|
|
@@ -15210,34 +15537,31 @@ async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
|
|
|
15210
15537
|
var signature = /*#__PURE__*/Object.freeze({
|
|
15211
15538
|
__proto__: null,
|
|
15212
15539
|
parseSignatureParams: parseSignatureParams,
|
|
15213
|
-
verify: verify$
|
|
15214
|
-
sign: sign$
|
|
15540
|
+
verify: verify$5,
|
|
15541
|
+
sign: sign$5
|
|
15215
15542
|
});
|
|
15216
15543
|
|
|
15217
15544
|
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
15218
15545
|
|
|
15219
15546
|
class ECDHSymmetricKey {
|
|
15220
15547
|
constructor(data) {
|
|
15221
|
-
if (
|
|
15222
|
-
data =
|
|
15223
|
-
} else if (util.isString(data)) {
|
|
15224
|
-
data = util.stringToUint8Array(data);
|
|
15225
|
-
} else {
|
|
15226
|
-
data = new Uint8Array(data);
|
|
15548
|
+
if (data) {
|
|
15549
|
+
this.data = data;
|
|
15227
15550
|
}
|
|
15228
|
-
this.data = data;
|
|
15229
15551
|
}
|
|
15230
15552
|
|
|
15231
15553
|
/**
|
|
15232
|
-
* Read an ECDHSymmetricKey from an Uint8Array
|
|
15233
|
-
*
|
|
15554
|
+
* Read an ECDHSymmetricKey from an Uint8Array:
|
|
15555
|
+
* - 1 octect for the length `l`
|
|
15556
|
+
* - `l` octects of encoded session key data
|
|
15557
|
+
* @param {Uint8Array} bytes
|
|
15234
15558
|
* @returns {Number} Number of read bytes.
|
|
15235
15559
|
*/
|
|
15236
|
-
read(
|
|
15237
|
-
if (
|
|
15238
|
-
const length =
|
|
15239
|
-
if (
|
|
15240
|
-
this.data =
|
|
15560
|
+
read(bytes) {
|
|
15561
|
+
if (bytes.length >= 1) {
|
|
15562
|
+
const length = bytes[0];
|
|
15563
|
+
if (bytes.length >= 1 + length) {
|
|
15564
|
+
this.data = bytes.subarray(1, 1 + length);
|
|
15241
15565
|
return 1 + this.data.length;
|
|
15242
15566
|
}
|
|
15243
15567
|
}
|
|
@@ -15246,7 +15570,7 @@ class ECDHSymmetricKey {
|
|
|
15246
15570
|
|
|
15247
15571
|
/**
|
|
15248
15572
|
* Write an ECDHSymmetricKey as an Uint8Array
|
|
15249
|
-
* @returns {Uint8Array}
|
|
15573
|
+
* @returns {Uint8Array} Serialised data
|
|
15250
15574
|
*/
|
|
15251
15575
|
write() {
|
|
15252
15576
|
return util.concatUint8Array([new Uint8Array([this.data.length]), this.data]);
|
|
@@ -15286,6 +15610,9 @@ class KDFParams {
|
|
|
15286
15610
|
* @returns {Number} Number of read bytes.
|
|
15287
15611
|
*/
|
|
15288
15612
|
read(input) {
|
|
15613
|
+
if (input.length < 4 || (input[1] !== 1 && input[1] !== VERSION_FORWARDING)) {
|
|
15614
|
+
throw new UnsupportedError('Cannot read KDFParams');
|
|
15615
|
+
}
|
|
15289
15616
|
const totalBytes = input[0];
|
|
15290
15617
|
this.version = input[1];
|
|
15291
15618
|
this.hash = input[2];
|
|
@@ -15373,12 +15700,57 @@ const AEADEnum = type_enum(enums.aead);
|
|
|
15373
15700
|
const SymAlgoEnum = type_enum(enums.symmetric);
|
|
15374
15701
|
const HashEnum = type_enum(enums.hash);
|
|
15375
15702
|
|
|
15703
|
+
/**
|
|
15704
|
+
* Encoded symmetric key for x25519 and x448
|
|
15705
|
+
* The payload format varies for v3 and v6 PKESK:
|
|
15706
|
+
* the former includes an algorithm byte preceeding the encrypted session key.
|
|
15707
|
+
*
|
|
15708
|
+
* @module type/x25519x448_symkey
|
|
15709
|
+
*/
|
|
15710
|
+
|
|
15711
|
+
class ECDHXSymmetricKey {
|
|
15712
|
+
static fromObject({ wrappedKey, algorithm }) {
|
|
15713
|
+
const instance = new ECDHXSymmetricKey();
|
|
15714
|
+
instance.wrappedKey = wrappedKey;
|
|
15715
|
+
instance.algorithm = algorithm;
|
|
15716
|
+
return instance;
|
|
15717
|
+
}
|
|
15718
|
+
|
|
15719
|
+
/**
|
|
15720
|
+
* - 1 octect for the length `l`
|
|
15721
|
+
* - `l` octects of encoded session key data (with optional leading algorithm byte)
|
|
15722
|
+
* @param {Uint8Array} bytes
|
|
15723
|
+
* @returns {Number} Number of read bytes.
|
|
15724
|
+
*/
|
|
15725
|
+
read(bytes) {
|
|
15726
|
+
let read = 0;
|
|
15727
|
+
let followLength = bytes[read++];
|
|
15728
|
+
this.algorithm = followLength % 2 ? bytes[read++] : null; // session key size is always even
|
|
15729
|
+
followLength -= followLength % 2;
|
|
15730
|
+
this.wrappedKey = bytes.subarray(read, read + followLength); read += followLength;
|
|
15731
|
+
}
|
|
15732
|
+
|
|
15733
|
+
/**
|
|
15734
|
+
* Write an MontgomerySymmetricKey as an Uint8Array
|
|
15735
|
+
* @returns {Uint8Array} Serialised data
|
|
15736
|
+
*/
|
|
15737
|
+
write() {
|
|
15738
|
+
return util.concatUint8Array([
|
|
15739
|
+
this.algorithm ?
|
|
15740
|
+
new Uint8Array([this.wrappedKey.length + 1, this.algorithm]) :
|
|
15741
|
+
new Uint8Array([this.wrappedKey.length]),
|
|
15742
|
+
this.wrappedKey
|
|
15743
|
+
]);
|
|
15744
|
+
}
|
|
15745
|
+
}
|
|
15746
|
+
|
|
15376
15747
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
15377
15748
|
|
|
15378
15749
|
/**
|
|
15379
15750
|
* Encrypts data using specified algorithm and public key parameters.
|
|
15380
15751
|
* See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1} for public key algorithms.
|
|
15381
|
-
* @param {module:enums.publicKey}
|
|
15752
|
+
* @param {module:enums.publicKey} keyAlgo - Public key algorithm
|
|
15753
|
+
* @param {module:enums.symmetric} symmetricAlgo - Cipher algorithm
|
|
15382
15754
|
* @param {Object} publicParams - Algorithm-specific public key parameters
|
|
15383
15755
|
* @param {Object} privateParams - Algorithm-specific private key parameters
|
|
15384
15756
|
* @param {Uint8Array} data - Data to be encrypted
|
|
@@ -15386,8 +15758,8 @@ const HashEnum = type_enum(enums.hash);
|
|
|
15386
15758
|
* @returns {Promise<Object>} Encrypted session key parameters.
|
|
15387
15759
|
* @async
|
|
15388
15760
|
*/
|
|
15389
|
-
async function publicKeyEncrypt(
|
|
15390
|
-
switch (
|
|
15761
|
+
async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, privateParams, data, fingerprint) {
|
|
15762
|
+
switch (keyAlgo) {
|
|
15391
15763
|
case enums.publicKey.rsaEncrypt:
|
|
15392
15764
|
case enums.publicKey.rsaEncryptSign: {
|
|
15393
15765
|
const { n, e } = publicParams;
|
|
@@ -15404,6 +15776,17 @@ async function publicKeyEncrypt(algo, publicParams, privateParams, data, fingerp
|
|
|
15404
15776
|
oid, kdfParams, data, Q, fingerprint);
|
|
15405
15777
|
return { V, C: new ECDHSymmetricKey(C) };
|
|
15406
15778
|
}
|
|
15779
|
+
case enums.publicKey.x25519: {
|
|
15780
|
+
if (!util.isAES(symmetricAlgo)) {
|
|
15781
|
+
// see https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/276
|
|
15782
|
+
throw new Error('X25519 keys can only encrypt AES session keys');
|
|
15783
|
+
}
|
|
15784
|
+
const { A } = publicParams;
|
|
15785
|
+
const { ephemeralPublicKey, wrappedKey } = await publicKey.elliptic.ecdhX.encrypt(
|
|
15786
|
+
keyAlgo, data, A);
|
|
15787
|
+
const C = ECDHXSymmetricKey.fromObject({ algorithm: symmetricAlgo, wrappedKey });
|
|
15788
|
+
return { ephemeralPublicKey, C };
|
|
15789
|
+
}
|
|
15407
15790
|
case enums.publicKey.aead: {
|
|
15408
15791
|
if (!privateParams) {
|
|
15409
15792
|
throw new Error('Cannot encrypt with symmetric key missing private parameters');
|
|
@@ -15460,6 +15843,16 @@ async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, session
|
|
|
15460
15843
|
return publicKey.elliptic.ecdh.decrypt(
|
|
15461
15844
|
oid, kdfParams, V, C.data, Q, d, fingerprint);
|
|
15462
15845
|
}
|
|
15846
|
+
case enums.publicKey.x25519: {
|
|
15847
|
+
const { A } = publicKeyParams;
|
|
15848
|
+
const { k } = privateKeyParams;
|
|
15849
|
+
const { ephemeralPublicKey, C } = sessionKeyParams;
|
|
15850
|
+
if (!util.isAES(C.algorithm)) {
|
|
15851
|
+
throw new Error('AES session key expected');
|
|
15852
|
+
}
|
|
15853
|
+
return publicKey.elliptic.ecdhX.decrypt(
|
|
15854
|
+
algo, ephemeralPublicKey, C.wrappedKey, A, k);
|
|
15855
|
+
}
|
|
15463
15856
|
case enums.publicKey.aead: {
|
|
15464
15857
|
const { cipher: algo } = publicKeyParams;
|
|
15465
15858
|
const algoValue = algo.getValue();
|
|
@@ -15511,7 +15904,8 @@ function parsePublicKeyParams(algo, bytes) {
|
|
|
15511
15904
|
const Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
|
|
15512
15905
|
return { read: read, publicParams: { oid, Q } };
|
|
15513
15906
|
}
|
|
15514
|
-
case enums.publicKey.eddsa:
|
|
15907
|
+
case enums.publicKey.eddsa:
|
|
15908
|
+
case enums.publicKey.ed25519Legacy: {
|
|
15515
15909
|
const oid = new OID(); read += oid.read(bytes);
|
|
15516
15910
|
checkSupportedCurve(oid);
|
|
15517
15911
|
let Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
|
|
@@ -15525,6 +15919,11 @@ function parsePublicKeyParams(algo, bytes) {
|
|
|
15525
15919
|
const kdfParams = new KDFParams(); read += kdfParams.read(bytes.subarray(read));
|
|
15526
15920
|
return { read: read, publicParams: { oid, Q, kdfParams } };
|
|
15527
15921
|
}
|
|
15922
|
+
case enums.publicKey.ed25519:
|
|
15923
|
+
case enums.publicKey.x25519: {
|
|
15924
|
+
const A = bytes.subarray(read, read + 32); read += A.length;
|
|
15925
|
+
return { read, publicParams: { A } };
|
|
15926
|
+
}
|
|
15528
15927
|
case enums.publicKey.hmac:
|
|
15529
15928
|
case enums.publicKey.aead: {
|
|
15530
15929
|
const algo = new SymAlgoEnum(); read += algo.read(bytes);
|
|
@@ -15563,17 +15962,26 @@ function parsePrivateKeyParams(algo, bytes, publicParams) {
|
|
|
15563
15962
|
}
|
|
15564
15963
|
case enums.publicKey.ecdsa:
|
|
15565
15964
|
case enums.publicKey.ecdh: {
|
|
15566
|
-
const curve = new
|
|
15965
|
+
const curve = new CurveWithOID(publicParams.oid);
|
|
15567
15966
|
let d = util.readMPI(bytes.subarray(read)); read += d.length + 2;
|
|
15568
15967
|
d = util.leftPad(d, curve.payloadSize);
|
|
15569
15968
|
return { read, privateParams: { d } };
|
|
15570
15969
|
}
|
|
15571
|
-
case enums.publicKey.eddsa:
|
|
15572
|
-
|
|
15970
|
+
case enums.publicKey.eddsa:
|
|
15971
|
+
case enums.publicKey.ed25519Legacy: {
|
|
15972
|
+
const curve = new CurveWithOID(publicParams.oid);
|
|
15573
15973
|
let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2;
|
|
15574
15974
|
seed = util.leftPad(seed, curve.payloadSize);
|
|
15575
15975
|
return { read, privateParams: { seed } };
|
|
15576
15976
|
}
|
|
15977
|
+
case enums.publicKey.ed25519: {
|
|
15978
|
+
const seed = bytes.subarray(read, read + 32); read += seed.length;
|
|
15979
|
+
return { read, privateParams: { seed } };
|
|
15980
|
+
}
|
|
15981
|
+
case enums.publicKey.x25519: {
|
|
15982
|
+
const k = bytes.subarray(read, read + 32); read += k.length;
|
|
15983
|
+
return { read, privateParams: { k } };
|
|
15984
|
+
}
|
|
15577
15985
|
case enums.publicKey.hmac: {
|
|
15578
15986
|
const { cipher: algo } = publicParams;
|
|
15579
15987
|
const keySize = hash.getHashByteLength(algo.getValue());
|
|
@@ -15625,6 +16033,16 @@ function parseEncSessionKeyParams(algo, bytes) {
|
|
|
15625
16033
|
const C = new ECDHSymmetricKey(); C.read(bytes.subarray(read));
|
|
15626
16034
|
return { V, C };
|
|
15627
16035
|
}
|
|
16036
|
+
// Algorithm-Specific Fields for X25519 encrypted session keys:
|
|
16037
|
+
// - 32 octets representing an ephemeral X25519 public key.
|
|
16038
|
+
// - A one-octet size of the following fields.
|
|
16039
|
+
// - The one-octet algorithm identifier, if it was passed (in the case of a v3 PKESK packet).
|
|
16040
|
+
// - The encrypted session key.
|
|
16041
|
+
case enums.publicKey.x25519: {
|
|
16042
|
+
const ephemeralPublicKey = bytes.subarray(read, read + 32); read += ephemeralPublicKey.length;
|
|
16043
|
+
const C = new ECDHXSymmetricKey(); C.read(bytes.subarray(read));
|
|
16044
|
+
return { ephemeralPublicKey, C };
|
|
16045
|
+
}
|
|
15628
16046
|
// Algorithm-Specific Fields for symmetric AEAD encryption:
|
|
15629
16047
|
// - AEAD algorithm
|
|
15630
16048
|
// - Starting initialization vector
|
|
@@ -15651,22 +16069,13 @@ function parseEncSessionKeyParams(algo, bytes) {
|
|
|
15651
16069
|
* @returns {Uint8Array} The array containing the MPIs.
|
|
15652
16070
|
*/
|
|
15653
16071
|
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
|
-
}
|
|
16072
|
+
// Some algorithms do not rely on MPIs to store the binary params
|
|
16073
|
+
const algosWithNativeRepresentation = new Set([enums.publicKey.ed25519, enums.publicKey.x25519, enums.publicKey.aead, enums.publicKey.hmac]);
|
|
16074
|
+
const orderedParams = Object.keys(params).map(name => {
|
|
16075
|
+
const param = params[name];
|
|
16076
|
+
if (!util.isUint8Array(param)) return param.write();
|
|
16077
|
+
return algosWithNativeRepresentation.has(algo) ? param : util.uint8ArrayToMPI(param);
|
|
16078
|
+
});
|
|
15670
16079
|
return util.concatUint8Array(orderedParams);
|
|
15671
16080
|
}
|
|
15672
16081
|
|
|
@@ -15695,6 +16104,7 @@ function generateParams(algo, bits, oid, symmetric) {
|
|
|
15695
16104
|
publicParams: { oid: new OID(oid), Q }
|
|
15696
16105
|
}));
|
|
15697
16106
|
case enums.publicKey.eddsa:
|
|
16107
|
+
case enums.publicKey.ed25519Legacy:
|
|
15698
16108
|
return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
|
|
15699
16109
|
privateParams: { seed: secret },
|
|
15700
16110
|
publicParams: { oid: new OID(oid), Q }
|
|
@@ -15708,6 +16118,16 @@ function generateParams(algo, bits, oid, symmetric) {
|
|
|
15708
16118
|
kdfParams: new KDFParams({ hash, cipher })
|
|
15709
16119
|
}
|
|
15710
16120
|
}));
|
|
16121
|
+
case enums.publicKey.ed25519:
|
|
16122
|
+
return publicKey.elliptic.eddsa.generate(algo).then(({ A, seed }) => ({
|
|
16123
|
+
privateParams: { seed },
|
|
16124
|
+
publicParams: { A }
|
|
16125
|
+
}));
|
|
16126
|
+
case enums.publicKey.x25519:
|
|
16127
|
+
return publicKey.elliptic.ecdhX.generate(algo).then(({ A, k }) => ({
|
|
16128
|
+
privateParams: { k },
|
|
16129
|
+
publicParams: { A }
|
|
16130
|
+
}));
|
|
15711
16131
|
case enums.publicKey.hmac: {
|
|
15712
16132
|
const symAlgo = enums.write(enums.hash, symmetric);
|
|
15713
16133
|
const keyMaterial = getRandomBytes(hash.getHashByteLength(symAlgo));
|
|
@@ -15749,7 +16169,7 @@ async function createSymmetricParams(key, algo) {
|
|
|
15749
16169
|
* @returns {Promise<Boolean>} Whether the parameters are valid.
|
|
15750
16170
|
* @async
|
|
15751
16171
|
*/
|
|
15752
|
-
async function validateParams$
|
|
16172
|
+
async function validateParams$8(algo, publicParams, privateParams) {
|
|
15753
16173
|
if (!publicParams || !privateParams) {
|
|
15754
16174
|
throw new Error('Missing key parameters');
|
|
15755
16175
|
}
|
|
@@ -15778,10 +16198,21 @@ async function validateParams$6(algo, publicParams, privateParams) {
|
|
|
15778
16198
|
const { d } = privateParams;
|
|
15779
16199
|
return algoModule.validateParams(oid, Q, d);
|
|
15780
16200
|
}
|
|
15781
|
-
case enums.publicKey.eddsa:
|
|
15782
|
-
|
|
16201
|
+
case enums.publicKey.eddsa:
|
|
16202
|
+
case enums.publicKey.ed25519Legacy: {
|
|
16203
|
+
const { Q, oid } = publicParams;
|
|
16204
|
+
const { seed } = privateParams;
|
|
16205
|
+
return publicKey.elliptic.eddsaLegacy.validateParams(oid, Q, seed);
|
|
16206
|
+
}
|
|
16207
|
+
case enums.publicKey.ed25519: {
|
|
16208
|
+
const { A } = publicParams;
|
|
15783
16209
|
const { seed } = privateParams;
|
|
15784
|
-
return publicKey.elliptic.eddsa.validateParams(
|
|
16210
|
+
return publicKey.elliptic.eddsa.validateParams(algo, A, seed);
|
|
16211
|
+
}
|
|
16212
|
+
case enums.publicKey.x25519: {
|
|
16213
|
+
const { A } = publicParams;
|
|
16214
|
+
const { k } = privateParams;
|
|
16215
|
+
return publicKey.elliptic.ecdhX.validateParams(algo, A, k);
|
|
15785
16216
|
}
|
|
15786
16217
|
case enums.publicKey.hmac: {
|
|
15787
16218
|
const { cipher: algo, digest } = publicParams;
|
|
@@ -15860,7 +16291,7 @@ var crypto$1 = /*#__PURE__*/Object.freeze({
|
|
|
15860
16291
|
parseEncSessionKeyParams: parseEncSessionKeyParams,
|
|
15861
16292
|
serializeParams: serializeParams,
|
|
15862
16293
|
generateParams: generateParams,
|
|
15863
|
-
validateParams: validateParams$
|
|
16294
|
+
validateParams: validateParams$8,
|
|
15864
16295
|
getPrefixRandom: getPrefixRandom,
|
|
15865
16296
|
generateSessionKey: generateSessionKey,
|
|
15866
16297
|
getAEADMode: getAEADMode,
|
|
@@ -16107,15 +16538,15 @@ class GenericS2K {
|
|
|
16107
16538
|
this.type = 'gnu-dummy';
|
|
16108
16539
|
// GnuPG extension mode 1001 -- don't write secret key at all
|
|
16109
16540
|
} else {
|
|
16110
|
-
throw new
|
|
16541
|
+
throw new UnsupportedError('Unknown s2k gnu protection mode.');
|
|
16111
16542
|
}
|
|
16112
16543
|
} else {
|
|
16113
|
-
throw new
|
|
16544
|
+
throw new UnsupportedError('Unknown s2k type.');
|
|
16114
16545
|
}
|
|
16115
16546
|
break;
|
|
16116
16547
|
|
|
16117
16548
|
default:
|
|
16118
|
-
throw new
|
|
16549
|
+
throw new UnsupportedError('Unknown s2k type.'); // unreachable
|
|
16119
16550
|
}
|
|
16120
16551
|
|
|
16121
16552
|
return i;
|
|
@@ -16219,7 +16650,7 @@ function newS2KFromType(type, config$1 = config) {
|
|
|
16219
16650
|
case enums.s2k.simple:
|
|
16220
16651
|
return new GenericS2K(type, config$1);
|
|
16221
16652
|
default:
|
|
16222
|
-
throw new
|
|
16653
|
+
throw new UnsupportedError(`Unsupported S2K type ${type}`);
|
|
16223
16654
|
}
|
|
16224
16655
|
}
|
|
16225
16656
|
|
|
@@ -24973,13 +25404,17 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
24973
25404
|
* @param {Uint8Array} bytes - Payload of a tag 1 packet
|
|
24974
25405
|
*/
|
|
24975
25406
|
read(bytes) {
|
|
24976
|
-
|
|
25407
|
+
let i = 0;
|
|
25408
|
+
this.version = bytes[i++];
|
|
24977
25409
|
if (this.version !== VERSION$3) {
|
|
24978
25410
|
throw new UnsupportedError(`Version ${this.version} of the PKESK packet is unsupported.`);
|
|
24979
25411
|
}
|
|
24980
|
-
this.publicKeyID.read(bytes.subarray(
|
|
24981
|
-
this.publicKeyAlgorithm = bytes[
|
|
24982
|
-
this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(
|
|
25412
|
+
i += this.publicKeyID.read(bytes.subarray(i));
|
|
25413
|
+
this.publicKeyAlgorithm = bytes[i++];
|
|
25414
|
+
this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(i), this.version);
|
|
25415
|
+
if (this.publicKeyAlgorithm === enums.publicKey.x25519) {
|
|
25416
|
+
this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm);
|
|
25417
|
+
}
|
|
24983
25418
|
}
|
|
24984
25419
|
|
|
24985
25420
|
/**
|
|
@@ -25005,15 +25440,11 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
25005
25440
|
* @async
|
|
25006
25441
|
*/
|
|
25007
25442
|
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
25443
|
const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
|
|
25444
|
+
const encoded = encodeSessionKey(this.version, algo, this.sessionKeyAlgorithm, this.sessionKey);
|
|
25014
25445
|
const privateParams = algo === enums.publicKey.aead ? key.privateParams : null;
|
|
25015
25446
|
this.encrypted = await mod.publicKeyEncrypt(
|
|
25016
|
-
algo, key.publicParams, privateParams,
|
|
25447
|
+
algo, this.sessionKeyAlgorithm, key.publicParams, privateParams, encoded, key.getFingerprintBytes());
|
|
25017
25448
|
}
|
|
25018
25449
|
|
|
25019
25450
|
/**
|
|
@@ -25030,34 +25461,86 @@ class PublicKeyEncryptedSessionKeyPacket {
|
|
|
25030
25461
|
throw new Error('Decryption error');
|
|
25031
25462
|
}
|
|
25032
25463
|
|
|
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);
|
|
25464
|
+
const randomPayload = randomSessionKey ?
|
|
25465
|
+
encodeSessionKey(this.version, this.publicKeyAlgorithm, randomSessionKey.sessionKeyAlgorithm, randomSessionKey.sessionKey) :
|
|
25466
|
+
null;
|
|
25467
|
+
const decryptedData = await mod.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes(), randomPayload);
|
|
25051
25468
|
|
|
25052
|
-
}
|
|
25053
|
-
|
|
25054
|
-
|
|
25055
|
-
|
|
25056
|
-
|
|
25469
|
+
const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey);
|
|
25470
|
+
|
|
25471
|
+
// v3 Montgomery curves have cleartext cipher algo
|
|
25472
|
+
if (this.publicKeyAlgorithm !== enums.publicKey.x25519) {
|
|
25473
|
+
this.sessionKeyAlgorithm = sessionKeyAlgorithm;
|
|
25474
|
+
}
|
|
25475
|
+
this.sessionKey = sessionKey;
|
|
25476
|
+
}
|
|
25477
|
+
}
|
|
25478
|
+
|
|
25479
|
+
|
|
25480
|
+
function encodeSessionKey(version, keyAlgo, cipherAlgo, sessionKeyData) {
|
|
25481
|
+
switch (keyAlgo) {
|
|
25482
|
+
case enums.publicKey.rsaEncrypt:
|
|
25483
|
+
case enums.publicKey.rsaEncryptSign:
|
|
25484
|
+
case enums.publicKey.elgamal:
|
|
25485
|
+
case enums.publicKey.ecdh:
|
|
25486
|
+
case enums.publicKey.aead: {
|
|
25487
|
+
// add checksum
|
|
25488
|
+
return util.concatUint8Array([
|
|
25489
|
+
new Uint8Array([cipherAlgo]),
|
|
25490
|
+
sessionKeyData,
|
|
25491
|
+
util.writeChecksum(sessionKeyData.subarray(sessionKeyData.length % 8))
|
|
25492
|
+
]);
|
|
25493
|
+
}
|
|
25494
|
+
case enums.publicKey.x25519:
|
|
25495
|
+
return sessionKeyData;
|
|
25496
|
+
default:
|
|
25497
|
+
throw new Error('Unsupported public key algorithm');
|
|
25498
|
+
}
|
|
25499
|
+
}
|
|
25500
|
+
|
|
25501
|
+
|
|
25502
|
+
function decodeSessionKey(version, keyAlgo, decryptedData, randomSessionKey) {
|
|
25503
|
+
switch (keyAlgo) {
|
|
25504
|
+
case enums.publicKey.rsaEncrypt:
|
|
25505
|
+
case enums.publicKey.rsaEncryptSign:
|
|
25506
|
+
case enums.publicKey.elgamal:
|
|
25507
|
+
case enums.publicKey.ecdh:
|
|
25508
|
+
case enums.publicKey.aead: {
|
|
25509
|
+
// verify checksum in constant time
|
|
25510
|
+
const result = decryptedData.subarray(0, decryptedData.length - 2);
|
|
25511
|
+
const checksum = decryptedData.subarray(decryptedData.length - 2);
|
|
25512
|
+
const computedChecksum = util.writeChecksum(result.subarray(result.length % 8));
|
|
25513
|
+
const isValidChecksum = computedChecksum[0] === checksum[0] & computedChecksum[1] === checksum[1];
|
|
25514
|
+
const decryptedSessionKey = { sessionKeyAlgorithm: result[0], sessionKey: result.subarray(1) };
|
|
25515
|
+
if (randomSessionKey) {
|
|
25516
|
+
// We must not leak info about the validity of the decrypted checksum or cipher algo.
|
|
25517
|
+
// 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.
|
|
25518
|
+
const isValidPayload = isValidChecksum &
|
|
25519
|
+
decryptedSessionKey.sessionKeyAlgorithm === randomSessionKey.sessionKeyAlgorithm &
|
|
25520
|
+
decryptedSessionKey.sessionKey.length === randomSessionKey.sessionKey.length;
|
|
25521
|
+
return {
|
|
25522
|
+
sessionKey: util.selectUint8Array(isValidPayload, decryptedSessionKey.sessionKey, randomSessionKey.sessionKey),
|
|
25523
|
+
sessionKeyAlgorithm: util.selectUint8(
|
|
25524
|
+
isValidPayload,
|
|
25525
|
+
decryptedSessionKey.sessionKeyAlgorithm,
|
|
25526
|
+
randomSessionKey.sessionKeyAlgorithm
|
|
25527
|
+
)
|
|
25528
|
+
};
|
|
25057
25529
|
} else {
|
|
25058
|
-
|
|
25530
|
+
const isValidPayload = isValidChecksum && enums.read(enums.symmetric, decryptedSessionKey.sessionKeyAlgorithm);
|
|
25531
|
+
if (isValidPayload) {
|
|
25532
|
+
return decryptedSessionKey;
|
|
25533
|
+
} else {
|
|
25534
|
+
throw new Error('Decryption error');
|
|
25535
|
+
}
|
|
25059
25536
|
}
|
|
25060
25537
|
}
|
|
25538
|
+
case enums.publicKey.x25519:
|
|
25539
|
+
return {
|
|
25540
|
+
sessionKey: decryptedData
|
|
25541
|
+
};
|
|
25542
|
+
default:
|
|
25543
|
+
throw new Error('Unsupported public key algorithm');
|
|
25061
25544
|
}
|
|
25062
25545
|
}
|
|
25063
25546
|
|
|
@@ -25488,7 +25971,7 @@ class PublicKeyPacket {
|
|
|
25488
25971
|
result.bits = util.uint8ArrayBitLength(modulo);
|
|
25489
25972
|
} else if (this.publicParams.oid) {
|
|
25490
25973
|
result.curve = this.publicParams.oid.getName();
|
|
25491
|
-
} else {
|
|
25974
|
+
} else if (this.publicParams.cipher) {
|
|
25492
25975
|
result.symmetric = this.publicParams.cipher.getName();
|
|
25493
25976
|
}
|
|
25494
25977
|
return result;
|
|
@@ -25820,6 +26303,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25820
26303
|
async read(bytes) {
|
|
25821
26304
|
// - A Public-Key or Public-Subkey packet, as described above.
|
|
25822
26305
|
let i = await this.readPublicKey(bytes);
|
|
26306
|
+
const startOfSecretKeyData = i;
|
|
25823
26307
|
|
|
25824
26308
|
// - One octet indicating string-to-key usage conventions. Zero
|
|
25825
26309
|
// indicates that the secret-key data is not encrypted. 255 or 254
|
|
@@ -25833,41 +26317,48 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25833
26317
|
i++;
|
|
25834
26318
|
}
|
|
25835
26319
|
|
|
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
|
-
|
|
26320
|
+
try {
|
|
25847
26321
|
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
|
|
25848
|
-
//
|
|
25849
|
-
|
|
25850
|
-
|
|
25851
|
-
|
|
25852
|
-
|
|
26322
|
+
// one-octet symmetric encryption algorithm.
|
|
26323
|
+
if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
|
|
26324
|
+
this.symmetric = bytes[i++];
|
|
26325
|
+
|
|
26326
|
+
// - [Optional] If string-to-key usage octet was 253, a one-octet
|
|
26327
|
+
// AEAD algorithm.
|
|
26328
|
+
if (this.s2kUsage === 253) {
|
|
26329
|
+
this.aead = bytes[i++];
|
|
26330
|
+
}
|
|
25853
26331
|
|
|
25854
|
-
|
|
25855
|
-
|
|
26332
|
+
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
|
|
26333
|
+
// string-to-key specifier. The length of the string-to-key
|
|
26334
|
+
// specifier is implied by its type, as described above.
|
|
26335
|
+
const s2kType = bytes[i++];
|
|
26336
|
+
this.s2k = newS2KFromType(s2kType);
|
|
26337
|
+
i += this.s2k.read(bytes.subarray(i, bytes.length));
|
|
26338
|
+
|
|
26339
|
+
if (this.s2k.type === 'gnu-dummy') {
|
|
26340
|
+
return;
|
|
26341
|
+
}
|
|
26342
|
+
} else if (this.s2kUsage) {
|
|
26343
|
+
this.symmetric = this.s2kUsage;
|
|
25856
26344
|
}
|
|
25857
|
-
} else if (this.s2kUsage) {
|
|
25858
|
-
this.symmetric = this.s2kUsage;
|
|
25859
|
-
}
|
|
25860
26345
|
|
|
25861
|
-
|
|
25862
|
-
|
|
25863
|
-
|
|
25864
|
-
|
|
25865
|
-
|
|
25866
|
-
|
|
25867
|
-
|
|
25868
|
-
|
|
26346
|
+
// - [Optional] If secret data is encrypted (string-to-key usage octet
|
|
26347
|
+
// not zero), an Initial Vector (IV) of the same length as the
|
|
26348
|
+
// cipher's block size.
|
|
26349
|
+
if (this.s2kUsage) {
|
|
26350
|
+
this.iv = bytes.subarray(
|
|
26351
|
+
i,
|
|
26352
|
+
i + mod.getCipher(this.symmetric).blockSize
|
|
26353
|
+
);
|
|
25869
26354
|
|
|
25870
|
-
|
|
26355
|
+
i += this.iv.length;
|
|
26356
|
+
}
|
|
26357
|
+
} catch (e) {
|
|
26358
|
+
// if the s2k is unsupported, we still want to support encrypting and verifying with the given key
|
|
26359
|
+
if (!this.s2kUsage) throw e; // always throw for decrypted keys
|
|
26360
|
+
this.unparseableKeyMaterial = bytes.subarray(startOfSecretKeyData);
|
|
26361
|
+
this.isEncrypted = true;
|
|
25871
26362
|
}
|
|
25872
26363
|
|
|
25873
26364
|
// - Only for a version 5 packet, a four-octet scalar octet count for
|
|
@@ -25903,8 +26394,15 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25903
26394
|
* @returns {Uint8Array} A string of bytes containing the secret key OpenPGP packet.
|
|
25904
26395
|
*/
|
|
25905
26396
|
write() {
|
|
25906
|
-
const
|
|
26397
|
+
const serializedPublicKey = this.writePublicKey();
|
|
26398
|
+
if (this.unparseableKeyMaterial) {
|
|
26399
|
+
return util.concatUint8Array([
|
|
26400
|
+
serializedPublicKey,
|
|
26401
|
+
this.unparseableKeyMaterial
|
|
26402
|
+
]);
|
|
26403
|
+
}
|
|
25907
26404
|
|
|
26405
|
+
const arr = [serializedPublicKey];
|
|
25908
26406
|
arr.push(new Uint8Array([this.s2kUsage]));
|
|
25909
26407
|
|
|
25910
26408
|
const optionalFieldsArr = [];
|
|
@@ -25964,6 +26462,18 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25964
26462
|
return this.isEncrypted === false;
|
|
25965
26463
|
}
|
|
25966
26464
|
|
|
26465
|
+
/**
|
|
26466
|
+
* Check whether the key includes secret key material.
|
|
26467
|
+
* Some secret keys do not include it, and can thus only be used
|
|
26468
|
+
* for public-key operations (encryption and verification).
|
|
26469
|
+
* Such keys are:
|
|
26470
|
+
* - GNU-dummy keys, where the secret material has been stripped away
|
|
26471
|
+
* - encrypted keys with unsupported S2K or cipher
|
|
26472
|
+
*/
|
|
26473
|
+
isMissingSecretKeyMaterial() {
|
|
26474
|
+
return this.unparseableKeyMaterial !== undefined || this.isDummy();
|
|
26475
|
+
}
|
|
26476
|
+
|
|
25967
26477
|
/**
|
|
25968
26478
|
* Check whether this is a gnu-dummy key
|
|
25969
26479
|
* @returns {Boolean}
|
|
@@ -25984,6 +26494,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
25984
26494
|
if (this.isDecrypted()) {
|
|
25985
26495
|
this.clearPrivateParams();
|
|
25986
26496
|
}
|
|
26497
|
+
delete this.unparseableKeyMaterial;
|
|
25987
26498
|
this.isEncrypted = null;
|
|
25988
26499
|
this.keyMaterial = null;
|
|
25989
26500
|
this.s2k = newS2KFromType(enums.s2k.gnu, config$1);
|
|
@@ -26055,6 +26566,10 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
26055
26566
|
return false;
|
|
26056
26567
|
}
|
|
26057
26568
|
|
|
26569
|
+
if (this.unparseableKeyMaterial) {
|
|
26570
|
+
throw new Error('Key packet cannot be decrypted: unsupported S2K or cipher algo');
|
|
26571
|
+
}
|
|
26572
|
+
|
|
26058
26573
|
if (this.isDecrypted()) {
|
|
26059
26574
|
throw new Error('Key packet is already decrypted.');
|
|
26060
26575
|
}
|
|
@@ -26139,7 +26654,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|
|
26139
26654
|
* Clear private key parameters
|
|
26140
26655
|
*/
|
|
26141
26656
|
clearPrivateParams() {
|
|
26142
|
-
if (this.
|
|
26657
|
+
if (this.isMissingSecretKeyMaterial()) {
|
|
26143
26658
|
return;
|
|
26144
26659
|
}
|
|
26145
26660
|
|
|
@@ -27832,6 +28347,7 @@ function isValidSigningKeyPacket(keyPacket, signature) {
|
|
|
27832
28347
|
return keyAlgo !== enums.publicKey.rsaEncrypt &&
|
|
27833
28348
|
keyAlgo !== enums.publicKey.elgamal &&
|
|
27834
28349
|
keyAlgo !== enums.publicKey.ecdh &&
|
|
28350
|
+
keyAlgo !== enums.publicKey.x25519 &&
|
|
27835
28351
|
(!signature.keyFlags ||
|
|
27836
28352
|
(signature.keyFlags[0] & enums.keyFlags.signData) !== 0);
|
|
27837
28353
|
}
|
|
@@ -27842,6 +28358,7 @@ function isValidEncryptionKeyPacket(keyPacket, signature) {
|
|
|
27842
28358
|
keyAlgo !== enums.publicKey.rsaSign &&
|
|
27843
28359
|
keyAlgo !== enums.publicKey.ecdsa &&
|
|
27844
28360
|
keyAlgo !== enums.publicKey.eddsa &&
|
|
28361
|
+
keyAlgo !== enums.publicKey.ed25519 &&
|
|
27845
28362
|
(!signature.keyFlags ||
|
|
27846
28363
|
(signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 ||
|
|
27847
28364
|
(signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0);
|
|
@@ -29396,7 +29913,7 @@ function createKey(packetlist) {
|
|
|
29396
29913
|
* @static
|
|
29397
29914
|
* @private
|
|
29398
29915
|
*/
|
|
29399
|
-
async function generate$
|
|
29916
|
+
async function generate$4(options, config) {
|
|
29400
29917
|
options.sign = true; // primary key is always a signing key
|
|
29401
29918
|
options = sanitizeKeyOptions(options);
|
|
29402
29919
|
options.subkeys = options.subkeys.map((subkey, index) => sanitizeKeyOptions(options.subkeys[index], options));
|
|
@@ -30075,6 +30592,15 @@ class Message {
|
|
|
30075
30592
|
enums.read(enums.aead, await getPreferredAlgo('aead', encryptionKeys, date, userIDs, config$1)) :
|
|
30076
30593
|
undefined;
|
|
30077
30594
|
|
|
30595
|
+
await Promise.all(encryptionKeys.map(key => key.getEncryptionKey()
|
|
30596
|
+
.catch(() => null) // ignore key strength requirements
|
|
30597
|
+
.then(maybeKey => {
|
|
30598
|
+
if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519) && !util.isAES(algo)) {
|
|
30599
|
+
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.');
|
|
30600
|
+
}
|
|
30601
|
+
})
|
|
30602
|
+
));
|
|
30603
|
+
|
|
30078
30604
|
const sessionKeyData = mod.generateSessionKey(algo);
|
|
30079
30605
|
return { data: sessionKeyData, algorithm: algorithmName, aeadAlgorithm: aeadAlgorithmName };
|
|
30080
30606
|
}
|
|
@@ -30382,7 +30908,7 @@ class Message {
|
|
|
30382
30908
|
if (literalDataList.length !== 1) {
|
|
30383
30909
|
throw new Error('Can only verify message with one literal data packet.');
|
|
30384
30910
|
}
|
|
30385
|
-
const signatureList = signature.packets;
|
|
30911
|
+
const signatureList = signature.packets.filterByTag(enums.packet.signature); // drop UnparsablePackets
|
|
30386
30912
|
return createVerificationObjects(signatureList, literalDataList, verificationKeys, date, true, config$1);
|
|
30387
30913
|
}
|
|
30388
30914
|
|
|
@@ -30729,7 +31255,7 @@ class CleartextMessage {
|
|
|
30729
31255
|
* @async
|
|
30730
31256
|
*/
|
|
30731
31257
|
verify(keys, date = new Date(), config$1 = config) {
|
|
30732
|
-
const signatureList = this.signature.packets;
|
|
31258
|
+
const signatureList = this.signature.packets.filterByTag(enums.packet.signature); // drop UnparsablePackets
|
|
30733
31259
|
const literalDataPacket = new LiteralDataPacket();
|
|
30734
31260
|
// we assume that cleartext signature is generated based on UTF8 cleartext
|
|
30735
31261
|
literalDataPacket.setText(this.text);
|
|
@@ -30814,7 +31340,7 @@ function verifyHeaders$1(headers, packetlist) {
|
|
|
30814
31340
|
let oneHeader = null;
|
|
30815
31341
|
let hashAlgos = [];
|
|
30816
31342
|
headers.forEach(function(header) {
|
|
30817
|
-
oneHeader = header.match(
|
|
31343
|
+
oneHeader = header.match(/^Hash: (.+)$/); // get header value
|
|
30818
31344
|
if (oneHeader) {
|
|
30819
31345
|
oneHeader = oneHeader[1].replace(/\s/g, ''); // remove whitespace
|
|
30820
31346
|
oneHeader = oneHeader.split(',');
|
|
@@ -30906,7 +31432,7 @@ async function generateKey({ userIDs = [], passphrase, type = 'ecc', rsaBits = 4
|
|
|
30906
31432
|
const options = { userIDs, passphrase, type, rsaBits, curve, keyExpirationTime, date, subkeys, symmetricHash, symmetricCipher };
|
|
30907
31433
|
|
|
30908
31434
|
try {
|
|
30909
|
-
const { key, revocationCertificate } = await generate$
|
|
31435
|
+
const { key, revocationCertificate } = await generate$4(options, config$1);
|
|
30910
31436
|
key.getKeys().forEach(({ keyPacket }) => checkKeyRequirements(keyPacket, config$1));
|
|
30911
31437
|
|
|
30912
31438
|
return {
|
|
@@ -31100,7 +31626,7 @@ async function encryptKey({ privateKey, passphrase, config: config$1, ...rest })
|
|
|
31100
31626
|
* @async
|
|
31101
31627
|
* @static
|
|
31102
31628
|
*/
|
|
31103
|
-
async function encrypt$
|
|
31629
|
+
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
31630
|
config$1 = { ...config, ...config$1 }; checkConfig(config$1);
|
|
31105
31631
|
checkMessage(message); checkOutputMessageFormat(format);
|
|
31106
31632
|
encryptionKeys = toArray$1(encryptionKeys); signingKeys = toArray$1(signingKeys); passwords = toArray$1(passwords);
|
|
@@ -31169,7 +31695,7 @@ async function encrypt$4({ message, encryptionKeys, signingKeys, passwords, sess
|
|
|
31169
31695
|
* @async
|
|
31170
31696
|
* @static
|
|
31171
31697
|
*/
|
|
31172
|
-
async function decrypt$
|
|
31698
|
+
async function decrypt$5({ message, decryptionKeys, passwords, sessionKeys, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
|
|
31173
31699
|
config$1 = { ...config, ...config$1 }; checkConfig(config$1);
|
|
31174
31700
|
checkMessage(message); verificationKeys = toArray$1(verificationKeys); decryptionKeys = toArray$1(decryptionKeys); passwords = toArray$1(passwords); sessionKeys = toArray$1(sessionKeys);
|
|
31175
31701
|
if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.decrypt, pass `decryptionKeys` instead');
|
|
@@ -31232,7 +31758,7 @@ async function decrypt$4({ message, decryptionKeys, passwords, sessionKeys, veri
|
|
|
31232
31758
|
* @async
|
|
31233
31759
|
* @static
|
|
31234
31760
|
*/
|
|
31235
|
-
async function sign$
|
|
31761
|
+
async function sign$6({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
|
|
31236
31762
|
config$1 = { ...config, ...config$1 }; checkConfig(config$1);
|
|
31237
31763
|
checkCleartextOrMessage(message); checkOutputMessageFormat(format);
|
|
31238
31764
|
signingKeys = toArray$1(signingKeys); signingKeyIDs = toArray$1(signingKeyIDs); signingUserIDs = toArray$1(signingUserIDs); signatureNotations = toArray$1(signatureNotations);
|
|
@@ -31301,7 +31827,7 @@ async function sign$5({ message, signingKeys, format = 'armored', detached = fal
|
|
|
31301
31827
|
* @async
|
|
31302
31828
|
* @static
|
|
31303
31829
|
*/
|
|
31304
|
-
async function verify$
|
|
31830
|
+
async function verify$6({ message, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
|
|
31305
31831
|
config$1 = { ...config, ...config$1 }; checkConfig(config$1);
|
|
31306
31832
|
checkCleartextOrMessage(message); verificationKeys = toArray$1(verificationKeys);
|
|
31307
31833
|
if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.verify, pass `verificationKeys` instead');
|
|
@@ -31567,4 +32093,4 @@ function formatObject(object, format, config) {
|
|
|
31567
32093
|
}
|
|
31568
32094
|
}
|
|
31569
32095
|
|
|
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$
|
|
32096
|
+
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 };
|