@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.
@@ -1,4 +1,4 @@
1
- /*! OpenPGP.js v5.9.1-1 - 2023-09-06 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
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
- // GPG4Browsers - An OpenPGP implementation in javascript
1510
+ /**
1511
+ * @module enums
1512
+ */
1511
1513
 
1512
- const debugMode = (() => {
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
- const util = {
1520
- isString: function(data) {
1521
- return typeof data === 'string' || data instanceof String;
1522
- },
1516
+ var enums = {
1523
1517
 
1524
- isArray: function(data) {
1525
- return data instanceof Array;
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
- isUint8Array: isUint8Array,
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
- isStream: isStream,
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
- readNumber: function (bytes) {
1533
- let n = 0;
1534
- for (let i = 0; i < bytes.length; i++) {
1535
- n += (256 ** i) * bytes[bytes.length - 1 - i];
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
- writeNumber: function (n, bytes) {
1541
- const b = new Uint8Array(bytes);
1542
- for (let i = 0; i < bytes; i++) {
1543
- b[i] = (n >> (8 * (bytes - i - 1))) & 0xFF;
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
- return b;
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
- readDate: function (bytes) {
1550
- const n = util.readNumber(bytes);
1551
- const d = new Date(n * 1000);
1552
- return d;
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
- writeDate: function (time) {
1556
- const numeric = Math.floor(time.getTime() / 1000);
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
- return util.writeNumber(numeric, 4);
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
- normalizeDate: function (time = Date.now()) {
1562
- return time === null || time === Infinity ? time : new Date(Math.floor(+time / 1000) * 1000);
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
- * Read one MPI from bytes in input
1567
- * @param {Uint8Array} bytes - Input data to parse
1568
- * @returns {Uint8Array} Parsed MPI.
1603
+ /** A string to key specifier type
1604
+ * @enum {Integer}
1605
+ * @readonly
1569
1606
  */
1570
- readMPI: function (bytes) {
1571
- const bits = (bytes[0] << 8) | bytes[1];
1572
- const bytelen = (bits + 7) >>> 3;
1573
- return bytes.subarray(2, 2 + bytelen);
1607
+ s2k: {
1608
+ simple: 0,
1609
+ salted: 1,
1610
+ iterated: 3,
1611
+ argon2: 4,
1612
+ gnu: 101
1574
1613
  },
1575
1614
 
1576
- /**
1577
- * Left-pad Uint8Array to length by adding 0x0 bytes
1578
- * @param {Uint8Array} bytes - Data to pad
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
- leftPad(bytes, length) {
1583
- const padded = new Uint8Array(length);
1584
- const offset = length - bytes.length;
1585
- padded.set(bytes, offset);
1586
- return padded;
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
- * Convert a Uint8Array to an MPI-formatted Uint8Array.
1591
- * @param {Uint8Array} bin - An array of 8-bit integers to convert
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
- uint8ArrayToMPI: function (bin) {
1595
- const bitSize = util.uint8ArrayBitLength(bin);
1596
- if (bitSize === 0) {
1597
- throw new Error('Zero MPI');
1598
- }
1599
- const stripped = bin.subarray(bin.length - Math.ceil(bitSize / 8));
1600
- const prefix = new Uint8Array([(bitSize & 0xFF00) >> 8, bitSize & 0xFF]);
1601
- return util.concatUint8Array([prefix, stripped]);
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
- * Return bit length of the input data
1606
- * @param {Uint8Array} bin input data (big endian)
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
- uint8ArrayBitLength: function (bin) {
1610
- let i; // index of leading non-zero byte
1611
- for (i = 0; i < bin.length; i++) if (bin[i] !== 0) break;
1612
- if (i === bin.length) {
1613
- return 0;
1614
- }
1615
- const stripped = bin.subarray(i);
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
- * Convert a hex string to an array of 8-bit integers
1621
- * @param {String} hex - A hex string to convert
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
- hexToUint8Array: function (hex) {
1625
- const result = new Uint8Array(hex.length >> 1);
1626
- for (let k = 0; k < hex.length >> 1; k++) {
1627
- result[k] = parseInt(hex.substr(k << 1, 2), 16);
1628
- }
1629
- return result;
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
- * Convert an array of 8-bit integers to a hex string
1634
- * @param {Uint8Array} bytes - Array of 8-bit integers to convert
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
- uint8ArrayToHex: function (bytes) {
1638
- const r = [];
1639
- const e = bytes.length;
1640
- let c = 0;
1641
- let h;
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
- * Convert an array of 8-bit integers to a string
1673
- * @param {Uint8Array} bytes - An array of 8-bit integers to convert
1674
- * @returns {String} String representation of the array.
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
- uint8ArrayToString: function (bytes) {
1677
- bytes = new Uint8Array(bytes);
1678
- const result = [];
1679
- const bs = 1 << 14;
1680
- const j = bytes.length;
1681
-
1682
- for (let i = 0; i < j; i += bs) {
1683
- result.push(String.fromCharCode.apply(String, bytes.subarray(i, i + bs < j ? i + bs : j)));
1684
- }
1685
- return result.join('');
1715
+ aead: {
1716
+ eax: 1,
1717
+ ocb: 2,
1718
+ experimentalGCM: 100 // Private algorithm
1686
1719
  },
1687
1720
 
1688
- /**
1689
- * Convert a native javascript string to a Uint8Array of utf8 bytes
1690
- * @param {String|ReadableStream} str - The string to convert
1691
- * @returns {Uint8Array|ReadableStream} A valid squence of utf8 bytes.
1721
+ /** A list of packet types and numeric tags associated with them.
1722
+ * @enum {Integer}
1723
+ * @readonly
1692
1724
  */
1693
- encodeUTF8: function (str) {
1694
- const encoder = new TextEncoder('utf-8');
1695
- // eslint-disable-next-line no-inner-declarations
1696
- function process(value, lastChunk = false) {
1697
- return encoder.encode(value, { stream: !lastChunk });
1698
- }
1699
- return transform(str, process, () => process('', true));
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
- * Convert a Uint8Array of utf8 bytes to a native javascript string
1704
- * @param {Uint8Array|ReadableStream} utf8 - A valid squence of utf8 bytes
1705
- * @returns {String|ReadableStream} A native javascript string.
1746
+ /** Data types in the literal packet
1747
+ * @enum {Integer}
1748
+ * @readonly
1706
1749
  */
1707
- decodeUTF8: function (utf8) {
1708
- const decoder = new TextDecoder('utf-8');
1709
- // eslint-disable-next-line no-inner-declarations
1710
- function process(value, lastChunk = false) {
1711
- return decoder.decode(value, { stream: !lastChunk });
1712
- }
1713
- return transform(utf8, process, () => process(new Uint8Array(), true));
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
- * Concat Uint8Arrays
1726
- * @param {Array<Uint8Array>} Array - Of Uint8Arrays to concatenate
1727
- * @returns {Uint8Array} Concatenated array.
1762
+ /** One pass signature packet type
1763
+ * @enum {Integer}
1764
+ * @readonly
1728
1765
  */
1729
- concatUint8Array: concatUint8Array,
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
- * Check Uint8Array equality
1733
- * @param {Uint8Array} array1 - First array
1734
- * @param {Uint8Array} array2 - Second array
1735
- * @returns {Boolean} Equality.
1884
+ /** Signature subpacket type
1885
+ * @enum {Integer}
1886
+ * @readonly
1736
1887
  */
1737
- equalsUint8Array: function (array1, array2) {
1738
- if (!util.isUint8Array(array1) || !util.isUint8Array(array2)) {
1739
- throw new Error('Data must be in the form of a Uint8Array');
1740
- }
1741
-
1742
- if (array1.length !== array2.length) {
1743
- return false;
1744
- }
1745
-
1746
- for (let i = 0; i < array1.length; i++) {
1747
- if (array1[i] !== array2[i]) {
1748
- return false;
1749
- }
1750
- }
1751
- return true;
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
- * Calculates a 16bit sum of a Uint8Array by adding each character
1756
- * codes modulus 65535
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
- writeChecksum: function (text) {
1761
- let s = 0;
1762
- for (let i = 0; i < text.length; i++) {
1763
- s = (s + text[i]) & 0xFFFF;
1764
- }
1765
- return util.writeNumber(s, 2);
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
- * Helper function to print a debug message. Debug
1770
- * messages are only printed if
1771
- * @param {String} str - String of the debug message
1942
+ /** Armor type
1943
+ * @enum {Integer}
1944
+ * @readonly
1772
1945
  */
1773
- printDebug: function (str) {
1774
- if (debugMode) {
1775
- console.log('[OpenPGP.js debug]', str);
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
- * Helper function to print a debug error. Debug
1781
- * messages are only printed if
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
- printDebugError: function (error) {
1785
- if (debugMode) {
1786
- console.error('[OpenPGP.js debug]', error);
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
- // returns bit length of the integer x
1791
- nbits: function (x) {
1792
- let r = 1;
1793
- let t = x >>> 16;
1794
- if (t !== 0) {
1795
- x = t;
1796
- r += 16;
1797
- }
1798
- t = x >> 8;
1799
- if (t !== 0) {
1800
- x = t;
1801
- r += 8;
1802
- }
1803
- t = x >> 4;
1804
- if (t !== 0) {
1805
- x = t;
1806
- r += 4;
1807
- }
1808
- t = x >> 2;
1809
- if (t !== 0) {
1810
- x = t;
1811
- r += 2;
1812
- }
1813
- t = x >> 1;
1814
- if (t !== 0) {
1815
- x = t;
1816
- r += 1;
1817
- }
1818
- return r;
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
- * If S[1] == 0, then double(S) == (S[2..128] || 0);
1823
- * otherwise, double(S) == (S[2..128] || 0) xor
1824
- * (zeros(120) || 10000111).
1825
- *
1826
- * Both OCB and EAX (through CMAC) require this function to be constant-time.
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
- double: function(data) {
1831
- const doubleVar = new Uint8Array(data.length);
1832
- const last = data.length - 1;
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
- * Shift a Uint8Array to the right by n bits
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
- * Get BigInteger class
1869
- * It wraps the native BigInt type if it's available
1870
- * Otherwise it relies on bn.js
1871
- * @returns {BigInteger}
1872
- * @async
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
- getBigInteger,
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
- * Get native Node.js crypto api.
1878
- * @returns {Object} The crypto module or 'undefined'.
1879
- */
1880
- getNodeCrypto: function() {
1881
- return void('crypto');
1882
- },
2022
+ if (type[byValue][e] !== undefined) {
2023
+ return type[byValue][e];
2024
+ }
1883
2025
 
1884
- getNodeZlib: function() {
1885
- return void('zlib');
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
- getHardwareConcurrency: function() {
1898
- if (typeof navigator !== 'undefined') {
1899
- return navigator.hardwareConcurrency || 1;
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
- const os = void('os'); // Assume we're on Node.js.
1903
- return os.cpus().length;
2039
+ const util = {
2040
+ isString: function(data) {
2041
+ return typeof data === 'string' || data instanceof String;
1904
2042
  },
1905
2043
 
1906
- isEmailAddress: function(data) {
1907
- if (!util.isString(data)) {
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
- return transform(data, bytes => {
1924
- if (carryOverCR) {
1925
- bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
1926
- }
2050
+ isStream: isStream,
1927
2051
 
1928
- if (bytes[bytes.length - 1] === CR) {
1929
- carryOverCR = true;
1930
- bytes = bytes.subarray(0, -1);
1931
- } else {
1932
- carryOverCR = false;
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
- let index;
1936
- const indices = [];
1937
- for (let i = 0; ; i = index) {
1938
- index = bytes.indexOf(LF, i) + 1;
1939
- if (index) {
1940
- if (bytes[index - 2] !== CR) indices.push(index);
1941
- } else {
1942
- break;
1943
- }
1944
- }
1945
- if (!indices.length) {
1946
- return bytes;
1947
- }
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
- const normalized = new Uint8Array(bytes.length + indices.length);
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
- * Convert line endings from canonicalized <CR><LF> to native <LF>
1966
- * Support any encoding where CR=0x0D, LF=0x0A
1967
- */
1968
- nativeEOL: function(data) {
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
- return transform(data, bytes => {
1974
- if (carryOverCR && bytes[0] !== LF) {
1975
- bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
1976
- } else {
1977
- bytes = new Uint8Array(bytes); // Don't mutate passed bytes
1978
- }
2075
+ writeDate: function (time) {
2076
+ const numeric = Math.floor(time.getTime() / 1000);
1979
2077
 
1980
- if (bytes[bytes.length - 1] === CR) {
1981
- carryOverCR = true;
1982
- bytes = bytes.subarray(0, -1);
1983
- } else {
1984
- carryOverCR = false;
1985
- }
2078
+ return util.writeNumber(numeric, 4);
2079
+ },
1986
2080
 
1987
- let index;
1988
- let j = 0;
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
- * Remove trailing spaces, carriage returns and tabs from each line
2086
+ * Read one MPI from bytes in input
2087
+ * @param {Uint8Array} bytes - Input data to parse
2088
+ * @returns {Uint8Array} Parsed MPI.
2002
2089
  */
2003
- removeTrailingSpaces: function(text) {
2004
- return text.split('\n').map(line => {
2005
- let i = line.length - 1;
2006
- for (; i >= 0 && (line[i] === ' ' || line[i] === '\t' || line[i] === '\r'); i--);
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
- wrapError: function(message, error) {
2012
- if (!error) {
2013
- return new Error(message);
2014
- }
2015
-
2016
- // update error message
2017
- try {
2018
- error.message = message + ': ' + error.message;
2019
- } catch (e) {}
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
- return error;
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
- * Map allowed packet tags to corresponding classes
2026
- * Meant to be used to format `allowedPacket` for Packetlist.read
2027
- * @param {Array<Object>} allowedClasses
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
- constructAllowedPackets: function(allowedClasses) {
2031
- const map = {};
2032
- allowedClasses.forEach(PacketClass => {
2033
- if (!PacketClass.tag) {
2034
- throw new Error('Invalid input: expected a packet class');
2035
- }
2036
- map[PacketClass.tag] = PacketClass;
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
- * Return a Promise that will resolve as soon as one of the promises in input resolves
2043
- * or will reject if all input promises all rejected
2044
- * (similar to Promise.any, but with slightly different error handling)
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
- anyPromise: function(promises) {
2050
- // eslint-disable-next-line no-async-promise-executor
2051
- return new Promise(async (resolve, reject) => {
2052
- let exception;
2053
- await Promise.all(promises.map(async promise => {
2054
- try {
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
- * Return either `a` or `b` based on `cond`, in algorithmic constant time.
2066
- * @param {Boolean} cond
2067
- * @param {Uint8Array} a
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
- selectUint8Array: function(cond, a, b) {
2072
- const length = Math.max(a.length, b.length);
2073
- const result = new Uint8Array(length);
2074
- let end = 0;
2075
- for (let i = 0; i < result.length; i++) {
2076
- result[i] = (a[i] & (256 - cond)) | (b[i] & (255 + cond));
2077
- end += (cond & i < a.length) | ((1 - cond) & i < b.length);
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 result.subarray(0, end);
2169
+ return r.join('');
2080
2170
  },
2171
+
2081
2172
  /**
2082
- * Return either `a` or `b` based on `cond`, in algorithmic constant time.
2083
- * NB: it only supports `a, b` with values between 0-255.
2084
- * @param {Boolean} cond
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
- selectUint8: function(cond, a, b) {
2090
- return (a & (256 - cond)) | (b & (255 + cond));
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
- /* OpenPGP radix-64/base64 string encoding/decoding
2095
- * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de
2096
- * version 1.0, check www.haneWIN.de for the latest version
2097
- *
2098
- * This software is provided as-is, without express or implied warranty.
2099
- * Permission to use, copy, modify, distribute or sell this software, with or
2100
- * without fee, for any purpose and by any individual or organization, is hereby
2101
- * granted, provided that the above copyright notice and this paragraph appear
2102
- * in all copies. Distribution as a part of an application or binary must
2103
- * include the above copyright notice in the documentation and/or other materials
2104
- * provided with the application or distribution.
2105
- */
2106
-
2107
- const Buffer = util.getNodeBuffer();
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
- let encodeChunk;
2110
- let decodeChunk;
2111
- if (Buffer) {
2112
- encodeChunk = buf => Buffer.from(buf).toString('base64');
2113
- decodeChunk = str => {
2114
- const b = Buffer.from(str, 'base64');
2115
- return new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
2116
- };
2117
- } else {
2118
- encodeChunk = buf => btoa(util.uint8ArrayToString(buf));
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
- * Convert binary array to radix-64
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
- buf = buf.subarray(bytes);
2142
- return r.join('');
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
- // Count how many whitespace characters there are in buf
2158
- let spaces = 0;
2159
- const spacechars = [' ', '\t', '\r', '\n'];
2160
- for (let i = 0; i < spacechars.length; i++) {
2161
- const spacechar = spacechars[i];
2162
- for (let pos = buf.indexOf(spacechar); pos !== -1; pos = buf.indexOf(spacechar, pos + 1)) {
2163
- spaces++;
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
- // Backtrack until we have 4n non-whitespace characters
2168
- // that we can safely base64-decode
2169
- let length = buf.length;
2170
- for (; length > 0 && (length - spaces) % 4 !== 0; length--) {
2171
- if (spacechars.includes(buf[length])) spaces--;
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
- const decoded = decodeChunk(buf.substr(0, length));
2175
- buf = buf.substr(length);
2176
- return decoded;
2177
- }, () => decodeChunk(buf));
2178
- }
2179
-
2180
- /**
2181
- * Convert a Base-64 encoded string an array of 8-bit integer
2182
- *
2183
- * Note: accepts both Radix-64 and URL-safe strings
2184
- * @param {String} base64 - Base-64 encoded string to convert
2185
- * @returns {Uint8Array} An array of 8-bit integers.
2186
- */
2187
- function b64ToUint8Array(base64) {
2188
- return decode(base64.replace(/-/g, '+').replace(/_/g, '/'));
2189
- }
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
- * Convert an array of 8-bit integer to a Base-64 encoded string
2193
- * @param {Uint8Array} bytes - An array of 8-bit integers to convert
2194
- * @param {bool} url - If true, output is URL-safe
2195
- * @returns {String} Base-64 encoded string.
2196
- */
2197
- function uint8ArrayToB64(bytes, url) {
2198
- let encoded = encode(bytes).replace(/[\r\n]/g, '');
2199
- if (url) {
2200
- encoded = encoded.replace(/[+]/g, '-').replace(/[/]/g, '_').replace(/[=]/g, '');
2201
- }
2202
- return encoded;
2203
- }
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
- * @module enums
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
- const byValue = Symbol('byValue');
2262
+ if (array1.length !== array2.length) {
2263
+ return false;
2264
+ }
2210
2265
 
2211
- var enums = {
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
- /** Maps curve names under various standards to one
2214
- * @see {@link https://wiki.gnupg.org/ECC|ECC - GnuPG wiki}
2215
- * @enum {String}
2216
- * @readonly
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
- curve: {
2219
- /** NIST P-256 Curve */
2220
- 'p256': 'p256',
2221
- 'P-256': 'p256',
2222
- 'secp256r1': 'p256',
2223
- 'prime256v1': 'p256',
2224
- '1.2.840.10045.3.1.7': 'p256',
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
- /** SECG SECP256k1 Curve */
2245
- 'secp256k1': 'secp256k1',
2246
- '1.3.132.0.10': 'secp256k1',
2247
- '2b8104000a': 'secp256k1',
2248
- '2B8104000A': 'secp256k1',
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
- /** Ed25519 */
2251
- 'ED25519': 'ed25519',
2252
- 'ed25519': 'ed25519',
2253
- 'Ed25519': 'ed25519',
2254
- '1.3.6.1.4.1.11591.15.1': 'ed25519',
2255
- '2b06010401da470f01': 'ed25519',
2256
- '2B06010401DA470F01': 'ed25519',
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
- /** Curve25519 */
2259
- 'X25519': 'curve25519',
2260
- 'cv25519': 'curve25519',
2261
- 'curve25519': 'curve25519',
2262
- 'Curve25519': 'curve25519',
2263
- '1.3.6.1.4.1.3029.1.5.1': 'curve25519',
2264
- '2b060104019755010501': 'curve25519',
2265
- '2B060104019755010501': 'curve25519',
2266
-
2267
- /** BrainpoolP256r1 Curve */
2268
- 'brainpoolP256r1': 'brainpoolP256r1',
2269
- '1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1',
2270
- '2b2403030208010107': 'brainpoolP256r1',
2271
- '2B2403030208010107': 'brainpoolP256r1',
2272
-
2273
- /** BrainpoolP384r1 Curve */
2274
- 'brainpoolP384r1': 'brainpoolP384r1',
2275
- '1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1',
2276
- '2b240303020801010b': 'brainpoolP384r1',
2277
- '2B240303020801010B': 'brainpoolP384r1',
2278
-
2279
- /** BrainpoolP512r1 Curve */
2280
- 'brainpoolP512r1': 'brainpoolP512r1',
2281
- '1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1',
2282
- '2b240303020801010d': 'brainpoolP512r1',
2283
- '2B240303020801010D': 'brainpoolP512r1'
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
- /** KDF parameters flags
2287
- * Non-standard extensions (for now) to allow email forwarding
2288
- * @enum {Integer}
2289
- * @readonly
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
- kdfFlags: {
2292
- /** Specify fingerprint to use instead of the recipient's */
2293
- replace_fingerprint: 0x01,
2294
- /** Specify custom parameters to use in the KDF digest computation */
2295
- replace_kdf_params: 0x02
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
- /** A string to key specifier type
2299
- * @enum {Integer}
2300
- * @readonly
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
- s2k: {
2303
- simple: 0,
2304
- salted: 1,
2305
- iterated: 3,
2306
- argon2: 4,
2307
- gnu: 101
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
- /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.1|RFC4880bis-04, section 9.1}
2311
- * @enum {Integer}
2312
- * @readonly
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
- publicKey: {
2315
- /** RSA (Encrypt or Sign) [HAC] */
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
- /** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
2343
- * @enum {Integer}
2344
- * @readonly
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
- symmetric: {
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
- /** {@link https://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
2360
- * @enum {Integer}
2361
- * @readonly
2396
+ /**
2397
+ * Get native Node.js crypto api.
2398
+ * @returns {Object} The crypto module or 'undefined'.
2362
2399
  */
2363
- compression: {
2364
- uncompressed: 0,
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
- /** {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
2373
- * @enum {Integer}
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
- /** A list of hash names as accepted by webCrypto functions.
2387
- * {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest|Parameters, algo}
2388
- * @enum {String}
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
- webHash: {
2391
- 'SHA-1': 2,
2392
- 'SHA-256': 8,
2393
- 'SHA-384': 9,
2394
- 'SHA-512': 10
2413
+ getNodeBuffer: function() {
2414
+ return ({}).Buffer;
2395
2415
  },
2396
2416
 
2397
- /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.6|RFC4880bis-04, section 9.6}
2398
- * @enum {Integer}
2399
- * @readonly
2400
- */
2401
- aead: {
2402
- eax: 1,
2403
- ocb: 2,
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
- /** A list of packet types and numeric tags associated with them.
2408
- * @enum {Integer}
2409
- * @readonly
2410
- */
2411
- packet: {
2412
- publicKeyEncryptedSessionKey: 1,
2413
- signature: 2,
2414
- symEncryptedSessionKey: 3,
2415
- onePassSignature: 4,
2416
- secretKey: 5,
2417
- publicKey: 6,
2418
- secretSubkey: 7,
2419
- compressedData: 8,
2420
- symmetricallyEncryptedData: 9,
2421
- marker: 10,
2422
- literalData: 11,
2423
- trust: 12,
2424
- userID: 13,
2425
- publicSubkey: 14,
2426
- userAttribute: 17,
2427
- symEncryptedIntegrityProtectedData: 18,
2428
- modificationDetectionCode: 19,
2429
- aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
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
- /** Data types in the literal packet
2433
- * @enum {Integer}
2434
- * @readonly
2434
+ /**
2435
+ * Normalize line endings to <CR><LF>
2436
+ * Support any encoding where CR=0x0D, LF=0x0A
2435
2437
  */
2436
- literal: {
2437
- /** Binary data 'b' */
2438
- binary: 'b'.charCodeAt(),
2439
- /** Text data 't' */
2440
- text: 't'.charCodeAt(),
2441
- /** Utf8 data 'u' */
2442
- utf8: 'u'.charCodeAt(),
2443
- /** MIME message body part 'm' */
2444
- mime: 'm'.charCodeAt()
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
- /** One pass signature packet type
2449
- * @enum {Integer}
2450
- * @readonly
2451
- */
2452
- signature: {
2453
- /** 0x00: Signature of a binary document. */
2454
- binary: 0,
2455
- /** 0x01: Signature of a canonical text document.
2456
- *
2457
- * Canonicalyzing the document by converting line endings. */
2458
- text: 1,
2459
- /** 0x02: Standalone signature.
2460
- *
2461
- * This signature is a signature of only its own subpacket contents.
2462
- * It is calculated identically to a signature over a zero-lengh
2463
- * binary document. Note that it doesn't make sense to have a V3
2464
- * standalone signature. */
2465
- standalone: 2,
2466
- /** 0x10: Generic certification of a User ID and Public-Key packet.
2467
- *
2468
- * The issuer of this certification does not make any particular
2469
- * assertion as to how well the certifier has checked that the owner
2470
- * of the key is in fact the person described by the User ID. */
2471
- certGeneric: 16,
2472
- /** 0x11: Persona certification of a User ID and Public-Key packet.
2473
- *
2474
- * The issuer of this certification has not done any verification of
2475
- * the claim that the owner of this key is the User ID specified. */
2476
- certPersona: 17,
2477
- /** 0x12: Casual certification of a User ID and Public-Key packet.
2478
- *
2479
- * The issuer of this certification has done some casual
2480
- * verification of the claim of identity. */
2481
- certCasual: 18,
2482
- /** 0x13: Positive certification of a User ID and Public-Key packet.
2483
- *
2484
- * The issuer of this certification has done substantial
2485
- * verification of the claim of identity.
2486
- *
2487
- * Most OpenPGP implementations make their "key signatures" as 0x10
2488
- * certifications. Some implementations can issue 0x11-0x13
2489
- * certifications, but few differentiate between the types. */
2490
- certPositive: 19,
2491
- /** 0x30: Certification revocation signature
2492
- *
2493
- * This signature revokes an earlier User ID certification signature
2494
- * (signature class 0x10 through 0x13) or direct-key signature
2495
- * (0x1F). It should be issued by the same key that issued the
2496
- * revoked signature or an authorized revocation key. The signature
2497
- * is computed over the same data as the certificate that it
2498
- * revokes, and should have a later creation date than that
2499
- * certificate. */
2500
- certRevocation: 48,
2501
- /** 0x18: Subkey Binding Signature
2502
- *
2503
- * This signature is a statement by the top-level signing key that
2504
- * indicates that it owns the subkey. This signature is calculated
2505
- * directly on the primary key and subkey, and not on any User ID or
2506
- * other packets. A signature that binds a signing subkey MUST have
2507
- * an Embedded Signature subpacket in this binding signature that
2508
- * contains a 0x19 signature made by the signing subkey on the
2509
- * primary key and subkey. */
2510
- subkeyBinding: 24,
2511
- /** 0x19: Primary Key Binding Signature
2512
- *
2513
- * This signature is a statement by a signing subkey, indicating
2514
- * that it is owned by the primary key and subkey. This signature
2515
- * is calculated the same way as a 0x18 signature: directly on the
2516
- * primary key and subkey, and not on any User ID or other packets.
2517
- *
2518
- * When a signature is made over a key, the hash data starts with the
2519
- * octet 0x99, followed by a two-octet length of the key, and then body
2520
- * of the key packet. (Note that this is an old-style packet header for
2521
- * a key packet with two-octet length.) A subkey binding signature
2522
- * (type 0x18) or primary key binding signature (type 0x19) then hashes
2523
- * the subkey using the same format as the main key (also using 0x99 as
2524
- * the first octet). */
2525
- keyBinding: 25,
2526
- /** 0x1F: Signature directly on a key
2527
- *
2528
- * This signature is calculated directly on a key. It binds the
2529
- * information in the Signature subpackets to the key, and is
2530
- * appropriate to be used for subpackets that provide information
2531
- * about the key, such as the Revocation Key subpacket. It is also
2532
- * appropriate for statements that non-self certifiers want to make
2533
- * about the key itself, rather than the binding between a key and a
2534
- * name. */
2535
- key: 31,
2536
- /** 0x20: Key revocation signature
2537
- *
2538
- * The signature is calculated directly on the key being revoked. A
2539
- * revoked key is not to be used. Only revocation signatures by the
2540
- * key being revoked, or by an authorized revocation key, should be
2541
- * considered valid revocation signatures.a */
2542
- keyRevocation: 32,
2543
- /** 0x28: Subkey revocation signature
2544
- *
2545
- * The signature is calculated directly on the subkey being revoked.
2546
- * A revoked subkey is not to be used. Only revocation signatures
2547
- * by the top-level signature key that is bound to this subkey, or
2548
- * by an authorized revocation key, should be considered valid
2549
- * revocation signatures.
2550
- *
2551
- * Key revocation signatures (types 0x20 and 0x28)
2552
- * hash only the key being revoked. */
2553
- subkeyRevocation: 40,
2554
- /** 0x40: Timestamp signature.
2555
- * This signature is only meaningful for the timestamp contained in
2556
- * it. */
2557
- timestamp: 64,
2558
- /** 0x50: Third-Party Confirmation signature.
2559
- *
2560
- * This signature is a signature over some other OpenPGP Signature
2561
- * packet(s). It is analogous to a notary seal on the signed data.
2562
- * A third-party signature SHOULD include Signature Target
2563
- * subpacket(s) to give easy identification. Note that we really do
2564
- * mean SHOULD. There are plausible uses for this (such as a blind
2565
- * party that only sees the signature, not the key or source
2566
- * document) that cannot include a target subpacket. */
2567
- thirdParty: 80
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
- /** Signature subpacket type
2571
- * @enum {Integer}
2572
- * @readonly
2484
+ /**
2485
+ * Convert line endings from canonicalized <CR><LF> to native <LF>
2486
+ * Support any encoding where CR=0x0D, LF=0x0A
2573
2487
  */
2574
- signatureSubpacket: {
2575
- signatureCreationTime: 2,
2576
- signatureExpirationTime: 3,
2577
- exportableCertification: 4,
2578
- trustSignature: 5,
2579
- regularExpression: 6,
2580
- revocable: 7,
2581
- keyExpirationTime: 9,
2582
- placeholderBackwardsCompatibility: 10,
2583
- preferredSymmetricAlgorithms: 11,
2584
- revocationKey: 12,
2585
- issuer: 16,
2586
- notationData: 20,
2587
- preferredHashAlgorithms: 21,
2588
- preferredCompressionAlgorithms: 22,
2589
- keyServerPreferences: 23,
2590
- preferredKeyServer: 24,
2591
- primaryUserID: 25,
2592
- policyURI: 26,
2593
- keyFlags: 27,
2594
- signersUserID: 28,
2595
- reasonForRevocation: 29,
2596
- features: 30,
2597
- signatureTarget: 31,
2598
- embeddedSignature: 32,
2599
- issuerFingerprint: 33,
2600
- preferredAEADAlgorithms: 34
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
- /** Key flags
2604
- * @enum {Integer}
2605
- * @readonly
2520
+ /**
2521
+ * Remove trailing spaces, carriage returns and tabs from each line
2606
2522
  */
2607
- keyFlags: {
2608
- /** 0x01 - This key may be used to certify other keys. */
2609
- certifyKeys: 1,
2610
- /** 0x02 - This key may be used to sign data. */
2611
- signData: 2,
2612
- /** 0x04 - This key may be used to encrypt communications. */
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
- /** Armor type
2629
- * @enum {Integer}
2630
- * @readonly
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
- armor: {
2633
- multipartSection: 0,
2634
- multipartLast: 1,
2635
- signed: 2,
2636
- message: 3,
2637
- publicKey: 4,
2638
- privateKey: 5,
2639
- signature: 6
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
- /** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
2643
- * @enum {Integer}
2644
- * @readonly
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
- reasonForRevocation: {
2647
- /** No reason specified (key revocations or cert revocations) */
2648
- noReason: 0,
2649
- /** Key is superseded (key revocations) */
2650
- keySuperseded: 1,
2651
- /** Key material has been compromised (key revocations) */
2652
- keyCompromised: 2,
2653
- /** Key is retired and no longer used (key revocations) */
2654
- keyRetired: 3,
2655
- /** User ID information is no longer valid (cert revocations) */
2656
- userIDInvalid: 32
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
- /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
2660
- * @enum {Integer}
2661
- * @readonly
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
- features: {
2664
- /** 0x01 - Modification Detection (packets 18 and 19) */
2665
- modificationDetection: 1,
2666
- /** 0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
2667
- * Symmetric-Key Encrypted Session Key Packets (packet 3) */
2668
- aead: 2,
2669
- /** 0x04 - Version 5 Public-Key Packet format and corresponding new
2670
- * fingerprint format */
2671
- v5Keys: 4
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
- * Asserts validity of given value and converts from string/integer to integer.
2676
- * @param {Object} type target enum type
2677
- * @param {String|Integer} e value to check and/or convert
2678
- * @returns {Integer} enum value if it exists
2679
- * @throws {Error} if the value is invalid
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
- write: function(type, e) {
2682
- if (typeof e === 'number') {
2683
- e = this.read(type, e);
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
- if (type[e] !== undefined) {
2687
- return type[e];
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
- throw new Error('Invalid enum value.');
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
- * Converts enum integer value to the corresponding string, if it exists.
2695
- * @param {Object} type target enum type
2696
- * @param {Integer} e value to convert
2697
- * @returns {String} name of enum value if it exists
2698
- * @throws {Error} if the value is invalid
2699
- */
2700
- read: function(type, e) {
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
- if (type[byValue][e] !== undefined) {
2709
- return type[byValue][e];
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
- throw new Error('Invalid enum value.');
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.9.1-1',
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 (algoName.substr(0, 3) === 'aes') {
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 (algoName.substr(0, 3) === 'aes') {
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 Curve {
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 Curve(curve);
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 Curve(oid);
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 Curve(oid);
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 Curve(oid);
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$3(oid, Q, k) {
14197
- // Check whether the given curve is supported
14198
- if (oid.getName() !== 'ed25519') {
14199
- return false;
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
- * Derive public point Q' = dG from private key
14204
- * and expect Q == Q'
14205
- */
14206
- const { publicKey } = naclFastLight.sign.keyPair.fromSeed(k);
14207
- const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
14208
- return util.equalsUint8Array(Q, dG);
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
- sign: sign$2,
14214
- verify: verify$2,
14215
- validateParams: validateParams$3
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$4(oid, Q, d) {
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 {Curve} curve - Elliptic curve object
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 Curve(oid);
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 {Curve} curve - Elliptic curve object
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 Curve(oid);
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 {Curve} curve - Elliptic curve object
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 {Curve} curve - Elliptic curve object
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 {Curve} curve - Elliptic curve object
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 {Curve} curve - Elliptic curve object
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 {Curve} curve - Elliptic curve object
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 {Curve} curve - Elliptic curve object
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$4,
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
- Curve: Curve,
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$3(hashAlgo, hashed, g, p, q, x) {
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$3(hashAlgo, r, s, hashed, g, p, q, y) {
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$5(p, q, g, y, x) {
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$3,
14939
- verify: verify$3,
14940
- validateParams: validateParams$5
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$4(algo, hashAlgo, signature, publicParams, privateParams, data, hashed) {
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.Curve(oid).payloadSize;
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.eddsa.verify(oid, hashAlgo, signature, data, Q, hashed);
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$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) {
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.eddsa.sign(oid, hashAlgo, data, Q, seed, hashed);
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$4,
15214
- sign: sign$4
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 (typeof data === 'undefined') {
15222
- data = new Uint8Array([]);
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
- * @param {Uint8Array} input - Where to read the encoded symmetric key from
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(input) {
15237
- if (input.length >= 1) {
15238
- const length = input[0];
15239
- if (input.length >= 1 + length) {
15240
- this.data = input.subarray(1, 1 + length);
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} An array containing the value
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} algo - Public key algorithm
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(algo, publicParams, privateParams, data, fingerprint) {
15390
- switch (algo) {
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 Curve(publicParams.oid);
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
- const curve = new Curve(publicParams.oid);
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
- let orderedParams;
15655
- switch (algo) {
15656
- case enums.publicKey.hmac:
15657
- case enums.publicKey.aead: {
15658
- orderedParams = Object.keys(params).map(name => {
15659
- const param = params[name];
15660
- return util.isUint8Array(param) ? param : param.write();
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$6(algo, publicParams, privateParams) {
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
- const { oid, Q } = publicParams;
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(oid, Q, seed);
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$6,
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 Error('Unknown s2k gnu protection mode.');
16541
+ throw new UnsupportedError('Unknown s2k gnu protection mode.');
16111
16542
  }
16112
16543
  } else {
16113
- throw new Error('Unknown s2k type.');
16544
+ throw new UnsupportedError('Unknown s2k type.');
16114
16545
  }
16115
16546
  break;
16116
16547
 
16117
16548
  default:
16118
- throw new Error('Unknown s2k type.');
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 Error(`Unsupported S2K type ${type}`);
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
- this.version = bytes[0];
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(1, bytes.length));
24981
- this.publicKeyAlgorithm = bytes[9];
24982
- this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(10));
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, data, key.getFingerprintBytes());
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 ? util.concatUint8Array([
25034
- new Uint8Array([randomSessionKey.sessionKeyAlgorithm]),
25035
- randomSessionKey.sessionKey,
25036
- util.writeChecksum(randomSessionKey.sessionKey)
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
- } else {
25053
- const isValidPayload = isValidChecksum && enums.read(enums.symmetric, symmetricAlgoByte);
25054
- if (isValidPayload) {
25055
- this.sessionKey = sessionKey;
25056
- this.sessionKeyAlgorithm = symmetricAlgoByte;
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
- throw new Error('Decryption error');
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
- // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
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
- // string-to-key specifier. The length of the string-to-key
25849
- // specifier is implied by its type, as described above.
25850
- const s2kType = bytes[i++];
25851
- this.s2k = newS2KFromType(s2kType);
25852
- i += this.s2k.read(bytes.subarray(i, bytes.length));
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
- if (this.s2k.type === 'gnu-dummy') {
25855
- return;
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
- // - [Optional] If secret data is encrypted (string-to-key usage octet
25862
- // not zero), an Initial Vector (IV) of the same length as the
25863
- // cipher's block size.
25864
- if (this.s2kUsage) {
25865
- this.iv = bytes.subarray(
25866
- i,
25867
- i + mod.getCipher(this.symmetric).blockSize
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
- i += this.iv.length;
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 arr = [this.writePublicKey()];
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.isDummy()) {
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$2(options, config) {
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(/Hash: (.+)/); // get header value
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$2(options, config$1);
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$4({ message, encryptionKeys, signingKeys, passwords, sessionKey, format = 'armored', signature = null, wildcard = false, signingKeyIDs = [], encryptionKeyIDs = [], date = new Date(), signingUserIDs = [], encryptionUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
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$4({ message, decryptionKeys, passwords, sessionKeys, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
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$5({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
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$5({ message, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
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$4 as decrypt, decryptKey, decryptSessionKeys, _256 as e, encrypt$4 as encrypt, encryptKey, encryptSessionKey, enums, _384 as f, _512 as g, generateKey, generateSessionKey$1 as generateSessionKey, inherits_browser as i, minimalisticAssert as m, ripemd as r, readCleartextMessage, readKey, readKeys, readMessage, readPrivateKey, readPrivateKeys, readSignature, reformatKey, revokeKey, sign$5 as sign, utils as u, unarmor, verify$5 as verify };
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 };