@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
  const globalThis = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
3
3
 
4
4
  import buffer from 'buffer';
@@ -249,18 +249,17 @@ if (NodeReadableStream$1) {
249
249
  this.push(null);
250
250
  break;
251
251
  }
252
- if (!this.push(value) || this._cancelling) {
253
- this._reading = false;
252
+ if (!this.push(value)) {
254
253
  break;
255
254
  }
256
255
  }
257
- } catch(e) {
258
- this.emit('error', e);
256
+ } catch (e) {
257
+ this.destroy(e);
259
258
  }
260
259
  }
261
260
 
262
- _destroy(reason) {
263
- this._reader.cancel(reason);
261
+ async _destroy(error, callback) {
262
+ this._reader.cancel(error).then(callback, callback);
264
263
  }
265
264
  }
266
265
 
@@ -295,7 +294,7 @@ function Reader(input) {
295
294
  const reader = input.getReader();
296
295
  this._read = reader.read.bind(reader);
297
296
  this._releaseLock = () => {};
298
- this._cancel = () => {};
297
+ this._cancel = async () => {};
299
298
  return;
300
299
  }
301
300
  let streamType = isStream(input);
@@ -1515,6 +1514,533 @@ async function getBigInteger() {
1515
1514
  }
1516
1515
  }
1517
1516
 
