@protontech/openpgp 5.9.1-1 → 5.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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.11.0 - 2023-11-27 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
2
2
  'use strict';
3
3
 
4
4
  const globalThis = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@@ -263,18 +263,17 @@ if (NodeReadableStream$1) {
263
263
  this.push(null);
264
264
  break;
265
265
  }
266
- if (!this.push(value) || this._cancelling) {
267
- this._reading = false;
266
+ if (!this.push(value)) {
268
267
  break;
269
268
  }
270
269
  }
271
- } catch(e) {
272
- this.emit('error', e);
270
+ } catch (e) {
271
+ this.destroy(e);
273
272
  }
274
273
  }
275
274
 
276
- _destroy(reason) {
277
- this._reader.cancel(reason);
275
+ async _destroy(error, callback) {
276
+ this._reader.cancel(error).then(callback, callback);
278
277
  }
279
278
  }
280
279
 
@@ -309,7 +308,7 @@ function Reader(input) {
309
308
  const reader = input.getReader();
310
309
  this._read = reader.read.bind(reader);
311
310
  this._releaseLock = () => {};
312
- this._cancel = () => {};
311
+ this._cancel = async () => {};
313
312
  return;
314
313
  }
315
314
  let streamType = isStream(input);
@@ -1529,6 +1528,533 @@ async function getBigInteger() {
1529
1528
  }
1530
1529
  }
1531
1530
 
1531
+ /**
1532
+ * @module enums
1533
+ */
1534
+
1535
+ const byValue = Symbol('byValue');
1536
+
1537
+ var enums = {
1538
+
1539
+ /** Maps curve names under various standards to one
1540
+ * @see {@link https://wiki.gnupg.org/ECC|ECC - GnuPG wiki}
1541
+ * @enum {String}
1542
+ * @readonly
1543
+ */
1544
+ curve: {
1545
+ /** NIST P-256 Curve */
1546
+ 'p256': 'p256',
1547
+ 'P-256': 'p256',
1548
+ 'secp256r1': 'p256',
1549
+ 'prime256v1': 'p256',
1550
+ '1.2.840.10045.3.1.7': 'p256',
1551
+ '2a8648ce3d030107': 'p256',
1552
+ '2A8648CE3D030107': 'p256',
1553
+
1554
+ /** NIST P-384 Curve */
1555
+ 'p384': 'p384',
1556
+ 'P-384': 'p384',
1557
+ 'secp384r1': 'p384',
1558
+ '1.3.132.0.34': 'p384',
1559
+ '2b81040022': 'p384',
1560
+ '2B81040022': 'p384',
1561
+
1562
+ /** NIST P-521 Curve */
1563
+ 'p521': 'p521',
1564
+ 'P-521': 'p521',
1565
+ 'secp521r1': 'p521',
1566
+ '1.3.132.0.35': 'p521',
1567
+ '2b81040023': 'p521',
1568
+ '2B81040023': 'p521',
1569
+
1570
+ /** SECG SECP256k1 Curve */
1571
+ 'secp256k1': 'secp256k1',
1572
+ '1.3.132.0.10': 'secp256k1',
1573
+ '2b8104000a': 'secp256k1',
1574
+ '2B8104000A': 'secp256k1',
1575
+
1576
+ /** Ed25519 - deprecated by crypto-refresh (replaced by standaone Ed25519 algo) */
1577
+ 'ed25519Legacy': 'ed25519',
1578
+ 'ED25519': 'ed25519',
1579
+ /** @deprecated use `ed25519Legacy` instead */
1580
+ 'ed25519': 'ed25519',
1581
+ 'Ed25519': 'ed25519',
1582
+ '1.3.6.1.4.1.11591.15.1': 'ed25519',
1583
+ '2b06010401da470f01': 'ed25519',
1584
+ '2B06010401DA470F01': 'ed25519',
1585
+
1586
+ /** Curve25519 - deprecated by crypto-refresh (replaced by standaone X25519 algo) */
1587
+ 'curve25519Legacy': 'curve25519',
1588
+ 'X25519': 'curve25519',
1589
+ 'cv25519': 'curve25519',
1590
+ /** @deprecated use `curve25519Legacy` instead */
1591
+ 'curve25519': 'curve25519',
1592
+ 'Curve25519': 'curve25519',
1593
+ '1.3.6.1.4.1.3029.1.5.1': 'curve25519',
1594
+ '2b060104019755010501': 'curve25519',
1595
+ '2B060104019755010501': 'curve25519',
1596
+
1597
+ /** BrainpoolP256r1 Curve */
1598
+ 'brainpoolP256r1': 'brainpoolP256r1',
1599
+ '1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1',
1600
+ '2b2403030208010107': 'brainpoolP256r1',
1601
+ '2B2403030208010107': 'brainpoolP256r1',
1602
+
1603
+ /** BrainpoolP384r1 Curve */
1604
+ 'brainpoolP384r1': 'brainpoolP384r1',
1605
+ '1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1',
1606
+ '2b240303020801010b': 'brainpoolP384r1',
1607
+ '2B240303020801010B': 'brainpoolP384r1',
1608
+
1609
+ /** BrainpoolP512r1 Curve */
1610
+ 'brainpoolP512r1': 'brainpoolP512r1',
1611
+ '1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1',
1612
+ '2b240303020801010d': 'brainpoolP512r1',
1613
+ '2B240303020801010D': 'brainpoolP512r1'
1614
+ },
1615
+
1616
+ /** KDF parameters flags
1617
+ * Non-standard extensions (for now) to allow email forwarding
1618
+ * @enum {Integer}
1619
+ * @readonly
1620
+ */
1621
+ kdfFlags: {
1622
+ /** Specify fingerprint to use instead of the recipient's */
1623
+ replace_fingerprint: 0x01,
1624
+ /** Specify custom parameters to use in the KDF digest computation */
1625
+ replace_kdf_params: 0x02
1626
+ },
1627
+
1628
+ /** A string to key specifier type
1629
+ * @enum {Integer}
1630
+ * @readonly
1631
+ */
1632
+ s2k: {
1633
+ simple: 0,
1634
+ salted: 1,
1635
+ iterated: 3,
1636
+ argon2: 4,
1637
+ gnu: 101
1638
+ },
1639
+
1640
+ /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-crypto-refresh-08.html#section-9.1|crypto-refresh RFC, section 9.1}
1641
+ * @enum {Integer}
1642
+ * @readonly
1643
+ */
1644
+ publicKey: {
1645
+ /** RSA (Encrypt or Sign) [HAC] */
1646
+ rsaEncryptSign: 1,
1647
+ /** RSA (Encrypt only) [HAC] */
1648
+ rsaEncrypt: 2,
1649
+ /** RSA (Sign only) [HAC] */
1650
+ rsaSign: 3,
1651
+ /** Elgamal (Encrypt only) [ELGAMAL] [HAC] */
1652
+ elgamal: 16,
1653
+ /** DSA (Sign only) [FIPS186] [HAC] */
1654
+ dsa: 17,
1655
+ /** ECDH (Encrypt only) [RFC6637] */
1656
+ ecdh: 18,
1657
+ /** ECDSA (Sign only) [RFC6637] */
1658
+ ecdsa: 19,
1659
+ /** EdDSA (Sign only) - deprecated by crypto-refresh (replaced by `ed25519` identifier below)
1660
+ * [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */
1661
+ eddsaLegacy: 22, // NB: this is declared before `eddsa` to translate 22 to 'eddsa' for backwards compatibility
1662
+ /** @deprecated use `eddsaLegacy` instead */
1663
+ ed25519Legacy: 22,
1664
+ /** @deprecated use `eddsaLegacy` instead */
1665
+ eddsa: 22,
1666
+ /** Reserved for AEDH */
1667
+ aedh: 23,
1668
+ /** Reserved for AEDSA */
1669
+ aedsa: 24,
1670
+ /** X25519 (Encrypt only) */
1671
+ x25519: 25,
1672
+ /** X448 (Encrypt only) */
1673
+ x448: 26,
1674
+ /** Ed25519 (Sign only) */
1675
+ ed25519: 27,
1676
+ /** Ed448 (Sign only) */
1677
+ ed448: 28,
1678
+ /** Symmetric authenticated encryption algorithms */
1679
+ aead: 100,
1680
+ /** Authentication using CMAC */
1681
+ hmac: 101
1682
+ },
1683
+
1684
+ /** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
1685
+ * @enum {Integer}
1686
+ * @readonly
1687
+ */
1688
+ symmetric: {
1689
+ plaintext: 0,
1690
+ /** Not implemented! */
1691
+ idea: 1,
1692
+ tripledes: 2,
1693
+ cast5: 3,
1694
+ blowfish: 4,
1695
+ aes128: 7,
1696
+ aes192: 8,
1697
+ aes256: 9,
1698
+ twofish: 10
1699
+ },
1700
+
1701
+ /** {@link https://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
1702
+ * @enum {Integer}
1703
+ * @readonly
1704
+ */
1705
+ compression: {
1706
+ uncompressed: 0,
1707
+ /** RFC1951 */
1708
+ zip: 1,
1709
+ /** RFC1950 */
1710
+ zlib: 2,
1711
+ bzip2: 3
1712
+ },
1713
+
1714
+ /** {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
1715
+ * @enum {Integer}
1716
+ * @readonly
1717
+ */
1718
+ hash: {
1719
+ md5: 1,
1720
+ sha1: 2,
1721
+ ripemd: 3,
1722
+ sha256: 8,
1723
+ sha384: 9,
1724
+ sha512: 10,
1725
+ sha224: 11
1726
+ },
1727
+
1728
+ /** A list of hash names as accepted by webCrypto functions.
1729
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest|Parameters, algo}
1730
+ * @enum {String}
1731
+ */
1732
+ webHash: {
1733
+ 'SHA-1': 2,
1734
+ 'SHA-256': 8,
1735
+ 'SHA-384': 9,
1736
+ 'SHA-512': 10
1737
+ },
1738
+
1739
+ /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.6|RFC4880bis-04, section 9.6}
1740
+ * @enum {Integer}
1741
+ * @readonly
1742
+ */
1743
+ aead: {
1744
+ eax: 1,
1745
+ ocb: 2,
1746
+ experimentalGCM: 100 // Private algorithm
1747
+ },
1748
+
1749
+ /** A list of packet types and numeric tags associated with them.
1750
+ * @enum {Integer}
1751
+ * @readonly
1752
+ */
1753
+ packet: {
1754
+ publicKeyEncryptedSessionKey: 1,
1755
+ signature: 2,
1756
+ symEncryptedSessionKey: 3,
1757
+ onePassSignature: 4,
1758
+ secretKey: 5,
1759
+ publicKey: 6,
1760
+ secretSubkey: 7,
1761
+ compressedData: 8,
1762
+ symmetricallyEncryptedData: 9,
1763
+ marker: 10,
1764
+ literalData: 11,
1765
+ trust: 12,
1766
+ userID: 13,
1767
+ publicSubkey: 14,
1768
+ userAttribute: 17,
1769
+ symEncryptedIntegrityProtectedData: 18,
1770
+ modificationDetectionCode: 19,
1771
+ aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
1772
+ },
1773
+
1774
+ /** Data types in the literal packet
1775
+ * @enum {Integer}
1776
+ * @readonly
1777
+ */
1778
+ literal: {
1779
+ /** Binary data 'b' */
1780
+ binary: 'b'.charCodeAt(),
1781
+ /** Text data 't' */
1782
+ text: 't'.charCodeAt(),
1783
+ /** Utf8 data 'u' */
1784
+ utf8: 'u'.charCodeAt(),
1785
+ /** MIME message body part 'm' */
1786
+ mime: 'm'.charCodeAt()
1787
+ },
1788
+
1789
+
1790
+ /** One pass signature packet type
1791
+ * @enum {Integer}
1792
+ * @readonly
1793
+ */
1794
+ signature: {
1795
+ /** 0x00: Signature of a binary document. */
1796
+ binary: 0,
1797
+ /** 0x01: Signature of a canonical text document.
1798
+ *
1799
+ * Canonicalyzing the document by converting line endings. */
1800
+ text: 1,
1801
+ /** 0x02: Standalone signature.
1802
+ *
1803
+ * This signature is a signature of only its own subpacket contents.
1804
+ * It is calculated identically to a signature over a zero-lengh
1805
+ * binary document. Note that it doesn't make sense to have a V3
1806
+ * standalone signature. */
1807
+ standalone: 2,
1808
+ /** 0x10: Generic certification of a User ID and Public-Key packet.
1809
+ *
1810
+ * The issuer of this certification does not make any particular
1811
+ * assertion as to how well the certifier has checked that the owner
1812
+ * of the key is in fact the person described by the User ID. */
1813
+ certGeneric: 16,
1814
+ /** 0x11: Persona certification of a User ID and Public-Key packet.
1815
+ *
1816
+ * The issuer of this certification has not done any verification of
1817
+ * the claim that the owner of this key is the User ID specified. */
1818
+ certPersona: 17,
1819
+ /** 0x12: Casual certification of a User ID and Public-Key packet.
1820
+ *
1821
+ * The issuer of this certification has done some casual
1822
+ * verification of the claim of identity. */
1823
+ certCasual: 18,
1824
+ /** 0x13: Positive certification of a User ID and Public-Key packet.
1825
+ *
1826
+ * The issuer of this certification has done substantial
1827
+ * verification of the claim of identity.
1828
+ *
1829
+ * Most OpenPGP implementations make their "key signatures" as 0x10
1830
+ * certifications. Some implementations can issue 0x11-0x13
1831
+ * certifications, but few differentiate between the types. */
1832
+ certPositive: 19,
1833
+ /** 0x30: Certification revocation signature
1834
+ *
1835
+ * This signature revokes an earlier User ID certification signature
1836
+ * (signature class 0x10 through 0x13) or direct-key signature
1837
+ * (0x1F). It should be issued by the same key that issued the
1838
+ * revoked signature or an authorized revocation key. The signature
1839
+ * is computed over the same data as the certificate that it
1840
+ * revokes, and should have a later creation date than that
1841
+ * certificate. */
1842
+ certRevocation: 48,
1843
+ /** 0x18: Subkey Binding Signature
1844
+ *
1845
+ * This signature is a statement by the top-level signing key that
1846
+ * indicates that it owns the subkey. This signature is calculated
1847
+ * directly on the primary key and subkey, and not on any User ID or
1848
+ * other packets. A signature that binds a signing subkey MUST have
1849
+ * an Embedded Signature subpacket in this binding signature that
1850
+ * contains a 0x19 signature made by the signing subkey on the
1851
+ * primary key and subkey. */
1852
+ subkeyBinding: 24,
1853
+ /** 0x19: Primary Key Binding Signature
1854
+ *
1855
+ * This signature is a statement by a signing subkey, indicating
1856
+ * that it is owned by the primary key and subkey. This signature
1857
+ * is calculated the same way as a 0x18 signature: directly on the
1858
+ * primary key and subkey, and not on any User ID or other packets.
1859
+ *
1860
+ * When a signature is made over a key, the hash data starts with the
1861
+ * octet 0x99, followed by a two-octet length of the key, and then body
1862
+ * of the key packet. (Note that this is an old-style packet header for
1863
+ * a key packet with two-octet length.) A subkey binding signature
1864
+ * (type 0x18) or primary key binding signature (type 0x19) then hashes
1865
+ * the subkey using the same format as the main key (also using 0x99 as
1866
+ * the first octet). */
1867
+ keyBinding: 25,
1868
+ /** 0x1F: Signature directly on a key
1869
+ *
1870
+ * This signature is calculated directly on a key. It binds the
1871
+ * information in the Signature subpackets to the key, and is
1872
+ * appropriate to be used for subpackets that provide information
1873
+ * about the key, such as the Revocation Key subpacket. It is also
1874
+ * appropriate for statements that non-self certifiers want to make
1875
+ * about the key itself, rather than the binding between a key and a
1876
+ * name. */
1877
+ key: 31,
1878
+ /** 0x20: Key revocation signature
1879
+ *
1880
+ * The signature is calculated directly on the key being revoked. A
1881
+ * revoked key is not to be used. Only revocation signatures by the
1882
+ * key being revoked, or by an authorized revocation key, should be
1883
+ * considered valid revocation signatures.a */
1884
+ keyRevocation: 32,
1885
+ /** 0x28: Subkey revocation signature
1886
+ *
1887
+ * The signature is calculated directly on the subkey being revoked.
1888
+ * A revoked subkey is not to be used. Only revocation signatures
1889
+ * by the top-level signature key that is bound to this subkey, or
1890
+ * by an authorized revocation key, should be considered valid
1891
+ * revocation signatures.
1892
+ *
1893
+ * Key revocation signatures (types 0x20 and 0x28)
1894
+ * hash only the key being revoked. */
1895
+ subkeyRevocation: 40,
1896
+ /** 0x40: Timestamp signature.
1897
+ * This signature is only meaningful for the timestamp contained in
1898
+ * it. */
1899
+ timestamp: 64,
1900
+ /** 0x50: Third-Party Confirmation signature.
1901
+ *
1902
+ * This signature is a signature over some other OpenPGP Signature
1903
+ * packet(s). It is analogous to a notary seal on the signed data.
1904
+ * A third-party signature SHOULD include Signature Target
1905
+ * subpacket(s) to give easy identification. Note that we really do
1906
+ * mean SHOULD. There are plausible uses for this (such as a blind
1907
+ * party that only sees the signature, not the key or source
1908
+ * document) that cannot include a target subpacket. */
1909
+ thirdParty: 80
1910
+ },
1911
+
1912
+ /** Signature subpacket type
1913
+ * @enum {Integer}
1914
+ * @readonly
1915
+ */
1916
+ signatureSubpacket: {
1917
+ signatureCreationTime: 2,
1918
+ signatureExpirationTime: 3,
1919
+ exportableCertification: 4,
1920
+ trustSignature: 5,
1921
+ regularExpression: 6,
1922
+ revocable: 7,
1923
+ keyExpirationTime: 9,
1924
+ placeholderBackwardsCompatibility: 10,
1925
+ preferredSymmetricAlgorithms: 11,
1926
+ revocationKey: 12,
1927
+ issuer: 16,
1928
+ notationData: 20,
1929
+ preferredHashAlgorithms: 21,
1930
+ preferredCompressionAlgorithms: 22,
1931
+ keyServerPreferences: 23,
1932
+ preferredKeyServer: 24,
1933
+ primaryUserID: 25,
1934
+ policyURI: 26,
1935
+ keyFlags: 27,
1936
+ signersUserID: 28,
1937
+ reasonForRevocation: 29,
1938
+ features: 30,
1939
+ signatureTarget: 31,
1940
+ embeddedSignature: 32,
1941
+ issuerFingerprint: 33,
1942
+ preferredAEADAlgorithms: 34
1943
+ },
1944
+
1945
+ /** Key flags
1946
+ * @enum {Integer}
1947
+ * @readonly
1948
+ */
1949
+ keyFlags: {
1950
+ /** 0x01 - This key may be used to certify other keys. */
1951
+ certifyKeys: 1,
1952
+ /** 0x02 - This key may be used to sign data. */
1953
+ signData: 2,
1954
+ /** 0x04 - This key may be used to encrypt communications. */
1955
+ encryptCommunication: 4,
1956
+ /** 0x08 - This key may be used to encrypt storage. */
1957
+ encryptStorage: 8,
1958
+ /** 0x10 - The private component of this key may have been split
1959
+ * by a secret-sharing mechanism. */
1960
+ splitPrivateKey: 16,
1961
+ /** 0x20 - This key may be used for authentication. */
1962
+ authentication: 32,
1963
+ /** This key may be used for forwarded communications */
1964
+ forwardedCommunication: 64,
1965
+ /** 0x80 - The private component of this key may be in the
1966
+ * possession of more than one person. */
1967
+ sharedPrivateKey: 128
1968
+ },
1969
+
1970
+ /** Armor type
1971
+ * @enum {Integer}
1972
+ * @readonly
1973
+ */
1974
+ armor: {
1975
+ multipartSection: 0,
1976
+ multipartLast: 1,
1977
+ signed: 2,
1978
+ message: 3,
1979
+ publicKey: 4,
1980
+ privateKey: 5,
1981
+ signature: 6
1982
+ },
1983
+
1984
+ /** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
1985
+ * @enum {Integer}
1986
+ * @readonly
1987
+ */
1988
+ reasonForRevocation: {
1989
+ /** No reason specified (key revocations or cert revocations) */
1990
+ noReason: 0,
1991
+ /** Key is superseded (key revocations) */
1992
+ keySuperseded: 1,
1993
+ /** Key material has been compromised (key revocations) */
1994
+ keyCompromised: 2,
1995
+ /** Key is retired and no longer used (key revocations) */
1996
+ keyRetired: 3,
1997
+ /** User ID information is no longer valid (cert revocations) */
1998
+ userIDInvalid: 32
1999
+ },
2000
+
2001
+ /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
2002
+ * @enum {Integer}
2003
+ * @readonly
2004
+ */
2005
+ features: {
2006
+ /** 0x01 - Modification Detection (packets 18 and 19) */
2007
+ modificationDetection: 1,
2008
+ /** 0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
2009
+ * Symmetric-Key Encrypted Session Key Packets (packet 3) */
2010
+ aead: 2,
2011
+ /** 0x04 - Version 5 Public-Key Packet format and corresponding new
2012
+ * fingerprint format */
2013
+ v5Keys: 4
2014
+ },
2015
+
2016
+ /**
2017
+ * Asserts validity of given value and converts from string/integer to integer.
2018
+ * @param {Object} type target enum type
2019
+ * @param {String|Integer} e value to check and/or convert
2020
+ * @returns {Integer} enum value if it exists
2021
+ * @throws {Error} if the value is invalid
2022
+ */
2023
+ write: function(type, e) {
2024
+ if (typeof e === 'number') {
2025
+ e = this.read(type, e);
2026
+ }
2027
+
2028
+ if (type[e] !== undefined) {
2029
+ return type[e];
2030
+ }
2031
+
2032
+ throw new Error('Invalid enum value.');
2033
+ },
2034
+
2035
+ /**
2036
+ * Converts enum integer value to the corresponding string, if it exists.
2037
+ * @param {Object} type target enum type
2038
+ * @param {Integer} e value to convert
2039
+ * @returns {String} name of enum value if it exists
2040
+ * @throws {Error} if the value is invalid
2041
+ */
2042
+ read: function(type, e) {
2043
+ if (!type[byValue]) {
2044
+ type[byValue] = [];
2045
+ Object.entries(type).forEach(([key, value]) => {
2046
+ type[byValue][value] = key;
2047
+ });
2048
+ }
2049
+
2050
+ if (type[byValue][e] !== undefined) {
2051
+ return type[byValue][e];
2052
+ }
2053
+
2054
+ throw new Error('Invalid enum value.');
2055
+ }
2056
+ };
2057
+
1532
2058
  const debugMode = (() => {
1533
2059
  try {
1534
2060
  return process.env.NODE_ENV === 'development'; // eslint-disable-line no-process-env
@@ -2108,6 +2634,12 @@ const util = {
2108
2634
  */
2109
2635
  selectUint8: function(cond, a, b) {
2110
2636
  return (a & (256 - cond)) | (b & (255 + cond));
2637
+ },
2638
+ /**
2639
+ * @param {module:enums.symmetric} cipherAlgo
2640
+ */
2641
+ isAES: function(cipherAlgo) {
2642
+ return cipherAlgo === enums.symmetric.aes128 || cipherAlgo === enums.symmetric.aes192 || cipherAlgo === enums.symmetric.aes256;
2111
2643
  }
2112
2644
  };
2113
2645
 
@@ -2222,517 +2754,6 @@ function uint8ArrayToB64(bytes, url) {
2222
2754
  return encoded;
2223
2755
  }
2224
2756
 
2225
- /**
2226
- * @module enums
2227
- */
2228
-
2229
- const byValue = Symbol('byValue');
2230
-
2231
- var enums = {
2232
-
2233
- /** Maps curve names under various standards to one
2234
- * @see {@link https://wiki.gnupg.org/ECC|ECC - GnuPG wiki}
2235
- * @enum {String}
2236
- * @readonly
2237
- */
2238
- curve: {
2239
- /** NIST P-256 Curve */
2240
- 'p256': 'p256',
2241
- 'P-256': 'p256',
2242
- 'secp256r1': 'p256',
2243
- 'prime256v1': 'p256',
2244
- '1.2.840.10045.3.1.7': 'p256',
2245
- '2a8648ce3d030107': 'p256',
2246
- '2A8648CE3D030107': 'p256',
2247
-
2248
- /** NIST P-384 Curve */
2249
- 'p384': 'p384',
2250
- 'P-384': 'p384',
2251
- 'secp384r1': 'p384',
2252
- '1.3.132.0.34': 'p384',
2253
- '2b81040022': 'p384',
2254
- '2B81040022': 'p384',
2255
-
2256
- /** NIST P-521 Curve */
2257
- 'p521': 'p521',
2258
- 'P-521': 'p521',
2259
- 'secp521r1': 'p521',
2260
- '1.3.132.0.35': 'p521',
2261
- '2b81040023': 'p521',
2262
- '2B81040023': 'p521',
2263
-
2264
- /** SECG SECP256k1 Curve */
2265
- 'secp256k1': 'secp256k1',
2266
- '1.3.132.0.10': 'secp256k1',
2267
- '2b8104000a': 'secp256k1',
2268
- '2B8104000A': 'secp256k1',
2269
-
2270
- /** Ed25519 */
2271
- 'ED25519': 'ed25519',
2272
- 'ed25519': 'ed25519',
2273
- 'Ed25519': 'ed25519',
2274
- '1.3.6.1.4.1.11591.15.1': 'ed25519',
2275
- '2b06010401da470f01': 'ed25519',
2276
- '2B06010401DA470F01': 'ed25519',
2277
-
2278
- /** Curve25519 */
2279
- 'X25519': 'curve25519',
2280
- 'cv25519': 'curve25519',
2281
- 'curve25519': 'curve25519',
2282
- 'Curve25519': 'curve25519',
2283
- '1.3.6.1.4.1.3029.1.5.1': 'curve25519',
2284
- '2b060104019755010501': 'curve25519',
2285
- '2B060104019755010501': 'curve25519',
2286
-
2287
- /** BrainpoolP256r1 Curve */
2288
- 'brainpoolP256r1': 'brainpoolP256r1',
2289
- '1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1',
2290
- '2b2403030208010107': 'brainpoolP256r1',
2291
- '2B2403030208010107': 'brainpoolP256r1',
2292
-
2293
- /** BrainpoolP384r1 Curve */
2294
- 'brainpoolP384r1': 'brainpoolP384r1',
2295
- '1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1',
2296
- '2b240303020801010b': 'brainpoolP384r1',
2297
- '2B240303020801010B': 'brainpoolP384r1',
2298
-
2299
- /** BrainpoolP512r1 Curve */
2300
- 'brainpoolP512r1': 'brainpoolP512r1',
2301
- '1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1',
2302
- '2b240303020801010d': 'brainpoolP512r1',
2303
- '2B240303020801010D': 'brainpoolP512r1'
2304
- },
2305
-
2306
- /** KDF parameters flags
2307
- * Non-standard extensions (for now) to allow email forwarding
2308
- * @enum {Integer}
2309
- * @readonly
2310
- */
2311
- kdfFlags: {
2312
- /** Specify fingerprint to use instead of the recipient's */
2313
- replace_fingerprint: 0x01,
2314
- /** Specify custom parameters to use in the KDF digest computation */
2315
- replace_kdf_params: 0x02
2316
- },
2317
-
2318
- /** A string to key specifier type
2319
- * @enum {Integer}
2320
- * @readonly
2321
- */
2322
- s2k: {
2323
- simple: 0,
2324
- salted: 1,
2325
- iterated: 3,
2326
- argon2: 4,
2327
- gnu: 101
2328
- },
2329
-
2330
- /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.1|RFC4880bis-04, section 9.1}
2331
- * @enum {Integer}
2332
- * @readonly
2333
- */
2334
- publicKey: {
2335
- /** RSA (Encrypt or Sign) [HAC] */
2336
- rsaEncryptSign: 1,
2337
- /** RSA (Encrypt only) [HAC] */
2338
- rsaEncrypt: 2,
2339
- /** RSA (Sign only) [HAC] */
2340
- rsaSign: 3,
2341
- /** Elgamal (Encrypt only) [ELGAMAL] [HAC] */
2342
- elgamal: 16,
2343
- /** DSA (Sign only) [FIPS186] [HAC] */
2344
- dsa: 17,
2345
- /** ECDH (Encrypt only) [RFC6637] */
2346
- ecdh: 18,
2347
- /** ECDSA (Sign only) [RFC6637] */
2348
- ecdsa: 19,
2349
- /** EdDSA (Sign only)
2350
- * [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */
2351
- eddsa: 22,
2352
- /** Reserved for AEDH */
2353
- aedh: 23,
2354
- /** Reserved for AEDSA */
2355
- aedsa: 24,
2356
- /** Symmetric authenticated encryption algorithms */
2357
- aead: 100,
2358
- /** Authentication using CMAC */
2359
- hmac: 101
2360
- },
2361
-
2362
- /** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
2363
- * @enum {Integer}
2364
- * @readonly
2365
- */
2366
- symmetric: {
2367
- plaintext: 0,
2368
- /** Not implemented! */
2369
- idea: 1,
2370
- tripledes: 2,
2371
- cast5: 3,
2372
- blowfish: 4,
2373
- aes128: 7,
2374
- aes192: 8,
2375
- aes256: 9,
2376
- twofish: 10
2377
- },
2378
-
2379
- /** {@link https://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
2380
- * @enum {Integer}
2381
- * @readonly
2382
- */
2383
- compression: {
2384
- uncompressed: 0,
2385
- /** RFC1951 */
2386
- zip: 1,
2387
- /** RFC1950 */
2388
- zlib: 2,
2389
- bzip2: 3
2390
- },
2391
-
2392
- /** {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
2393
- * @enum {Integer}
2394
- * @readonly
2395
- */
2396
- hash: {
2397
- md5: 1,
2398
- sha1: 2,
2399
- ripemd: 3,
2400
- sha256: 8,
2401
- sha384: 9,
2402
- sha512: 10,
2403
- sha224: 11
2404
- },
2405
-
2406
- /** A list of hash names as accepted by webCrypto functions.
2407
- * {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest|Parameters, algo}
2408
- * @enum {String}
2409
- */
2410
- webHash: {
2411
- 'SHA-1': 2,
2412
- 'SHA-256': 8,
2413
- 'SHA-384': 9,
2414
- 'SHA-512': 10
2415
- },
2416
-
2417
- /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.6|RFC4880bis-04, section 9.6}
2418
- * @enum {Integer}
2419
- * @readonly
2420
- */
2421
- aead: {
2422
- eax: 1,
2423
- ocb: 2,
2424
- experimentalGCM: 100 // Private algorithm
2425
- },
2426
-
2427
- /** A list of packet types and numeric tags associated with them.
2428
- * @enum {Integer}
2429
- * @readonly
2430
- */
2431
- packet: {
2432
- publicKeyEncryptedSessionKey: 1,
2433
- signature: 2,
2434
- symEncryptedSessionKey: 3,
2435
- onePassSignature: 4,
2436
- secretKey: 5,
2437
- publicKey: 6,
2438
- secretSubkey: 7,
2439
- compressedData: 8,
2440
- symmetricallyEncryptedData: 9,
2441
- marker: 10,
2442
- literalData: 11,
2443
- trust: 12,
2444
- userID: 13,
2445
- publicSubkey: 14,
2446
- userAttribute: 17,
2447
- symEncryptedIntegrityProtectedData: 18,
2448
- modificationDetectionCode: 19,
2449
- aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
2450
- },
2451
-
2452
- /** Data types in the literal packet
2453
- * @enum {Integer}
2454
- * @readonly
2455
- */
2456
- literal: {
2457
- /** Binary data 'b' */
2458
- binary: 'b'.charCodeAt(),
2459
- /** Text data 't' */
2460
- text: 't'.charCodeAt(),
2461
- /** Utf8 data 'u' */
2462
- utf8: 'u'.charCodeAt(),
2463
- /** MIME message body part 'm' */
2464
- mime: 'm'.charCodeAt()
2465
- },
2466
-
2467
-
2468
- /** One pass signature packet type
2469
- * @enum {Integer}
2470
- * @readonly
2471
- */
2472
- signature: {
2473
- /** 0x00: Signature of a binary document. */
2474
- binary: 0,
2475
- /** 0x01: Signature of a canonical text document.
2476
- *
2477
- * Canonicalyzing the document by converting line endings. */
2478
- text: 1,
2479
- /** 0x02: Standalone signature.
2480
- *
2481
- * This signature is a signature of only its own subpacket contents.
2482
- * It is calculated identically to a signature over a zero-lengh
2483
- * binary document. Note that it doesn't make sense to have a V3
2484
- * standalone signature. */
2485
- standalone: 2,
2486
- /** 0x10: Generic certification of a User ID and Public-Key packet.
2487
- *
2488
- * The issuer of this certification does not make any particular
2489
- * assertion as to how well the certifier has checked that the owner
2490
- * of the key is in fact the person described by the User ID. */
2491
- certGeneric: 16,
2492
- /** 0x11: Persona certification of a User ID and Public-Key packet.
2493
- *
2494
- * The issuer of this certification has not done any verification of
2495
- * the claim that the owner of this key is the User ID specified. */
2496
- certPersona: 17,
2497
- /** 0x12: Casual certification of a User ID and Public-Key packet.
2498
- *
2499
- * The issuer of this certification has done some casual
2500
- * verification of the claim of identity. */
2501
- certCasual: 18,
2502
- /** 0x13: Positive certification of a User ID and Public-Key packet.
2503
- *
2504
- * The issuer of this certification has done substantial
2505
- * verification of the claim of identity.
2506
- *
2507
- * Most OpenPGP implementations make their "key signatures" as 0x10
2508
- * certifications. Some implementations can issue 0x11-0x13
2509
- * certifications, but few differentiate between the types. */
2510
- certPositive: 19,
2511
- /** 0x30: Certification revocation signature
2512
- *
2513
- * This signature revokes an earlier User ID certification signature
2514
- * (signature class 0x10 through 0x13) or direct-key signature
2515
- * (0x1F). It should be issued by the same key that issued the
2516
- * revoked signature or an authorized revocation key. The signature
2517
- * is computed over the same data as the certificate that it
2518
- * revokes, and should have a later creation date than that
2519
- * certificate. */
2520
- certRevocation: 48,
2521
- /** 0x18: Subkey Binding Signature
2522
- *
2523
- * This signature is a statement by the top-level signing key that
2524
- * indicates that it owns the subkey. This signature is calculated
2525
- * directly on the primary key and subkey, and not on any User ID or
2526
- * other packets. A signature that binds a signing subkey MUST have
2527
- * an Embedded Signature subpacket in this binding signature that
2528
- * contains a 0x19 signature made by the signing subkey on the
2529
- * primary key and subkey. */
2530
- subkeyBinding: 24,
2531
- /** 0x19: Primary Key Binding Signature
2532
- *
2533
- * This signature is a statement by a signing subkey, indicating
2534
- * that it is owned by the primary key and subkey. This signature
2535
- * is calculated the same way as a 0x18 signature: directly on the
2536
- * primary key and subkey, and not on any User ID or other packets.
2537
- *
2538
- * When a signature is made over a key, the hash data starts with the
2539
- * octet 0x99, followed by a two-octet length of the key, and then body
2540
- * of the key packet. (Note that this is an old-style packet header for
2541
- * a key packet with two-octet length.) A subkey binding signature
2542
- * (type 0x18) or primary key binding signature (type 0x19) then hashes
2543
- * the subkey using the same format as the main key (also using 0x99 as
2544
- * the first octet). */
2545
- keyBinding: 25,
2546
- /** 0x1F: Signature directly on a key
2547
- *
2548
- * This signature is calculated directly on a key. It binds the
2549
- * information in the Signature subpackets to the key, and is
2550
- * appropriate to be used for subpackets that provide information
2551
- * about the key, such as the Revocation Key subpacket. It is also
2552
- * appropriate for statements that non-self certifiers want to make
2553
- * about the key itself, rather than the binding between a key and a
2554
- * name. */
2555
- key: 31,
2556
- /** 0x20: Key revocation signature
2557
- *
2558
- * The signature is calculated directly on the key being revoked. A
2559
- * revoked key is not to be used. Only revocation signatures by the
2560
- * key being revoked, or by an authorized revocation key, should be
2561
- * considered valid revocation signatures.a */
2562
- keyRevocation: 32,
2563
- /** 0x28: Subkey revocation signature
2564
- *
2565
- * The signature is calculated directly on the subkey being revoked.
2566
- * A revoked subkey is not to be used. Only revocation signatures
2567
- * by the top-level signature key that is bound to this subkey, or
2568
- * by an authorized revocation key, should be considered valid
2569
- * revocation signatures.
2570
- *
2571
- * Key revocation signatures (types 0x20 and 0x28)
2572
- * hash only the key being revoked. */
2573
- subkeyRevocation: 40,
2574
- /** 0x40: Timestamp signature.
2575
- * This signature is only meaningful for the timestamp contained in
2576
- * it. */
2577
- timestamp: 64,
2578
- /** 0x50: Third-Party Confirmation signature.
2579
- *
2580
- * This signature is a signature over some other OpenPGP Signature
2581
- * packet(s). It is analogous to a notary seal on the signed data.
2582
- * A third-party signature SHOULD include Signature Target
2583
- * subpacket(s) to give easy identification. Note that we really do
2584
- * mean SHOULD. There are plausible uses for this (such as a blind
2585
- * party that only sees the signature, not the key or source
2586
- * document) that cannot include a target subpacket. */
2587
- thirdParty: 80
2588
- },
2589
-
2590
- /** Signature subpacket type
2591
- * @enum {Integer}
2592
- * @readonly
2593
- */
2594
- signatureSubpacket: {
2595
- signatureCreationTime: 2,
2596
- signatureExpirationTime: 3,
2597
- exportableCertification: 4,
2598
- trustSignature: 5,
2599
- regularExpression: 6,
2600
- revocable: 7,
2601
- keyExpirationTime: 9,
2602
- placeholderBackwardsCompatibility: 10,
2603
- preferredSymmetricAlgorithms: 11,
2604
- revocationKey: 12,
2605
- issuer: 16,
2606
- notationData: 20,
2607
- preferredHashAlgorithms: 21,
2608
- preferredCompressionAlgorithms: 22,
2609
- keyServerPreferences: 23,
2610
- preferredKeyServer: 24,
2611
- primaryUserID: 25,
2612
- policyURI: 26,
2613
- keyFlags: 27,
2614
- signersUserID: 28,
2615
- reasonForRevocation: 29,
2616
- features: 30,
2617
- signatureTarget: 31,
2618
- embeddedSignature: 32,
2619
- issuerFingerprint: 33,
2620
- preferredAEADAlgorithms: 34
2621
- },
2622
-
2623
- /** Key flags
2624
- * @enum {Integer}
2625
- * @readonly
2626
- */
2627
- keyFlags: {
2628
- /** 0x01 - This key may be used to certify other keys. */
2629
- certifyKeys: 1,
2630
- /** 0x02 - This key may be used to sign data. */
2631
- signData: 2,
2632
- /** 0x04 - This key may be used to encrypt communications. */
2633
- encryptCommunication: 4,
2634
- /** 0x08 - This key may be used to encrypt storage. */
2635
- encryptStorage: 8,
2636
- /** 0x10 - The private component of this key may have been split
2637
- * by a secret-sharing mechanism. */
2638
- splitPrivateKey: 16,
2639
- /** 0x20 - This key may be used for authentication. */
2640
- authentication: 32,
2641
- /** This key may be used for forwarded communications */
2642
- forwardedCommunication: 64,
2643
- /** 0x80 - The private component of this key may be in the
2644
- * possession of more than one person. */
2645
- sharedPrivateKey: 128
2646
- },
2647
-
2648
- /** Armor type
2649
- * @enum {Integer}
2650
- * @readonly
2651
- */
2652
- armor: {
2653
- multipartSection: 0,
2654
- multipartLast: 1,
2655
- signed: 2,
2656
- message: 3,
2657
- publicKey: 4,
2658
- privateKey: 5,
2659
- signature: 6
2660
- },
2661
-
2662
- /** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
2663
- * @enum {Integer}
2664
- * @readonly
2665
- */
2666
- reasonForRevocation: {
2667
- /** No reason specified (key revocations or cert revocations) */
2668
- noReason: 0,
2669
- /** Key is superseded (key revocations) */
2670
- keySuperseded: 1,
2671
- /** Key material has been compromised (key revocations) */
2672
- keyCompromised: 2,
2673
- /** Key is retired and no longer used (key revocations) */
2674
- keyRetired: 3,
2675
- /** User ID information is no longer valid (cert revocations) */
2676
- userIDInvalid: 32
2677
- },
2678
-
2679
- /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
2680
- * @enum {Integer}
2681
- * @readonly
2682
- */
2683
- features: {
2684
- /** 0x01 - Modification Detection (packets 18 and 19) */
2685
- modificationDetection: 1,
2686
- /** 0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
2687
- * Symmetric-Key Encrypted Session Key Packets (packet 3) */
2688
- aead: 2,
2689
- /** 0x04 - Version 5 Public-Key Packet format and corresponding new
2690
- * fingerprint format */
2691
- v5Keys: 4
2692
- },
2693
-
2694
- /**
2695
- * Asserts validity of given value and converts from string/integer to integer.
2696
- * @param {Object} type target enum type
2697
- * @param {String|Integer} e value to check and/or convert
2698
- * @returns {Integer} enum value if it exists
2699
- * @throws {Error} if the value is invalid
2700
- */
2701
- write: function(type, e) {
2702
- if (typeof e === 'number') {
2703
- e = this.read(type, e);
2704
- }
2705
-
2706
- if (type[e] !== undefined) {
2707
- return type[e];
2708
- }
2709
-
2710
- throw new Error('Invalid enum value.');
2711
- },
2712
-
2713
- /**
2714
- * Converts enum integer value to the corresponding string, if it exists.
2715
- * @param {Object} type target enum type
2716
- * @param {Integer} e value to convert
2717
- * @returns {String} name of enum value if it exists
2718
- * @throws {Error} if the value is invalid
2719
- */
2720
- read: function(type, e) {
2721
- if (!type[byValue]) {
2722
- type[byValue] = [];
2723
- Object.entries(type).forEach(([key, value]) => {
2724
- type[byValue][value] = key;
2725
- });
2726
- }
2727
-
2728
- if (type[byValue][e] !== undefined) {
2729
- return type[byValue][e];
2730
- }
2731
-
2732
- throw new Error('Invalid enum value.');
2733
- }
2734
- };
2735
-
2736
2757
  // GPG4Browsers - An OpenPGP implementation in javascript
2737
2758
 
2738
2759
  var config = {
@@ -2949,7 +2970,7 @@ var config = {
2949
2970
  * @memberof module:config
2950
2971
  * @property {String} versionString A version string to be included in armored messages
2951
2972
  */
2952
- versionString: 'OpenPGP.js 5.9.1-1',
2973
+ versionString: 'OpenPGP.js 5.11.0',
2953
2974
  /**
2954
2975
  * @memberof module:config
2955
2976
  * @property {String} commentString A comment string to be included in armored messages
@@ -3000,7 +3021,14 @@ var config = {
3000
3021
  * @memberof module:config
3001
3022
  * @property {Set<String>} rejectCurves {@link module:enums.curve}
3002
3023
  */
3003
- rejectCurves: new Set([enums.curve.secp256k1])
3024
+ rejectCurves: new Set([enums.curve.secp256k1]),
3025
+ /**
3026
+ * Whether to validate generated EdDSA signatures before returning them, to ensure they are not faulty signatures.
3027
+ * This check will make signing 2-3 times slower.
3028
+ * Faulty signatures may be generated (in principle) if random bitflips occur at specific points in the signature
3029
+ * computation, and could be used to recover the signer's secret key given a second signature over the same data.
3030
+ */
3031
+ checkEdDSAFaultySignatures: true
3004
3032
  };
3005
3033
 
3006
3034
  /**
@@ -3441,6 +3469,7 @@ class KeyID {
3441
3469
  */
3442
3470
  read(bytes) {
3443
3471
  this.bytes = util.uint8ArrayToString(bytes.subarray(0, 8));
3472
+ return this.bytes.length;
3444
3473
  }
3445
3474
 
3446
3475
  /**
@@ -9997,7 +10026,7 @@ async function encrypt(algo, key, plaintext, iv, config) {
9997
10026
  if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
9998
10027
  return nodeEncrypt(algo, key, plaintext, iv);
9999
10028
  }
10000
- if (algoName.substr(0, 3) === 'aes') {
10029
+ if (util.isAES(algo)) {
10001
10030
  return aesEncrypt(algo, key, plaintext, iv, config);
10002
10031
  }
10003
10032
 
@@ -10040,7 +10069,7 @@ async function decrypt(algo, key, ciphertext, iv) {
10040
10069
  if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
10041
10070
  return nodeDecrypt(algo, key, ciphertext, iv);
10042
10071
  }
10043
- if (algoName.substr(0, 3) === 'aes') {
10072
+ if (util.isAES(algo)) {
10044
10073
  return aesDecrypt(algo, key, ciphertext, iv);
10045
10074
  }
10046
10075
 
@@ -10059,7 +10088,7 @@ async function decrypt(algo, key, ciphertext, iv) {
10059
10088
  let j = 0;
10060
10089
  while (chunk ? ct.length >= block_size : ct.length) {
10061
10090
  const decblock = cipherfn.encrypt(blockp);
10062
- blockp = ct;
10091
+ blockp = ct.subarray(0, block_size);
10063
10092
  for (i = 0; i < block_size; i++) {
10064
10093
  plaintext[j++] = blockp[i] ^ decblock[i];
10065
10094
  }
@@ -10985,42 +11014,42 @@ async function GCM(cipher, key) {
10985
11014
  throw new Error('GCM mode supports only AES cipher');
10986
11015
  }
10987
11016
 
10988
- if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
10989
- const _key = await webCrypto$4.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
10990
-
11017
+ if (util.getNodeCrypto()) { // Node crypto library
10991
11018
  return {
10992
11019
  encrypt: async function(pt, iv, adata = new Uint8Array()) {
10993
- if (!pt.length) { // iOS does not support GCM-en/decrypting empty messages
10994
- return AES_GCM.encrypt(pt, key, iv, adata);
10995
- }
10996
- const ct = await webCrypto$4.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, pt);
11020
+ const en = new nodeCrypto$4.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
11021
+ en.setAAD(adata);
11022
+ const ct = Buffer$3.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
10997
11023
  return new Uint8Array(ct);
10998
11024
  },
10999
11025
 
11000
11026
  decrypt: async function(ct, iv, adata = new Uint8Array()) {
11001
- if (ct.length === tagLength$2) { // iOS does not support GCM-en/decrypting empty messages
11002
- return AES_GCM.decrypt(ct, key, iv, adata);
11003
- }
11004
- const pt = await webCrypto$4.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, ct);
11027
+ const de = new nodeCrypto$4.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
11028
+ de.setAAD(adata);
11029
+ de.setAuthTag(ct.slice(ct.length - tagLength$2, ct.length)); // read auth tag at end of ciphertext
11030
+ const pt = Buffer$3.concat([de.update(ct.slice(0, ct.length - tagLength$2)), de.final()]);
11005
11031
  return new Uint8Array(pt);
11006
11032
  }
11007
11033
  };
11008
11034
  }
11009
11035
 
11010
- if (util.getNodeCrypto()) { // Node crypto library
11036
+ if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
11037
+ const _key = await webCrypto$4.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
11038
+
11011
11039
  return {
11012
11040
  encrypt: async function(pt, iv, adata = new Uint8Array()) {
11013
- const en = new nodeCrypto$4.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
11014
- en.setAAD(adata);
11015
- const ct = Buffer$3.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
11041
+ if (!pt.length) { // iOS does not support GCM-en/decrypting empty messages
11042
+ return AES_GCM.encrypt(pt, key, iv, adata);
11043
+ }
11044
+ const ct = await webCrypto$4.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, pt);
11016
11045
  return new Uint8Array(ct);
11017
11046
  },
11018
11047
 
11019
11048
  decrypt: async function(ct, iv, adata = new Uint8Array()) {
11020
- const de = new nodeCrypto$4.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
11021
- de.setAAD(adata);
11022
- de.setAuthTag(ct.slice(ct.length - tagLength$2, ct.length)); // read auth tag at end of ciphertext
11023
- const pt = Buffer$3.concat([de.update(ct.slice(0, ct.length - tagLength$2)), de.final()]);
11049
+ if (ct.length === tagLength$2) { // iOS does not support GCM-en/decrypting empty messages
11050
+ return AES_GCM.decrypt(ct, key, iv, adata);
11051
+ }
11052
+ const pt = await webCrypto$4.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, ct);
11024
11053
  return new Uint8Array(pt);
11025
11054
  }
11026
11055
  };
@@ -12023,11 +12052,11 @@ const nodeCrypto$5 = util.getNodeCrypto();
12023
12052
  */
12024
12053
  function getRandomBytes(length) {
12025
12054
  const buf = new Uint8Array(length);
12026
- if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
12027
- crypto.getRandomValues(buf);
12028
- } else if (nodeCrypto$5) {
12055
+ if (nodeCrypto$5) {
12029
12056
  const bytes = nodeCrypto$5.randomBytes(buf.length);
12030
12057
  buf.set(bytes);
12058
+ } else if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
12059
+ crypto.getRandomValues(buf);
12031
12060
  } else {
12032
12061
  throw new Error('No secure random number generator available.');
12033
12062
  }
@@ -13587,7 +13616,7 @@ const curves = {
13587
13616
  },
13588
13617
  ed25519: {
13589
13618
  oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01],
13590
- keyType: enums.publicKey.eddsa,
13619
+ keyType: enums.publicKey.eddsaLegacy,
13591
13620
  hash: enums.hash.sha512,
13592
13621
  node: false, // nodeCurves.ed25519 TODO
13593
13622
  payloadSize: 32
@@ -13626,7 +13655,7 @@ const curves = {
13626
13655
  }
13627
13656
  };
13628
13657
 
13629
- class Curve {
13658
+ class CurveWithOID {
13630
13659
  constructor(oidOrName, params) {
13631
13660
  try {
13632
13661
  if (util.isArray(oidOrName) ||
@@ -13703,7 +13732,7 @@ class Curve {
13703
13732
  async function generate$1(curve) {
13704
13733
  const BigInteger = await util.getBigInteger();
13705
13734
 
13706
- curve = new Curve(curve);
13735
+ curve = new CurveWithOID(curve);
13707
13736
  const keyPair = await curve.genKeyPair();
13708
13737
  const Q = new BigInteger(keyPair.publicKey).toUint8Array();
13709
13738
  const secret = new BigInteger(keyPair.privateKey).toUint8Array('be', curve.payloadSize);
@@ -13892,7 +13921,7 @@ const nodeCrypto$8 = util.getNodeCrypto();
13892
13921
  * @async
13893
13922
  */
13894
13923
  async function sign$1(oid, hashAlgo, message, publicKey, privateKey, hashed) {
13895
- const curve = new Curve(oid);
13924
+ const curve = new CurveWithOID(oid);
13896
13925
  if (message && !util.isStream(message)) {
13897
13926
  const keyPair = { publicKey, privateKey };
13898
13927
  switch (curve.type) {
@@ -13937,7 +13966,7 @@ async function sign$1(oid, hashAlgo, message, publicKey, privateKey, hashed) {
13937
13966
  * @async
13938
13967
  */
13939
13968
  async function verify$1(oid, hashAlgo, signature, message, publicKey, hashed) {
13940
- const curve = new Curve(oid);
13969
+ const curve = new CurveWithOID(oid);
13941
13970
  if (message && !util.isStream(message)) {
13942
13971
  switch (curve.type) {
13943
13972
  case 'web':
@@ -13971,7 +14000,7 @@ async function verify$1(oid, hashAlgo, signature, message, publicKey, hashed) {
13971
14000
  * @async
13972
14001
  */
13973
14002
  async function validateParams$2(oid, Q, d) {
13974
- const curve = new Curve(oid);
14003
+ const curve = new CurveWithOID(oid);
13975
14004
  // Reject curves x25519 and ed25519
13976
14005
  if (curve.keyType !== enums.publicKey.ecdsa) {
13977
14006
  return false;
@@ -14174,7 +14203,7 @@ var ecdsa = /*#__PURE__*/Object.freeze({
14174
14203
  naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
14175
14204
 
14176
14205
  /**
14177
- * Sign a message using the provided key
14206
+ * Sign a message using the provided legacy EdDSA key
14178
14207
  * @param {module:type/oid} oid - Elliptic curve object identifier
14179
14208
  * @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
14180
14209
  * @param {Uint8Array} message - Message to sign
@@ -14190,10 +14219,24 @@ naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
14190
14219
  async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
14191
14220
  if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
14192
14221
  // see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
14193
- throw new Error('Hash algorithm too weak: sha256 or stronger is required for EdDSA.');
14222
+ throw new Error('Hash algorithm too weak for EdDSA.');
14194
14223
  }
14195
14224
  const secretKey = util.concatUint8Array([privateKey, publicKey.subarray(1)]);
14196
14225
  const signature = naclFastLight.sign.detached(hashed, secretKey);
14226
+ if (config.checkEdDSAFaultySignatures && !naclFastLight.sign.detached.verify(hashed, signature, publicKey.subarray(1))) {
14227
+ /**
14228
+ * Detect faulty signatures caused by random bitflips during `crypto_sign` which could lead to private key extraction
14229
+ * if two signatures over the same message are obtained.
14230
+ * See https://github.com/jedisct1/libsodium/issues/170.
14231
+ * If the input data is not deterministic, e.g. thanks to the random salt in v6 OpenPGP signatures (not yet implemented),
14232
+ * then the generated signature is always safe, and the verification step is skipped.
14233
+ * Otherwise, we need to verify the generated to ensure that no bitflip occured:
14234
+ * - in M between the computation of `r` and `h`.
14235
+ * - in the public key before computing `h`
14236
+ * The verification step is almost 2-3 times as slow as signing, but it's faster than re-signing + re-deriving the public key for separate checks.
14237
+ */
14238
+ throw new Error('Transient signing failure');
14239
+ }
14197
14240
  // EdDSA signature params are returned in little-endian format
14198
14241
  return {
14199
14242
  r: signature.subarray(0, 32),
@@ -14202,7 +14245,7 @@ async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
14202
14245
  }
14203
14246
 
14204
14247
  /**
14205
- * Verifies if a signature is valid for a message
14248
+ * Verifies if a legacy EdDSA signature is valid for a message
14206
14249
  * @param {module:type/oid} oid - Elliptic curve object identifier
14207
14250
  * @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
14208
14251
  * @param {{r: Uint8Array,
@@ -14214,11 +14257,14 @@ async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
14214
14257
  * @async
14215
14258
  */
14216
14259
  async function verify$2(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
14260
+ if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
14261
+ throw new Error('Hash algorithm too weak for EdDSA.');
14262
+ }
14217
14263
  const signature = util.concatUint8Array([r, s]);
14218
14264
  return naclFastLight.sign.detached.verify(hashed, signature, publicKey.subarray(1));
14219
14265
  }
14220
14266
  /**
14221
- * Validate EdDSA parameters
14267
+ * Validate legacy EdDSA parameters
14222
14268
  * @param {module:type/oid} oid - Elliptic curve object identifier
14223
14269
  * @param {Uint8Array} Q - EdDSA public point
14224
14270
  * @param {Uint8Array} k - EdDSA secret seed
@@ -14238,9 +14284,10 @@ async function validateParams$3(oid, Q, k) {
14238
14284
  const { publicKey } = naclFastLight.sign.keyPair.fromSeed(k);
14239
14285
  const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
14240
14286
  return util.equalsUint8Array(Q, dG);
14287
+
14241
14288
  }
14242
14289
 
14243
- var eddsa = /*#__PURE__*/Object.freeze({
14290
+ var eddsa_legacy = /*#__PURE__*/Object.freeze({
14244
14291
  __proto__: null,
14245
14292
  sign: sign$2,
14246
14293
  verify: verify$2,
@@ -14249,6 +14296,139 @@ var eddsa = /*#__PURE__*/Object.freeze({
14249
14296
 
14250
14297
  // OpenPGP.js - An OpenPGP implementation in javascript
14251
14298
 
14299
+ naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
14300
+
14301
+ /**
14302
+ * Generate (non-legacy) EdDSA key
14303
+ * @param {module:enums.publicKey} algo - Algorithm identifier
14304
+ * @returns {Promise<{ A: Uint8Array, seed: Uint8Array }>}
14305
+ */
14306
+ async function generate$2(algo) {
14307
+ switch (algo) {
14308
+ case enums.publicKey.ed25519: {
14309
+ const seed = getRandomBytes(32);
14310
+ const { publicKey: A } = naclFastLight.sign.keyPair.fromSeed(seed);
14311
+ return { A, seed };
14312
+ }
14313
+ default:
14314
+ throw new Error('Unsupported EdDSA algorithm');
14315
+ }
14316
+ }
14317
+
14318
+ /**
14319
+ * Sign a message using the provided key
14320
+ * @param {module:enums.publicKey} algo - Algorithm identifier
14321
+ * @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
14322
+ * @param {Uint8Array} message - Message to sign
14323
+ * @param {Uint8Array} publicKey - Public key
14324
+ * @param {Uint8Array} privateKey - Private key used to sign the message
14325
+ * @param {Uint8Array} hashed - The hashed message
14326
+ * @returns {Promise<{
14327
+ * RS: Uint8Array
14328
+ * }>} Signature of the message
14329
+ * @async
14330
+ */
14331
+ async function sign$3(algo, hashAlgo, message, publicKey, privateKey, hashed) {
14332
+ if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo$1(algo))) {
14333
+ throw new Error('Hash algorithm too weak for EdDSA.');
14334
+ }
14335
+ switch (algo) {
14336
+ case enums.publicKey.ed25519: {
14337
+ const secretKey = util.concatUint8Array([privateKey, publicKey]);
14338
+ const signature = naclFastLight.sign.detached(hashed, secretKey);
14339
+ if (config.checkEdDSAFaultySignatures && !naclFastLight.sign.detached.verify(hashed, signature, publicKey)) {
14340
+ /**
14341
+ * Detect faulty signatures caused by random bitflips during `crypto_sign` which could lead to private key extraction
14342
+ * if two signatures over the same message are obtained.
14343
+ * See https://github.com/jedisct1/libsodium/issues/170.
14344
+ * If the input data is not deterministic, e.g. thanks to the random salt in v6 OpenPGP signatures (not yet implemented),
14345
+ * then the generated signature is always safe, and the verification step is skipped.
14346
+ * Otherwise, we need to verify the generated to ensure that no bitflip occured:
14347
+ * - in M between the computation of `r` and `h`.
14348
+ * - in the public key before computing `h`
14349
+ * The verification step is almost 2-3 times as slow as signing, but it's faster than re-signing + re-deriving the public key for separate checks.
14350
+ */
14351
+ throw new Error('Transient signing failure');
14352
+ }
14353
+ return { RS: signature };
14354
+ }
14355
+ case enums.publicKey.ed448:
14356
+ default:
14357
+ throw new Error('Unsupported EdDSA algorithm');
14358
+ }
14359
+
14360
+ }
14361
+
14362
+ /**
14363
+ * Verifies if a signature is valid for a message
14364
+ * @param {module:enums.publicKey} algo - Algorithm identifier
14365
+ * @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
14366
+ * @param {{ RS: Uint8Array }} signature Signature to verify the message
14367
+ * @param {Uint8Array} m - Message to verify
14368
+ * @param {Uint8Array} publicKey - Public key used to verify the message
14369
+ * @param {Uint8Array} hashed - The hashed message
14370
+ * @returns {Boolean}
14371
+ * @async
14372
+ */
14373
+ async function verify$3(algo, hashAlgo, { RS }, m, publicKey, hashed) {
14374
+ if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo$1(algo))) {
14375
+ throw new Error('Hash algorithm too weak for EdDSA.');
14376
+ }
14377
+ switch (algo) {
14378
+ case enums.publicKey.ed25519: {
14379
+ return naclFastLight.sign.detached.verify(hashed, RS, publicKey);
14380
+ }
14381
+ case enums.publicKey.ed448:
14382
+ default:
14383
+ throw new Error('Unsupported EdDSA algorithm');
14384
+ }
14385
+ }
14386
+ /**
14387
+ * Validate (non-legacy) EdDSA parameters
14388
+ * @param {module:enums.publicKey} algo - Algorithm identifier
14389
+ * @param {Uint8Array} A - EdDSA public point
14390
+ * @param {Uint8Array} seed - EdDSA secret seed
14391
+ * @param {Uint8Array} oid - (legacy only) EdDSA OID
14392
+ * @returns {Promise<Boolean>} Whether params are valid.
14393
+ * @async
14394
+ */
14395
+ async function validateParams$4(algo, A, seed) {
14396
+ switch (algo) {
14397
+ case enums.publicKey.ed25519: {
14398
+ /**
14399
+ * Derive public point A' from private key
14400
+ * and expect A == A'
14401
+ */
14402
+ const { publicKey } = naclFastLight.sign.keyPair.fromSeed(seed);
14403
+ return util.equalsUint8Array(A, publicKey);
14404
+ }
14405
+
14406
+ case enums.publicKey.ed448: // unsupported
14407
+ default:
14408
+ return false;
14409
+ }
14410
+ }
14411
+
14412
+ function getPreferredHashAlgo$1(algo) {
14413
+ switch (algo) {
14414
+ case enums.publicKey.ed25519:
14415
+ return enums.hash.sha256;
14416
+ default:
14417
+ throw new Error('Unknown EdDSA algo');
14418
+ }
14419
+ }
14420
+
14421
+ var eddsa = /*#__PURE__*/Object.freeze({
14422
+ __proto__: null,
14423
+ generate: generate$2,
14424
+ sign: sign$3,
14425
+ verify: verify$3,
14426
+ validateParams: validateParams$4,
14427
+ getPreferredHashAlgo: getPreferredHashAlgo$1
14428
+ });
14429
+
14430
+ // OpenPGP.js - An OpenPGP implementation in javascript
14431
+
14252
14432
  /**
14253
14433
  * AES key wrap
14254
14434
  * @function
@@ -14436,7 +14616,7 @@ const nodeCrypto$9 = util.getNodeCrypto();
14436
14616
  * @returns {Promise<Boolean>} Whether params are valid.
14437
14617
  * @async
14438
14618
  */
14439
- async function validateParams$4(oid, Q, d) {
14619
+ async function validateParams$5(oid, Q, d) {
14440
14620
  return validateStandardParams(enums.publicKey.ecdh, oid, Q, d);
14441
14621
  }
14442
14622
 
@@ -14478,7 +14658,7 @@ async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTraili
14478
14658
  /**
14479
14659
  * Generate ECDHE ephemeral key and secret from public key
14480
14660
  *
14481
- * @param {Curve} curve - Elliptic curve object
14661
+ * @param {CurveWithOID} curve - Elliptic curve object
14482
14662
  * @param {Uint8Array} Q - Recipient public key
14483
14663
  * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
14484
14664
  * @async
@@ -14521,7 +14701,7 @@ async function genPublicEphemeralKey(curve, Q) {
14521
14701
  async function encrypt$3(oid, kdfParams, data, Q, fingerprint) {
14522
14702
  const m = encode$1(data);
14523
14703
 
14524
- const curve = new Curve(oid);
14704
+ const curve = new CurveWithOID(oid);
14525
14705
  const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
14526
14706
  const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
14527
14707
  const { keySize } = getCipher(kdfParams.cipher);
@@ -14533,7 +14713,7 @@ async function encrypt$3(oid, kdfParams, data, Q, fingerprint) {
14533
14713
  /**
14534
14714
  * Generate ECDHE secret from private key and public part of ephemeral key
14535
14715
  *
14536
- * @param {Curve} curve - Elliptic curve object
14716
+ * @param {CurveWithOID} curve - Elliptic curve object
14537
14717
  * @param {Uint8Array} V - Public part of ephemeral key
14538
14718
  * @param {Uint8Array} Q - Recipient public key
14539
14719
  * @param {Uint8Array} d - Recipient private key
@@ -14581,7 +14761,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) {
14581
14761
  * @async
14582
14762
  */
14583
14763
  async function decrypt$3(oid, kdfParams, V, C, Q, d, fingerprint) {
14584
- const curve = new Curve(oid);
14764
+ const curve = new CurveWithOID(oid);
14585
14765
  const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
14586
14766
  const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
14587
14767
  const { keySize } = getCipher(kdfParams.cipher);
@@ -14601,7 +14781,7 @@ async function decrypt$3(oid, kdfParams, V, C, Q, d, fingerprint) {
14601
14781
  /**
14602
14782
  * Generate ECDHE secret from private key and public part of ephemeral key using webCrypto
14603
14783
  *
14604
- * @param {Curve} curve - Elliptic curve object
14784
+ * @param {CurveWithOID} curve - Elliptic curve object
14605
14785
  * @param {Uint8Array} V - Public part of ephemeral key
14606
14786
  * @param {Uint8Array} Q - Recipient public key
14607
14787
  * @param {Uint8Array} d - Recipient private key
@@ -14654,7 +14834,7 @@ async function webPrivateEphemeralKey(curve, V, Q, d) {
14654
14834
  /**
14655
14835
  * Generate ECDHE ephemeral key and secret from public key using webCrypto
14656
14836
  *
14657
- * @param {Curve} curve - Elliptic curve object
14837
+ * @param {CurveWithOID} curve - Elliptic curve object
14658
14838
  * @param {Uint8Array} Q - Recipient public key
14659
14839
  * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
14660
14840
  * @async
@@ -14702,7 +14882,7 @@ async function webPublicEphemeralKey(curve, Q) {
14702
14882
  /**
14703
14883
  * Generate ECDHE secret from private key and public part of ephemeral key using indutny/elliptic
14704
14884
  *
14705
- * @param {Curve} curve - Elliptic curve object
14885
+ * @param {CurveWithOID} curve - Elliptic curve object
14706
14886
  * @param {Uint8Array} V - Public part of ephemeral key
14707
14887
  * @param {Uint8Array} d - Recipient private key
14708
14888
  * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
@@ -14722,7 +14902,7 @@ async function ellipticPrivateEphemeralKey(curve, V, d) {
14722
14902
  /**
14723
14903
  * Generate ECDHE ephemeral key and secret from public key using indutny/elliptic
14724
14904
  *
14725
- * @param {Curve} curve - Elliptic curve object
14905
+ * @param {CurveWithOID} curve - Elliptic curve object
14726
14906
  * @param {Uint8Array} Q - Recipient public key
14727
14907
  * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
14728
14908
  * @async
@@ -14742,7 +14922,7 @@ async function ellipticPublicEphemeralKey(curve, Q) {
14742
14922
  /**
14743
14923
  * Generate ECDHE secret from private key and public part of ephemeral key using nodeCrypto
14744
14924
  *
14745
- * @param {Curve} curve - Elliptic curve object
14925
+ * @param {CurveWithOID} curve - Elliptic curve object
14746
14926
  * @param {Uint8Array} V - Public part of ephemeral key
14747
14927
  * @param {Uint8Array} d - Recipient private key
14748
14928
  * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
@@ -14759,7 +14939,7 @@ async function nodePrivateEphemeralKey(curve, V, d) {
14759
14939
  /**
14760
14940
  * Generate ECDHE ephemeral key and secret from public key using nodeCrypto
14761
14941
  *
14762
- * @param {Curve} curve - Elliptic curve object
14942
+ * @param {CurveWithOID} curve - Elliptic curve object
14763
14943
  * @param {Uint8Array} Q - Recipient public key
14764
14944
  * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
14765
14945
  * @async
@@ -14774,18 +14954,202 @@ async function nodePublicEphemeralKey(curve, Q) {
14774
14954
 
14775
14955
  var ecdh = /*#__PURE__*/Object.freeze({
14776
14956
  __proto__: null,
14777
- validateParams: validateParams$4,
14957
+ validateParams: validateParams$5,
14778
14958
  encrypt: encrypt$3,
14779
14959
  decrypt: decrypt$3
14780
14960
  });
14781
14961
 
14962
+ /**
14963
+ * @fileoverview This module implements HKDF using either the WebCrypto API or Node.js' crypto API.
14964
+ * @module crypto/hkdf
14965
+ * @private
14966
+ */
14967
+
14968
+ const webCrypto$9 = util.getWebCrypto();
14969
+ const nodeCrypto$a = util.getNodeCrypto();
14970
+ const nodeSubtleCrypto = nodeCrypto$a && nodeCrypto$a.webcrypto && nodeCrypto$a.webcrypto.subtle;
14971
+
14972
+ async function HKDF(hashAlgo, inputKey, salt, info, outLen) {
14973
+ const hash = enums.read(enums.webHash, hashAlgo);
14974
+ if (!hash) throw new Error('Hash algo not supported with HKDF');
14975
+
14976
+ if (webCrypto$9 || nodeSubtleCrypto) {
14977
+ const crypto = webCrypto$9 || nodeSubtleCrypto;
14978
+ const importedKey = await crypto.importKey('raw', inputKey, 'HKDF', false, ['deriveBits']);
14979
+ const bits = await crypto.deriveBits({ name: 'HKDF', hash, salt, info }, importedKey, outLen * 8);
14980
+ return new Uint8Array(bits);
14981
+ }
14982
+
14983
+ if (nodeCrypto$a) {
14984
+ const hashAlgoName = enums.read(enums.hash, hashAlgo);
14985
+ // Node-only HKDF implementation based on https://www.rfc-editor.org/rfc/rfc5869
14986
+
14987
+ const computeHMAC = (hmacKey, hmacMessage) => nodeCrypto$a.createHmac(hashAlgoName, hmacKey).update(hmacMessage).digest();
14988
+ // Step 1: Extract
14989
+ // PRK = HMAC-Hash(salt, IKM)
14990
+ const pseudoRandomKey = computeHMAC(salt, inputKey);
14991
+
14992
+ const hashLen = pseudoRandomKey.length;
14993
+
14994
+ // Step 2: Expand
14995
+ // HKDF-Expand(PRK, info, L) -> OKM
14996
+ const n = Math.ceil(outLen / hashLen);
14997
+ const outputKeyingMaterial = new Uint8Array(n * hashLen);
14998
+
14999
+ // HMAC input buffer updated at each iteration
15000
+ const roundInput = new Uint8Array(hashLen + info.length + 1);
15001
+ // T_i and last byte are updated at each iteration, but `info` remains constant
15002
+ roundInput.set(info, hashLen);
15003
+
15004
+ for (let i = 0; i < n; i++) {
15005
+ // T(0) = empty string (zero length)
15006
+ // T(i) = HMAC-Hash(PRK, T(i-1) | info | i)
15007
+ roundInput[roundInput.length - 1] = i + 1;
15008
+ // t = T(i+1)
15009
+ const t = computeHMAC(pseudoRandomKey, i > 0 ? roundInput : roundInput.subarray(hashLen));
15010
+ roundInput.set(t, 0);
15011
+
15012
+ outputKeyingMaterial.set(t, i * hashLen);
15013
+ }
15014
+
15015
+ return outputKeyingMaterial.subarray(0, outLen);
15016
+ }
15017
+
15018
+ throw new Error('No HKDF implementation available');
15019
+ }
15020
+
15021
+ /**
15022
+ * @fileoverview Key encryption and decryption for RFC 6637 ECDH
15023
+ * @module crypto/public_key/elliptic/ecdh
15024
+ * @private
15025
+ */
15026
+
15027
+ const HKDF_INFO = {
15028
+ x25519: util.encodeUTF8('OpenPGP X25519')
15029
+ };
15030
+
15031
+ /**
15032
+ * Generate ECDH key for Montgomery curves
15033
+ * @param {module:enums.publicKey} algo - Algorithm identifier
15034
+ * @returns {Promise<{ A: Uint8Array, k: Uint8Array }>}
15035
+ */
15036
+ async function generate$3(algo) {
15037
+ switch (algo) {
15038
+ case enums.publicKey.x25519: {
15039
+ // k stays in little-endian, unlike legacy ECDH over curve25519
15040
+ const k = getRandomBytes(32);
15041
+ const { publicKey: A } = naclFastLight.box.keyPair.fromSecretKey(k);
15042
+ return { A, k };
15043
+ }
15044
+ default:
15045
+ throw new Error('Unsupported ECDH algorithm');
15046
+ }
15047
+ }
15048
+
15049
+ /**
15050
+ * Validate ECDH parameters
15051
+ * @param {module:enums.publicKey} algo - Algorithm identifier
15052
+ * @param {Uint8Array} A - ECDH public point
15053
+ * @param {Uint8Array} k - ECDH secret scalar
15054
+ * @returns {Promise<Boolean>} Whether params are valid.
15055
+ * @async
15056
+ */
15057
+ async function validateParams$6(algo, A, k) {
15058
+ switch (algo) {
15059
+ case enums.publicKey.x25519: {
15060
+ /**
15061
+ * Derive public point A' from private key
15062
+ * and expect A == A'
15063
+ */
15064
+ const { publicKey } = naclFastLight.box.keyPair.fromSecretKey(k);
15065
+ return util.equalsUint8Array(A, publicKey);
15066
+ }
15067
+
15068
+ default:
15069
+ return false;
15070
+ }
15071
+ }
15072
+
15073
+ /**
15074
+ * Wrap and encrypt a session key
15075
+ *
15076
+ * @param {module:enums.publicKey} algo - Algorithm identifier
15077
+ * @param {Uint8Array} data - session key data to be encrypted
15078
+ * @param {Uint8Array} recipientA - Recipient public key (K_B)
15079
+ * @returns {Promise<{
15080
+ * ephemeralPublicKey: Uint8Array,
15081
+ * wrappedKey: Uint8Array
15082
+ * }>} ephemeral public key (K_A) and encrypted key
15083
+ * @async
15084
+ */
15085
+ async function encrypt$4(algo, data, recipientA) {
15086
+ switch (algo) {
15087
+ case enums.publicKey.x25519: {
15088
+ const ephemeralSecretKey = getRandomBytes(32);
15089
+ const sharedSecret = naclFastLight.scalarMult(ephemeralSecretKey, recipientA);
15090
+ const { publicKey: ephemeralPublicKey } = naclFastLight.box.keyPair.fromSecretKey(ephemeralSecretKey);
15091
+ const hkdfInput = util.concatUint8Array([
15092
+ ephemeralPublicKey,
15093
+ recipientA,
15094
+ sharedSecret
15095
+ ]);
15096
+ const { keySize } = getCipher(enums.symmetric.aes128);
15097
+ const encryptionKey = await HKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
15098
+ const wrappedKey = wrap(encryptionKey, data);
15099
+ return { ephemeralPublicKey, wrappedKey };
15100
+ }
15101
+
15102
+ default:
15103
+ throw new Error('Unsupported ECDH algorithm');
15104
+ }
15105
+ }
15106
+
15107
+ /**
15108
+ * Decrypt and unwrap the session key
15109
+ *
15110
+ * @param {module:enums.publicKey} algo - Algorithm identifier
15111
+ * @param {Uint8Array} ephemeralPublicKey - (K_A)
15112
+ * @param {Uint8Array} wrappedKey,
15113
+ * @param {Uint8Array} A - Recipient public key (K_b), needed for KDF
15114
+ * @param {Uint8Array} k - Recipient secret key (b)
15115
+ * @returns {Promise<Uint8Array>} decrypted session key data
15116
+ * @async
15117
+ */
15118
+ async function decrypt$4(algo, ephemeralPublicKey, wrappedKey, A, k) {
15119
+ switch (algo) {
15120
+ case enums.publicKey.x25519: {
15121
+ const sharedSecret = naclFastLight.scalarMult(k, ephemeralPublicKey);
15122
+ const hkdfInput = util.concatUint8Array([
15123
+ ephemeralPublicKey,
15124
+ A,
15125
+ sharedSecret
15126
+ ]);
15127
+ const { keySize } = getCipher(enums.symmetric.aes128);
15128
+ const encryptionKey = await HKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
15129
+ return unwrap(encryptionKey, wrappedKey);
15130
+ }
15131
+ default:
15132
+ throw new Error('Unsupported ECDH algorithm');
15133
+ }
15134
+ }
15135
+
15136
+ var ecdh_x = /*#__PURE__*/Object.freeze({
15137
+ __proto__: null,
15138
+ generate: generate$3,
15139
+ validateParams: validateParams$6,
15140
+ encrypt: encrypt$4,
15141
+ decrypt: decrypt$4
15142
+ });
15143
+
14782
15144
  // OpenPGP.js - An OpenPGP implementation in javascript
14783
15145
 
14784
15146
  var elliptic = /*#__PURE__*/Object.freeze({
14785
15147
  __proto__: null,
14786
- Curve: Curve,
15148
+ CurveWithOID: CurveWithOID,
14787
15149
  ecdh: ecdh,
15150
+ ecdhX: ecdh_x,
14788
15151
  ecdsa: ecdsa,
15152
+ eddsaLegacy: eddsa_legacy,
14789
15153
  eddsa: eddsa,
14790
15154
  generate: generate$1,
14791
15155
  getPreferredHashAlgo: getPreferredHashAlgo
@@ -14810,7 +15174,7 @@ var elliptic = /*#__PURE__*/Object.freeze({
14810
15174
  * @returns {Promise<{ r: Uint8Array, s: Uint8Array }>}
14811
15175
  * @async
14812
15176
  */
14813
- async function sign$3(hashAlgo, hashed, g, p, q, x) {
15177
+ async function sign$4(hashAlgo, hashed, g, p, q, x) {
14814
15178
  const BigInteger = await util.getBigInteger();
14815
15179
  const one = new BigInteger(1);
14816
15180
  p = new BigInteger(p);
@@ -14869,7 +15233,7 @@ async function sign$3(hashAlgo, hashed, g, p, q, x) {
14869
15233
  * @returns {boolean}
14870
15234
  * @async
14871
15235
  */
14872
- async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
15236
+ async function verify$4(hashAlgo, r, s, hashed, g, p, q, y) {
14873
15237
  const BigInteger = await util.getBigInteger();
14874
15238
  const zero = new BigInteger(0);
14875
15239
  r = new BigInteger(r);
@@ -14912,7 +15276,7 @@ async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
14912
15276
  * @returns {Promise<Boolean>} Whether params are valid.
14913
15277
  * @async
14914
15278
  */
14915
- async function validateParams$5(p, q, g, y, x) {
15279
+ async function validateParams$7(p, q, g, y, x) {
14916
15280
  const BigInteger = await util.getBigInteger();
14917
15281
  p = new BigInteger(p);
14918
15282
  q = new BigInteger(q);
@@ -14967,9 +15331,9 @@ async function validateParams$5(p, q, g, y, x) {
14967
15331
 
14968
15332
  var dsa = /*#__PURE__*/Object.freeze({
14969
15333
  __proto__: null,
14970
- sign: sign$3,
14971
- verify: verify$3,
14972
- validateParams: validateParams$5
15334
+ sign: sign$4,
15335
+ verify: verify$4,
15336
+ validateParams: validateParams$7
14973
15337
  });
14974
15338
 
14975
15339
  /**
@@ -15105,10 +15469,10 @@ function parseSignatureParams(algo, signature) {
15105
15469
  const s = util.readMPI(signature.subarray(read));
15106
15470
  return { r, s };
15107
15471
  }
15108
- // Algorithm-Specific Fields for EdDSA signatures:
15472
+ // Algorithm-Specific Fields for legacy EdDSA signatures:
15109
15473
  // - MPI of an EC point r.
15110
15474
  // - EdDSA value s, in MPI, in the little endian representation
15111
- case enums.publicKey.eddsa: {
15475
+ case enums.publicKey.eddsaLegacy: {
15112
15476
  // When parsing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
15113
15477
  // https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
15114
15478
  let r = util.readMPI(signature.subarray(read)); read += r.length + 2;
@@ -15117,7 +15481,12 @@ function parseSignatureParams(algo, signature) {
15117
15481
  s = util.leftPad(s, 32);
15118
15482
  return { r, s };
15119
15483
  }
15120
-
15484
+ // Algorithm-Specific Fields for Ed25519 signatures:
15485
+ // - 64 octets of the native signature
15486
+ case enums.publicKey.ed25519: {
15487
+ const RS = signature.subarray(read, read + 64); read += RS.length;
15488
+ return { RS };
15489
+ }
15121
15490
  case enums.publicKey.hmac: {
15122
15491
  const mac = new ShortByteString(); mac.read(signature.subarray(read));
15123
15492
  return { mac };
@@ -15142,7 +15511,7 @@ function parseSignatureParams(algo, signature) {
15142
15511
  * @returns {Promise<Boolean>} True if signature is valid.
15143
15512
  * @async
15144
15513
  */
15145
- async function verify$4(algo, hashAlgo, signature, publicParams, privateParams, data, hashed) {
15514
+ async function verify$5(algo, hashAlgo, signature, publicParams, privateParams, data, hashed) {
15146
15515
  switch (algo) {
15147
15516
  case enums.publicKey.rsaEncryptSign:
15148
15517
  case enums.publicKey.rsaEncrypt:
@@ -15158,16 +15527,20 @@ async function verify$4(algo, hashAlgo, signature, publicParams, privateParams,
15158
15527
  }
15159
15528
  case enums.publicKey.ecdsa: {
15160
15529
  const { oid, Q } = publicParams;
15161
- const curveSize = new publicKey.elliptic.Curve(oid).payloadSize;
15530
+ const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize;
15162
15531
  // padding needed for webcrypto
15163
15532
  const r = util.leftPad(signature.r, curveSize);
15164
15533
  const s = util.leftPad(signature.s, curveSize);
15165
15534
  return publicKey.elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
15166
15535
  }
15167
- case enums.publicKey.eddsa: {
15536
+ case enums.publicKey.eddsaLegacy: {
15168
15537
  const { oid, Q } = publicParams;
15169
15538
  // signature already padded on parsing
15170
- return publicKey.elliptic.eddsa.verify(oid, hashAlgo, signature, data, Q, hashed);
15539
+ return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, signature, data, Q, hashed);
15540
+ }
15541
+ case enums.publicKey.ed25519: {
15542
+ const { A } = publicParams;
15543
+ return publicKey.elliptic.eddsa.verify(algo, hashAlgo, signature, data, A, hashed);
15171
15544
  }
15172
15545
  case enums.publicKey.hmac: {
15173
15546
  if (!privateParams) {
@@ -15197,7 +15570,7 @@ async function verify$4(algo, hashAlgo, signature, publicParams, privateParams,
15197
15570
  * @returns {Promise<Object>} Signature Object containing named signature parameters.
15198
15571
  * @async
15199
15572
  */
15200
- async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) {
15573
+ async function sign$5(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) {
15201
15574
  if (!publicKeyParams || !privateKeyParams) {
15202
15575
  throw new Error('Missing key parameters');
15203
15576
  }
@@ -15223,10 +15596,15 @@ async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
15223
15596
  const { d } = privateKeyParams;
15224
15597
  return publicKey.elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
15225
15598
  }
15226
- case enums.publicKey.eddsa: {
15599
+ case enums.publicKey.eddsaLegacy: {
15227
15600
  const { oid, Q } = publicKeyParams;
15228
15601
  const { seed } = privateKeyParams;
15229
- return publicKey.elliptic.eddsa.sign(oid, hashAlgo, data, Q, seed, hashed);
15602
+ return publicKey.elliptic.eddsaLegacy.sign(oid, hashAlgo, data, Q, seed, hashed);
15603
+ }
15604
+ case enums.publicKey.ed25519: {
15605
+ const { A } = publicKeyParams;
15606
+ const { seed } = privateKeyParams;
15607
+ return publicKey.elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed);
15230
15608
  }
15231
15609
  case enums.publicKey.hmac: {
15232
15610
  const { cipher: algo } = publicKeyParams;
@@ -15242,34 +15620,31 @@ async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
15242
15620
  var signature = /*#__PURE__*/Object.freeze({
15243
15621
  __proto__: null,
15244
15622
  parseSignatureParams: parseSignatureParams,
15245
- verify: verify$4,
15246
- sign: sign$4
15623
+ verify: verify$5,
15624
+ sign: sign$5
15247
15625
  });
15248
15626
 
15249
15627
  // OpenPGP.js - An OpenPGP implementation in javascript
15250
15628
 
15251
15629
  class ECDHSymmetricKey {
15252
15630
  constructor(data) {
15253
- if (typeof data === 'undefined') {
15254
- data = new Uint8Array([]);
15255
- } else if (util.isString(data)) {
15256
- data = util.stringToUint8Array(data);
15257
- } else {
15258
- data = new Uint8Array(data);
15631
+ if (data) {
15632
+ this.data = data;
15259
15633
  }
15260
- this.data = data;
15261
15634
  }
15262
15635
 
15263
15636
  /**
15264
- * Read an ECDHSymmetricKey from an Uint8Array
15265
- * @param {Uint8Array} input - Where to read the encoded symmetric key from
15637
+ * Read an ECDHSymmetricKey from an Uint8Array:
15638
+ * - 1 octect for the length `l`
15639
+ * - `l` octects of encoded session key data
15640
+ * @param {Uint8Array} bytes
15266
15641
  * @returns {Number} Number of read bytes.
15267
15642
  */
15268
- read(input) {
15269
- if (input.length >= 1) {
15270
- const length = input[0];
15271
- if (input.length >= 1 + length) {
15272
- this.data = input.subarray(1, 1 + length);
15643
+ read(bytes) {
15644
+ if (bytes.length >= 1) {
15645
+ const length = bytes[0];
15646
+ if (bytes.length >= 1 + length) {
15647
+ this.data = bytes.subarray(1, 1 + length);
15273
15648
  return 1 + this.data.length;
15274
15649
  }
15275
15650
  }
@@ -15278,7 +15653,7 @@ class ECDHSymmetricKey {
15278
15653
 
15279
15654
  /**
15280
15655
  * Write an ECDHSymmetricKey as an Uint8Array
15281
- * @returns {Uint8Array} An array containing the value
15656
+ * @returns {Uint8Array} Serialised data
15282
15657
  */
15283
15658
  write() {
15284
15659
  return util.concatUint8Array([new Uint8Array([this.data.length]), this.data]);
@@ -15318,6 +15693,9 @@ class KDFParams {
15318
15693
  * @returns {Number} Number of read bytes.
15319
15694
  */
15320
15695
  read(input) {
15696
+ if (input.length < 4 || (input[1] !== 1 && input[1] !== VERSION_FORWARDING)) {
15697
+ throw new UnsupportedError('Cannot read KDFParams');
15698
+ }
15321
15699
  const totalBytes = input[0];
15322
15700
  this.version = input[1];
15323
15701
  this.hash = input[2];
@@ -15405,12 +15783,57 @@ const AEADEnum = type_enum(enums.aead);
15405
15783
  const SymAlgoEnum = type_enum(enums.symmetric);
15406
15784
  const HashEnum = type_enum(enums.hash);
15407
15785
 
15786
+ /**
15787
+ * Encoded symmetric key for x25519 and x448
15788
+ * The payload format varies for v3 and v6 PKESK:
15789
+ * the former includes an algorithm byte preceeding the encrypted session key.
15790
+ *
15791
+ * @module type/x25519x448_symkey
15792
+ */
15793
+
15794
+ class ECDHXSymmetricKey {
15795
+ static fromObject({ wrappedKey, algorithm }) {
15796
+ const instance = new ECDHXSymmetricKey();
15797
+ instance.wrappedKey = wrappedKey;
15798
+ instance.algorithm = algorithm;
15799
+ return instance;
15800
+ }
15801
+
15802
+ /**
15803
+ * - 1 octect for the length `l`
15804
+ * - `l` octects of encoded session key data (with optional leading algorithm byte)
15805
+ * @param {Uint8Array} bytes
15806
+ * @returns {Number} Number of read bytes.
15807
+ */
15808
+ read(bytes) {
15809
+ let read = 0;
15810
+ let followLength = bytes[read++];
15811
+ this.algorithm = followLength % 2 ? bytes[read++] : null; // session key size is always even
15812
+ followLength -= followLength % 2;
15813
+ this.wrappedKey = bytes.subarray(read, read + followLength); read += followLength;
15814
+ }
15815
+
15816
+ /**
15817
+ * Write an MontgomerySymmetricKey as an Uint8Array
15818
+ * @returns {Uint8Array} Serialised data
15819
+ */
15820
+ write() {
15821
+ return util.concatUint8Array([
15822
+ this.algorithm ?
15823
+ new Uint8Array([this.wrappedKey.length + 1, this.algorithm]) :
15824
+ new Uint8Array([this.wrappedKey.length]),
15825
+ this.wrappedKey
15826
+ ]);
15827
+ }
15828
+ }
15829
+
15408
15830
  // GPG4Browsers - An OpenPGP implementation in javascript
15409
15831
 
15410
15832
  /**
15411
15833
  * Encrypts data using specified algorithm and public key parameters.
15412
15834
  * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1} for public key algorithms.
15413
- * @param {module:enums.publicKey} algo - Public key algorithm
15835
+ * @param {module:enums.publicKey} keyAlgo - Public key algorithm
15836
+ * @param {module:enums.symmetric} symmetricAlgo - Cipher algorithm
15414
15837
  * @param {Object} publicParams - Algorithm-specific public key parameters
15415
15838
  * @param {Object} privateParams - Algorithm-specific private key parameters
15416
15839
  * @param {Uint8Array} data - Data to be encrypted
@@ -15418,8 +15841,8 @@ const HashEnum = type_enum(enums.hash);
15418
15841
  * @returns {Promise<Object>} Encrypted session key parameters.
15419
15842
  * @async
15420
15843
  */
15421
- async function publicKeyEncrypt(algo, publicParams, privateParams, data, fingerprint) {
15422
- switch (algo) {
15844
+ async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, privateParams, data, fingerprint) {
15845
+ switch (keyAlgo) {
15423
15846
  case enums.publicKey.rsaEncrypt:
15424
15847
  case enums.publicKey.rsaEncryptSign: {
15425
15848
  const { n, e } = publicParams;
@@ -15436,6 +15859,17 @@ async function publicKeyEncrypt(algo, publicParams, privateParams, data, fingerp
15436
15859
  oid, kdfParams, data, Q, fingerprint);
15437
15860
  return { V, C: new ECDHSymmetricKey(C) };
15438
15861
  }
15862
+ case enums.publicKey.x25519: {
15863
+ if (!util.isAES(symmetricAlgo)) {
15864
+ // see https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/276
15865
+ throw new Error('X25519 keys can only encrypt AES session keys');
15866
+ }
15867
+ const { A } = publicParams;
15868
+ const { ephemeralPublicKey, wrappedKey } = await publicKey.elliptic.ecdhX.encrypt(
15869
+ keyAlgo, data, A);
15870
+ const C = ECDHXSymmetricKey.fromObject({ algorithm: symmetricAlgo, wrappedKey });
15871
+ return { ephemeralPublicKey, C };
15872
+ }
15439
15873
  case enums.publicKey.aead: {
15440
15874
  if (!privateParams) {
15441
15875
  throw new Error('Cannot encrypt with symmetric key missing private parameters');
@@ -15492,6 +15926,16 @@ async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, session
15492
15926
  return publicKey.elliptic.ecdh.decrypt(
15493
15927
  oid, kdfParams, V, C.data, Q, d, fingerprint);
15494
15928
  }
15929
+ case enums.publicKey.x25519: {
15930
+ const { A } = publicKeyParams;
15931
+ const { k } = privateKeyParams;
15932
+ const { ephemeralPublicKey, C } = sessionKeyParams;
15933
+ if (!util.isAES(C.algorithm)) {
15934
+ throw new Error('AES session key expected');
15935
+ }
15936
+ return publicKey.elliptic.ecdhX.decrypt(
15937
+ algo, ephemeralPublicKey, C.wrappedKey, A, k);
15938
+ }
15495
15939
  case enums.publicKey.aead: {
15496
15940
  const { cipher: algo } = publicKeyParams;
15497
15941
  const algoValue = algo.getValue();
@@ -15543,7 +15987,7 @@ function parsePublicKeyParams(algo, bytes) {
15543
15987
  const Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
15544
15988
  return { read: read, publicParams: { oid, Q } };
15545
15989
  }
15546
- case enums.publicKey.eddsa: {
15990
+ case enums.publicKey.eddsaLegacy: {
15547
15991
  const oid = new OID(); read += oid.read(bytes);
15548
15992
  checkSupportedCurve(oid);
15549
15993
  let Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
@@ -15557,6 +16001,11 @@ function parsePublicKeyParams(algo, bytes) {
15557
16001
  const kdfParams = new KDFParams(); read += kdfParams.read(bytes.subarray(read));
15558
16002
  return { read: read, publicParams: { oid, Q, kdfParams } };
15559
16003
  }
16004
+ case enums.publicKey.ed25519:
16005
+ case enums.publicKey.x25519: {
16006
+ const A = bytes.subarray(read, read + 32); read += A.length;
16007
+ return { read, publicParams: { A } };
16008
+ }
15560
16009
  case enums.publicKey.hmac:
15561
16010
  case enums.publicKey.aead: {
15562
16011
  const algo = new SymAlgoEnum(); read += algo.read(bytes);
@@ -15595,17 +16044,25 @@ function parsePrivateKeyParams(algo, bytes, publicParams) {
15595
16044
  }
15596
16045
  case enums.publicKey.ecdsa:
15597
16046
  case enums.publicKey.ecdh: {
15598
- const curve = new Curve(publicParams.oid);
16047
+ const curve = new CurveWithOID(publicParams.oid);
15599
16048
  let d = util.readMPI(bytes.subarray(read)); read += d.length + 2;
15600
16049
  d = util.leftPad(d, curve.payloadSize);
15601
16050
  return { read, privateParams: { d } };
15602
16051
  }
15603
- case enums.publicKey.eddsa: {
15604
- const curve = new Curve(publicParams.oid);
16052
+ case enums.publicKey.eddsaLegacy: {
16053
+ const curve = new CurveWithOID(publicParams.oid);
15605
16054
  let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2;
15606
16055
  seed = util.leftPad(seed, curve.payloadSize);
15607
16056
  return { read, privateParams: { seed } };
15608
16057
  }
16058
+ case enums.publicKey.ed25519: {
16059
+ const seed = bytes.subarray(read, read + 32); read += seed.length;
16060
+ return { read, privateParams: { seed } };
16061
+ }
16062
+ case enums.publicKey.x25519: {
16063
+ const k = bytes.subarray(read, read + 32); read += k.length;
16064
+ return { read, privateParams: { k } };
16065
+ }
15609
16066
  case enums.publicKey.hmac: {
15610
16067
  const { cipher: algo } = publicParams;
15611
16068
  const keySize = hash.getHashByteLength(algo.getValue());
@@ -15657,6 +16114,16 @@ function parseEncSessionKeyParams(algo, bytes) {
15657
16114
  const C = new ECDHSymmetricKey(); C.read(bytes.subarray(read));
15658
16115
  return { V, C };
15659
16116
  }
16117
+ // Algorithm-Specific Fields for X25519 encrypted session keys:
16118
+ // - 32 octets representing an ephemeral X25519 public key.
16119
+ // - A one-octet size of the following fields.
16120
+ // - The one-octet algorithm identifier, if it was passed (in the case of a v3 PKESK packet).
16121
+ // - The encrypted session key.
16122
+ case enums.publicKey.x25519: {
16123
+ const ephemeralPublicKey = bytes.subarray(read, read + 32); read += ephemeralPublicKey.length;
16124
+ const C = new ECDHXSymmetricKey(); C.read(bytes.subarray(read));
16125
+ return { ephemeralPublicKey, C };
16126
+ }
15660
16127
  // Algorithm-Specific Fields for symmetric AEAD encryption:
15661
16128
  // - AEAD algorithm
15662
16129
  // - Starting initialization vector
@@ -15683,22 +16150,13 @@ function parseEncSessionKeyParams(algo, bytes) {
15683
16150
  * @returns {Uint8Array} The array containing the MPIs.
15684
16151
  */
15685
16152
  function serializeParams(algo, params) {
15686
- let orderedParams;
15687
- switch (algo) {
15688
- case enums.publicKey.hmac:
15689
- case enums.publicKey.aead: {
15690
- orderedParams = Object.keys(params).map(name => {
15691
- const param = params[name];
15692
- return util.isUint8Array(param) ? param : param.write();
15693
- });
15694
- break;
15695
- }
15696
- default:
15697
- orderedParams = Object.keys(params).map(name => {
15698
- const param = params[name];
15699
- return util.isUint8Array(param) ? util.uint8ArrayToMPI(param) : param.write();
15700
- });
15701
- }
16153
+ // Some algorithms do not rely on MPIs to store the binary params
16154
+ const algosWithNativeRepresentation = new Set([enums.publicKey.ed25519, enums.publicKey.x25519, enums.publicKey.aead, enums.publicKey.hmac]);
16155
+ const orderedParams = Object.keys(params).map(name => {
16156
+ const param = params[name];
16157
+ if (!util.isUint8Array(param)) return param.write();
16158
+ return algosWithNativeRepresentation.has(algo) ? param : util.uint8ArrayToMPI(param);
16159
+ });
15702
16160
  return util.concatUint8Array(orderedParams);
15703
16161
  }
15704
16162
 
@@ -15726,7 +16184,7 @@ function generateParams(algo, bits, oid, symmetric) {
15726
16184
  privateParams: { d: secret },
15727
16185
  publicParams: { oid: new OID(oid), Q }
15728
16186
  }));
15729
- case enums.publicKey.eddsa:
16187
+ case enums.publicKey.eddsaLegacy:
15730
16188
  return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
15731
16189
  privateParams: { seed: secret },
15732
16190
  publicParams: { oid: new OID(oid), Q }
@@ -15740,6 +16198,16 @@ function generateParams(algo, bits, oid, symmetric) {
15740
16198
  kdfParams: new KDFParams({ hash, cipher })
15741
16199
  }
15742
16200
  }));
16201
+ case enums.publicKey.ed25519:
16202
+ return publicKey.elliptic.eddsa.generate(algo).then(({ A, seed }) => ({
16203
+ privateParams: { seed },
16204
+ publicParams: { A }
16205
+ }));
16206
+ case enums.publicKey.x25519:
16207
+ return publicKey.elliptic.ecdhX.generate(algo).then(({ A, k }) => ({
16208
+ privateParams: { k },
16209
+ publicParams: { A }
16210
+ }));
15743
16211
  case enums.publicKey.hmac: {
15744
16212
  const symAlgo = enums.write(enums.hash, symmetric);
15745
16213
  const keyMaterial = getRandomBytes(hash.getHashByteLength(symAlgo));
@@ -15781,7 +16249,7 @@ async function createSymmetricParams(key, algo) {
15781
16249
  * @returns {Promise<Boolean>} Whether the parameters are valid.
15782
16250
  * @async
15783
16251
  */
15784
- async function validateParams$6(algo, publicParams, privateParams) {
16252
+ async function validateParams$8(algo, publicParams, privateParams) {
15785
16253
  if (!publicParams || !privateParams) {
15786
16254
  throw new Error('Missing key parameters');
15787
16255
  }
@@ -15810,10 +16278,20 @@ async function validateParams$6(algo, publicParams, privateParams) {
15810
16278
  const { d } = privateParams;
15811
16279
  return algoModule.validateParams(oid, Q, d);
15812
16280
  }
15813
- case enums.publicKey.eddsa: {
15814
- const { oid, Q } = publicParams;
16281
+ case enums.publicKey.eddsaLegacy: {
16282
+ const { Q, oid } = publicParams;
16283
+ const { seed } = privateParams;
16284
+ return publicKey.elliptic.eddsaLegacy.validateParams(oid, Q, seed);
16285
+ }
16286
+ case enums.publicKey.ed25519: {
16287
+ const { A } = publicParams;
15815
16288
  const { seed } = privateParams;
15816
- return publicKey.elliptic.eddsa.validateParams(oid, Q, seed);
16289
+ return publicKey.elliptic.eddsa.validateParams(algo, A, seed);
16290
+ }
16291
+ case enums.publicKey.x25519: {
16292
+ const { A } = publicParams;
16293
+ const { k } = privateParams;
16294
+ return publicKey.elliptic.ecdhX.validateParams(algo, A, k);
15817
16295
  }
15818
16296
  case enums.publicKey.hmac: {
15819
16297
  const { cipher: algo, digest } = publicParams;
@@ -15883,6 +16361,23 @@ function checkSupportedCurve(oid) {
15883
16361
  }
15884
16362
  }
15885
16363
 
16364
+ /**
16365
+ * Get preferred hash algo for a given elliptic algo
16366
+ * @param {module:enums.publicKey} algo - alrogithm identifier
16367
+ * @param {module:type/oid} [oid] - curve OID if needed by algo
16368
+ */
16369
+ function getPreferredCurveHashAlgo(algo, oid) {
16370
+ switch (algo) {
16371
+ case enums.publicKey.ecdsa:
16372
+ case enums.publicKey.eddsaLegacy:
16373
+ return publicKey.elliptic.getPreferredHashAlgo(oid);
16374
+ case enums.publicKey.ed25519:
16375
+ return publicKey.elliptic.eddsa.getPreferredHashAlgo(algo);
16376
+ default:
16377
+ throw new Error('Unknown elliptic signing algo');
16378
+ }
16379
+ }
16380
+
15886
16381
  var crypto$1 = /*#__PURE__*/Object.freeze({
15887
16382
  __proto__: null,
15888
16383
  publicKeyEncrypt: publicKeyEncrypt,
@@ -15892,11 +16387,12 @@ var crypto$1 = /*#__PURE__*/Object.freeze({
15892
16387
  parseEncSessionKeyParams: parseEncSessionKeyParams,
15893
16388
  serializeParams: serializeParams,
15894
16389
  generateParams: generateParams,
15895
- validateParams: validateParams$6,
16390
+ validateParams: validateParams$8,
15896
16391
  getPrefixRandom: getPrefixRandom,
15897
16392
  generateSessionKey: generateSessionKey,
15898
16393
  getAEADMode: getAEADMode,
15899
- getCipher: getCipher
16394
+ getCipher: getCipher,
16395
+ getPreferredCurveHashAlgo: getPreferredCurveHashAlgo
15900
16396
  });
15901
16397
 
15902
16398
  /**
@@ -16139,15 +16635,15 @@ class GenericS2K {
16139
16635
  this.type = 'gnu-dummy';
16140
16636
  // GnuPG extension mode 1001 -- don't write secret key at all
16141
16637
  } else {
16142
- throw new Error('Unknown s2k gnu protection mode.');
16638
+ throw new UnsupportedError('Unknown s2k gnu protection mode.');
16143
16639
  }
16144
16640
  } else {
16145
- throw new Error('Unknown s2k type.');
16641
+ throw new UnsupportedError('Unknown s2k type.');
16146
16642
  }
16147
16643
  break;
16148
16644
 
16149
16645
  default:
16150
- throw new Error('Unknown s2k type.');
16646
+ throw new UnsupportedError('Unknown s2k type.'); // unreachable
16151
16647
  }
16152
16648
 
16153
16649
  return i;
@@ -16251,7 +16747,7 @@ function newS2KFromType(type, config$1 = config) {
16251
16747
  case enums.s2k.simple:
16252
16748
  return new GenericS2K(type, config$1);
16253
16749
  default:
16254
- throw new Error(`Unsupported S2K type ${type}`);
16750
+ throw new UnsupportedError(`Unsupported S2K type ${type}`);
16255
16751
  }
16256
16752
  }
16257
16753
 
@@ -25005,13 +25501,17 @@ class PublicKeyEncryptedSessionKeyPacket {
25005
25501
  * @param {Uint8Array} bytes - Payload of a tag 1 packet
25006
25502
  */
25007
25503
  read(bytes) {
25008
- this.version = bytes[0];
25504
+ let i = 0;
25505
+ this.version = bytes[i++];
25009
25506
  if (this.version !== VERSION$3) {
25010
25507
  throw new UnsupportedError(`Version ${this.version} of the PKESK packet is unsupported.`);
25011
25508
  }
25012
- this.publicKeyID.read(bytes.subarray(1, bytes.length));
25013
- this.publicKeyAlgorithm = bytes[9];
25014
- this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(10));
25509
+ i += this.publicKeyID.read(bytes.subarray(i));
25510
+ this.publicKeyAlgorithm = bytes[i++];
25511
+ this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(i), this.version);
25512
+ if (this.publicKeyAlgorithm === enums.publicKey.x25519) {
25513
+ this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm);
25514
+ }
25015
25515
  }
25016
25516
 
25017
25517
  /**
@@ -25037,15 +25537,11 @@ class PublicKeyEncryptedSessionKeyPacket {
25037
25537
  * @async
25038
25538
  */
25039
25539
  async encrypt(key) {
25040
- const data = util.concatUint8Array([
25041
- new Uint8Array([enums.write(enums.symmetric, this.sessionKeyAlgorithm)]),
25042
- this.sessionKey,
25043
- util.writeChecksum(this.sessionKey)
25044
- ]);
25045
25540
  const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
25541
+ const encoded = encodeSessionKey(this.version, algo, this.sessionKeyAlgorithm, this.sessionKey);
25046
25542
  const privateParams = algo === enums.publicKey.aead ? key.privateParams : null;
25047
25543
  this.encrypted = await mod.publicKeyEncrypt(
25048
- algo, key.publicParams, privateParams, data, key.getFingerprintBytes());
25544
+ algo, this.sessionKeyAlgorithm, key.publicParams, privateParams, encoded, key.getFingerprintBytes());
25049
25545
  }
25050
25546
 
25051
25547
  /**
@@ -25062,34 +25558,86 @@ class PublicKeyEncryptedSessionKeyPacket {
25062
25558
  throw new Error('Decryption error');
25063
25559
  }
25064
25560
 
25065
- const randomPayload = randomSessionKey ? util.concatUint8Array([
25066
- new Uint8Array([randomSessionKey.sessionKeyAlgorithm]),
25067
- randomSessionKey.sessionKey,
25068
- util.writeChecksum(randomSessionKey.sessionKey)
25069
- ]) : null;
25070
- const decoded = await mod.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes(), randomPayload);
25071
- const symmetricAlgoByte = decoded[0];
25072
- const sessionKey = decoded.subarray(1, decoded.length - 2);
25073
- const checksum = decoded.subarray(decoded.length - 2);
25074
- const computedChecksum = util.writeChecksum(sessionKey);
25075
- const isValidChecksum = computedChecksum[0] === checksum[0] & computedChecksum[1] === checksum[1];
25076
-
25077
- if (randomSessionKey) {
25078
- // We must not leak info about the validity of the decrypted checksum or cipher algo.
25079
- // 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.
25080
- const isValidPayload = isValidChecksum & symmetricAlgoByte === randomSessionKey.sessionKeyAlgorithm & sessionKey.length === randomSessionKey.sessionKey.length;
25081
- this.sessionKeyAlgorithm = util.selectUint8(isValidPayload, symmetricAlgoByte, randomSessionKey.sessionKeyAlgorithm);
25082
- this.sessionKey = util.selectUint8Array(isValidPayload, sessionKey, randomSessionKey.sessionKey);
25561
+ const randomPayload = randomSessionKey ?
25562
+ encodeSessionKey(this.version, this.publicKeyAlgorithm, randomSessionKey.sessionKeyAlgorithm, randomSessionKey.sessionKey) :
25563
+ null;
25564
+ const decryptedData = await mod.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes(), randomPayload);
25083
25565
 
25084
- } else {
25085
- const isValidPayload = isValidChecksum && enums.read(enums.symmetric, symmetricAlgoByte);
25086
- if (isValidPayload) {
25087
- this.sessionKey = sessionKey;
25088
- this.sessionKeyAlgorithm = symmetricAlgoByte;
25566
+ const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey);
25567
+
25568
+ // v3 Montgomery curves have cleartext cipher algo
25569
+ if (this.publicKeyAlgorithm !== enums.publicKey.x25519) {
25570
+ this.sessionKeyAlgorithm = sessionKeyAlgorithm;
25571
+ }
25572
+ this.sessionKey = sessionKey;
25573
+ }
25574
+ }
25575
+
25576
+
25577
+ function encodeSessionKey(version, keyAlgo, cipherAlgo, sessionKeyData) {
25578
+ switch (keyAlgo) {
25579
+ case enums.publicKey.rsaEncrypt:
25580
+ case enums.publicKey.rsaEncryptSign:
25581
+ case enums.publicKey.elgamal:
25582
+ case enums.publicKey.ecdh:
25583
+ case enums.publicKey.aead: {
25584
+ // add checksum
25585
+ return util.concatUint8Array([
25586
+ new Uint8Array([cipherAlgo]),
25587
+ sessionKeyData,
25588
+ util.writeChecksum(sessionKeyData.subarray(sessionKeyData.length % 8))
25589
+ ]);
25590
+ }
25591
+ case enums.publicKey.x25519:
25592
+ return sessionKeyData;
25593
+ default:
25594
+ throw new Error('Unsupported public key algorithm');
25595
+ }
25596
+ }
25597
+
25598
+
25599
+ function decodeSessionKey(version, keyAlgo, decryptedData, randomSessionKey) {
25600
+ switch (keyAlgo) {
25601
+ case enums.publicKey.rsaEncrypt:
25602
+ case enums.publicKey.rsaEncryptSign:
25603
+ case enums.publicKey.elgamal:
25604
+ case enums.publicKey.ecdh:
25605
+ case enums.publicKey.aead: {
25606
+ // verify checksum in constant time
25607
+ const result = decryptedData.subarray(0, decryptedData.length - 2);
25608
+ const checksum = decryptedData.subarray(decryptedData.length - 2);
25609
+ const computedChecksum = util.writeChecksum(result.subarray(result.length % 8));
25610
+ const isValidChecksum = computedChecksum[0] === checksum[0] & computedChecksum[1] === checksum[1];
25611
+ const decryptedSessionKey = { sessionKeyAlgorithm: result[0], sessionKey: result.subarray(1) };
25612
+ if (randomSessionKey) {
25613
+ // We must not leak info about the validity of the decrypted checksum or cipher algo.
25614
+ // 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.
25615
+ const isValidPayload = isValidChecksum &
25616
+ decryptedSessionKey.sessionKeyAlgorithm === randomSessionKey.sessionKeyAlgorithm &
25617
+ decryptedSessionKey.sessionKey.length === randomSessionKey.sessionKey.length;
25618
+ return {
25619
+ sessionKey: util.selectUint8Array(isValidPayload, decryptedSessionKey.sessionKey, randomSessionKey.sessionKey),
25620
+ sessionKeyAlgorithm: util.selectUint8(
25621
+ isValidPayload,
25622
+ decryptedSessionKey.sessionKeyAlgorithm,
25623
+ randomSessionKey.sessionKeyAlgorithm
25624
+ )
25625
+ };
25089
25626
  } else {
25090
- throw new Error('Decryption error');
25627
+ const isValidPayload = isValidChecksum && enums.read(enums.symmetric, decryptedSessionKey.sessionKeyAlgorithm);
25628
+ if (isValidPayload) {
25629
+ return decryptedSessionKey;
25630
+ } else {
25631
+ throw new Error('Decryption error');
25632
+ }
25091
25633
  }
25092
25634
  }
25635
+ case enums.publicKey.x25519:
25636
+ return {
25637
+ sessionKey: decryptedData
25638
+ };
25639
+ default:
25640
+ throw new Error('Unsupported public key algorithm');
25093
25641
  }
25094
25642
  }
25095
25643
 
@@ -25520,7 +26068,7 @@ class PublicKeyPacket {
25520
26068
  result.bits = util.uint8ArrayBitLength(modulo);
25521
26069
  } else if (this.publicParams.oid) {
25522
26070
  result.curve = this.publicParams.oid.getName();
25523
- } else {
26071
+ } else if (this.publicParams.cipher) {
25524
26072
  result.symmetric = this.publicParams.cipher.getName();
25525
26073
  }
25526
26074
  return result;
@@ -25852,6 +26400,7 @@ class SecretKeyPacket extends PublicKeyPacket {
25852
26400
  async read(bytes) {
25853
26401
  // - A Public-Key or Public-Subkey packet, as described above.
25854
26402
  let i = await this.readPublicKey(bytes);
26403
+ const startOfSecretKeyData = i;
25855
26404
 
25856
26405
  // - One octet indicating string-to-key usage conventions. Zero
25857
26406
  // indicates that the secret-key data is not encrypted. 255 or 254
@@ -25865,41 +26414,48 @@ class SecretKeyPacket extends PublicKeyPacket {
25865
26414
  i++;
25866
26415
  }
25867
26416
 
25868
- // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
25869
- // one-octet symmetric encryption algorithm.
25870
- if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
25871
- this.symmetric = bytes[i++];
26417
+ try {
26418
+ // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
26419
+ // one-octet symmetric encryption algorithm.
26420
+ if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
26421
+ this.symmetric = bytes[i++];
25872
26422
 
25873
- // - [Optional] If string-to-key usage octet was 253, a one-octet
25874
- // AEAD algorithm.
25875
- if (this.s2kUsage === 253) {
25876
- this.aead = bytes[i++];
25877
- }
26423
+ // - [Optional] If string-to-key usage octet was 253, a one-octet
26424
+ // AEAD algorithm.
26425
+ if (this.s2kUsage === 253) {
26426
+ this.aead = bytes[i++];
26427
+ }
25878
26428
 
25879
- // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
25880
- // string-to-key specifier. The length of the string-to-key
25881
- // specifier is implied by its type, as described above.
25882
- const s2kType = bytes[i++];
25883
- this.s2k = newS2KFromType(s2kType);
25884
- i += this.s2k.read(bytes.subarray(i, bytes.length));
26429
+ // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
26430
+ // string-to-key specifier. The length of the string-to-key
26431
+ // specifier is implied by its type, as described above.
26432
+ const s2kType = bytes[i++];
26433
+ this.s2k = newS2KFromType(s2kType);
26434
+ i += this.s2k.read(bytes.subarray(i, bytes.length));
25885
26435
 
25886
- if (this.s2k.type === 'gnu-dummy') {
25887
- return;
26436
+ if (this.s2k.type === 'gnu-dummy') {
26437
+ return;
26438
+ }
26439
+ } else if (this.s2kUsage) {
26440
+ this.symmetric = this.s2kUsage;
25888
26441
  }
25889
- } else if (this.s2kUsage) {
25890
- this.symmetric = this.s2kUsage;
25891
- }
25892
26442
 
25893
- // - [Optional] If secret data is encrypted (string-to-key usage octet
25894
- // not zero), an Initial Vector (IV) of the same length as the
25895
- // cipher's block size.
25896
- if (this.s2kUsage) {
25897
- this.iv = bytes.subarray(
25898
- i,
25899
- i + mod.getCipher(this.symmetric).blockSize
25900
- );
26443
+ // - [Optional] If secret data is encrypted (string-to-key usage octet
26444
+ // not zero), an Initial Vector (IV) of the same length as the
26445
+ // cipher's block size.
26446
+ if (this.s2kUsage) {
26447
+ this.iv = bytes.subarray(
26448
+ i,
26449
+ i + mod.getCipher(this.symmetric).blockSize
26450
+ );
25901
26451
 
25902
- i += this.iv.length;
26452
+ i += this.iv.length;
26453
+ }
26454
+ } catch (e) {
26455
+ // if the s2k is unsupported, we still want to support encrypting and verifying with the given key
26456
+ if (!this.s2kUsage) throw e; // always throw for decrypted keys
26457
+ this.unparseableKeyMaterial = bytes.subarray(startOfSecretKeyData);
26458
+ this.isEncrypted = true;
25903
26459
  }
25904
26460
 
25905
26461
  // - Only for a version 5 packet, a four-octet scalar octet count for
@@ -25935,8 +26491,15 @@ class SecretKeyPacket extends PublicKeyPacket {
25935
26491
  * @returns {Uint8Array} A string of bytes containing the secret key OpenPGP packet.
25936
26492
  */
25937
26493
  write() {
25938
- const arr = [this.writePublicKey()];
26494
+ const serializedPublicKey = this.writePublicKey();
26495
+ if (this.unparseableKeyMaterial) {
26496
+ return util.concatUint8Array([
26497
+ serializedPublicKey,
26498
+ this.unparseableKeyMaterial
26499
+ ]);
26500
+ }
25939
26501
 
26502
+ const arr = [serializedPublicKey];
25940
26503
  arr.push(new Uint8Array([this.s2kUsage]));
25941
26504
 
25942
26505
  const optionalFieldsArr = [];
@@ -25996,6 +26559,18 @@ class SecretKeyPacket extends PublicKeyPacket {
25996
26559
  return this.isEncrypted === false;
25997
26560
  }
25998
26561
 
26562
+ /**
26563
+ * Check whether the key includes secret key material.
26564
+ * Some secret keys do not include it, and can thus only be used
26565
+ * for public-key operations (encryption and verification).
26566
+ * Such keys are:
26567
+ * - GNU-dummy keys, where the secret material has been stripped away
26568
+ * - encrypted keys with unsupported S2K or cipher
26569
+ */
26570
+ isMissingSecretKeyMaterial() {
26571
+ return this.unparseableKeyMaterial !== undefined || this.isDummy();
26572
+ }
26573
+
25999
26574
  /**
26000
26575
  * Check whether this is a gnu-dummy key
26001
26576
  * @returns {Boolean}
@@ -26016,6 +26591,7 @@ class SecretKeyPacket extends PublicKeyPacket {
26016
26591
  if (this.isDecrypted()) {
26017
26592
  this.clearPrivateParams();
26018
26593
  }
26594
+ delete this.unparseableKeyMaterial;
26019
26595
  this.isEncrypted = null;
26020
26596
  this.keyMaterial = null;
26021
26597
  this.s2k = newS2KFromType(enums.s2k.gnu, config$1);
@@ -26087,6 +26663,10 @@ class SecretKeyPacket extends PublicKeyPacket {
26087
26663
  return false;
26088
26664
  }
26089
26665
 
26666
+ if (this.unparseableKeyMaterial) {
26667
+ throw new Error('Key packet cannot be decrypted: unsupported S2K or cipher algo');
26668
+ }
26669
+
26090
26670
  if (this.isDecrypted()) {
26091
26671
  throw new Error('Key packet is already decrypted.');
26092
26672
  }
@@ -26171,7 +26751,7 @@ class SecretKeyPacket extends PublicKeyPacket {
26171
26751
  * Clear private key parameters
26172
26752
  */
26173
26753
  clearPrivateParams() {
26174
- if (this.isDummy()) {
26754
+ if (this.isMissingSecretKeyMaterial()) {
26175
26755
  return;
26176
26756
  }
26177
26757
 
@@ -27570,25 +28150,22 @@ async function createBindingSignature(subkey, primaryKey, options, config) {
27570
28150
  const dataToSign = {};
27571
28151
  dataToSign.key = primaryKey;
27572
28152
  dataToSign.bind = subkey;
27573
- const subkeySignaturePacket = new SignaturePacket();
27574
- subkeySignaturePacket.signatureType = enums.signature.subkeyBinding;
27575
- subkeySignaturePacket.publicKeyAlgorithm = primaryKey.algorithm;
27576
- subkeySignaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(null, subkey, undefined, undefined, config);
28153
+ const signatureProperties = { signatureType: enums.signature.subkeyBinding };
27577
28154
  if (options.sign) {
27578
- subkeySignaturePacket.keyFlags = [enums.keyFlags.signData];
27579
- subkeySignaturePacket.embeddedSignature = await createSignaturePacket(dataToSign, null, subkey, {
28155
+ signatureProperties.keyFlags = [enums.keyFlags.signData];
28156
+ signatureProperties.embeddedSignature = await createSignaturePacket(dataToSign, null, subkey, {
27580
28157
  signatureType: enums.signature.keyBinding
27581
28158
  }, options.date, undefined, undefined, undefined, config);
27582
28159
  } else {
27583
- subkeySignaturePacket.keyFlags = options.forwarding ?
28160
+ signatureProperties.keyFlags = options.forwarding ?
27584
28161
  [enums.keyFlags.forwardedCommunication] :
27585
28162
  [enums.keyFlags.encryptCommunication | enums.keyFlags.encryptStorage];
27586
28163
  }
27587
28164
  if (options.keyExpirationTime > 0) {
27588
- subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime;
27589
- subkeySignaturePacket.keyNeverExpires = false;
28165
+ signatureProperties.keyExpirationTime = options.keyExpirationTime;
28166
+ signatureProperties.keyNeverExpires = false;
27590
28167
  }
27591
- await subkeySignaturePacket.sign(primaryKey, dataToSign, options.date);
28168
+ const subkeySignaturePacket = await createSignaturePacket(dataToSign, null, primaryKey, signatureProperties, options.date, undefined, undefined, undefined, config);
27592
28169
  return subkeySignaturePacket;
27593
28170
  }
27594
28171
 
@@ -27602,7 +28179,7 @@ async function createBindingSignature(subkey, primaryKey, options, config) {
27602
28179
  * @returns {Promise<enums.hash>}
27603
28180
  * @async
27604
28181
  */
27605
- async function getPreferredHashAlgo$1(key, keyPacket, date = new Date(), userID = {}, config) {
28182
+ async function getPreferredHashAlgo$2(key, keyPacket, date = new Date(), userID = {}, config) {
27606
28183
  let hashAlgo = config.preferredHashAlgorithm;
27607
28184
  let prefAlgo = hashAlgo;
27608
28185
  if (key) {
@@ -27613,17 +28190,11 @@ async function getPreferredHashAlgo$1(key, keyPacket, date = new Date(), userID
27613
28190
  prefAlgo : hashAlgo;
27614
28191
  }
27615
28192
  }
27616
- switch (Object.getPrototypeOf(keyPacket)) {
27617
- case SecretKeyPacket.prototype:
27618
- case PublicKeyPacket.prototype:
27619
- case SecretSubkeyPacket.prototype:
27620
- case PublicSubkeyPacket.prototype:
27621
- switch (keyPacket.algorithm) {
27622
- case enums.publicKey.ecdh:
27623
- case enums.publicKey.ecdsa:
27624
- case enums.publicKey.eddsa:
27625
- prefAlgo = mod.publicKey.elliptic.getPreferredHashAlgo(keyPacket.publicParams.oid);
27626
- }
28193
+ switch (keyPacket.algorithm) {
28194
+ case enums.publicKey.ecdsa:
28195
+ case enums.publicKey.eddsaLegacy:
28196
+ case enums.publicKey.ed25519:
28197
+ prefAlgo = mod.getPreferredCurveHashAlgo(keyPacket.algorithm, keyPacket.publicParams.oid);
27627
28198
  }
27628
28199
  return mod.hash.getHashByteLength(hashAlgo) <= mod.hash.getHashByteLength(prefAlgo) ?
27629
28200
  prefAlgo : hashAlgo;
@@ -27691,7 +28262,7 @@ async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, s
27691
28262
  const signaturePacket = new SignaturePacket();
27692
28263
  Object.assign(signaturePacket, signatureProperties);
27693
28264
  signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
27694
- signaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(privateKey, signingKeyPacket, date, userID, config);
28265
+ signaturePacket.hashAlgorithm = await getPreferredHashAlgo$2(privateKey, signingKeyPacket, date, userID, config);
27695
28266
  signaturePacket.rawNotations = notations;
27696
28267
  await signaturePacket.sign(signingKeyPacket, dataToSign, date, detached);
27697
28268
  return signaturePacket;
@@ -27832,11 +28403,11 @@ function sanitizeKeyOptions(options, subkeyDefaults = {}) {
27832
28403
  } catch (e) {
27833
28404
  throw new Error('Unknown curve');
27834
28405
  }
27835
- if (options.curve === enums.curve.ed25519 || options.curve === enums.curve.curve25519) {
27836
- options.curve = options.sign ? enums.curve.ed25519 : enums.curve.curve25519;
28406
+ if (options.curve === enums.curve.ed25519Legacy || options.curve === enums.curve.curve25519Legacy) {
28407
+ options.curve = options.sign ? enums.curve.ed25519Legacy : enums.curve.curve25519Legacy;
27837
28408
  }
27838
28409
  if (options.sign) {
27839
- options.algorithm = options.curve === enums.curve.ed25519 ? enums.publicKey.eddsa : enums.publicKey.ecdsa;
28410
+ options.algorithm = options.curve === enums.curve.ed25519Legacy ? enums.publicKey.eddsaLegacy : enums.publicKey.ecdsa;
27840
28411
  } else {
27841
28412
  options.algorithm = enums.publicKey.ecdh;
27842
28413
  }
@@ -27864,6 +28435,7 @@ function isValidSigningKeyPacket(keyPacket, signature) {
27864
28435
  return keyAlgo !== enums.publicKey.rsaEncrypt &&
27865
28436
  keyAlgo !== enums.publicKey.elgamal &&
27866
28437
  keyAlgo !== enums.publicKey.ecdh &&
28438
+ keyAlgo !== enums.publicKey.x25519 &&
27867
28439
  (!signature.keyFlags ||
27868
28440
  (signature.keyFlags[0] & enums.keyFlags.signData) !== 0);
27869
28441
  }
@@ -27873,7 +28445,8 @@ function isValidEncryptionKeyPacket(keyPacket, signature) {
27873
28445
  return keyAlgo !== enums.publicKey.dsa &&
27874
28446
  keyAlgo !== enums.publicKey.rsaSign &&
27875
28447
  keyAlgo !== enums.publicKey.ecdsa &&
27876
- keyAlgo !== enums.publicKey.eddsa &&
28448
+ keyAlgo !== enums.publicKey.eddsaLegacy &&
28449
+ keyAlgo !== enums.publicKey.ed25519 &&
27877
28450
  (!signature.keyFlags ||
27878
28451
  (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 ||
27879
28452
  (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0);
@@ -27918,7 +28491,7 @@ function checkKeyRequirements(keyPacket, config) {
27918
28491
  }
27919
28492
  break;
27920
28493
  case enums.publicKey.ecdsa:
27921
- case enums.publicKey.eddsa:
28494
+ case enums.publicKey.eddsaLegacy:
27922
28495
  case enums.publicKey.ecdh:
27923
28496
  if (config.rejectCurves.has(algoInfo.curve)) {
27924
28497
  throw new Error(`Support for ${algoInfo.algorithm} keys using curve ${algoInfo.curve} is disabled.`);
@@ -29428,7 +30001,7 @@ function createKey(packetlist) {
29428
30001
  * @static
29429
30002
  * @private
29430
30003
  */
29431
- async function generate$2(options, config) {
30004
+ async function generate$4(options, config) {
29432
30005
  options.sign = true; // primary key is always a signing key
29433
30006
  options = sanitizeKeyOptions(options);
29434
30007
  options.subkeys = options.subkeys.map((subkey, index) => sanitizeKeyOptions(options.subkeys[index], options));
@@ -29545,50 +30118,50 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
29545
30118
  const dataToSign = {};
29546
30119
  dataToSign.userID = userIDPacket;
29547
30120
  dataToSign.key = secretKeyPacket;
29548
- const signaturePacket = new SignaturePacket();
29549
- signaturePacket.signatureType = enums.signature.certGeneric;
29550
- signaturePacket.publicKeyAlgorithm = secretKeyPacket.algorithm;
29551
- signaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(null, secretKeyPacket, undefined, undefined, config);
29552
- signaturePacket.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData];
29553
- signaturePacket.preferredSymmetricAlgorithms = createPreferredAlgos([
30121
+
30122
+ const signatureProperties = {};
30123
+ signatureProperties.signatureType = enums.signature.certGeneric;
30124
+ signatureProperties.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData];
30125
+ signatureProperties.preferredSymmetricAlgorithms = createPreferredAlgos([
29554
30126
  // prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support)
29555
30127
  enums.symmetric.aes256,
29556
30128
  enums.symmetric.aes128,
29557
30129
  enums.symmetric.aes192
29558
30130
  ], config.preferredSymmetricAlgorithm);
29559
30131
  if (config.aeadProtect) {
29560
- signaturePacket.preferredAEADAlgorithms = createPreferredAlgos([
30132
+ signatureProperties.preferredAEADAlgorithms = createPreferredAlgos([
29561
30133
  enums.aead.eax,
29562
30134
  enums.aead.ocb
29563
30135
  ], config.preferredAEADAlgorithm);
29564
30136
  }
29565
- signaturePacket.preferredHashAlgorithms = createPreferredAlgos([
30137
+ signatureProperties.preferredHashAlgorithms = createPreferredAlgos([
29566
30138
  // prefer fast asm.js implementations (SHA-256)
29567
30139
  enums.hash.sha256,
29568
30140
  enums.hash.sha512
29569
30141
  ], config.preferredHashAlgorithm);
29570
- signaturePacket.preferredCompressionAlgorithms = createPreferredAlgos([
30142
+ signatureProperties.preferredCompressionAlgorithms = createPreferredAlgos([
29571
30143
  enums.compression.zlib,
29572
30144
  enums.compression.zip,
29573
30145
  enums.compression.uncompressed
29574
30146
  ], config.preferredCompressionAlgorithm);
29575
30147
  if (index === 0) {
29576
- signaturePacket.isPrimaryUserID = true;
30148
+ signatureProperties.isPrimaryUserID = true;
29577
30149
  }
29578
30150
  // integrity protection always enabled
29579
- signaturePacket.features = [0];
29580
- signaturePacket.features[0] |= enums.features.modificationDetection;
30151
+ signatureProperties.features = [0];
30152
+ signatureProperties.features[0] |= enums.features.modificationDetection;
29581
30153
  if (config.aeadProtect) {
29582
- signaturePacket.features[0] |= enums.features.aead;
30154
+ signatureProperties.features[0] |= enums.features.aead;
29583
30155
  }
29584
30156
  if (config.v5Keys) {
29585
- signaturePacket.features[0] |= enums.features.v5Keys;
30157
+ signatureProperties.features[0] |= enums.features.v5Keys;
29586
30158
  }
29587
30159
  if (options.keyExpirationTime > 0) {
29588
- signaturePacket.keyExpirationTime = options.keyExpirationTime;
29589
- signaturePacket.keyNeverExpires = false;
30160
+ signatureProperties.keyExpirationTime = options.keyExpirationTime;
30161
+ signatureProperties.keyNeverExpires = false;
29590
30162
  }
29591
- await signaturePacket.sign(secretKeyPacket, dataToSign, options.date);
30163
+
30164
+ const signaturePacket = await createSignaturePacket(dataToSign, null, secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config);
29592
30165
 
29593
30166
  return { userIDPacket, signaturePacket };
29594
30167
  })).then(list => {
@@ -30107,6 +30680,15 @@ class Message {
30107
30680
  enums.read(enums.aead, await getPreferredAlgo('aead', encryptionKeys, date, userIDs, config$1)) :
30108
30681
  undefined;
30109
30682
 
30683
+ await Promise.all(encryptionKeys.map(key => key.getEncryptionKey()
30684
+ .catch(() => null) // ignore key strength requirements
30685
+ .then(maybeKey => {
30686
+ if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519) && !util.isAES(algo)) {
30687
+ 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.');
30688
+ }
30689
+ })
30690
+ ));
30691
+
30110
30692
  const sessionKeyData = mod.generateSessionKey(algo);
30111
30693
  return { data: sessionKeyData, algorithm: algorithmName, aeadAlgorithm: aeadAlgorithmName };
30112
30694
  }
@@ -30281,7 +30863,7 @@ class Message {
30281
30863
  const signingKey = await primaryKey.getSigningKey(signingKeyID, date, userIDs, config$1);
30282
30864
  const onePassSig = new OnePassSignaturePacket();
30283
30865
  onePassSig.signatureType = signatureType;
30284
- onePassSig.hashAlgorithm = await getPreferredHashAlgo$1(primaryKey, signingKey.keyPacket, date, userIDs, config$1);
30866
+ onePassSig.hashAlgorithm = await getPreferredHashAlgo$2(primaryKey, signingKey.keyPacket, date, userIDs, config$1);
30285
30867
  onePassSig.publicKeyAlgorithm = signingKey.keyPacket.algorithm;
30286
30868
  onePassSig.issuerKeyID = signingKey.getKeyID();
30287
30869
  if (i === signingKeys.length - 1) {
@@ -30414,7 +30996,7 @@ class Message {
30414
30996
  if (literalDataList.length !== 1) {
30415
30997
  throw new Error('Can only verify message with one literal data packet.');
30416
30998
  }
30417
- const signatureList = signature.packets;
30999
+ const signatureList = signature.packets.filterByTag(enums.packet.signature); // drop UnparsablePackets
30418
31000
  return createVerificationObjects(signatureList, literalDataList, verificationKeys, date, true, config$1);
30419
31001
  }
30420
31002
 
@@ -30761,7 +31343,7 @@ class CleartextMessage {
30761
31343
  * @async
30762
31344
  */
30763
31345
  verify(keys, date = new Date(), config$1 = config) {
30764
- const signatureList = this.signature.packets;
31346
+ const signatureList = this.signature.packets.filterByTag(enums.packet.signature); // drop UnparsablePackets
30765
31347
  const literalDataPacket = new LiteralDataPacket();
30766
31348
  // we assume that cleartext signature is generated based on UTF8 cleartext
30767
31349
  literalDataPacket.setText(this.text);
@@ -30846,7 +31428,7 @@ function verifyHeaders$1(headers, packetlist) {
30846
31428
  let oneHeader = null;
30847
31429
  let hashAlgos = [];
30848
31430
  headers.forEach(function(header) {
30849
- oneHeader = header.match(/Hash: (.+)/); // get header value
31431
+ oneHeader = header.match(/^Hash: (.+)$/); // get header value
30850
31432
  if (oneHeader) {
30851
31433
  oneHeader = oneHeader[1].replace(/\s/g, ''); // remove whitespace
30852
31434
  oneHeader = oneHeader.split(',');
@@ -30938,7 +31520,7 @@ async function generateKey({ userIDs = [], passphrase, type = 'ecc', rsaBits = 4
30938
31520
  const options = { userIDs, passphrase, type, rsaBits, curve, keyExpirationTime, date, subkeys, symmetricHash, symmetricCipher };
30939
31521
 
30940
31522
  try {
30941
- const { key, revocationCertificate } = await generate$2(options, config$1);
31523
+ const { key, revocationCertificate } = await generate$4(options, config$1);
30942
31524
  key.getKeys().forEach(({ keyPacket }) => checkKeyRequirements(keyPacket, config$1));
30943
31525
 
30944
31526
  return {
@@ -31132,7 +31714,7 @@ async function encryptKey({ privateKey, passphrase, config: config$1, ...rest })
31132
31714
  * @async
31133
31715
  * @static
31134
31716
  */
31135
- 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 }) {
31717
+ 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 }) {
31136
31718
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
31137
31719
  checkMessage(message); checkOutputMessageFormat(format);
31138
31720
  encryptionKeys = toArray$1(encryptionKeys); signingKeys = toArray$1(signingKeys); passwords = toArray$1(passwords);
@@ -31201,7 +31783,7 @@ async function encrypt$4({ message, encryptionKeys, signingKeys, passwords, sess
31201
31783
  * @async
31202
31784
  * @static
31203
31785
  */
31204
- async function decrypt$4({ message, decryptionKeys, passwords, sessionKeys, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
31786
+ async function decrypt$5({ message, decryptionKeys, passwords, sessionKeys, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
31205
31787
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
31206
31788
  checkMessage(message); verificationKeys = toArray$1(verificationKeys); decryptionKeys = toArray$1(decryptionKeys); passwords = toArray$1(passwords); sessionKeys = toArray$1(sessionKeys);
31207
31789
  if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.decrypt, pass `decryptionKeys` instead');
@@ -31264,7 +31846,7 @@ async function decrypt$4({ message, decryptionKeys, passwords, sessionKeys, veri
31264
31846
  * @async
31265
31847
  * @static
31266
31848
  */
31267
- async function sign$5({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
31849
+ async function sign$6({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
31268
31850
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
31269
31851
  checkCleartextOrMessage(message); checkOutputMessageFormat(format);
31270
31852
  signingKeys = toArray$1(signingKeys); signingKeyIDs = toArray$1(signingKeyIDs); signingUserIDs = toArray$1(signingUserIDs); signatureNotations = toArray$1(signatureNotations);
@@ -31333,7 +31915,7 @@ async function sign$5({ message, signingKeys, format = 'armored', detached = fal
31333
31915
  * @async
31334
31916
  * @static
31335
31917
  */
31336
- async function verify$5({ message, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
31918
+ async function verify$6({ message, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
31337
31919
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
31338
31920
  checkCleartextOrMessage(message); verificationKeys = toArray$1(verificationKeys);
31339
31921
  if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.verify, pass `verificationKeys` instead');
@@ -44502,7 +45084,7 @@ function* makePRNG(wasmContext, pass, lane, slice, m_, totalPasses, segmentLengt
44502
45084
  return [];
44503
45085
  }
44504
45086
 
44505
- function validateParams$7({ type, version, tagLength, password, salt, ad, secret, parallelism, memorySize, passes }) {
45087
+ function validateParams$9({ type, version, tagLength, password, salt, ad, secret, parallelism, memorySize, passes }) {
44506
45088
  const assertLength = (name, value, min, max) => {
44507
45089
  if (value < min || value > max) { throw new Error(`${name} size should be between ${min} and ${max} bytes`); }
44508
45090
  };
@@ -44525,7 +45107,7 @@ const WASM_PAGE_SIZE = 64 * KB;
44525
45107
  function argon2id(params, { memory, instance: wasmInstance }) {
44526
45108
  if (!isLittleEndian$1) throw new Error('BigEndian system not supported'); // optmisations assume LE system
44527
45109
 
44528
- const ctx = validateParams$7({ type: TYPE$2, version: VERSION$4, ...params });
45110
+ const ctx = validateParams$9({ type: TYPE$2, version: VERSION$4, ...params });
44529
45111
 
44530
45112
  const { G:wasmG, G2:wasmG2, xor:wasmXOR, getLZ:wasmLZ } = wasmInstance.exports;
44531
45113
  const wasmRefs = {};
@@ -44835,10 +45417,10 @@ exports.armor = armor;
44835
45417
  exports.config = config;
44836
45418
  exports.createCleartextMessage = createCleartextMessage;
44837
45419
  exports.createMessage = createMessage;
44838
- exports.decrypt = decrypt$4;
45420
+ exports.decrypt = decrypt$5;
44839
45421
  exports.decryptKey = decryptKey;
44840
45422
  exports.decryptSessionKeys = decryptSessionKeys;
44841
- exports.encrypt = encrypt$4;
45423
+ exports.encrypt = encrypt$5;
44842
45424
  exports.encryptKey = encryptKey;
44843
45425
  exports.encryptSessionKey = encryptSessionKey;
44844
45426
  exports.enums = enums;
@@ -44853,6 +45435,6 @@ exports.readPrivateKeys = readPrivateKeys;
44853
45435
  exports.readSignature = readSignature;
44854
45436
  exports.reformatKey = reformatKey;
44855
45437
  exports.revokeKey = revokeKey;
44856
- exports.sign = sign$5;
45438
+ exports.sign = sign$6;
44857
45439
  exports.unarmor = unarmor;
44858
- exports.verify = verify$5;
45440
+ exports.verify = verify$6;