1517
+ /**
1518
+ * @module enums
1519
+ */
1520
+
1521
+ const byValue = Symbol('byValue');
1522
+
1523
+ var enums = {
1524
+
1525
+ /** Maps curve names under various standards to one
1526
+ * @see {@link https://wiki.gnupg.org/ECC|ECC - GnuPG wiki}
1527
+ * @enum {String}
1528
+ * @readonly
1529
+ */
1530
+ curve: {
1531
+ /** NIST P-256 Curve */
1532
+ 'p256': 'p256',
1533
+ 'P-256': 'p256',
1534
+ 'secp256r1': 'p256',
1535
+ 'prime256v1': 'p256',
1536
+ '1.2.840.10045.3.1.7': 'p256',
1537
+ '2a8648ce3d030107': 'p256',
1538
+ '2A8648CE3D030107': 'p256',
1539
+
1540
+ /** NIST P-384 Curve */
1541
+ 'p384': 'p384',
1542
+ 'P-384': 'p384',
1543
+ 'secp384r1': 'p384',
1544
+ '1.3.132.0.34': 'p384',
1545
+ '2b81040022': 'p384',
1546
+ '2B81040022': 'p384',
1547
+
1548
+ /** NIST P-521 Curve */
1549
+ 'p521': 'p521',
1550
+ 'P-521': 'p521',
1551
+ 'secp521r1': 'p521',
1552
+ '1.3.132.0.35': 'p521',
1553
+ '2b81040023': 'p521',
1554
+ '2B81040023': 'p521',
1555
+
1556
+ /** SECG SECP256k1 Curve */
1557
+ 'secp256k1': 'secp256k1',
1558
+ '1.3.132.0.10': 'secp256k1',
1559
+ '2b8104000a': 'secp256k1',
1560
+ '2B8104000A': 'secp256k1',
1561
+
1562
+ /** Ed25519 - deprecated by crypto-refresh (replaced by standaone Ed25519 algo) */
1563
+ 'ed25519Legacy': 'ed25519',
1564
+ 'ED25519': 'ed25519',
1565
+ /** @deprecated use `ed25519Legacy` instead */
1566
+ 'ed25519': 'ed25519',
1567
+ 'Ed25519': 'ed25519',
1568
+ '1.3.6.1.4.1.11591.15.1': 'ed25519',
1569
+ '2b06010401da470f01': 'ed25519',
1570
+ '2B06010401DA470F01': 'ed25519',
1571
+
1572
+ /** Curve25519 - deprecated by crypto-refresh (replaced by standaone X25519 algo) */
1573
+ 'curve25519Legacy': 'curve25519',
1574
+ 'X25519': 'curve25519',
1575
+ 'cv25519': 'curve25519',
1576
+ /** @deprecated use `curve25519Legacy` instead */
1577
+ 'curve25519': 'curve25519',
1578
+ 'Curve25519': 'curve25519',
1579
+ '1.3.6.1.4.1.3029.1.5.1': 'curve25519',
1580
+ '2b060104019755010501': 'curve25519',
1581
+ '2B060104019755010501': 'curve25519',
1582
+
1583
+ /** BrainpoolP256r1 Curve */
1584
+ 'brainpoolP256r1': 'brainpoolP256r1',
1585
+ '1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1',
1586
+ '2b2403030208010107': 'brainpoolP256r1',
1587
+ '2B2403030208010107': 'brainpoolP256r1',
1588
+
1589
+ /** BrainpoolP384r1 Curve */
1590
+ 'brainpoolP384r1': 'brainpoolP384r1',
1591
+ '1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1',
1592
+ '2b240303020801010b': 'brainpoolP384r1',
1593
+ '2B240303020801010B': 'brainpoolP384r1',
1594
+
1595
+ /** BrainpoolP512r1 Curve */
1596
+ 'brainpoolP512r1': 'brainpoolP512r1',
1597
+ '1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1',
1598
+ '2b240303020801010d': 'brainpoolP512r1',
1599
+ '2B240303020801010D': 'brainpoolP512r1'
1600
+ },
1601
+
1602
+ /** KDF parameters flags
1603
+ * Non-standard extensions (for now) to allow email forwarding
1604
+ * @enum {Integer}
1605
+ * @readonly
1606
+ */
1607
+ kdfFlags: {
1608
+ /** Specify fingerprint to use instead of the recipient's */
1609
+ replace_fingerprint: 0x01,
1610
+ /** Specify custom parameters to use in the KDF digest computation */
1611
+ replace_kdf_params: 0x02
1612
+ },
1613
+
1614
+ /** A string to key specifier type
1615
+ * @enum {Integer}
1616
+ * @readonly
1617
+ */
1618
+ s2k: {
1619
+ simple: 0,
1620
+ salted: 1,
1621
+ iterated: 3,
1622
+ argon2: 4,
1623
+ gnu: 101
1624
+ },
1625
+
1626
+ /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-crypto-refresh-08.html#section-9.1|crypto-refresh RFC, section 9.1}
1627
+ * @enum {Integer}
1628
+ * @readonly
1629
+ */
1630
+ publicKey: {
1631
+ /** RSA (Encrypt or Sign) [HAC] */
1632
+ rsaEncryptSign: 1,
1633
+ /** RSA (Encrypt only) [HAC] */
1634
+ rsaEncrypt: 2,
1635
+ /** RSA (Sign only) [HAC] */
1636
+ rsaSign: 3,
1637
+ /** Elgamal (Encrypt only) [ELGAMAL] [HAC] */
1638
+ elgamal: 16,
1639
+ /** DSA (Sign only) [FIPS186] [HAC] */
1640
+ dsa: 17,
1641
+ /** ECDH (Encrypt only) [RFC6637] */
1642
+ ecdh: 18,
1643
+ /** ECDSA (Sign only) [RFC6637] */
1644
+ ecdsa: 19,
1645
+ /** EdDSA (Sign only) - deprecated by crypto-refresh (replaced by `ed25519` identifier below)
1646
+ * [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */
1647
+ eddsaLegacy: 22, // NB: this is declared before `eddsa` to translate 22 to 'eddsa' for backwards compatibility
1648
+ /** @deprecated use `eddsaLegacy` instead */
1649
+ ed25519Legacy: 22,
1650
+ /** @deprecated use `eddsaLegacy` instead */
1651
+ eddsa: 22,
1652
+ /** Reserved for AEDH */
1653
+ aedh: 23,
1654
+ /** Reserved for AEDSA */
1655
+ aedsa: 24,
1656
+ /** X25519 (Encrypt only) */
1657
+ x25519: 25,
1658
+ /** X448 (Encrypt only) */
1659
+ x448: 26,
1660
+ /** Ed25519 (Sign only) */
1661
+ ed25519: 27,
1662
+ /** Ed448 (Sign only) */
1663
+ ed448: 28,
1664
+ /** Symmetric authenticated encryption algorithms */
1665
+ aead: 100,
1666
+ /** Authentication using CMAC */
1667
+ hmac: 101
1668
+ },
1669
+
1670
+ /** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
1671
+ * @enum {Integer}
1672
+ * @readonly
1673
+ */
1674
+ symmetric: {
1675
+ plaintext: 0,
1676
+ /** Not implemented! */
1677
+ idea: 1,
1678
+ tripledes: 2,
1679
+ cast5: 3,
1680
+ blowfish: 4,
1681
+ aes128: 7,
1682
+ aes192: 8,
1683
+ aes256: 9,
1684
+ twofish: 10
1685
+ },
1686
+
1687
+ /** {@link https://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
1688
+ * @enum {Integer}
1689
+ * @readonly
1690
+ */
1691
+ compression: {
1692
+ uncompressed: 0,
1693
+ /** RFC1951 */
1694
+ zip: 1,
1695
+ /** RFC1950 */
1696
+ zlib: 2,
1697
+ bzip2: 3
1698
+ },
1699
+
1700
+ /** {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
1701
+ * @enum {Integer}
1702
+ * @readonly
1703
+ */
1704
+ hash: {
1705
+ md5: 1,
1706
+ sha1: 2,
1707
+ ripemd: 3,
1708
+ sha256: 8,
1709
+ sha384: 9,
1710
+ sha512: 10,
1711
+ sha224: 11
1712
+ },
1713
+
1714
+ /** A list of hash names as accepted by webCrypto functions.
1715
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest|Parameters, algo}
1716
+ * @enum {String}
1717
+ */
1718
+ webHash: {
1719
+ 'SHA-1': 2,
1720
+ 'SHA-256': 8,
1721
+ 'SHA-384': 9,
1722
+ 'SHA-512': 10
1723
+ },
1724
+
1725
+ /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.6|RFC4880bis-04, section 9.6}
1726
+ * @enum {Integer}
1727
+ * @readonly
1728
+ */
1729
+ aead: {
1730
+ eax: 1,
1731
+ ocb: 2,
1732
+ experimentalGCM: 100 // Private algorithm
1733
+ },
1734
+
1735
+ /** A list of packet types and numeric tags associated with them.
1736
+ * @enum {Integer}
1737
+ * @readonly
1738
+ */
1739
+ packet: {
1740
+ publicKeyEncryptedSessionKey: 1,
1741
+ signature: 2,
1742
+ symEncryptedSessionKey: 3,
1743
+ onePassSignature: 4,
1744
+ secretKey: 5,
1745
+ publicKey: 6,
1746
+ secretSubkey: 7,
1747
+ compressedData: 8,
1748
+ symmetricallyEncryptedData: 9,
1749
+ marker: 10,
1750
+ literalData: 11,
1751
+ trust: 12,
1752
+ userID: 13,
1753
+ publicSubkey: 14,
1754
+ userAttribute: 17,
1755
+ symEncryptedIntegrityProtectedData: 18,
1756
+ modificationDetectionCode: 19,
1757
+ aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
1758
+ },
1759
+
1760
+ /** Data types in the literal packet
1761
+ * @enum {Integer}
1762
+ * @readonly
1763
+ */
1764
+ literal: {
1765
+ /** Binary data 'b' */
1766
+ binary: 'b'.charCodeAt(),
1767
+ /** Text data 't' */
1768
+ text: 't'.charCodeAt(),
1769
+ /** Utf8 data 'u' */
1770
+ utf8: 'u'.charCodeAt(),
1771
+ /** MIME message body part 'm' */
1772
+ mime: 'm'.charCodeAt()
1773
+ },
1774
+
1775
+
1776
+ /** One pass signature packet type
1777
+ * @enum {Integer}
1778
+ * @readonly
1779
+ */
1780
+ signature: {
1781
+ /** 0x00: Signature of a binary document. */
1782
+ binary: 0,
1783
+ /** 0x01: Signature of a canonical text document.
1784
+ *
1785
+ * Canonicalyzing the document by converting line endings. */
1786
+ text: 1,
1787
+ /** 0x02: Standalone signature.
1788
+ *
1789
+ * This signature is a signature of only its own subpacket contents.
1790
+ * It is calculated identically to a signature over a zero-lengh
1791
+ * binary document. Note that it doesn't make sense to have a V3
1792
+ * standalone signature. */
1793
+ standalone: 2,
1794
+ /** 0x10: Generic certification of a User ID and Public-Key packet.
1795
+ *
1796
+ * The issuer of this certification does not make any particular
1797
+ * assertion as to how well the certifier has checked that the owner
1798
+ * of the key is in fact the person described by the User ID. */
1799
+ certGeneric: 16,
1800
+ /** 0x11: Persona certification of a User ID and Public-Key packet.
1801
+ *
1802
+ * The issuer of this certification has not done any verification of
1803
+ * the claim that the owner of this key is the User ID specified. */
1804
+ certPersona: 17,
1805
+ /** 0x12: Casual certification of a User ID and Public-Key packet.
1806
+ *
1807
+ * The issuer of this certification has done some casual
1808
+ * verification of the claim of identity. */
1809
+ certCasual: 18,
1810
+ /** 0x13: Positive certification of a User ID and Public-Key packet.
1811
+ *
1812
+ * The issuer of this certification has done substantial
1813
+ * verification of the claim of identity.
1814
+ *
1815
+ * Most OpenPGP implementations make their "key signatures" as 0x10
1816
+ * certifications. Some implementations can issue 0x11-0x13
1817
+ * certifications, but few differentiate between the types. */
1818
+ certPositive: 19,
1819
+ /** 0x30: Certification revocation signature
1820
+ *
1821
+ * This signature revokes an earlier User ID certification signature
1822
+ * (signature class 0x10 through 0x13) or direct-key signature
1823
+ * (0x1F). It should be issued by the same key that issued the
1824
+ * revoked signature or an authorized revocation key. The signature
1825
+ * is computed over the same data as the certificate that it
1826
+ * revokes, and should have a later creation date than that
1827
+ * certificate. */
1828
+ certRevocation: 48,
1829
+ /** 0x18: Subkey Binding Signature
1830
+ *
1831
+ * This signature is a statement by the top-level signing key that
1832
+ * indicates that it owns the subkey. This signature is calculated
1833
+ * directly on the primary key and subkey, and not on any User ID or
1834
+ * other packets. A signature that binds a signing subkey MUST have
1835
+ * an Embedded Signature subpacket in this binding signature that
1836
+ * contains a 0x19 signature made by the signing subkey on the
1837
+ * primary key and subkey. */
1838
+ subkeyBinding: 24,
1839
+ /** 0x19: Primary Key Binding Signature
1840
+ *
1841
+ * This signature is a statement by a signing subkey, indicating
1842
+ * that it is owned by the primary key and subkey. This signature
1843
+ * is calculated the same way as a 0x18 signature: directly on the
1844
+ * primary key and subkey, and not on any User ID or other packets.
1845
+ *
1846
+ * When a signature is made over a key, the hash data starts with the
1847
+ * octet 0x99, followed by a two-octet length of the key, and then body
1848
+ * of the key packet. (Note that this is an old-style packet header for
1849
+ * a key packet with two-octet length.) A subkey binding signature
1850
+ * (type 0x18) or primary key binding signature (type 0x19) then hashes
1851
+ * the subkey using the same format as the main key (also using 0x99 as
1852
+ * the first octet). */
1853
+ keyBinding: 25,
1854
+ /** 0x1F: Signature directly on a key
1855
+ *
1856
+ * This signature is calculated directly on a key. It binds the
1857
+ * information in the Signature subpackets to the key, and is
1858
+ * appropriate to be used for subpackets that provide information
1859
+ * about the key, such as the Revocation Key subpacket. It is also
1860
+ * appropriate for statements that non-self certifiers want to make
1861
+ * about the key itself, rather than the binding between a key and a
1862
+ * name. */
1863
+ key: 31,
1864
+ /** 0x20: Key revocation signature
1865
+ *
1866
+ * The signature is calculated directly on the key being revoked. A
1867
+ * revoked key is not to be used. Only revocation signatures by the
1868
+ * key being revoked, or by an authorized revocation key, should be
1869
+ * considered valid revocation signatures.a */
1870
+ keyRevocation: 32,
1871
+ /** 0x28: Subkey revocation signature
1872
+ *
1873
+ * The signature is calculated directly on the subkey being revoked.
1874
+ * A revoked subkey is not to be used. Only revocation signatures
1875
+ * by the top-level signature key that is bound to this subkey, or
1876
+ * by an authorized revocation key, should be considered valid
1877
+ * revocation signatures.
1878
+ *
1879
+ * Key revocation signatures (types 0x20 and 0x28)
1880
+ * hash only the key being revoked. */
1881
+ subkeyRevocation: 40,
1882
+ /** 0x40: Timestamp signature.
1883
+ * This signature is only meaningful for the timestamp contained in
1884
+ * it. */
1885
+ timestamp: 64,
1886
+ /** 0x50: Third-Party Confirmation signature.
1887
+ *
1888
+ * This signature is a signature over some other OpenPGP Signature
1889
+ * packet(s). It is analogous to a notary seal on the signed data.
1890
+ * A third-party signature SHOULD include Signature Target
1891
+ * subpacket(s) to give easy identification. Note that we really do
1892
+ * mean SHOULD. There are plausible uses for this (such as a blind
1893
+ * party that only sees the signature, not the key or source
1894
+ * document) that cannot include a target subpacket. */
1895
+ thirdParty: 80
1896
+ },
1897
+
1898
+ /** Signature subpacket type
1899
+ * @enum {Integer}
1900
+ * @readonly
1901
+ */
1902
+ signatureSubpacket: {
1903
+ signatureCreationTime: 2,
1904
+ signatureExpirationTime: 3,
1905
+ exportableCertification: 4,
1906
+ trustSignature: 5,
1907
+ regularExpression: 6,
1908
+ revocable: 7,
1909
+ keyExpirationTime: 9,
1910
+ placeholderBackwardsCompatibility: 10,
1911
+ preferredSymmetricAlgorithms: 11,
1912
+ revocationKey: 12,
1913
+ issuer: 16,
1914
+ notationData: 20,
1915
+ preferredHashAlgorithms: 21,
1916
+ preferredCompressionAlgorithms: 22,
1917
+ keyServerPreferences: 23,
1918
+ preferredKeyServer: 24,
1919
+ primaryUserID: 25,
1920
+ policyURI: 26,
1921
+ keyFlags: 27,
1922
+ signersUserID: 28,
1923
+ reasonForRevocation: 29,
1924
+ features: 30,
1925
+ signatureTarget: 31,
1926
+ embeddedSignature: 32,
1927
+ issuerFingerprint: 33,
1928
+ preferredAEADAlgorithms: 34
1929
+ },
1930
+
1931
+ /** Key flags
1932
+ * @enum {Integer}
1933
+ * @readonly
1934
+ */
1935
+ keyFlags: {
1936
+ /** 0x01 - This key may be used to certify other keys. */
1937
+ certifyKeys: 1,
1938
+ /** 0x02 - This key may be used to sign data. */
1939
+ signData: 2,
1940
+ /** 0x04 - This key may be used to encrypt communications. */
1941
+ encryptCommunication: 4,
1942
+ /** 0x08 - This key may be used to encrypt storage. */
1943
+ encryptStorage: 8,
1944
+ /** 0x10 - The private component of this key may have been split
1945
+ * by a secret-sharing mechanism. */
1946
+ splitPrivateKey: 16,
1947
+ /** 0x20 - This key may be used for authentication. */
1948
+ authentication: 32,
1949
+ /** This key may be used for forwarded communications */
1950
+ forwardedCommunication: 64,
1951
+ /** 0x80 - The private component of this key may be in the
1952
+ * possession of more than one person. */
1953
+ sharedPrivateKey: 128
1954
+ },
1955
+
1956
+ /** Armor type
1957
+ * @enum {Integer}
1958
+ * @readonly
1959
+ */
1960
+ armor: {
1961
+ multipartSection: 0,
1962
+ multipartLast: 1,
1963
+ signed: 2,
1964
+ message: 3,
1965
+ publicKey: 4,
1966
+ privateKey: 5,
1967
+ signature: 6
1968
+ },
1969
+
1970
+ /** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
1971
+ * @enum {Integer}
1972
+ * @readonly
1973
+ */
1974
+ reasonForRevocation: {
1975
+ /** No reason specified (key revocations or cert revocations) */
1976
+ noReason: 0,
1977
+ /** Key is superseded (key revocations) */
1978
+ keySuperseded: 1,
1979
+ /** Key material has been compromised (key revocations) */
1980
+ keyCompromised: 2,
1981
+ /** Key is retired and no longer used (key revocations) */
1982
+ keyRetired: 3,
1983
+ /** User ID information is no longer valid (cert revocations) */
1984
+ userIDInvalid: 32
1985
+ },
1986
+
1987
+ /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
1988
+ * @enum {Integer}
1989
+ * @readonly
1990
+ */
1991
+ features: {
1992
+ /** 0x01 - Modification Detection (packets 18 and 19) */
1993
+ modificationDetection: 1,
1994
+ /** 0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
1995
+ * Symmetric-Key Encrypted Session Key Packets (packet 3) */
1996
+ aead: 2,
1997
+ /** 0x04 - Version 5 Public-Key Packet format and corresponding new
1998
+ * fingerprint format */
1999
+ v5Keys: 4
2000
+ },
2001
+
2002
+ /**
2003
+ * Asserts validity of given value and converts from string/integer to integer.
2004
+ * @param {Object} type target enum type
2005
+ * @param {String|Integer} e value to check and/or convert
2006
+ * @returns {Integer} enum value if it exists
2007
+ * @throws {Error} if the value is invalid
2008
+ */
2009
+ write: function(type, e) {
2010
+ if (typeof e === 'number') {
2011
+ e = this.read(type, e);
2012
+ }
2013
+
2014
+ if (type[e] !== undefined) {
2015
+ return type[e];
2016
+ }
2017
+
2018
+ throw new Error('Invalid enum value.');
2019
+ },
2020
+
2021
+ /**
2022
+ * Converts enum integer value to the corresponding string, if it exists.
2023
+ * @param {Object} type target enum type
2024
+ * @param {Integer} e value to convert
2025
+ * @returns {String} name of enum value if it exists
2026
+ * @throws {Error} if the value is invalid
2027
+ */
2028
+ read: function(type, e) {
2029
+ if (!type[byValue]) {
2030
+ type[byValue] = [];
2031
+ Object.entries(type).forEach(([key, value]) => {
2032
+ type[byValue][value] = key;
2033
+ });
2034
+ }
2035
+
2036
+ if (type[byValue][e] !== undefined) {
2037
+ return type[byValue][e];
2038
+ }
2039
+
2040
+ throw new Error('Invalid enum value.');
2041
+ }
2042
+ };
2043
+
1518
2044
  const debugMode = (() => {
1519
2045
  try {
1520
2046
  return process.env.NODE_ENV === 'development'; // eslint-disable-line no-process-env
@@ -2094,6 +2620,12 @@ const util = {
2094
2620
  */
2095
2621
  selectUint8: function(cond, a, b) {
2096
2622
  return (a & (256 - cond)) | (b & (255 + cond));
2623
+ },
2624
+ /**
2625
+ * @param {module:enums.symmetric} cipherAlgo
2626
+ */
2627
+ isAES: function(cipherAlgo) {
2628
+ return cipherAlgo === enums.symmetric.aes128 || cipherAlgo === enums.symmetric.aes192 || cipherAlgo === enums.symmetric.aes256;
2097
2629
  }
2098
2630
  };
2099
2631
 
@@ -2208,517 +2740,6 @@ function uint8ArrayToB64(bytes, url) {
2208
2740
  return encoded;
2209
2741
  }
2210
2742
 
2211
- /**
2212
- * @module enums
2213
- */
2214
-
2215
- const byValue = Symbol('byValue');
2216
-
2217
- var enums = {
2218
-
2219
- /** Maps curve names under various standards to one
2220
- * @see {@link https://wiki.gnupg.org/ECC|ECC - GnuPG wiki}
2221
- * @enum {String}
2222
- * @readonly
2223
- */
2224
- curve: {
2225
- /** NIST P-256 Curve */
2226
- 'p256': 'p256',
2227
- 'P-256': 'p256',
2228
- 'secp256r1': 'p256',
2229
- 'prime256v1': 'p256',
2230
- '1.2.840.10045.3.1.7': 'p256',
2231
- '2a8648ce3d030107': 'p256',
2232
- '2A8648CE3D030107': 'p256',
2233
-
2234
- /** NIST P-384 Curve */
2235
- 'p384': 'p384',
2236
- 'P-384': 'p384',
2237
- 'secp384r1': 'p384',
2238
- '1.3.132.0.34': 'p384',
2239
- '2b81040022': 'p384',
2240
- '2B81040022': 'p384',
2241
-
2242
- /** NIST P-521 Curve */
2243
- 'p521': 'p521',
2244
- 'P-521': 'p521',
2245
- 'secp521r1': 'p521',
2246
- '1.3.132.0.35': 'p521',
2247
- '2b81040023': 'p521',
2248
- '2B81040023': 'p521',
2249
-
2250
- /** SECG SECP256k1 Curve */
2251
- 'secp256k1': 'secp256k1',
2252
- '1.3.132.0.10': 'secp256k1',
2253
- '2b8104000a': 'secp256k1',
2254
- '2B8104000A': 'secp256k1',
2255
-
2256
- /** Ed25519 */
2257
- 'ED25519': 'ed25519',
2258
- 'ed25519': 'ed25519',
2259
- 'Ed25519': 'ed25519',
2260
- '1.3.6.1.4.1.11591.15.1': 'ed25519',
2261
- '2b06010401da470f01': 'ed25519',
2262
- '2B06010401DA470F01': 'ed25519',
2263
-
2264
- /** Curve25519 */
2265
- 'X25519': 'curve25519',
2266
- 'cv25519': 'curve25519',
2267
- 'curve25519': 'curve25519',
2268
- 'Curve25519': 'curve25519',
2269
- '1.3.6.1.4.1.3029.1.5.1': 'curve25519',
2270
- '2b060104019755010501': 'curve25519',
2271
- '2B060104019755010501': 'curve25519',
2272
-
2273
- /** BrainpoolP256r1 Curve */
2274
- 'brainpoolP256r1': 'brainpoolP256r1',
2275
- '1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1',
2276
- '2b2403030208010107': 'brainpoolP256r1',
2277
- '2B2403030208010107': 'brainpoolP256r1',
2278
-
2279
- /** BrainpoolP384r1 Curve */
2280
- 'brainpoolP384r1': 'brainpoolP384r1',
2281
- '1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1',
2282
- '2b240303020801010b': 'brainpoolP384r1',
2283
- '2B240303020801010B': 'brainpoolP384r1',
2284
-
2285
- /** BrainpoolP512r1 Curve */
2286
- 'brainpoolP512r1': 'brainpoolP512r1',
2287
- '1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1',
2288
- '2b240303020801010d': 'brainpoolP512r1',
2289
- '2B240303020801010D': 'brainpoolP512r1'
2290
- },
2291
-
2292
- /** KDF parameters flags
2293
- * Non-standard extensions (for now) to allow email forwarding
2294
- * @enum {Integer}
2295
- * @readonly
2296
- */
2297
- kdfFlags: {
2298
- /** Specify fingerprint to use instead of the recipient's */
2299
- replace_fingerprint: 0x01,
2300
- /** Specify custom parameters to use in the KDF digest computation */
2301
- replace_kdf_params: 0x02
2302
- },
2303
-
2304
- /** A string to key specifier type
2305
- * @enum {Integer}
2306
- * @readonly
2307
- */
2308
- s2k: {
2309
- simple: 0,
2310
- salted: 1,
2311
- iterated: 3,
2312
- argon2: 4,
2313
- gnu: 101
2314
- },
2315
-
2316
- /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.1|RFC4880bis-04, section 9.1}
2317
- * @enum {Integer}
2318
- * @readonly
2319
- */
2320
- publicKey: {
2321
- /** RSA (Encrypt or Sign) [HAC] */
2322
- rsaEncryptSign: 1,
2323
- /** RSA (Encrypt only) [HAC] */
2324
- rsaEncrypt: 2,
2325
- /** RSA (Sign only) [HAC] */
2326
- rsaSign: 3,
2327
- /** Elgamal (Encrypt only) [ELGAMAL] [HAC] */
2328
- elgamal: 16,
2329
- /** DSA (Sign only) [FIPS186] [HAC] */
2330
- dsa: 17,
2331
- /** ECDH (Encrypt only) [RFC6637] */
2332
- ecdh: 18,
2333
- /** ECDSA (Sign only) [RFC6637] */
2334
- ecdsa: 19,
2335
- /** EdDSA (Sign only)
2336
- * [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */
2337
- eddsa: 22,
2338
- /** Reserved for AEDH */
2339
- aedh: 23,
2340
- /** Reserved for AEDSA */
2341
- aedsa: 24,
2342
- /** Symmetric authenticated encryption algorithms */
2343
- aead: 100,
2344
- /** Authentication using CMAC */
2345
- hmac: 101
2346
- },
2347
-
2348
- /** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
2349
- * @enum {Integer}
2350
- * @readonly
2351
- */
2352
- symmetric: {
2353
- plaintext: 0,
2354
- /** Not implemented! */
2355
- idea: 1,
2356
- tripledes: 2,
2357
- cast5: 3,
2358
- blowfish: 4,
2359
- aes128: 7,
2360
- aes192: 8,
2361
- aes256: 9,
2362
- twofish: 10
2363
- },
2364
-
2365
- /** {@link https://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
2366
- * @enum {Integer}
2367
- * @readonly
2368
- */
2369
- compression: {
2370
- uncompressed: 0,
2371
- /** RFC1951 */
2372
- zip: 1,
2373
- /** RFC1950 */
2374
- zlib: 2,
2375
- bzip2: 3
2376
- },
2377
-
2378
- /** {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
2379
- * @enum {Integer}
2380
- * @readonly
2381
- */
2382
- hash: {
2383
- md5: 1,
2384
- sha1: 2,
2385
- ripemd: 3,
2386
- sha256: 8,
2387
- sha384: 9,
2388
- sha512: 10,
2389
- sha224: 11
2390
- },
2391
-
2392
- /** A list of hash names as accepted by webCrypto functions.
2393
- * {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest|Parameters, algo}
2394
- * @enum {String}
2395
- */
2396
- webHash: {
2397
- 'SHA-1': 2,
2398
- 'SHA-256': 8,
2399
- 'SHA-384': 9,
2400
- 'SHA-512': 10
2401
- },
2402
-
2403
- /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.6|RFC4880bis-04, section 9.6}
2404
- * @enum {Integer}
2405
- * @readonly
2406
- */
2407
- aead: {
2408
- eax: 1,
2409
- ocb: 2,
2410
- experimentalGCM: 100 // Private algorithm
2411
- },
2412
-
2413
- /** A list of packet types and numeric tags associated with them.
2414
- * @enum {Integer}
2415
- * @readonly
2416
- */
2417
- packet: {
2418
- publicKeyEncryptedSessionKey: 1,
2419
- signature: 2,
2420
- symEncryptedSessionKey: 3,
2421
- onePassSignature: 4,
2422
- secretKey: 5,
2423
- publicKey: 6,
2424
- secretSubkey: 7,
2425
- compressedData: 8,
2426
- symmetricallyEncryptedData: 9,
2427
- marker: 10,
2428
- literalData: 11,
2429
- trust: 12,
2430
- userID: 13,
2431
- publicSubkey: 14,
2432
- userAttribute: 17,
2433
- symEncryptedIntegrityProtectedData: 18,
2434
- modificationDetectionCode: 19,
2435
- aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
2436
- },
2437
-
2438
- /** Data types in the literal packet
2439
- * @enum {Integer}
2440
- * @readonly
2441
- */
2442
- literal: {
2443
- /** Binary data 'b' */
2444
- binary: 'b'.charCodeAt(),
2445
- /** Text data 't' */
2446
- text: 't'.charCodeAt(),
2447
- /** Utf8 data 'u' */
2448
- utf8: 'u'.charCodeAt(),
2449
- /** MIME message body part 'm' */
2450
- mime: 'm'.charCodeAt()
2451
- },
2452
-
2453
-
2454
- /** One pass signature packet type
2455
- * @enum {Integer}
2456
- * @readonly
2457
- */
2458
- signature: {
2459
- /** 0x00: Signature of a binary document. */
2460
- binary: 0,
2461
- /** 0x01: Signature of a canonical text document.
2462
- *
2463
- * Canonicalyzing the document by converting line endings. */
2464
- text: 1,
2465
- /** 0x02: Standalone signature.
2466
- *
2467
- * This signature is a signature of only its own subpacket contents.
2468
- * It is calculated identically to a signature over a zero-lengh
2469
- * binary document. Note that it doesn't make sense to have a V3
2470
- * standalone signature. */
2471
- standalone: 2,
2472
- /** 0x10: Generic certification of a User ID and Public-Key packet.
2473
- *
2474
- * The issuer of this certification does not make any particular
2475
- * assertion as to how well the certifier has checked that the owner
2476
- * of the key is in fact the person described by the User ID. */
2477
- certGeneric: 16,
2478
- /** 0x11: Persona certification of a User ID and Public-Key packet.
2479
- *
2480
- * The issuer of this certification has not done any verification of
2481
- * the claim that the owner of this key is the User ID specified. */
2482
- certPersona: 17,
2483
- /** 0x12: Casual certification of a User ID and Public-Key packet.
2484
- *
2485
- * The issuer of this certification has done some casual
2486
- * verification of the claim of identity. */
2487
- certCasual: 18,
2488
- /** 0x13: Positive certification of a User ID and Public-Key packet.
2489
- *
2490
- * The issuer of this certification has done substantial
2491
- * verification of the claim of identity.
2492
- *
2493
- * Most OpenPGP implementations make their "key signatures" as 0x10
2494
- * certifications. Some implementations can issue 0x11-0x13
2495
- * certifications, but few differentiate between the types. */
2496
- certPositive: 19,
2497
- /** 0x30: Certification revocation signature
2498
- *
2499
- * This signature revokes an earlier User ID certification signature
2500
- * (signature class 0x10 through 0x13) or direct-key signature
2501
- * (0x1F). It should be issued by the same key that issued the
2502
- * revoked signature or an authorized revocation key. The signature
2503
- * is computed over the same data as the certificate that it
2504
- * revokes, and should have a later creation date than that
2505
- * certificate. */
2506
- certRevocation: 48,
2507
- /** 0x18: Subkey Binding Signature
2508
- *
2509
- * This signature is a statement by the top-level signing key that
2510
- * indicates that it owns the subkey. This signature is calculated
2511
- * directly on the primary key and subkey, and not on any User ID or
2512
- * other packets. A signature that binds a signing subkey MUST have
2513
- * an Embedded Signature subpacket in this binding signature that
2514
- * contains a 0x19 signature made by the signing subkey on the
2515
- * primary key and subkey. */
2516
- subkeyBinding: 24,
2517
- /** 0x19: Primary Key Binding Signature
2518
- *
2519
- * This signature is a statement by a signing subkey, indicating
2520
- * that it is owned by the primary key and subkey. This signature
2521
- * is calculated the same way as a 0x18 signature: directly on the
2522
- * primary key and subkey, and not on any User ID or other packets.
2523
- *
2524
- * When a signature is made over a key, the hash data starts with the
2525
- * octet 0x99, followed by a two-octet length of the key, and then body
2526
- * of the key packet. (Note that this is an old-style packet header for
2527
- * a key packet with two-octet length.) A subkey binding signature
2528
- * (type 0x18) or primary key binding signature (type 0x19) then hashes
2529
- * the subkey using the same format as the main key (also using 0x99 as
2530
- * the first octet). */
2531
- keyBinding: 25,
2532
- /** 0x1F: Signature directly on a key
2533
- *
2534
- * This signature is calculated directly on a key. It binds the
2535
- * information in the Signature subpackets to the key, and is
2536
- * appropriate to be used for subpackets that provide information
2537
- * about the key, such as the Revocation Key subpacket. It is also
2538
- * appropriate for statements that non-self certifiers want to make
2539
- * about the key itself, rather than the binding between a key and a
2540
- * name. */
2541
- key: 31,
2542
- /** 0x20: Key revocation signature
2543
- *
2544
- * The signature is calculated directly on the key being revoked. A
2545
- * revoked key is not to be used. Only revocation signatures by the
2546
- * key being revoked, or by an authorized revocation key, should be
2547
- * considered valid revocation signatures.a */
2548
- keyRevocation: 32,
2549
- /** 0x28: Subkey revocation signature
2550
- *
2551
- * The signature is calculated directly on the subkey being revoked.
2552
- * A revoked subkey is not to be used. Only revocation signatures
2553
- * by the top-level signature key that is bound to this subkey, or
2554
- * by an authorized revocation key, should be considered valid
2555
- * revocation signatures.
2556
- *
2557
- * Key revocation signatures (types 0x20 and 0x28)
2558
- * hash only the key being revoked. */
2559
- subkeyRevocation: 40,
2560
- /** 0x40: Timestamp signature.
2561
- * This signature is only meaningful for the timestamp contained in
2562
- * it. */
2563
- timestamp: 64,
2564
- /** 0x50: Third-Party Confirmation signature.
2565
- *
2566
- * This signature is a signature over some other OpenPGP Signature
2567
- * packet(s). It is analogous to a notary seal on the signed data.
2568
- * A third-party signature SHOULD include Signature Target
2569
- * subpacket(s) to give easy identification. Note that we really do
2570
- * mean SHOULD. There are plausible uses for this (such as a blind
2571
- * party that only sees the signature, not the key or source
2572
- * document) that cannot include a target subpacket. */
2573
- thirdParty: 80
2574
- },
2575
-
2576
- /** Signature subpacket type
2577
- * @enum {Integer}
2578
- * @readonly
2579
- */
2580
- signatureSubpacket: {
2581
- signatureCreationTime: 2,
2582
- signatureExpirationTime: 3,
2583
- exportableCertification: 4,
2584
- trustSignature: 5,
2585
- regularExpression: 6,
2586
- revocable: 7,
2587
- keyExpirationTime: 9,
2588
- placeholderBackwardsCompatibility: 10,
2589
- preferredSymmetricAlgorithms: 11,
2590
- revocationKey: 12,
2591
- issuer: 16,
2592
- notationData: 20,
2593
- preferredHashAlgorithms: 21,
2594
- preferredCompressionAlgorithms: 22,
2595
- keyServerPreferences: 23,
2596
- preferredKeyServer: 24,
2597
- primaryUserID: 25,
2598
- policyURI: 26,
2599
- keyFlags: 27,
2600
- signersUserID: 28,
2601
- reasonForRevocation: 29,
2602
- features: 30,
2603
- signatureTarget: 31,
2604
- embeddedSignature: 32,
2605
- issuerFingerprint: 33,
2606
- preferredAEADAlgorithms: 34
2607
- },
2608
-
2609
- /** Key flags
2610
- * @enum {Integer}
2611
- * @readonly
2612
- */
2613
- keyFlags: {
2614
- /** 0x01 - This key may be used to certify other keys. */
2615
- certifyKeys: 1,
2616
- /** 0x02 - This key may be used to sign data. */
2617
- signData: 2,
2618
- /** 0x04 - This key may be used to encrypt communications. */
2619
- encryptCommunication: 4,
2620
- /** 0x08 - This key may be used to encrypt storage. */
2621
- encryptStorage: 8,
2622
- /** 0x10 - The private component of this key may have been split
2623
- * by a secret-sharing mechanism. */
2624
- splitPrivateKey: 16,
2625
- /** 0x20 - This key may be used for authentication. */
2626
- authentication: 32,
2627
- /** This key may be used for forwarded communications */
2628
- forwardedCommunication: 64,
2629
- /** 0x80 - The private component of this key may be in the
2630
- * possession of more than one person. */
2631
- sharedPrivateKey: 128
2632
- },
2633
-
2634
- /** Armor type
2635
- * @enum {Integer}
2636
- * @readonly
2637
- */
2638
- armor: {
2639
- multipartSection: 0,
2640
- multipartLast: 1,
2641
- signed: 2,
2642
- message: 3,
2643
- publicKey: 4,
2644
- privateKey: 5,
2645
- signature: 6
2646
- },
2647
-
2648
- /** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
2649
- * @enum {Integer}
2650
- * @readonly
2651
- */
2652
- reasonForRevocation: {
2653
- /** No reason specified (key revocations or cert revocations) */
2654
- noReason: 0,
2655
- /** Key is superseded (key revocations) */
2656
- keySuperseded: 1,
2657
- /** Key material has been compromised (key revocations) */
2658
- keyCompromised: 2,
2659
- /** Key is retired and no longer used (key revocations) */
2660
- keyRetired: 3,
2661
- /** User ID information is no longer valid (cert revocations) */
2662
- userIDInvalid: 32
2663
- },
2664
-
2665
- /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
2666
- * @enum {Integer}
2667
- * @readonly
2668
- */
2669
- features: {
2670
- /** 0x01 - Modification Detection (packets 18 and 19) */
2671
- modificationDetection: 1,
2672
- /** 0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
2673
- * Symmetric-Key Encrypted Session Key Packets (packet 3) */
2674
- aead: 2,
2675
- /** 0x04 - Version 5 Public-Key Packet format and corresponding new
2676
- * fingerprint format */
2677
- v5Keys: 4
2678
- },
2679
-
2680
- /**
2681
- * Asserts validity of given value and converts from string/integer to integer.
2682
- * @param {Object} type target enum type
2683
- * @param {String|Integer} e value to check and/or convert
2684
- * @returns {Integer} enum value if it exists
2685
- * @throws {Error} if the value is invalid
2686
- */
2687
- write: function(type, e) {
2688
- if (typeof e === 'number') {
2689
- e = this.read(type, e);
2690
- }
2691
-
2692
- if (type[e] !== undefined) {
2693
- return type[e];
2694
- }
2695
-
2696
- throw new Error('Invalid enum value.');
2697
- },
2698
-
2699
- /**
2700
- * Converts enum integer value to the corresponding string, if it exists.
2701
- * @param {Object} type target enum type
2702
- * @param {Integer} e value to convert
2703
- * @returns {String} name of enum value if it exists
2704
- * @throws {Error} if the value is invalid
2705
- */
2706
- read: function(type, e) {
2707
- if (!type[byValue]) {
2708
- type[byValue] = [];
2709
- Object.entries(type).forEach(([key, value]) => {
2710
- type[byValue][value] = key;
2711
- });
2712
- }
2713
-
2714
- if (type[byValue][e] !== undefined) {
2715
- return type[byValue][e];
2716
- }
2717
-
2718
- throw new Error('Invalid enum value.');
2719
- }
2720
- };
2721
-
2722
2743
  // GPG4Browsers - An OpenPGP implementation in javascript
2723
2744
 
2724
2745
  var config = {
@@ -2935,7 +2956,7 @@ var config = {
2935
2956
  * @memberof module:config
2936
2957
  * @property {String} versionString A version string to be included in armored messages
2937
2958
  */
2938
- versionString: 'OpenPGP.js 5.9.1-1',
2959
+ versionString: 'OpenPGP.js 5.11.0',
2939
2960
  /**
2940
2961
  * @memberof module:config
2941
2962
  * @property {String} commentString A comment string to be included in armored messages
@@ -2986,7 +3007,14 @@ var config = {
2986
3007
  * @memberof module:config
2987
3008
  * @property {Set<String>} rejectCurves {@link module:enums.curve}
2988
3009
  */
2989
- rejectCurves: new Set([enums.curve.secp256k1])
3010
+ rejectCurves: new Set([enums.curve.secp256k1]),
3011
+ /**
3012
+ * Whether to validate generated EdDSA signatures before returning them, to ensure they are not faulty signatures.
3013
+ * This check will make signing 2-3 times slower.
3014
+ * Faulty signatures may be generated (in principle) if random bitflips occur at specific points in the signature
3015
+ * computation, and could be used to recover the signer's secret key given a second signature over the same data.
3016
+ */
3017
+ checkEdDSAFaultySignatures: true
2990
3018
  };
2991
3019
 
2992
3020
  /**
@@ -3427,6 +3455,7 @@ class KeyID {
3427
3455
  */
3428
3456
  read(bytes) {
3429
3457
  this.bytes = util.uint8ArrayToString(bytes.subarray(0, 8));
3458
+ return this.bytes.length;
3430
3459
  }
3431
3460
 
3432
3461
  /**
@@ -9983,7 +10012,7 @@ async function encrypt(algo, key, plaintext, iv, config) {
9983
10012
  if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
9984
10013
  return nodeEncrypt(algo, key, plaintext, iv);
9985
10014
  }
9986
- if (algoName.substr(0, 3) === 'aes') {
10015
+ if (util.isAES(algo)) {
9987
10016
  return aesEncrypt(algo, key, plaintext, iv, config);
9988
10017
  }
9989
10018
 
@@ -10026,7 +10055,7 @@ async function decrypt(algo, key, ciphertext, iv) {
10026
10055
  if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
10027
10056
  return nodeDecrypt(algo, key, ciphertext, iv);
10028
10057
  }
10029
- if (algoName.substr(0, 3) === 'aes') {
10058
+ if (util.isAES(algo)) {
10030
10059
  return aesDecrypt(algo, key, ciphertext, iv);
10031
10060
  }
10032
10061
 
@@ -10045,7 +10074,7 @@ async function decrypt(algo, key, ciphertext, iv) {
10045
10074
  let j = 0;
10046
10075
  while (chunk ? ct.length >= block_size : ct.length) {
10047
10076
  const decblock = cipherfn.encrypt(blockp);
10048
- blockp = ct;
10077
+ blockp = ct.subarray(0, block_size);
10049
10078
  for (i = 0; i < block_size; i++) {
10050
10079
  plaintext[j++] = blockp[i] ^ decblock[i];
10051
10080
  }
@@ -10971,42 +11000,42 @@ async function GCM(cipher, key) {
10971
11000
  throw new Error('GCM mode supports only AES cipher');
10972
11001
  }
10973
11002
 
10974
- if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
10975
- const _key = await webCrypto$4.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
10976
-
11003
+ if (util.getNodeCrypto()) { // Node crypto library
10977
11004
  return {
10978
11005
  encrypt: async function(pt, iv, adata = new Uint8Array()) {
10979
- if (!pt.length) { // iOS does not support GCM-en/decrypting empty messages
10980
- return AES_GCM.encrypt(pt, key, iv, adata);
10981
- }
10982
- const ct = await webCrypto$4.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, pt);
11006
+ const en = new nodeCrypto$4.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
11007
+ en.setAAD(adata);
11008
+ const ct = Buffer$3.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
10983
11009
  return new Uint8Array(ct);
10984
11010
  },
10985
11011
 
10986
11012
  decrypt: async function(ct, iv, adata = new Uint8Array()) {
10987
- if (ct.length === tagLength$2) { // iOS does not support GCM-en/decrypting empty messages
10988
- return AES_GCM.decrypt(ct, key, iv, adata);
10989
- }
10990
- const pt = await webCrypto$4.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, ct);
11013
+ const de = new nodeCrypto$4.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
11014
+ de.setAAD(adata);
11015
+ de.setAuthTag(ct.slice(ct.length - tagLength$2, ct.length)); // read auth tag at end of ciphertext
11016
+ const pt = Buffer$3.concat([de.update(ct.slice(0, ct.length - tagLength$2)), de.final()]);
10991
11017
  return new Uint8Array(pt);
10992
11018
  }
10993
11019
  };
10994
11020
  }
10995
11021
 
10996
- if (util.getNodeCrypto()) { // Node crypto library
11022
+ if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
11023
+ const _key = await webCrypto$4.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
11024
+
10997
11025
  return {
10998
11026
  encrypt: async function(pt, iv, adata = new Uint8Array()) {
10999
- const en = new nodeCrypto$4.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
11000
- en.setAAD(adata);
11001
- const ct = Buffer$3.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
11027
+ if (!pt.length) { // iOS does not support GCM-en/decrypting empty messages
11028
+ return AES_GCM.encrypt(pt, key, iv, adata);
11029
+ }
11030
+ const ct = await webCrypto$4.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, pt);
11002
11031
  return new Uint8Array(ct);
11003
11032
  },
11004
11033
 
11005
11034
  decrypt: async function(ct, iv, adata = new Uint8Array()) {
11006
- const de = new nodeCrypto$4.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
11007
- de.setAAD(adata);
11008
- de.setAuthTag(ct.slice(ct.length - tagLength$2, ct.length)); // read auth tag at end of ciphertext
11009
- const pt = Buffer$3.concat([de.update(ct.slice(0, ct.length - tagLength$2)), de.final()]);
11035
+ if (ct.length === tagLength$2) { // iOS does not support GCM-en/decrypting empty messages
11036
+ return AES_GCM.decrypt(ct, key, iv, adata);
11037
+ }
11038
+ const pt = await webCrypto$4.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, ct);
11010
11039
  return new Uint8Array(pt);
11011
11040
  }
11012
11041
  };
@@ -12009,11 +12038,11 @@ const nodeCrypto$5 = util.getNodeCrypto();
12009
12038
  */
12010
12039
  function getRandomBytes(length) {
12011
12040
  const buf = new Uint8Array(length);
12012
- if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
12013
- crypto.getRandomValues(buf);
12014
- } else if (nodeCrypto$5) {
12041
+ if (nodeCrypto$5) {
12015
12042
  const bytes = nodeCrypto$5.randomBytes(buf.length);
12016
12043
  buf.set(bytes);
12044
+ } else if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
12045
+ crypto.getRandomValues(buf);
12017
12046
  } else {
12018
12047
  throw new Error('No secure random number generator available.');
12019
12048
  }
@@ -13573,7 +13602,7 @@ const curves = {
13573
13602
  },
13574
13603
  ed25519: {
13575
13604
  oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01],
13576
- keyType: enums.publicKey.eddsa,
13605
+ keyType: enums.publicKey.eddsaLegacy,
13577
13606
  hash: enums.hash.sha512,
13578
13607
  node: false, // nodeCurves.ed25519 TODO
13579
13608
  payloadSize: 32
@@ -13612,7 +13641,7 @@ const curves = {
13612
13641
  }
13613
13642
  };
13614
13643
 
13615
- class Curve {
13644
+ class CurveWithOID {
13616
13645
  constructor(oidOrName, params) {
13617
13646
  try {
13618
13647
  if (util.isArray(oidOrName) ||
@@ -13689,7 +13718,7 @@ class Curve {
13689
13718
  async function generate$1(curve) {
13690
13719
  const BigInteger = await util.getBigInteger();
13691
13720
 
13692
- curve = new Curve(curve);
13721
+ curve = new CurveWithOID(curve);
13693
13722
  const keyPair = await curve.genKeyPair();
13694
13723
  const Q = new BigInteger(keyPair.publicKey).toUint8Array();
13695
13724
  const secret = new BigInteger(keyPair.privateKey).toUint8Array('be', curve.payloadSize);
@@ -13878,7 +13907,7 @@ const nodeCrypto$8 = util.getNodeCrypto();
13878
13907
  * @async
13879
13908
  */
13880
13909
  async function sign$1(oid, hashAlgo, message, publicKey, privateKey, hashed) {
13881
- const curve = new Curve(oid);
13910
+ const curve = new CurveWithOID(oid);
13882
13911
  if (message && !util.isStream(message)) {
13883
13912
  const keyPair = { publicKey, privateKey };
13884
13913
  switch (curve.type) {
@@ -13923,7 +13952,7 @@ async function sign$1(oid, hashAlgo, message, publicKey, privateKey, hashed) {
13923
13952
  * @async
13924
13953
  */
13925
13954
  async function verify$1(oid, hashAlgo, signature, message, publicKey, hashed) {
13926
- const curve = new Curve(oid);
13955
+ const curve = new CurveWithOID(oid);
13927
13956
  if (message && !util.isStream(message)) {
13928
13957
  switch (curve.type) {
13929
13958
  case 'web':
@@ -13957,7 +13986,7 @@ async function verify$1(oid, hashAlgo, signature, message, publicKey, hashed) {
13957
13986
  * @async
13958
13987
  */
13959
13988
  async function validateParams$2(oid, Q, d) {
13960
- const curve = new Curve(oid);
13989
+ const curve = new CurveWithOID(oid);
13961
13990
  // Reject curves x25519 and ed25519
13962
13991
  if (curve.keyType !== enums.publicKey.ecdsa) {
13963
13992
  return false;
@@ -14160,7 +14189,7 @@ var ecdsa = /*#__PURE__*/Object.freeze({
14160
14189
  naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
14161
14190
 
14162
14191
  /**
14163
- * Sign a message using the provided key
14192
+ * Sign a message using the provided legacy EdDSA key
14164
14193
  * @param {module:type/oid} oid - Elliptic curve object identifier
14165
14194
  * @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
14166
14195
  * @param {Uint8Array} message - Message to sign
@@ -14176,10 +14205,24 @@ naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
14176
14205
  async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
14177
14206
  if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
14178
14207
  // see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
14179
- throw new Error('Hash algorithm too weak: sha256 or stronger is required for EdDSA.');
14208
+ throw new Error('Hash algorithm too weak for EdDSA.');
14180
14209
  }
14181
14210
  const secretKey = util.concatUint8Array([privateKey, publicKey.subarray(1)]);
14182
14211
  const signature = naclFastLight.sign.detached(hashed, secretKey);
14212
+ if (config.checkEdDSAFaultySignatures && !naclFastLight.sign.detached.verify(hashed, signature, publicKey.subarray(1))) {
14213
+ /**
14214
+ * Detect faulty signatures caused by random bitflips during `crypto_sign` which could lead to private key extraction
14215
+ * if two signatures over the same message are obtained.
14216
+ * See https://github.com/jedisct1/libsodium/issues/170.
14217
+ * If the input data is not deterministic, e.g. thanks to the random salt in v6 OpenPGP signatures (not yet implemented),
14218
+ * then the generated signature is always safe, and the verification step is skipped.
14219
+ * Otherwise, we need to verify the generated to ensure that no bitflip occured:
14220
+ * - in M between the computation of `r` and `h`.
14221
+ * - in the public key before computing `h`
14222
+ * 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.
14223
+ */
14224
+ throw new Error('Transient signing failure');
14225
+ }
14183
14226
  // EdDSA signature params are returned in little-endian format
14184
14227
  return {
14185
14228
  r: signature.subarray(0, 32),
@@ -14188,7 +14231,7 @@ async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
14188
14231
  }
14189
14232
 
14190
14233
  /**
14191
- * Verifies if a signature is valid for a message
14234
+ * Verifies if a legacy EdDSA signature is valid for a message
14192
14235
  * @param {module:type/oid} oid - Elliptic curve object identifier
14193
14236
  * @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
14194
14237
  * @param {{r: Uint8Array,
@@ -14200,11 +14243,14 @@ async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
14200
14243
  * @async
14201
14244
  */
14202
14245
  async function verify$2(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
14246
+ if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
14247
+ throw new Error('Hash algorithm too weak for EdDSA.');
14248
+ }
14203
14249
  const signature = util.concatUint8Array([r, s]);
14204
14250
  return naclFastLight.sign.detached.verify(hashed, signature, publicKey.subarray(1));
14205
14251
  }
14206
14252
  /**
14207
- * Validate EdDSA parameters
14253
+ * Validate legacy EdDSA parameters
14208
14254
  * @param {module:type/oid} oid - Elliptic curve object identifier
14209
14255
  * @param {Uint8Array} Q - EdDSA public point
14210
14256
  * @param {Uint8Array} k - EdDSA secret seed
@@ -14224,9 +14270,10 @@ async function validateParams$3(oid, Q, k) {
14224
14270
  const { publicKey } = naclFastLight.sign.keyPair.fromSeed(k);
14225
14271
  const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
14226
14272
  return util.equalsUint8Array(Q, dG);
14273
+
14227
14274
  }
14228
14275
 
14229
- var eddsa = /*#__PURE__*/Object.freeze({
14276
+ var eddsa_legacy = /*#__PURE__*/Object.freeze({
14230
14277
  __proto__: null,
14231
14278
  sign: sign$2,
14232
14279
  verify: verify$2,
@@ -14235,6 +14282,139 @@ var eddsa = /*#__PURE__*/Object.freeze({
14235
14282
 
14236
14283
  // OpenPGP.js - An OpenPGP implementation in javascript
14237
14284
 
14285
+ naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
14286
+
14287
+ /**
14288
+ * Generate (non-legacy) EdDSA key
14289
+ * @param {module:enums.publicKey} algo - Algorithm identifier
14290
+ * @returns {Promise<{ A: Uint8Array, seed: Uint8Array }>}
14291
+ */
14292
+ async function generate$2(algo) {
14293
+ switch (algo) {
14294
+ case enums.publicKey.ed25519: {
14295
+ const seed = getRandomBytes(32);
14296
+ const { publicKey: A } = naclFastLight.sign.keyPair.fromSeed(seed);
14297
+ return { A, seed };
14298
+ }
14299
+ default:
14300
+ throw new Error('Unsupported EdDSA algorithm');
14301
+ }
14302
+ }
14303
+
14304
+ /**
14305
+ * Sign a message using the provided key
14306
+ * @param {module:enums.publicKey} algo - Algorithm identifier
14307
+ * @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
14308
+ * @param {Uint8Array} message - Message to sign
14309
+ * @param {Uint8Array} publicKey - Public key
14310
+ * @param {Uint8Array} privateKey - Private key used to sign the message
14311
+ * @param {Uint8Array} hashed - The hashed message
14312
+ * @returns {Promise<{
14313
+ * RS: Uint8Array
14314
+ * }>} Signature of the message
14315
+ * @async
14316
+ */
14317
+ async function sign$3(algo, hashAlgo, message, publicKey, privateKey, hashed) {
14318
+ if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo$1(algo))) {
14319
+ throw new Error('Hash algorithm too weak for EdDSA.');
14320
+ }
14321
+ switch (algo) {
14322
+ case enums.publicKey.ed25519: {
14323
+ const secretKey = util.concatUint8Array([privateKey, publicKey]);
14324
+ const signature = naclFastLight.sign.detached(hashed, secretKey);
14325
+ if (config.checkEdDSAFaultySignatures && !naclFastLight.sign.detached.verify(hashed, signature, publicKey)) {
14326
+ /**
14327
+ * Detect faulty signatures caused by random bitflips during `crypto_sign` which could lead to private key extraction
14328
+ * if two signatures over the same message are obtained.
14329
+ * See https://github.com/jedisct1/libsodium/issues/170.
14330
+ * If the input data is not deterministic, e.g. thanks to the random salt in v6 OpenPGP signatures (not yet implemented),
14331
+ * then the generated signature is always safe, and the verification step is skipped.
14332
+ * Otherwise, we need to verify the generated to ensure that no bitflip occured:
14333
+ * - in M between the computation of `r` and `h`.
14334
+ * - in the public key before computing `h`
14335
+ * 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.
14336
+ */
14337
+ throw new Error('Transient signing failure');
14338
+ }
14339
+ return { RS: signature };
14340
+ }
14341
+ case enums.publicKey.ed448:
14342
+ default:
14343
+ throw new Error('Unsupported EdDSA algorithm');
14344
+ }
14345
+
14346
+ }
14347
+
14348
+ /**
14349
+ * Verifies if a signature is valid for a message
14350
+ * @param {module:enums.publicKey} algo - Algorithm identifier
14351
+ * @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
14352
+ * @param {{ RS: Uint8Array }} signature Signature to verify the message
14353
+ * @param {Uint8Array} m - Message to verify
14354
+ * @param {Uint8Array} publicKey - Public key used to verify the message
14355
+ * @param {Uint8Array} hashed - The hashed message
14356
+ * @returns {Boolean}
14357
+ * @async
14358
+ */
14359
+ async function verify$3(algo, hashAlgo, { RS }, m, publicKey, hashed) {
14360
+ if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(getPreferredHashAlgo$1(algo))) {
14361
+ throw new Error('Hash algorithm too weak for EdDSA.');
14362
+ }
14363
+ switch (algo) {
14364
+ case enums.publicKey.ed25519: {
14365
+ return naclFastLight.sign.detached.verify(hashed, RS, publicKey);
14366
+ }
14367
+ case enums.publicKey.ed448:
14368
+ default:
14369
+ throw new Error('Unsupported EdDSA algorithm');
14370
+ }
14371
+ }
14372
+ /**
14373
+ * Validate (non-legacy) EdDSA parameters
14374
+ * @param {module:enums.publicKey} algo - Algorithm identifier
14375
+ * @param {Uint8Array} A - EdDSA public point
14376
+ * @param {Uint8Array} seed - EdDSA secret seed
14377
+ * @param {Uint8Array} oid - (legacy only) EdDSA OID
14378
+ * @returns {Promise<Boolean>} Whether params are valid.
14379
+ * @async
14380
+ */
14381
+ async function validateParams$4(algo, A, seed) {
14382
+ switch (algo) {
14383
+ case enums.publicKey.ed25519: {
14384
+ /**
14385
+ * Derive public point A' from private key
14386
+ * and expect A == A'
14387
+ */
14388
+ const { publicKey } = naclFastLight.sign.keyPair.fromSeed(seed);
14389
+ return util.equalsUint8Array(A, publicKey);
14390
+ }
14391
+
14392
+ case enums.publicKey.ed448: // unsupported
14393
+ default:
14394
+ return false;
14395
+ }
14396
+ }
14397
+
14398
+ function getPreferredHashAlgo$1(algo) {
14399
+ switch (algo) {
14400
+ case enums.publicKey.ed25519:
14401
+ return enums.hash.sha256;
14402
+ default:
14403
+ throw new Error('Unknown EdDSA algo');
14404
+ }
14405
+ }
14406
+
14407
+ var eddsa = /*#__PURE__*/Object.freeze({
14408
+ __proto__: null,
14409
+ generate: generate$2,
14410
+ sign: sign$3,
14411
+ verify: verify$3,
14412
+ validateParams: validateParams$4,
14413
+ getPreferredHashAlgo: getPreferredHashAlgo$1
14414
+ });
14415
+
14416
+ // OpenPGP.js - An OpenPGP implementation in javascript
14417
+
14238
14418
  /**
14239
14419
  * AES key wrap
14240
14420
  * @function
@@ -14422,7 +14602,7 @@ const nodeCrypto$9 = util.getNodeCrypto();
14422
14602
  * @returns {Promise<Boolean>} Whether params are valid.
14423
14603
  * @async
14424
14604
  */
14425
- async function validateParams$4(oid, Q, d) {
14605
+ async function validateParams$5(oid, Q, d) {
14426
14606
  return validateStandardParams(enums.publicKey.ecdh, oid, Q, d);
14427
14607
  }
14428
14608
 
@@ -14464,7 +14644,7 @@ async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTraili
14464
14644
  /**
14465
14645
  * Generate ECDHE ephemeral key and secret from public key
14466
14646
  *
14467
- * @param {Curve} curve - Elliptic curve object
14647
+ * @param {CurveWithOID} curve - Elliptic curve object
14468
14648
  * @param {Uint8Array} Q - Recipient public key
14469
14649
  * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
14470
14650
  * @async
@@ -14507,7 +14687,7 @@ async function genPublicEphemeralKey(curve, Q) {
14507
14687
  async function encrypt$3(oid, kdfParams, data, Q, fingerprint) {
14508
14688
  const m = encode$1(data);
14509
14689
 
14510
- const curve = new Curve(oid);
14690
+ const curve = new CurveWithOID(oid);
14511
14691
  const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
14512
14692
  const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
14513
14693
  const { keySize } = getCipher(kdfParams.cipher);
@@ -14519,7 +14699,7 @@ async function encrypt$3(oid, kdfParams, data, Q, fingerprint) {
14519
14699
  /**
14520
14700
  * Generate ECDHE secret from private key and public part of ephemeral key
14521
14701
  *
14522
- * @param {Curve} curve - Elliptic curve object
14702
+ * @param {CurveWithOID} curve - Elliptic curve object
14523
14703
  * @param {Uint8Array} V - Public part of ephemeral key
14524
14704
  * @param {Uint8Array} Q - Recipient public key
14525
14705
  * @param {Uint8Array} d - Recipient private key
@@ -14567,7 +14747,7 @@ async function genPrivateEphemeralKey(curve, V, Q, d) {
14567
14747
  * @async
14568
14748
  */
14569
14749
  async function decrypt$3(oid, kdfParams, V, C, Q, d, fingerprint) {
14570
- const curve = new Curve(oid);
14750
+ const curve = new CurveWithOID(oid);
14571
14751
  const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
14572
14752
  const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
14573
14753
  const { keySize } = getCipher(kdfParams.cipher);
@@ -14587,7 +14767,7 @@ async function decrypt$3(oid, kdfParams, V, C, Q, d, fingerprint) {
14587
14767
  /**
14588
14768
  * Generate ECDHE secret from private key and public part of ephemeral key using webCrypto
14589
14769
  *
14590
- * @param {Curve} curve - Elliptic curve object
14770
+ * @param {CurveWithOID} curve - Elliptic curve object
14591
14771
  * @param {Uint8Array} V - Public part of ephemeral key
14592
14772
  * @param {Uint8Array} Q - Recipient public key
14593
14773
  * @param {Uint8Array} d - Recipient private key
@@ -14640,7 +14820,7 @@ async function webPrivateEphemeralKey(curve, V, Q, d) {
14640
14820
  /**
14641
14821
  * Generate ECDHE ephemeral key and secret from public key using webCrypto
14642
14822
  *
14643
- * @param {Curve} curve - Elliptic curve object
14823
+ * @param {CurveWithOID} curve - Elliptic curve object
14644
14824
  * @param {Uint8Array} Q - Recipient public key
14645
14825
  * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
14646
14826
  * @async
@@ -14688,7 +14868,7 @@ async function webPublicEphemeralKey(curve, Q) {
14688
14868
  /**
14689
14869
  * Generate ECDHE secret from private key and public part of ephemeral key using indutny/elliptic
14690
14870
  *
14691
- * @param {Curve} curve - Elliptic curve object
14871
+ * @param {CurveWithOID} curve - Elliptic curve object
14692
14872
  * @param {Uint8Array} V - Public part of ephemeral key
14693
14873
  * @param {Uint8Array} d - Recipient private key
14694
14874
  * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
@@ -14708,7 +14888,7 @@ async function ellipticPrivateEphemeralKey(curve, V, d) {
14708
14888
  /**
14709
14889
  * Generate ECDHE ephemeral key and secret from public key using indutny/elliptic
14710
14890
  *
14711
- * @param {Curve} curve - Elliptic curve object
14891
+ * @param {CurveWithOID} curve - Elliptic curve object
14712
14892
  * @param {Uint8Array} Q - Recipient public key
14713
14893
  * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
14714
14894
  * @async
@@ -14728,7 +14908,7 @@ async function ellipticPublicEphemeralKey(curve, Q) {
14728
14908
  /**
14729
14909
  * Generate ECDHE secret from private key and public part of ephemeral key using nodeCrypto
14730
14910
  *
14731
- * @param {Curve} curve - Elliptic curve object
14911
+ * @param {CurveWithOID} curve - Elliptic curve object
14732
14912
  * @param {Uint8Array} V - Public part of ephemeral key
14733
14913
  * @param {Uint8Array} d - Recipient private key
14734
14914
  * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
@@ -14745,7 +14925,7 @@ async function nodePrivateEphemeralKey(curve, V, d) {
14745
14925
  /**
14746
14926
  * Generate ECDHE ephemeral key and secret from public key using nodeCrypto
14747
14927
  *
14748
- * @param {Curve} curve - Elliptic curve object
14928
+ * @param {CurveWithOID} curve - Elliptic curve object
14749
14929
  * @param {Uint8Array} Q - Recipient public key
14750
14930
  * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
14751
14931
  * @async
@@ -14760,18 +14940,202 @@ async function nodePublicEphemeralKey(curve, Q) {
14760
14940
 
14761
14941
  var ecdh = /*#__PURE__*/Object.freeze({
14762
14942
  __proto__: null,
14763
- validateParams: validateParams$4,
14943
+ validateParams: validateParams$5,
14764
14944
  encrypt: encrypt$3,
14765
14945
  decrypt: decrypt$3
14766
14946
  });
14767
14947
 
14948
+ /**
14949
+ * @fileoverview This module implements HKDF using either the WebCrypto API or Node.js' crypto API.
14950
+ * @module crypto/hkdf
14951
+ * @private
14952
+ */
14953
+
14954
+ const webCrypto$9 = util.getWebCrypto();
14955
+ const nodeCrypto$a = util.getNodeCrypto();
14956
+ const nodeSubtleCrypto = nodeCrypto$a && nodeCrypto$a.webcrypto && nodeCrypto$a.webcrypto.subtle;
14957
+
14958
+ async function HKDF(hashAlgo, inputKey, salt, info, outLen) {
14959
+ const hash = enums.read(enums.webHash, hashAlgo);
14960
+ if (!hash) throw new Error('Hash algo not supported with HKDF');
14961
+
14962
+ if (webCrypto$9 || nodeSubtleCrypto) {
14963
+ const crypto = webCrypto$9 || nodeSubtleCrypto;
14964
+ const importedKey = await crypto.importKey('raw', inputKey, 'HKDF', false, ['deriveBits']);
14965
+ const bits = await crypto.deriveBits({ name: 'HKDF', hash, salt, info }, importedKey, outLen * 8);
14966
+ return new Uint8Array(bits);
14967
+ }
14968
+
14969
+ if (nodeCrypto$a) {
14970
+ const hashAlgoName = enums.read(enums.hash, hashAlgo);
14971
+ // Node-only HKDF implementation based on https://www.rfc-editor.org/rfc/rfc5869
14972
+
14973
+ const computeHMAC = (hmacKey, hmacMessage) => nodeCrypto$a.createHmac(hashAlgoName, hmacKey).update(hmacMessage).digest();
14974
+ // Step 1: Extract
14975
+ // PRK = HMAC-Hash(salt, IKM)
14976
+ const pseudoRandomKey = computeHMAC(salt, inputKey);
14977
+
14978
+ const hashLen = pseudoRandomKey.length;
14979
+
14980
+ // Step 2: Expand
14981
+ // HKDF-Expand(PRK, info, L) -> OKM
14982
+ const n = Math.ceil(outLen / hashLen);
14983
+ const outputKeyingMaterial = new Uint8Array(n * hashLen);
14984
+
14985
+ // HMAC input buffer updated at each iteration
14986
+ const roundInput = new Uint8Array(hashLen + info.length + 1);
14987
+ // T_i and last byte are updated at each iteration, but `info` remains constant
14988
+ roundInput.set(info, hashLen);
14989
+
14990
+ for (let i = 0; i < n; i++) {
14991
+ // T(0) = empty string (zero length)
14992
+ // T(i) = HMAC-Hash(PRK, T(i-1) | info | i)
14993
+ roundInput[roundInput.length - 1] = i + 1;
14994
+ // t = T(i+1)
14995
+ const t = computeHMAC(pseudoRandomKey, i > 0 ? roundInput : roundInput.subarray(hashLen));
14996
+ roundInput.set(t, 0);
14997
+
14998
+ outputKeyingMaterial.set(t, i * hashLen);
14999
+ }
15000
+
15001
+ return outputKeyingMaterial.subarray(0, outLen);
15002
+ }
15003
+
15004
+ throw new Error('No HKDF implementation available');
15005
+ }
15006
+
15007
+ /**
15008
+ * @fileoverview Key encryption and decryption for RFC 6637 ECDH
15009
+ * @module crypto/public_key/elliptic/ecdh
15010
+ * @private
15011
+ */
15012
+
15013
+ const HKDF_INFO = {
15014
+ x25519: util.encodeUTF8('OpenPGP X25519')
15015
+ };
15016
+
15017
+ /**
15018
+ * Generate ECDH key for Montgomery curves
15019
+ * @param {module:enums.publicKey} algo - Algorithm identifier
15020
+ * @returns {Promise<{ A: Uint8Array, k: Uint8Array }>}
15021
+ */
15022
+ async function generate$3(algo) {
15023
+ switch (algo) {
15024
+ case enums.publicKey.x25519: {
15025
+ // k stays in little-endian, unlike legacy ECDH over curve25519
15026
+ const k = getRandomBytes(32);
15027
+ const { publicKey: A } = naclFastLight.box.keyPair.fromSecretKey(k);
15028
+ return { A, k };
15029
+ }
15030
+ default:
15031
+ throw new Error('Unsupported ECDH algorithm');
15032
+ }
15033
+ }
15034
+
15035
+ /**
15036
+ * Validate ECDH parameters
15037
+ * @param {module:enums.publicKey} algo - Algorithm identifier
15038
+ * @param {Uint8Array} A - ECDH public point
15039
+ * @param {Uint8Array} k - ECDH secret scalar
15040
+ * @returns {Promise<Boolean>} Whether params are valid.
15041
+ * @async
15042
+ */
15043
+ async function validateParams$6(algo, A, k) {
15044
+ switch (algo) {
15045
+ case enums.publicKey.x25519: {
15046
+ /**
15047
+ * Derive public point A' from private key
15048
+ * and expect A == A'
15049
+ */
15050
+ const { publicKey } = naclFastLight.box.keyPair.fromSecretKey(k);
15051
+ return util.equalsUint8Array(A, publicKey);
15052
+ }
15053
+
15054
+ default:
15055
+ return false;
15056
+ }
15057
+ }
15058
+
15059
+ /**
15060
+ * Wrap and encrypt a session key
15061
+ *
15062
+ * @param {module:enums.publicKey} algo - Algorithm identifier
15063
+ * @param {Uint8Array} data - session key data to be encrypted
15064
+ * @param {Uint8Array} recipientA - Recipient public key (K_B)
15065
+ * @returns {Promise<{
15066
+ * ephemeralPublicKey: Uint8Array,
15067
+ * wrappedKey: Uint8Array
15068
+ * }>} ephemeral public key (K_A) and encrypted key
15069
+ * @async
15070
+ */
15071
+ async function encrypt$4(algo, data, recipientA) {
15072
+ switch (algo) {
15073
+ case enums.publicKey.x25519: {
15074
+ const ephemeralSecretKey = getRandomBytes(32);
15075
+ const sharedSecret = naclFastLight.scalarMult(ephemeralSecretKey, recipientA);
15076
+ const { publicKey: ephemeralPublicKey } = naclFastLight.box.keyPair.fromSecretKey(ephemeralSecretKey);
15077
+ const hkdfInput = util.concatUint8Array([
15078
+ ephemeralPublicKey,
15079
+ recipientA,
15080
+ sharedSecret
15081
+ ]);
15082
+ const { keySize } = getCipher(enums.symmetric.aes128);
15083
+ const encryptionKey = await HKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
15084
+ const wrappedKey = wrap(encryptionKey, data);
15085
+ return { ephemeralPublicKey, wrappedKey };
15086
+ }
15087
+
15088
+ default:
15089
+ throw new Error('Unsupported ECDH algorithm');
15090
+ }
15091
+ }
15092
+
15093
+ /**
15094
+ * Decrypt and unwrap the session key
15095
+ *
15096
+ * @param {module:enums.publicKey} algo - Algorithm identifier
15097
+ * @param {Uint8Array} ephemeralPublicKey - (K_A)
15098
+ * @param {Uint8Array} wrappedKey,
15099
+ * @param {Uint8Array} A - Recipient public key (K_b), needed for KDF
15100
+ * @param {Uint8Array} k - Recipient secret key (b)
15101
+ * @returns {Promise<Uint8Array>} decrypted session key data
15102
+ * @async
15103
+ */
15104
+ async function decrypt$4(algo, ephemeralPublicKey, wrappedKey, A, k) {
15105
+ switch (algo) {
15106
+ case enums.publicKey.x25519: {
15107
+ const sharedSecret = naclFastLight.scalarMult(k, ephemeralPublicKey);
15108
+ const hkdfInput = util.concatUint8Array([
15109
+ ephemeralPublicKey,
15110
+ A,
15111
+ sharedSecret
15112
+ ]);
15113
+ const { keySize } = getCipher(enums.symmetric.aes128);
15114
+ const encryptionKey = await HKDF(enums.hash.sha256, hkdfInput, new Uint8Array(), HKDF_INFO.x25519, keySize);
15115
+ return unwrap(encryptionKey, wrappedKey);
15116
+ }
15117
+ default:
15118
+ throw new Error('Unsupported ECDH algorithm');
15119
+ }
15120
+ }
15121
+
15122
+ var ecdh_x = /*#__PURE__*/Object.freeze({
15123
+ __proto__: null,
15124
+ generate: generate$3,
15125
+ validateParams: validateParams$6,
15126
+ encrypt: encrypt$4,
15127
+ decrypt: decrypt$4
15128
+ });
15129
+
14768
15130
  // OpenPGP.js - An OpenPGP implementation in javascript
14769
15131
 
14770
15132
  var elliptic = /*#__PURE__*/Object.freeze({
14771
15133
  __proto__: null,
14772
- Curve: Curve,
15134
+ CurveWithOID: CurveWithOID,
14773
15135
  ecdh: ecdh,
15136
+ ecdhX: ecdh_x,
14774
15137
  ecdsa: ecdsa,
15138
+ eddsaLegacy: eddsa_legacy,
14775
15139
  eddsa: eddsa,
14776
15140
  generate: generate$1,
14777
15141
  getPreferredHashAlgo: getPreferredHashAlgo
@@ -14796,7 +15160,7 @@ var elliptic = /*#__PURE__*/Object.freeze({
14796
15160
  * @returns {Promise<{ r: Uint8Array, s: Uint8Array }>}
14797
15161
  * @async
14798
15162
  */
14799
- async function sign$3(hashAlgo, hashed, g, p, q, x) {
15163
+ async function sign$4(hashAlgo, hashed, g, p, q, x) {
14800
15164
  const BigInteger = await util.getBigInteger();
14801
15165
  const one = new BigInteger(1);
14802
15166
  p = new BigInteger(p);
@@ -14855,7 +15219,7 @@ async function sign$3(hashAlgo, hashed, g, p, q, x) {
14855
15219
  * @returns {boolean}
14856
15220
  * @async
14857
15221
  */
14858
- async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
15222
+ async function verify$4(hashAlgo, r, s, hashed, g, p, q, y) {
14859
15223
  const BigInteger = await util.getBigInteger();
14860
15224
  const zero = new BigInteger(0);
14861
15225
  r = new BigInteger(r);
@@ -14898,7 +15262,7 @@ async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
14898
15262
  * @returns {Promise<Boolean>} Whether params are valid.
14899
15263
  * @async
14900
15264
  */
14901
- async function validateParams$5(p, q, g, y, x) {
15265
+ async function validateParams$7(p, q, g, y, x) {
14902
15266
  const BigInteger = await util.getBigInteger();
14903
15267
  p = new BigInteger(p);
14904
15268
  q = new BigInteger(q);
@@ -14953,9 +15317,9 @@ async function validateParams$5(p, q, g, y, x) {
14953
15317
 
14954
15318
  var dsa = /*#__PURE__*/Object.freeze({
14955
15319
  __proto__: null,
14956
- sign: sign$3,
14957
- verify: verify$3,
14958
- validateParams: validateParams$5
15320
+ sign: sign$4,
15321
+ verify: verify$4,
15322
+ validateParams: validateParams$7
14959
15323
  });
14960
15324
 
14961
15325
  /**
@@ -15091,10 +15455,10 @@ function parseSignatureParams(algo, signature) {
15091
15455
  const s = util.readMPI(signature.subarray(read));
15092
15456
  return { r, s };
15093
15457
  }
15094
- // Algorithm-Specific Fields for EdDSA signatures:
15458
+ // Algorithm-Specific Fields for legacy EdDSA signatures:
15095
15459
  // - MPI of an EC point r.
15096
15460
  // - EdDSA value s, in MPI, in the little endian representation
15097
- case enums.publicKey.eddsa: {
15461
+ case enums.publicKey.eddsaLegacy: {
15098
15462
  // When parsing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
15099
15463
  // https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
15100
15464
  let r = util.readMPI(signature.subarray(read)); read += r.length + 2;
@@ -15103,7 +15467,12 @@ function parseSignatureParams(algo, signature) {
15103
15467
  s = util.leftPad(s, 32);
15104
15468
  return { r, s };
15105
15469
  }
15106
-
15470
+ // Algorithm-Specific Fields for Ed25519 signatures:
15471
+ // - 64 octets of the native signature
15472
+ case enums.publicKey.ed25519: {
15473
+ const RS = signature.subarray(read, read + 64); read += RS.length;
15474
+ return { RS };
15475
+ }
15107
15476
  case enums.publicKey.hmac: {
15108
15477
  const mac = new ShortByteString(); mac.read(signature.subarray(read));
15109
15478
  return { mac };
@@ -15128,7 +15497,7 @@ function parseSignatureParams(algo, signature) {
15128
15497
  * @returns {Promise<Boolean>} True if signature is valid.
15129
15498
  * @async
15130
15499
  */
15131
- async function verify$4(algo, hashAlgo, signature, publicParams, privateParams, data, hashed) {
15500
+ async function verify$5(algo, hashAlgo, signature, publicParams, privateParams, data, hashed) {
15132
15501
  switch (algo) {
15133
15502
  case enums.publicKey.rsaEncryptSign:
15134
15503
  case enums.publicKey.rsaEncrypt:
@@ -15144,16 +15513,20 @@ async function verify$4(algo, hashAlgo, signature, publicParams, privateParams,
15144
15513
  }
15145
15514
  case enums.publicKey.ecdsa: {
15146
15515
  const { oid, Q } = publicParams;
15147
- const curveSize = new publicKey.elliptic.Curve(oid).payloadSize;
15516
+ const curveSize = new publicKey.elliptic.CurveWithOID(oid).payloadSize;
15148
15517
  // padding needed for webcrypto
15149
15518
  const r = util.leftPad(signature.r, curveSize);
15150
15519
  const s = util.leftPad(signature.s, curveSize);
15151
15520
  return publicKey.elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
15152
15521
  }
15153
- case enums.publicKey.eddsa: {
15522
+ case enums.publicKey.eddsaLegacy: {
15154
15523
  const { oid, Q } = publicParams;
15155
15524
  // signature already padded on parsing
15156
- return publicKey.elliptic.eddsa.verify(oid, hashAlgo, signature, data, Q, hashed);
15525
+ return publicKey.elliptic.eddsaLegacy.verify(oid, hashAlgo, signature, data, Q, hashed);
15526
+ }
15527
+ case enums.publicKey.ed25519: {
15528
+ const { A } = publicParams;
15529
+ return publicKey.elliptic.eddsa.verify(algo, hashAlgo, signature, data, A, hashed);
15157
15530
  }
15158
15531
  case enums.publicKey.hmac: {
15159
15532
  if (!privateParams) {
@@ -15183,7 +15556,7 @@ async function verify$4(algo, hashAlgo, signature, publicParams, privateParams,
15183
15556
  * @returns {Promise<Object>} Signature Object containing named signature parameters.
15184
15557
  * @async
15185
15558
  */
15186
- async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) {
15559
+ async function sign$5(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) {
15187
15560
  if (!publicKeyParams || !privateKeyParams) {
15188
15561
  throw new Error('Missing key parameters');
15189
15562
  }
@@ -15209,10 +15582,15 @@ async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
15209
15582
  const { d } = privateKeyParams;
15210
15583
  return publicKey.elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
15211
15584
  }
15212
- case enums.publicKey.eddsa: {
15585
+ case enums.publicKey.eddsaLegacy: {
15213
15586
  const { oid, Q } = publicKeyParams;
15214
15587
  const { seed } = privateKeyParams;
15215
- return publicKey.elliptic.eddsa.sign(oid, hashAlgo, data, Q, seed, hashed);
15588
+ return publicKey.elliptic.eddsaLegacy.sign(oid, hashAlgo, data, Q, seed, hashed);
15589
+ }
15590
+ case enums.publicKey.ed25519: {
15591
+ const { A } = publicKeyParams;
15592
+ const { seed } = privateKeyParams;
15593
+ return publicKey.elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed);
15216
15594
  }
15217
15595
  case enums.publicKey.hmac: {
15218
15596
  const { cipher: algo } = publicKeyParams;
@@ -15228,34 +15606,31 @@ async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, h
15228
15606
  var signature = /*#__PURE__*/Object.freeze({
15229
15607
  __proto__: null,
15230
15608
  parseSignatureParams: parseSignatureParams,
15231
- verify: verify$4,
15232
- sign: sign$4
15609
+ verify: verify$5,
15610
+ sign: sign$5
15233
15611
  });
15234
15612
 
15235
15613
  // OpenPGP.js - An OpenPGP implementation in javascript
15236
15614
 
15237
15615
  class ECDHSymmetricKey {
15238
15616
  constructor(data) {
15239
- if (typeof data === 'undefined') {
15240
- data = new Uint8Array([]);
15241
- } else if (util.isString(data)) {
15242
- data = util.stringToUint8Array(data);
15243
- } else {
15244
- data = new Uint8Array(data);
15617
+ if (data) {
15618
+ this.data = data;
15245
15619
  }
15246
- this.data = data;
15247
15620
  }
15248
15621
 
15249
15622
  /**
15250
- * Read an ECDHSymmetricKey from an Uint8Array
15251
- * @param {Uint8Array} input - Where to read the encoded symmetric key from
15623
+ * Read an ECDHSymmetricKey from an Uint8Array:
15624
+ * - 1 octect for the length `l`
15625
+ * - `l` octects of encoded session key data
15626
+ * @param {Uint8Array} bytes
15252
15627
  * @returns {Number} Number of read bytes.
15253
15628
  */
15254
- read(input) {
15255
- if (input.length >= 1) {
15256
- const length = input[0];
15257
- if (input.length >= 1 + length) {
15258
- this.data = input.subarray(1, 1 + length);
15629
+ read(bytes) {
15630
+ if (bytes.length >= 1) {
15631
+ const length = bytes[0];
15632
+ if (bytes.length >= 1 + length) {
15633
+ this.data = bytes.subarray(1, 1 + length);
15259
15634
  return 1 + this.data.length;
15260
15635
  }
15261
15636
  }
@@ -15264,7 +15639,7 @@ class ECDHSymmetricKey {
15264
15639
 
15265
15640
  /**
15266
15641
  * Write an ECDHSymmetricKey as an Uint8Array
15267
- * @returns {Uint8Array} An array containing the value
15642
+ * @returns {Uint8Array} Serialised data
15268
15643
  */
15269
15644
  write() {
15270
15645
  return util.concatUint8Array([new Uint8Array([this.data.length]), this.data]);
@@ -15304,6 +15679,9 @@ class KDFParams {
15304
15679
  * @returns {Number} Number of read bytes.
15305
15680
  */
15306
15681
  read(input) {
15682
+ if (input.length < 4 || (input[1] !== 1 && input[1] !== VERSION_FORWARDING)) {
15683
+ throw new UnsupportedError('Cannot read KDFParams');
15684
+ }
15307
15685
  const totalBytes = input[0];
15308
15686
  this.version = input[1];
15309
15687
  this.hash = input[2];
@@ -15391,12 +15769,57 @@ const AEADEnum = type_enum(enums.aead);
15391
15769
  const SymAlgoEnum = type_enum(enums.symmetric);
15392
15770
  const HashEnum = type_enum(enums.hash);
15393
15771
 
15772
+ /**
15773
+ * Encoded symmetric key for x25519 and x448
15774
+ * The payload format varies for v3 and v6 PKESK:
15775
+ * the former includes an algorithm byte preceeding the encrypted session key.
15776
+ *
15777
+ * @module type/x25519x448_symkey
15778
+ */
15779
+
15780
+ class ECDHXSymmetricKey {
15781
+ static fromObject({ wrappedKey, algorithm }) {
15782
+ const instance = new ECDHXSymmetricKey();
15783
+ instance.wrappedKey = wrappedKey;
15784
+ instance.algorithm = algorithm;
15785
+ return instance;
15786
+ }
15787
+
15788
+ /**
15789
+ * - 1 octect for the length `l`
15790
+ * - `l` octects of encoded session key data (with optional leading algorithm byte)
15791
+ * @param {Uint8Array} bytes
15792
+ * @returns {Number} Number of read bytes.
15793
+ */
15794
+ read(bytes) {
15795
+ let read = 0;
15796
+ let followLength = bytes[read++];
15797
+ this.algorithm = followLength % 2 ? bytes[read++] : null; // session key size is always even
15798
+ followLength -= followLength % 2;
15799
+ this.wrappedKey = bytes.subarray(read, read + followLength); read += followLength;
15800
+ }
15801
+
15802
+ /**
15803
+ * Write an MontgomerySymmetricKey as an Uint8Array
15804
+ * @returns {Uint8Array} Serialised data
15805
+ */
15806
+ write() {
15807
+ return util.concatUint8Array([
15808
+ this.algorithm ?
15809
+ new Uint8Array([this.wrappedKey.length + 1, this.algorithm]) :
15810
+ new Uint8Array([this.wrappedKey.length]),
15811
+ this.wrappedKey
15812
+ ]);
15813
+ }
15814
+ }
15815
+
15394
15816
  // GPG4Browsers - An OpenPGP implementation in javascript
15395
15817
 
15396
15818
  /**
15397
15819
  * Encrypts data using specified algorithm and public key parameters.
15398
15820
  * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1} for public key algorithms.
15399
- * @param {module:enums.publicKey} algo - Public key algorithm
15821
+ * @param {module:enums.publicKey} keyAlgo - Public key algorithm
15822
+ * @param {module:enums.symmetric} symmetricAlgo - Cipher algorithm
15400
15823
  * @param {Object} publicParams - Algorithm-specific public key parameters
15401
15824
  * @param {Object} privateParams - Algorithm-specific private key parameters
15402
15825
  * @param {Uint8Array} data - Data to be encrypted
@@ -15404,8 +15827,8 @@ const HashEnum = type_enum(enums.hash);
15404
15827
  * @returns {Promise<Object>} Encrypted session key parameters.
15405
15828
  * @async
15406
15829
  */
15407
- async function publicKeyEncrypt(algo, publicParams, privateParams, data, fingerprint) {
15408
- switch (algo) {
15830
+ async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, privateParams, data, fingerprint) {
15831
+ switch (keyAlgo) {
15409
15832
  case enums.publicKey.rsaEncrypt:
15410
15833
  case enums.publicKey.rsaEncryptSign: {
15411
15834
  const { n, e } = publicParams;
@@ -15422,6 +15845,17 @@ async function publicKeyEncrypt(algo, publicParams, privateParams, data, fingerp
15422
15845
  oid, kdfParams, data, Q, fingerprint);
15423
15846
  return { V, C: new ECDHSymmetricKey(C) };
15424
15847
  }
15848
+ case enums.publicKey.x25519: {
15849
+ if (!util.isAES(symmetricAlgo)) {
15850
+ // see https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/276
15851
+ throw new Error('X25519 keys can only encrypt AES session keys');
15852
+ }
15853
+ const { A } = publicParams;
15854
+ const { ephemeralPublicKey, wrappedKey } = await publicKey.elliptic.ecdhX.encrypt(
15855
+ keyAlgo, data, A);
15856
+ const C = ECDHXSymmetricKey.fromObject({ algorithm: symmetricAlgo, wrappedKey });
15857
+ return { ephemeralPublicKey, C };
15858
+ }
15425
15859
  case enums.publicKey.aead: {
15426
15860
  if (!privateParams) {
15427
15861
  throw new Error('Cannot encrypt with symmetric key missing private parameters');
@@ -15478,6 +15912,16 @@ async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, session
15478
15912
  return publicKey.elliptic.ecdh.decrypt(
15479
15913
  oid, kdfParams, V, C.data, Q, d, fingerprint);
15480
15914
  }
15915
+ case enums.publicKey.x25519: {
15916
+ const { A } = publicKeyParams;
15917
+ const { k } = privateKeyParams;
15918
+ const { ephemeralPublicKey, C } = sessionKeyParams;
15919
+ if (!util.isAES(C.algorithm)) {
15920
+ throw new Error('AES session key expected');
15921
+ }
15922
+ return publicKey.elliptic.ecdhX.decrypt(
15923
+ algo, ephemeralPublicKey, C.wrappedKey, A, k);
15924
+ }
15481
15925
  case enums.publicKey.aead: {
15482
15926
  const { cipher: algo } = publicKeyParams;
15483
15927
  const algoValue = algo.getValue();
@@ -15529,7 +15973,7 @@ function parsePublicKeyParams(algo, bytes) {
15529
15973
  const Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
15530
15974
  return { read: read, publicParams: { oid, Q } };
15531
15975
  }
15532
- case enums.publicKey.eddsa: {
15976
+ case enums.publicKey.eddsaLegacy: {
15533
15977
  const oid = new OID(); read += oid.read(bytes);
15534
15978
  checkSupportedCurve(oid);
15535
15979
  let Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
@@ -15543,6 +15987,11 @@ function parsePublicKeyParams(algo, bytes) {
15543
15987
  const kdfParams = new KDFParams(); read += kdfParams.read(bytes.subarray(read));
15544
15988
  return { read: read, publicParams: { oid, Q, kdfParams } };
15545
15989
  }
15990
+ case enums.publicKey.ed25519:
15991
+ case enums.publicKey.x25519: {
15992
+ const A = bytes.subarray(read, read + 32); read += A.length;
15993
+ return { read, publicParams: { A } };
15994
+ }
15546
15995
  case enums.publicKey.hmac:
15547
15996
  case enums.publicKey.aead: {
15548
15997
  const algo = new SymAlgoEnum(); read += algo.read(bytes);
@@ -15581,17 +16030,25 @@ function parsePrivateKeyParams(algo, bytes, publicParams) {
15581
16030
  }
15582
16031
  case enums.publicKey.ecdsa:
15583
16032
  case enums.publicKey.ecdh: {
15584
- const curve = new Curve(publicParams.oid);
16033
+ const curve = new CurveWithOID(publicParams.oid);
15585
16034
  let d = util.readMPI(bytes.subarray(read)); read += d.length + 2;
15586
16035
  d = util.leftPad(d, curve.payloadSize);
15587
16036
  return { read, privateParams: { d } };
15588
16037
  }
15589
- case enums.publicKey.eddsa: {
15590
- const curve = new Curve(publicParams.oid);
16038
+ case enums.publicKey.eddsaLegacy: {
16039
+ const curve = new CurveWithOID(publicParams.oid);
15591
16040
  let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2;
15592
16041
  seed = util.leftPad(seed, curve.payloadSize);
15593
16042
  return { read, privateParams: { seed } };
15594
16043
  }
16044
+ case enums.publicKey.ed25519: {
16045
+ const seed = bytes.subarray(read, read + 32); read += seed.length;
16046
+ return { read, privateParams: { seed } };
16047
+ }
16048
+ case enums.publicKey.x25519: {
16049
+ const k = bytes.subarray(read, read + 32); read += k.length;
16050
+ return { read, privateParams: { k } };
16051
+ }
15595
16052
  case enums.publicKey.hmac: {
15596
16053
  const { cipher: algo } = publicParams;
15597
16054
  const keySize = hash.getHashByteLength(algo.getValue());
@@ -15643,6 +16100,16 @@ function parseEncSessionKeyParams(algo, bytes) {
15643
16100
  const C = new ECDHSymmetricKey(); C.read(bytes.subarray(read));
15644
16101
  return { V, C };
15645
16102
  }
16103
+ // Algorithm-Specific Fields for X25519 encrypted session keys:
16104
+ // - 32 octets representing an ephemeral X25519 public key.
16105
+ // - A one-octet size of the following fields.
16106
+ // - The one-octet algorithm identifier, if it was passed (in the case of a v3 PKESK packet).
16107
+ // - The encrypted session key.
16108
+ case enums.publicKey.x25519: {
16109
+ const ephemeralPublicKey = bytes.subarray(read, read + 32); read += ephemeralPublicKey.length;
16110
+ const C = new ECDHXSymmetricKey(); C.read(bytes.subarray(read));
16111
+ return { ephemeralPublicKey, C };
16112
+ }
15646
16113
  // Algorithm-Specific Fields for symmetric AEAD encryption:
15647
16114
  // - AEAD algorithm
15648
16115
  // - Starting initialization vector
@@ -15669,22 +16136,13 @@ function parseEncSessionKeyParams(algo, bytes) {
15669
16136
  * @returns {Uint8Array} The array containing the MPIs.
15670
16137
  */
15671
16138
  function serializeParams(algo, params) {
15672
- let orderedParams;
15673
- switch (algo) {
15674
- case enums.publicKey.hmac:
15675
- case enums.publicKey.aead: {
15676
- orderedParams = Object.keys(params).map(name => {
15677
- const param = params[name];
15678
- return util.isUint8Array(param) ? param : param.write();
15679
- });
15680
- break;
15681
- }
15682
- default:
15683
- orderedParams = Object.keys(params).map(name => {
15684
- const param = params[name];
15685
- return util.isUint8Array(param) ? util.uint8ArrayToMPI(param) : param.write();
15686
- });
15687
- }
16139
+ // Some algorithms do not rely on MPIs to store the binary params
16140
+ const algosWithNativeRepresentation = new Set([enums.publicKey.ed25519, enums.publicKey.x25519, enums.publicKey.aead, enums.publicKey.hmac]);
16141
+ const orderedParams = Object.keys(params).map(name => {
16142
+ const param = params[name];
16143
+ if (!util.isUint8Array(param)) return param.write();
16144
+ return algosWithNativeRepresentation.has(algo) ? param : util.uint8ArrayToMPI(param);
16145
+ });
15688
16146
  return util.concatUint8Array(orderedParams);
15689
16147
  }
15690
16148
 
@@ -15712,7 +16170,7 @@ function generateParams(algo, bits, oid, symmetric) {
15712
16170
  privateParams: { d: secret },
15713
16171
  publicParams: { oid: new OID(oid), Q }
15714
16172
  }));
15715
- case enums.publicKey.eddsa:
16173
+ case enums.publicKey.eddsaLegacy:
15716
16174
  return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
15717
16175
  privateParams: { seed: secret },
15718
16176
  publicParams: { oid: new OID(oid), Q }
@@ -15726,6 +16184,16 @@ function generateParams(algo, bits, oid, symmetric) {
15726
16184
  kdfParams: new KDFParams({ hash, cipher })
15727
16185
  }
15728
16186
  }));
16187
+ case enums.publicKey.ed25519:
16188
+ return publicKey.elliptic.eddsa.generate(algo).then(({ A, seed }) => ({
16189
+ privateParams: { seed },
16190
+ publicParams: { A }
16191
+ }));
16192
+ case enums.publicKey.x25519:
16193
+ return publicKey.elliptic.ecdhX.generate(algo).then(({ A, k }) => ({
16194
+ privateParams: { k },
16195
+ publicParams: { A }
16196
+ }));
15729
16197
  case enums.publicKey.hmac: {
15730
16198
  const symAlgo = enums.write(enums.hash, symmetric);
15731
16199
  const keyMaterial = getRandomBytes(hash.getHashByteLength(symAlgo));
@@ -15767,7 +16235,7 @@ async function createSymmetricParams(key, algo) {
15767
16235
  * @returns {Promise<Boolean>} Whether the parameters are valid.
15768
16236
  * @async
15769
16237
  */
15770
- async function validateParams$6(algo, publicParams, privateParams) {
16238
+ async function validateParams$8(algo, publicParams, privateParams) {
15771
16239
  if (!publicParams || !privateParams) {
15772
16240
  throw new Error('Missing key parameters');
15773
16241
  }
@@ -15796,10 +16264,20 @@ async function validateParams$6(algo, publicParams, privateParams) {
15796
16264
  const { d } = privateParams;
15797
16265
  return algoModule.validateParams(oid, Q, d);
15798
16266
  }
15799
- case enums.publicKey.eddsa: {
15800
- const { oid, Q } = publicParams;
16267
+ case enums.publicKey.eddsaLegacy: {
16268
+ const { Q, oid } = publicParams;
16269
+ const { seed } = privateParams;
16270
+ return publicKey.elliptic.eddsaLegacy.validateParams(oid, Q, seed);
16271
+ }
16272
+ case enums.publicKey.ed25519: {
16273
+ const { A } = publicParams;
15801
16274
  const { seed } = privateParams;
15802
- return publicKey.elliptic.eddsa.validateParams(oid, Q, seed);
16275
+ return publicKey.elliptic.eddsa.validateParams(algo, A, seed);
16276
+ }
16277
+ case enums.publicKey.x25519: {
16278
+ const { A } = publicParams;
16279
+ const { k } = privateParams;
16280
+ return publicKey.elliptic.ecdhX.validateParams(algo, A, k);
15803
16281
  }
15804
16282
  case enums.publicKey.hmac: {
15805
16283
  const { cipher: algo, digest } = publicParams;
@@ -15869,6 +16347,23 @@ function checkSupportedCurve(oid) {
15869
16347
  }
15870
16348
  }
15871
16349
 
16350
+ /**
16351
+ * Get preferred hash algo for a given elliptic algo
16352
+ * @param {module:enums.publicKey} algo - alrogithm identifier
16353
+ * @param {module:type/oid} [oid] - curve OID if needed by algo
16354
+ */
16355
+ function getPreferredCurveHashAlgo(algo, oid) {
16356
+ switch (algo) {
16357
+ case enums.publicKey.ecdsa:
16358
+ case enums.publicKey.eddsaLegacy:
16359
+ return publicKey.elliptic.getPreferredHashAlgo(oid);
16360
+ case enums.publicKey.ed25519:
16361
+ return publicKey.elliptic.eddsa.getPreferredHashAlgo(algo);
16362
+ default:
16363
+ throw new Error('Unknown elliptic signing algo');
16364
+ }
16365
+ }
16366
+
15872
16367
  var crypto$1 = /*#__PURE__*/Object.freeze({
15873
16368
  __proto__: null,
15874
16369
  publicKeyEncrypt: publicKeyEncrypt,
@@ -15878,11 +16373,12 @@ var crypto$1 = /*#__PURE__*/Object.freeze({
15878
16373
  parseEncSessionKeyParams: parseEncSessionKeyParams,
15879
16374
  serializeParams: serializeParams,
15880
16375
  generateParams: generateParams,
15881
- validateParams: validateParams$6,
16376
+ validateParams: validateParams$8,
15882
16377
  getPrefixRandom: getPrefixRandom,
15883
16378
  generateSessionKey: generateSessionKey,
15884
16379
  getAEADMode: getAEADMode,
15885
- getCipher: getCipher
16380
+ getCipher: getCipher,
16381
+ getPreferredCurveHashAlgo: getPreferredCurveHashAlgo
15886
16382
  });
15887
16383
 
15888
16384
  /**
@@ -16125,15 +16621,15 @@ class GenericS2K {
16125
16621
  this.type = 'gnu-dummy';
16126
16622
  // GnuPG extension mode 1001 -- don't write secret key at all
16127
16623
  } else {
16128
- throw new Error('Unknown s2k gnu protection mode.');
16624
+ throw new UnsupportedError('Unknown s2k gnu protection mode.');
16129
16625
  }
16130
16626
  } else {
16131
- throw new Error('Unknown s2k type.');
16627
+ throw new UnsupportedError('Unknown s2k type.');
16132
16628
  }
16133
16629
  break;
16134
16630
 
16135
16631
  default:
16136
- throw new Error('Unknown s2k type.');
16632
+ throw new UnsupportedError('Unknown s2k type.'); // unreachable
16137
16633
  }
16138
16634
 
16139
16635
  return i;
@@ -16237,7 +16733,7 @@ function newS2KFromType(type, config$1 = config) {
16237
16733
  case enums.s2k.simple:
16238
16734
  return new GenericS2K(type, config$1);
16239
16735
  default:
16240
- throw new Error(`Unsupported S2K type ${type}`);
16736
+ throw new UnsupportedError(`Unsupported S2K type ${type}`);
16241
16737
  }
16242
16738
  }
16243
16739
 
@@ -24991,13 +25487,17 @@ class PublicKeyEncryptedSessionKeyPacket {
24991
25487
  * @param {Uint8Array} bytes - Payload of a tag 1 packet
24992
25488
  */
24993
25489
  read(bytes) {
24994
- this.version = bytes[0];
25490
+ let i = 0;
25491
+ this.version = bytes[i++];
24995
25492
  if (this.version !== VERSION$3) {
24996
25493
  throw new UnsupportedError(`Version ${this.version} of the PKESK packet is unsupported.`);
24997
25494
  }
24998
- this.publicKeyID.read(bytes.subarray(1, bytes.length));
24999
- this.publicKeyAlgorithm = bytes[9];
25000
- this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(10));
25495
+ i += this.publicKeyID.read(bytes.subarray(i));
25496
+ this.publicKeyAlgorithm = bytes[i++];
25497
+ this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(i), this.version);
25498
+ if (this.publicKeyAlgorithm === enums.publicKey.x25519) {
25499
+ this.sessionKeyAlgorithm = enums.write(enums.symmetric, this.encrypted.C.algorithm);
25500
+ }
25001
25501
  }
25002
25502
 
25003
25503
  /**
@@ -25023,15 +25523,11 @@ class PublicKeyEncryptedSessionKeyPacket {
25023
25523
  * @async
25024
25524
  */
25025
25525
  async encrypt(key) {
25026
- const data = util.concatUint8Array([
25027
- new Uint8Array([enums.write(enums.symmetric, this.sessionKeyAlgorithm)]),
25028
- this.sessionKey,
25029
- util.writeChecksum(this.sessionKey)
25030
- ]);
25031
25526
  const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
25527
+ const encoded = encodeSessionKey(this.version, algo, this.sessionKeyAlgorithm, this.sessionKey);
25032
25528
  const privateParams = algo === enums.publicKey.aead ? key.privateParams : null;
25033
25529
  this.encrypted = await mod.publicKeyEncrypt(
25034
- algo, key.publicParams, privateParams, data, key.getFingerprintBytes());
25530
+ algo, this.sessionKeyAlgorithm, key.publicParams, privateParams, encoded, key.getFingerprintBytes());
25035
25531
  }
25036
25532
 
25037
25533
  /**
@@ -25048,34 +25544,86 @@ class PublicKeyEncryptedSessionKeyPacket {
25048
25544
  throw new Error('Decryption error');
25049
25545
  }
25050
25546
 
25051
- const randomPayload = randomSessionKey ? util.concatUint8Array([
25052
- new Uint8Array([randomSessionKey.sessionKeyAlgorithm]),
25053
- randomSessionKey.sessionKey,
25054
- util.writeChecksum(randomSessionKey.sessionKey)
25055
- ]) : null;
25056
- const decoded = await mod.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes(), randomPayload);
25057
- const symmetricAlgoByte = decoded[0];
25058
- const sessionKey = decoded.subarray(1, decoded.length - 2);
25059
- const checksum = decoded.subarray(decoded.length - 2);
25060
- const computedChecksum = util.writeChecksum(sessionKey);
25061
- const isValidChecksum = computedChecksum[0] === checksum[0] & computedChecksum[1] === checksum[1];
25062
-
25063
- if (randomSessionKey) {
25064
- // We must not leak info about the validity of the decrypted checksum or cipher algo.
25065
- // 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.
25066
- const isValidPayload = isValidChecksum & symmetricAlgoByte === randomSessionKey.sessionKeyAlgorithm & sessionKey.length === randomSessionKey.sessionKey.length;
25067
- this.sessionKeyAlgorithm = util.selectUint8(isValidPayload, symmetricAlgoByte, randomSessionKey.sessionKeyAlgorithm);
25068
- this.sessionKey = util.selectUint8Array(isValidPayload, sessionKey, randomSessionKey.sessionKey);
25547
+ const randomPayload = randomSessionKey ?
25548
+ encodeSessionKey(this.version, this.publicKeyAlgorithm, randomSessionKey.sessionKeyAlgorithm, randomSessionKey.sessionKey) :
25549
+ null;
25550
+ const decryptedData = await mod.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes(), randomPayload);
25069
25551
 
25070
- } else {
25071
- const isValidPayload = isValidChecksum && enums.read(enums.symmetric, symmetricAlgoByte);
25072
- if (isValidPayload) {
25073
- this.sessionKey = sessionKey;
25074
- this.sessionKeyAlgorithm = symmetricAlgoByte;
25552
+ const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey);
25553
+
25554
+ // v3 Montgomery curves have cleartext cipher algo
25555
+ if (this.publicKeyAlgorithm !== enums.publicKey.x25519) {
25556
+ this.sessionKeyAlgorithm = sessionKeyAlgorithm;
25557
+ }
25558
+ this.sessionKey = sessionKey;
25559
+ }
25560
+ }
25561
+
25562
+
25563
+ function encodeSessionKey(version, keyAlgo, cipherAlgo, sessionKeyData) {
25564
+ switch (keyAlgo) {
25565
+ case enums.publicKey.rsaEncrypt:
25566
+ case enums.publicKey.rsaEncryptSign:
25567
+ case enums.publicKey.elgamal:
25568
+ case enums.publicKey.ecdh:
25569
+ case enums.publicKey.aead: {
25570
+ // add checksum
25571
+ return util.concatUint8Array([
25572
+ new Uint8Array([cipherAlgo]),
25573
+ sessionKeyData,
25574
+ util.writeChecksum(sessionKeyData.subarray(sessionKeyData.length % 8))
25575
+ ]);
25576
+ }
25577
+ case enums.publicKey.x25519:
25578
+ return sessionKeyData;
25579
+ default:
25580
+ throw new Error('Unsupported public key algorithm');
25581
+ }
25582
+ }
25583
+
25584
+
25585
+ function decodeSessionKey(version, keyAlgo, decryptedData, randomSessionKey) {
25586
+ switch (keyAlgo) {
25587
+ case enums.publicKey.rsaEncrypt:
25588
+ case enums.publicKey.rsaEncryptSign:
25589
+ case enums.publicKey.elgamal:
25590
+ case enums.publicKey.ecdh:
25591
+ case enums.publicKey.aead: {
25592
+ // verify checksum in constant time
25593
+ const result = decryptedData.subarray(0, decryptedData.length - 2);
25594
+ const checksum = decryptedData.subarray(decryptedData.length - 2);
25595
+ const computedChecksum = util.writeChecksum(result.subarray(result.length % 8));
25596
+ const isValidChecksum = computedChecksum[0] === checksum[0] & computedChecksum[1] === checksum[1];
25597
+ const decryptedSessionKey = { sessionKeyAlgorithm: result[0], sessionKey: result.subarray(1) };
25598
+ if (randomSessionKey) {
25599
+ // We must not leak info about the validity of the decrypted checksum or cipher algo.
25600
+ // 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.
25601
+ const isValidPayload = isValidChecksum &
25602
+ decryptedSessionKey.sessionKeyAlgorithm === randomSessionKey.sessionKeyAlgorithm &
25603
+ decryptedSessionKey.sessionKey.length === randomSessionKey.sessionKey.length;
25604
+ return {
25605
+ sessionKey: util.selectUint8Array(isValidPayload, decryptedSessionKey.sessionKey, randomSessionKey.sessionKey),
25606
+ sessionKeyAlgorithm: util.selectUint8(
25607
+ isValidPayload,
25608
+ decryptedSessionKey.sessionKeyAlgorithm,
25609
+ randomSessionKey.sessionKeyAlgorithm
25610
+ )
25611
+ };
25075
25612
  } else {
25076
- throw new Error('Decryption error');
25613
+ const isValidPayload = isValidChecksum && enums.read(enums.symmetric, decryptedSessionKey.sessionKeyAlgorithm);
25614
+ if (isValidPayload) {
25615
+ return decryptedSessionKey;
25616
+ } else {
25617
+ throw new Error('Decryption error');
25618
+ }
25077
25619
  }
25078
25620
  }
25621
+ case enums.publicKey.x25519:
25622
+ return {
25623
+ sessionKey: decryptedData
25624
+ };
25625
+ default:
25626
+ throw new Error('Unsupported public key algorithm');
25079
25627
  }
25080
25628
  }
25081
25629
 
@@ -25506,7 +26054,7 @@ class PublicKeyPacket {
25506
26054
  result.bits = util.uint8ArrayBitLength(modulo);
25507
26055
  } else if (this.publicParams.oid) {
25508
26056
  result.curve = this.publicParams.oid.getName();
25509
- } else {
26057
+ } else if (this.publicParams.cipher) {
25510
26058
  result.symmetric = this.publicParams.cipher.getName();
25511
26059
  }
25512
26060
  return result;
@@ -25838,6 +26386,7 @@ class SecretKeyPacket extends PublicKeyPacket {
25838
26386
  async read(bytes) {
25839
26387
  // - A Public-Key or Public-Subkey packet, as described above.
25840
26388
  let i = await this.readPublicKey(bytes);
26389
+ const startOfSecretKeyData = i;
25841
26390
 
25842
26391
  // - One octet indicating string-to-key usage conventions. Zero
25843
26392
  // indicates that the secret-key data is not encrypted. 255 or 254
@@ -25851,41 +26400,48 @@ class SecretKeyPacket extends PublicKeyPacket {
25851
26400
  i++;
25852
26401
  }
25853
26402
 
25854
- // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
25855
- // one-octet symmetric encryption algorithm.
25856
- if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
25857
- this.symmetric = bytes[i++];
26403
+ try {
26404
+ // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
26405
+ // one-octet symmetric encryption algorithm.
26406
+ if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
26407
+ this.symmetric = bytes[i++];
25858
26408
 
25859
- // - [Optional] If string-to-key usage octet was 253, a one-octet
25860
- // AEAD algorithm.
25861
- if (this.s2kUsage === 253) {
25862
- this.aead = bytes[i++];
25863
- }
26409
+ // - [Optional] If string-to-key usage octet was 253, a one-octet
26410
+ // AEAD algorithm.
26411
+ if (this.s2kUsage === 253) {
26412
+ this.aead = bytes[i++];
26413
+ }
25864
26414
 
25865
- // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
25866
- // string-to-key specifier. The length of the string-to-key
25867
- // specifier is implied by its type, as described above.
25868
- const s2kType = bytes[i++];
25869
- this.s2k = newS2KFromType(s2kType);
25870
- i += this.s2k.read(bytes.subarray(i, bytes.length));
26415
+ // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
26416
+ // string-to-key specifier. The length of the string-to-key
26417
+ // specifier is implied by its type, as described above.
26418
+ const s2kType = bytes[i++];
26419
+ this.s2k = newS2KFromType(s2kType);
26420
+ i += this.s2k.read(bytes.subarray(i, bytes.length));
25871
26421
 
25872
- if (this.s2k.type === 'gnu-dummy') {
25873
- return;
26422
+ if (this.s2k.type === 'gnu-dummy') {
26423
+ return;
26424
+ }
26425
+ } else if (this.s2kUsage) {
26426
+ this.symmetric = this.s2kUsage;
25874
26427
  }
25875
- } else if (this.s2kUsage) {
25876
- this.symmetric = this.s2kUsage;
25877
- }
25878
26428
 
25879
- // - [Optional] If secret data is encrypted (string-to-key usage octet
25880
- // not zero), an Initial Vector (IV) of the same length as the
25881
- // cipher's block size.
25882
- if (this.s2kUsage) {
25883
- this.iv = bytes.subarray(
25884
- i,
25885
- i + mod.getCipher(this.symmetric).blockSize
25886
- );
26429
+ // - [Optional] If secret data is encrypted (string-to-key usage octet
26430
+ // not zero), an Initial Vector (IV) of the same length as the
26431
+ // cipher's block size.
26432
+ if (this.s2kUsage) {
26433
+ this.iv = bytes.subarray(
26434
+ i,
26435
+ i + mod.getCipher(this.symmetric).blockSize
26436
+ );
25887
26437
 
25888
- i += this.iv.length;
26438
+ i += this.iv.length;
26439
+ }
26440
+ } catch (e) {
26441
+ // if the s2k is unsupported, we still want to support encrypting and verifying with the given key
26442
+ if (!this.s2kUsage) throw e; // always throw for decrypted keys
26443
+ this.unparseableKeyMaterial = bytes.subarray(startOfSecretKeyData);
26444
+ this.isEncrypted = true;
25889
26445
  }
25890
26446
 
25891
26447
  // - Only for a version 5 packet, a four-octet scalar octet count for
@@ -25921,8 +26477,15 @@ class SecretKeyPacket extends PublicKeyPacket {
25921
26477
  * @returns {Uint8Array} A string of bytes containing the secret key OpenPGP packet.
25922
26478
  */
25923
26479
  write() {
25924
- const arr = [this.writePublicKey()];
26480
+ const serializedPublicKey = this.writePublicKey();
26481
+ if (this.unparseableKeyMaterial) {
26482
+ return util.concatUint8Array([
26483
+ serializedPublicKey,
26484
+ this.unparseableKeyMaterial
26485
+ ]);
26486
+ }
25925
26487
 
26488
+ const arr = [serializedPublicKey];
25926
26489
  arr.push(new Uint8Array([this.s2kUsage]));
25927
26490
 
25928
26491
  const optionalFieldsArr = [];
@@ -25982,6 +26545,18 @@ class SecretKeyPacket extends PublicKeyPacket {
25982
26545
  return this.isEncrypted === false;
25983
26546
  }
25984
26547
 
26548
+ /**
26549
+ * Check whether the key includes secret key material.
26550
+ * Some secret keys do not include it, and can thus only be used
26551
+ * for public-key operations (encryption and verification).
26552
+ * Such keys are:
26553
+ * - GNU-dummy keys, where the secret material has been stripped away
26554
+ * - encrypted keys with unsupported S2K or cipher
26555
+ */
26556
+ isMissingSecretKeyMaterial() {
26557
+ return this.unparseableKeyMaterial !== undefined || this.isDummy();
26558
+ }
26559
+
25985
26560
  /**
25986
26561
  * Check whether this is a gnu-dummy key
25987
26562
  * @returns {Boolean}
@@ -26002,6 +26577,7 @@ class SecretKeyPacket extends PublicKeyPacket {
26002
26577
  if (this.isDecrypted()) {
26003
26578
  this.clearPrivateParams();
26004
26579
  }
26580
+ delete this.unparseableKeyMaterial;
26005
26581
  this.isEncrypted = null;
26006
26582
  this.keyMaterial = null;
26007
26583
  this.s2k = newS2KFromType(enums.s2k.gnu, config$1);
@@ -26073,6 +26649,10 @@ class SecretKeyPacket extends PublicKeyPacket {
26073
26649
  return false;
26074
26650
  }
26075
26651
 
26652
+ if (this.unparseableKeyMaterial) {
26653
+ throw new Error('Key packet cannot be decrypted: unsupported S2K or cipher algo');
26654
+ }
26655
+
26076
26656
  if (this.isDecrypted()) {
26077
26657
  throw new Error('Key packet is already decrypted.');
26078
26658
  }
@@ -26157,7 +26737,7 @@ class SecretKeyPacket extends PublicKeyPacket {
26157
26737
  * Clear private key parameters
26158
26738
  */
26159
26739
  clearPrivateParams() {
26160
- if (this.isDummy()) {
26740
+ if (this.isMissingSecretKeyMaterial()) {
26161
26741
  return;
26162
26742
  }
26163
26743
 
@@ -27556,25 +28136,22 @@ async function createBindingSignature(subkey, primaryKey, options, config) {
27556
28136
  const dataToSign = {};
27557
28137
  dataToSign.key = primaryKey;
27558
28138
  dataToSign.bind = subkey;
27559
- const subkeySignaturePacket = new SignaturePacket();
27560
- subkeySignaturePacket.signatureType = enums.signature.subkeyBinding;
27561
- subkeySignaturePacket.publicKeyAlgorithm = primaryKey.algorithm;
27562
- subkeySignaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(null, subkey, undefined, undefined, config);
28139
+ const signatureProperties = { signatureType: enums.signature.subkeyBinding };
27563
28140
  if (options.sign) {
27564
- subkeySignaturePacket.keyFlags = [enums.keyFlags.signData];
27565
- subkeySignaturePacket.embeddedSignature = await createSignaturePacket(dataToSign, null, subkey, {
28141
+ signatureProperties.keyFlags = [enums.keyFlags.signData];
28142
+ signatureProperties.embeddedSignature = await createSignaturePacket(dataToSign, null, subkey, {
27566
28143
  signatureType: enums.signature.keyBinding
27567
28144
  }, options.date, undefined, undefined, undefined, config);
27568
28145
  } else {
27569
- subkeySignaturePacket.keyFlags = options.forwarding ?
28146
+ signatureProperties.keyFlags = options.forwarding ?
27570
28147
  [enums.keyFlags.forwardedCommunication] :
27571
28148
  [enums.keyFlags.encryptCommunication | enums.keyFlags.encryptStorage];
27572
28149
  }
27573
28150
  if (options.keyExpirationTime > 0) {
27574
- subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime;
27575
- subkeySignaturePacket.keyNeverExpires = false;
28151
+ signatureProperties.keyExpirationTime = options.keyExpirationTime;
28152
+ signatureProperties.keyNeverExpires = false;
27576
28153
  }
27577
- await subkeySignaturePacket.sign(primaryKey, dataToSign, options.date);
28154
+ const subkeySignaturePacket = await createSignaturePacket(dataToSign, null, primaryKey, signatureProperties, options.date, undefined, undefined, undefined, config);
27578
28155
  return subkeySignaturePacket;
27579
28156
  }
27580
28157
 
@@ -27588,7 +28165,7 @@ async function createBindingSignature(subkey, primaryKey, options, config) {
27588
28165
  * @returns {Promise<enums.hash>}
27589
28166
  * @async
27590
28167
  */
27591
- async function getPreferredHashAlgo$1(key, keyPacket, date = new Date(), userID = {}, config) {
28168
+ async function getPreferredHashAlgo$2(key, keyPacket, date = new Date(), userID = {}, config) {
27592
28169
  let hashAlgo = config.preferredHashAlgorithm;
27593
28170
  let prefAlgo = hashAlgo;
27594
28171
  if (key) {
@@ -27599,17 +28176,11 @@ async function getPreferredHashAlgo$1(key, keyPacket, date = new Date(), userID
27599
28176
  prefAlgo : hashAlgo;
27600
28177
  }
27601
28178
  }
27602
- switch (Object.getPrototypeOf(keyPacket)) {
27603
- case SecretKeyPacket.prototype:
27604
- case PublicKeyPacket.prototype:
27605
- case SecretSubkeyPacket.prototype:
27606
- case PublicSubkeyPacket.prototype:
27607
- switch (keyPacket.algorithm) {
27608
- case enums.publicKey.ecdh:
27609
- case enums.publicKey.ecdsa:
27610
- case enums.publicKey.eddsa:
27611
- prefAlgo = mod.publicKey.elliptic.getPreferredHashAlgo(keyPacket.publicParams.oid);
27612
- }
28179
+ switch (keyPacket.algorithm) {
28180
+ case enums.publicKey.ecdsa:
28181
+ case enums.publicKey.eddsaLegacy:
28182
+ case enums.publicKey.ed25519:
28183
+ prefAlgo = mod.getPreferredCurveHashAlgo(keyPacket.algorithm, keyPacket.publicParams.oid);
27613
28184
  }
27614
28185
  return mod.hash.getHashByteLength(hashAlgo) <= mod.hash.getHashByteLength(prefAlgo) ?
27615
28186
  prefAlgo : hashAlgo;
@@ -27677,7 +28248,7 @@ async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, s
27677
28248
  const signaturePacket = new SignaturePacket();
27678
28249
  Object.assign(signaturePacket, signatureProperties);
27679
28250
  signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
27680
- signaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(privateKey, signingKeyPacket, date, userID, config);
28251
+ signaturePacket.hashAlgorithm = await getPreferredHashAlgo$2(privateKey, signingKeyPacket, date, userID, config);
27681
28252
  signaturePacket.rawNotations = notations;
27682
28253
  await signaturePacket.sign(signingKeyPacket, dataToSign, date, detached);
27683
28254
  return signaturePacket;
@@ -27818,11 +28389,11 @@ function sanitizeKeyOptions(options, subkeyDefaults = {}) {
27818
28389
  } catch (e) {
27819
28390
  throw new Error('Unknown curve');
27820
28391
  }
27821
- if (options.curve === enums.curve.ed25519 || options.curve === enums.curve.curve25519) {
27822
- options.curve = options.sign ? enums.curve.ed25519 : enums.curve.curve25519;
28392
+ if (options.curve === enums.curve.ed25519Legacy || options.curve === enums.curve.curve25519Legacy) {
28393
+ options.curve = options.sign ? enums.curve.ed25519Legacy : enums.curve.curve25519Legacy;
27823
28394
  }
27824
28395
  if (options.sign) {
27825
- options.algorithm = options.curve === enums.curve.ed25519 ? enums.publicKey.eddsa : enums.publicKey.ecdsa;
28396
+ options.algorithm = options.curve === enums.curve.ed25519Legacy ? enums.publicKey.eddsaLegacy : enums.publicKey.ecdsa;
27826
28397
  } else {
27827
28398
  options.algorithm = enums.publicKey.ecdh;
27828
28399
  }
@@ -27850,6 +28421,7 @@ function isValidSigningKeyPacket(keyPacket, signature) {
27850
28421
  return keyAlgo !== enums.publicKey.rsaEncrypt &&
27851
28422
  keyAlgo !== enums.publicKey.elgamal &&
27852
28423
  keyAlgo !== enums.publicKey.ecdh &&
28424
+ keyAlgo !== enums.publicKey.x25519 &&
27853
28425
  (!signature.keyFlags ||
27854
28426
  (signature.keyFlags[0] & enums.keyFlags.signData) !== 0);
27855
28427
  }
@@ -27859,7 +28431,8 @@ function isValidEncryptionKeyPacket(keyPacket, signature) {
27859
28431
  return keyAlgo !== enums.publicKey.dsa &&
27860
28432
  keyAlgo !== enums.publicKey.rsaSign &&
27861
28433
  keyAlgo !== enums.publicKey.ecdsa &&
27862
- keyAlgo !== enums.publicKey.eddsa &&
28434
+ keyAlgo !== enums.publicKey.eddsaLegacy &&
28435
+ keyAlgo !== enums.publicKey.ed25519 &&
27863
28436
  (!signature.keyFlags ||
27864
28437
  (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 ||
27865
28438
  (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0);
@@ -27904,7 +28477,7 @@ function checkKeyRequirements(keyPacket, config) {
27904
28477
  }
27905
28478
  break;
27906
28479
  case enums.publicKey.ecdsa:
27907
- case enums.publicKey.eddsa:
28480
+ case enums.publicKey.eddsaLegacy:
27908
28481
  case enums.publicKey.ecdh:
27909
28482
  if (config.rejectCurves.has(algoInfo.curve)) {
27910
28483
  throw new Error(`Support for ${algoInfo.algorithm} keys using curve ${algoInfo.curve} is disabled.`);
@@ -29414,7 +29987,7 @@ function createKey(packetlist) {
29414
29987
  * @static
29415
29988
  * @private
29416
29989
  */
29417
- async function generate$2(options, config) {
29990
+ async function generate$4(options, config) {
29418
29991
  options.sign = true; // primary key is always a signing key
29419
29992
  options = sanitizeKeyOptions(options);
29420
29993
  options.subkeys = options.subkeys.map((subkey, index) => sanitizeKeyOptions(options.subkeys[index], options));
@@ -29531,50 +30104,50 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
29531
30104
  const dataToSign = {};
29532
30105
  dataToSign.userID = userIDPacket;
29533
30106
  dataToSign.key = secretKeyPacket;
29534
- const signaturePacket = new SignaturePacket();
29535
- signaturePacket.signatureType = enums.signature.certGeneric;
29536
- signaturePacket.publicKeyAlgorithm = secretKeyPacket.algorithm;
29537
- signaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(null, secretKeyPacket, undefined, undefined, config);
29538
- signaturePacket.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData];
29539
- signaturePacket.preferredSymmetricAlgorithms = createPreferredAlgos([
30107
+
30108
+ const signatureProperties = {};
30109
+ signatureProperties.signatureType = enums.signature.certGeneric;
30110
+ signatureProperties.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData];
30111
+ signatureProperties.preferredSymmetricAlgorithms = createPreferredAlgos([
29540
30112
  // prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support)
29541
30113
  enums.symmetric.aes256,
29542
30114
  enums.symmetric.aes128,
29543
30115
  enums.symmetric.aes192
29544
30116
  ], config.preferredSymmetricAlgorithm);
29545
30117
  if (config.aeadProtect) {
29546
- signaturePacket.preferredAEADAlgorithms = createPreferredAlgos([
30118
+ signatureProperties.preferredAEADAlgorithms = createPreferredAlgos([
29547
30119
  enums.aead.eax,
29548
30120
  enums.aead.ocb
29549
30121
  ], config.preferredAEADAlgorithm);
29550
30122
  }
29551
- signaturePacket.preferredHashAlgorithms = createPreferredAlgos([
30123
+ signatureProperties.preferredHashAlgorithms = createPreferredAlgos([
29552
30124
  // prefer fast asm.js implementations (SHA-256)
29553
30125
  enums.hash.sha256,
29554
30126
  enums.hash.sha512
29555
30127
  ], config.preferredHashAlgorithm);
29556
- signaturePacket.preferredCompressionAlgorithms = createPreferredAlgos([
30128
+ signatureProperties.preferredCompressionAlgorithms = createPreferredAlgos([
29557
30129
  enums.compression.zlib,
29558
30130
  enums.compression.zip,
29559
30131
  enums.compression.uncompressed
29560
30132
  ], config.preferredCompressionAlgorithm);
29561
30133
  if (index === 0) {
29562
- signaturePacket.isPrimaryUserID = true;
30134
+ signatureProperties.isPrimaryUserID = true;
29563
30135
  }
29564
30136
  // integrity protection always enabled
29565
- signaturePacket.features = [0];
29566
- signaturePacket.features[0] |= enums.features.modificationDetection;
30137
+ signatureProperties.features = [0];
30138
+ signatureProperties.features[0] |= enums.features.modificationDetection;
29567
30139
  if (config.aeadProtect) {
29568
- signaturePacket.features[0] |= enums.features.aead;
30140
+ signatureProperties.features[0] |= enums.features.aead;
29569
30141
  }
29570
30142
  if (config.v5Keys) {
29571
- signaturePacket.features[0] |= enums.features.v5Keys;
30143
+ signatureProperties.features[0] |= enums.features.v5Keys;
29572
30144
  }
29573
30145
  if (options.keyExpirationTime > 0) {
29574
- signaturePacket.keyExpirationTime = options.keyExpirationTime;
29575
- signaturePacket.keyNeverExpires = false;
30146
+ signatureProperties.keyExpirationTime = options.keyExpirationTime;
30147
+ signatureProperties.keyNeverExpires = false;
29576
30148
  }
29577
- await signaturePacket.sign(secretKeyPacket, dataToSign, options.date);
30149
+
30150
+ const signaturePacket = await createSignaturePacket(dataToSign, null, secretKeyPacket, signatureProperties, options.date, undefined, undefined, undefined, config);
29578
30151
 
29579
30152
  return { userIDPacket, signaturePacket };
29580
30153
  })).then(list => {
@@ -30093,6 +30666,15 @@ class Message {
30093
30666
  enums.read(enums.aead, await getPreferredAlgo('aead', encryptionKeys, date, userIDs, config$1)) :
30094
30667
  undefined;
30095
30668
 
30669
+ await Promise.all(encryptionKeys.map(key => key.getEncryptionKey()
30670
+ .catch(() => null) // ignore key strength requirements
30671
+ .then(maybeKey => {
30672
+ if (maybeKey && (maybeKey.keyPacket.algorithm === enums.publicKey.x25519) && !util.isAES(algo)) {
30673
+ 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.');
30674
+ }
30675
+ })
30676
+ ));
30677
+
30096
30678
  const sessionKeyData = mod.generateSessionKey(algo);
30097
30679
  return { data: sessionKeyData, algorithm: algorithmName, aeadAlgorithm: aeadAlgorithmName };
30098
30680
  }
@@ -30267,7 +30849,7 @@ class Message {
30267
30849
  const signingKey = await primaryKey.getSigningKey(signingKeyID, date, userIDs, config$1);
30268
30850
  const onePassSig = new OnePassSignaturePacket();
30269
30851
  onePassSig.signatureType = signatureType;
30270
- onePassSig.hashAlgorithm = await getPreferredHashAlgo$1(primaryKey, signingKey.keyPacket, date, userIDs, config$1);
30852
+ onePassSig.hashAlgorithm = await getPreferredHashAlgo$2(primaryKey, signingKey.keyPacket, date, userIDs, config$1);
30271
30853
  onePassSig.publicKeyAlgorithm = signingKey.keyPacket.algorithm;
30272
30854
  onePassSig.issuerKeyID = signingKey.getKeyID();
30273
30855
  if (i === signingKeys.length - 1) {
@@ -30400,7 +30982,7 @@ class Message {
30400
30982
  if (literalDataList.length !== 1) {
30401
30983
  throw new Error('Can only verify message with one literal data packet.');
30402
30984
  }
30403
- const signatureList = signature.packets;
30985
+ const signatureList = signature.packets.filterByTag(enums.packet.signature); // drop UnparsablePackets
30404
30986
  return createVerificationObjects(signatureList, literalDataList, verificationKeys, date, true, config$1);
30405
30987
  }
30406
30988
 
@@ -30747,7 +31329,7 @@ class CleartextMessage {
30747
31329
  * @async
30748
31330
  */
30749
31331
  verify(keys, date = new Date(), config$1 = config) {
30750
- const signatureList = this.signature.packets;
31332
+ const signatureList = this.signature.packets.filterByTag(enums.packet.signature); // drop UnparsablePackets
30751
31333
  const literalDataPacket = new LiteralDataPacket();
30752
31334
  // we assume that cleartext signature is generated based on UTF8 cleartext
30753
31335
  literalDataPacket.setText(this.text);
@@ -30832,7 +31414,7 @@ function verifyHeaders$1(headers, packetlist) {
30832
31414
  let oneHeader = null;
30833
31415
  let hashAlgos = [];
30834
31416
  headers.forEach(function(header) {
30835
- oneHeader = header.match(/Hash: (.+)/); // get header value
31417
+ oneHeader = header.match(/^Hash: (.+)$/); // get header value
30836
31418
  if (oneHeader) {
30837
31419
  oneHeader = oneHeader[1].replace(/\s/g, ''); // remove whitespace
30838
31420
  oneHeader = oneHeader.split(',');
@@ -30924,7 +31506,7 @@ async function generateKey({ userIDs = [], passphrase, type = 'ecc', rsaBits = 4
30924
31506
  const options = { userIDs, passphrase, type, rsaBits, curve, keyExpirationTime, date, subkeys, symmetricHash, symmetricCipher };
30925
31507
 
30926
31508
  try {
30927
- const { key, revocationCertificate } = await generate$2(options, config$1);
31509
+ const { key, revocationCertificate } = await generate$4(options, config$1);
30928
31510
  key.getKeys().forEach(({ keyPacket }) => checkKeyRequirements(keyPacket, config$1));
30929
31511
 
30930
31512
  return {
@@ -31118,7 +31700,7 @@ async function encryptKey({ privateKey, passphrase, config: config$1, ...rest })
31118
31700
  * @async
31119
31701
  * @static
31120
31702
  */
31121
- 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 }) {
31703
+ 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 }) {
31122
31704
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
31123
31705
  checkMessage(message); checkOutputMessageFormat(format);
31124
31706
  encryptionKeys = toArray$1(encryptionKeys); signingKeys = toArray$1(signingKeys); passwords = toArray$1(passwords);
@@ -31187,7 +31769,7 @@ async function encrypt$4({ message, encryptionKeys, signingKeys, passwords, sess
31187
31769
  * @async
31188
31770
  * @static
31189
31771
  */
31190
- async function decrypt$4({ message, decryptionKeys, passwords, sessionKeys, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
31772
+ async function decrypt$5({ message, decryptionKeys, passwords, sessionKeys, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
31191
31773
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
31192
31774
  checkMessage(message); verificationKeys = toArray$1(verificationKeys); decryptionKeys = toArray$1(decryptionKeys); passwords = toArray$1(passwords); sessionKeys = toArray$1(sessionKeys);
31193
31775
  if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.decrypt, pass `decryptionKeys` instead');
@@ -31250,7 +31832,7 @@ async function decrypt$4({ message, decryptionKeys, passwords, sessionKeys, veri
31250
31832
  * @async
31251
31833
  * @static
31252
31834
  */
31253
- async function sign$5({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
31835
+ async function sign$6({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], signatureNotations = [], config: config$1, ...rest }) {
31254
31836
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
31255
31837
  checkCleartextOrMessage(message); checkOutputMessageFormat(format);
31256
31838
  signingKeys = toArray$1(signingKeys); signingKeyIDs = toArray$1(signingKeyIDs); signingUserIDs = toArray$1(signingUserIDs); signatureNotations = toArray$1(signatureNotations);
@@ -31319,7 +31901,7 @@ async function sign$5({ message, signingKeys, format = 'armored', detached = fal
31319
31901
  * @async
31320
31902
  * @static
31321
31903
  */
31322
- async function verify$5({ message, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
31904
+ async function verify$6({ message, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config: config$1, ...rest }) {
31323
31905
  config$1 = { ...config, ...config$1 }; checkConfig(config$1);
31324
31906
  checkCleartextOrMessage(message); verificationKeys = toArray$1(verificationKeys);
31325
31907
  if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.verify, pass `verificationKeys` instead');
@@ -44488,7 +45070,7 @@ function* makePRNG(wasmContext, pass, lane, slice, m_, totalPasses, segmentLengt
44488
45070
  return [];
44489
45071
  }
44490
45072
 
44491
- function validateParams$7({ type, version, tagLength, password, salt, ad, secret, parallelism, memorySize, passes }) {
45073
+ function validateParams$9({ type, version, tagLength, password, salt, ad, secret, parallelism, memorySize, passes }) {
44492
45074
  const assertLength = (name, value, min, max) => {
44493
45075
  if (value < min || value > max) { throw new Error(`${name} size should be between ${min} and ${max} bytes`); }
44494
45076
  };
@@ -44511,7 +45093,7 @@ const WASM_PAGE_SIZE = 64 * KB;
44511
45093
  function argon2id(params, { memory, instance: wasmInstance }) {
44512
45094
  if (!isLittleEndian$1) throw new Error('BigEndian system not supported'); // optmisations assume LE system
44513
45095
 
44514
- const ctx = validateParams$7({ type: TYPE$2, version: VERSION$4, ...params });
45096
+ const ctx = validateParams$9({ type: TYPE$2, version: VERSION$4, ...params });
44515
45097
 
44516
45098
  const { G:wasmG, G2:wasmG2, xor:wasmXOR, getLZ:wasmLZ } = wasmInstance.exports;
44517
45099
  const wasmRefs = {};
@@ -44791,4 +45373,4 @@ var index = /*#__PURE__*/Object.freeze({
44791
45373
  'default': loadWasm
44792
45374
  });
44793
45375
 
44794
- export { AEADEncryptedDataPacket, CleartextMessage, CompressedDataPacket, KDFParams, LiteralDataPacket, MarkerPacket, Message, OnePassSignaturePacket, PacketList, PrivateKey, PublicKey, PublicKeyEncryptedSessionKeyPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, Signature, SignaturePacket, Subkey, SymEncryptedIntegrityProtectedDataPacket, SymEncryptedSessionKeyPacket, SymmetricallyEncryptedDataPacket, TrustPacket, UnparseablePacket, UserAttributePacket, UserIDPacket, armor, config, createCleartextMessage, createMessage, decrypt$4 as decrypt, decryptKey, decryptSessionKeys, encrypt$4 as encrypt, encryptKey, encryptSessionKey, enums, generateKey, generateSessionKey$1 as generateSessionKey, readCleartextMessage, readKey, readKeys, readMessage, readPrivateKey, readPrivateKeys, readSignature, reformatKey, revokeKey, sign$5 as sign, unarmor, verify$5 as verify };
45376
+ export { AEADEncryptedDataPacket, CleartextMessage, CompressedDataPacket, KDFParams, LiteralDataPacket, MarkerPacket, Message, OnePassSignaturePacket, PacketList, PrivateKey, PublicKey, PublicKeyEncryptedSessionKeyPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, Signature, SignaturePacket, Subkey, SymEncryptedIntegrityProtectedDataPacket, SymEncryptedSessionKeyPacket, SymmetricallyEncryptedDataPacket, TrustPacket, UnparseablePacket, UserAttributePacket, UserIDPacket, armor, config, createCleartextMessage, createMessage, decrypt$5 as decrypt, decryptKey, decryptSessionKeys, encrypt$5 as encrypt, encryptKey, encryptSessionKey, enums, generateKey, generateSessionKey$1 as generateSessionKey, readCleartextMessage, readKey, readKeys, readMessage, readPrivateKey, readPrivateKeys, readSignature, reformatKey, revokeKey, sign$6 as sign, unarmor, verify$6 as verify };