@protontech/openpgp 4.10.8 → 5.3.1

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.
Files changed (173) hide show
  1. package/README.md +311 -239
  2. package/dist/lightweight/bn.interface.min.mjs +3 -0
  3. package/dist/lightweight/bn.interface.min.mjs.map +1 -0
  4. package/dist/lightweight/bn.interface.mjs +340 -0
  5. package/dist/lightweight/bn.min.mjs +3 -0
  6. package/dist/lightweight/bn.min.mjs.map +1 -0
  7. package/dist/lightweight/bn.mjs +3434 -0
  8. package/dist/lightweight/elliptic.min.mjs +3 -0
  9. package/dist/lightweight/elliptic.min.mjs.map +1 -0
  10. package/dist/lightweight/elliptic.mjs +4313 -0
  11. package/dist/lightweight/openpgp.min.mjs +3 -0
  12. package/dist/lightweight/openpgp.min.mjs.map +1 -0
  13. package/dist/lightweight/openpgp.mjs +31375 -0
  14. package/dist/lightweight/ponyfill.es6.min.mjs +3 -0
  15. package/dist/lightweight/ponyfill.es6.min.mjs.map +1 -0
  16. package/dist/lightweight/ponyfill.es6.mjs +3831 -0
  17. package/dist/lightweight/web-streams-adapter.min.mjs +17 -0
  18. package/dist/lightweight/web-streams-adapter.min.mjs.map +1 -0
  19. package/dist/lightweight/web-streams-adapter.mjs +561 -0
  20. package/dist/node/openpgp.js +43943 -0
  21. package/dist/node/openpgp.min.js +17 -0
  22. package/dist/node/openpgp.min.js.map +1 -0
  23. package/dist/node/openpgp.min.mjs +17 -0
  24. package/dist/node/openpgp.min.mjs.map +1 -0
  25. package/dist/node/openpgp.mjs +43880 -0
  26. package/dist/openpgp.js +41077 -41609
  27. package/dist/openpgp.min.js +17 -2
  28. package/dist/openpgp.min.js.map +1 -0
  29. package/dist/openpgp.min.mjs +17 -0
  30. package/dist/openpgp.min.mjs.map +1 -0
  31. package/dist/openpgp.mjs +43868 -0
  32. package/lightweight/package.json +5 -0
  33. package/openpgp.d.ts +889 -0
  34. package/package.json +63 -57
  35. package/dist/compat/openpgp.js +0 -61152
  36. package/dist/compat/openpgp.min.js +0 -2
  37. package/dist/compat/openpgp.worker.js +0 -173
  38. package/dist/compat/openpgp.worker.min.js +0 -2
  39. package/dist/lightweight/elliptic.min.js +0 -5
  40. package/dist/lightweight/openpgp.js +0 -40071
  41. package/dist/lightweight/openpgp.min.js +0 -2
  42. package/dist/lightweight/openpgp.worker.js +0 -173
  43. package/dist/lightweight/openpgp.worker.min.js +0 -2
  44. package/dist/openpgp.worker.js +0 -173
  45. package/dist/openpgp.worker.min.js +0 -2
  46. package/src/cleartext.js +0 -220
  47. package/src/config/config.js +0 -232
  48. package/src/config/index.js +0 -7
  49. package/src/config/localStorage.js +0 -35
  50. package/src/crypto/aes_kw.js +0 -153
  51. package/src/crypto/cfb.js +0 -169
  52. package/src/crypto/cipher/aes.js +0 -27
  53. package/src/crypto/cipher/blowfish.js +0 -398
  54. package/src/crypto/cipher/cast5.js +0 -610
  55. package/src/crypto/cipher/des.js +0 -476
  56. package/src/crypto/cipher/index.js +0 -91
  57. package/src/crypto/cipher/twofish.js +0 -346
  58. package/src/crypto/cmac.js +0 -98
  59. package/src/crypto/crypto.js +0 -394
  60. package/src/crypto/eax.js +0 -172
  61. package/src/crypto/gcm.js +0 -141
  62. package/src/crypto/hash/index.js +0 -163
  63. package/src/crypto/hash/md5.js +0 -205
  64. package/src/crypto/index.js +0 -57
  65. package/src/crypto/ocb.js +0 -274
  66. package/src/crypto/pkcs1.js +0 -170
  67. package/src/crypto/pkcs5.js +0 -55
  68. package/src/crypto/public_key/dsa.js +0 -188
  69. package/src/crypto/public_key/elgamal.js +0 -137
  70. package/src/crypto/public_key/elliptic/curves.js +0 -385
  71. package/src/crypto/public_key/elliptic/ecdh.js +0 -414
  72. package/src/crypto/public_key/elliptic/ecdsa.js +0 -348
  73. package/src/crypto/public_key/elliptic/eddsa.js +0 -119
  74. package/src/crypto/public_key/elliptic/index.js +0 -34
  75. package/src/crypto/public_key/elliptic/indutnyKey.js +0 -85
  76. package/src/crypto/public_key/index.js +0 -28
  77. package/src/crypto/public_key/prime.js +0 -275
  78. package/src/crypto/public_key/rsa.js +0 -597
  79. package/src/crypto/random.js +0 -145
  80. package/src/crypto/signature.js +0 -137
  81. package/src/encoding/armor.js +0 -433
  82. package/src/encoding/base64.js +0 -96
  83. package/src/enums.js +0 -493
  84. package/src/hkp.js +0 -89
  85. package/src/index.js +0 -161
  86. package/src/key/factory.js +0 -326
  87. package/src/key/helper.js +0 -378
  88. package/src/key/index.js +0 -32
  89. package/src/key/key.js +0 -888
  90. package/src/key/subkey.js +0 -187
  91. package/src/key/user.js +0 -230
  92. package/src/keyring/index.js +0 -12
  93. package/src/keyring/keyring.js +0 -229
  94. package/src/keyring/localstore.js +0 -119
  95. package/src/lightweight_helper.js +0 -26
  96. package/src/message.js +0 -825
  97. package/src/openpgp.js +0 -717
  98. package/src/packet/all_packets.js +0 -116
  99. package/src/packet/clone.js +0 -189
  100. package/src/packet/compressed.js +0 -194
  101. package/src/packet/index.js +0 -20
  102. package/src/packet/literal.js +0 -168
  103. package/src/packet/marker.js +0 -62
  104. package/src/packet/one_pass_signature.js +0 -156
  105. package/src/packet/packet.js +0 -300
  106. package/src/packet/packetlist.js +0 -232
  107. package/src/packet/public_key.js +0 -280
  108. package/src/packet/public_key_encrypted_session_key.js +0 -161
  109. package/src/packet/public_subkey.js +0 -44
  110. package/src/packet/secret_key.js +0 -468
  111. package/src/packet/secret_subkey.js +0 -41
  112. package/src/packet/signature.js +0 -786
  113. package/src/packet/sym_encrypted_aead_protected.js +0 -189
  114. package/src/packet/sym_encrypted_integrity_protected.js +0 -139
  115. package/src/packet/sym_encrypted_session_key.js +0 -204
  116. package/src/packet/symmetrically_encrypted.js +0 -118
  117. package/src/packet/trust.js +0 -35
  118. package/src/packet/user_attribute.js +0 -94
  119. package/src/packet/userid.js +0 -87
  120. package/src/polyfills.js +0 -64
  121. package/src/signature.js +0 -73
  122. package/src/type/ecdh_symkey.js +0 -69
  123. package/src/type/kdf_params.js +0 -114
  124. package/src/type/keyid.js +0 -110
  125. package/src/type/mpi.js +0 -138
  126. package/src/type/oid.js +0 -110
  127. package/src/type/s2k.js +0 -203
  128. package/src/util.js +0 -836
  129. package/src/wkd.js +0 -84
  130. package/src/worker/async_proxy.js +0 -190
  131. package/src/worker/worker.js +0 -167
  132. package/test/crypto/aes_kw.js +0 -57
  133. package/test/crypto/cipher/aes.js +0 -86
  134. package/test/crypto/cipher/blowfish.js +0 -58
  135. package/test/crypto/cipher/cast5.js +0 -25
  136. package/test/crypto/cipher/des.js +0 -143
  137. package/test/crypto/cipher/index.js +0 -7
  138. package/test/crypto/cipher/twofish.js +0 -71
  139. package/test/crypto/crypto.js +0 -383
  140. package/test/crypto/eax.js +0 -150
  141. package/test/crypto/ecdh.js +0 -359
  142. package/test/crypto/elliptic.js +0 -251
  143. package/test/crypto/elliptic_data.js +0 -102
  144. package/test/crypto/hash/index.js +0 -5
  145. package/test/crypto/hash/md5.js +0 -16
  146. package/test/crypto/hash/ripemd.js +0 -14
  147. package/test/crypto/hash/sha.js +0 -20
  148. package/test/crypto/index.js +0 -14
  149. package/test/crypto/ocb.js +0 -183
  150. package/test/crypto/pkcs5.js +0 -39
  151. package/test/crypto/random.js +0 -79
  152. package/test/crypto/rsa.js +0 -180
  153. package/test/crypto/validate.js +0 -387
  154. package/test/general/armor.js +0 -408
  155. package/test/general/brainpool.js +0 -360
  156. package/test/general/decompression.js +0 -60
  157. package/test/general/ecc_nist.js +0 -115
  158. package/test/general/ecc_secp256k1.js +0 -242
  159. package/test/general/forwarding.js +0 -43
  160. package/test/general/hkp.js +0 -165
  161. package/test/general/index.js +0 -20
  162. package/test/general/key.js +0 -3491
  163. package/test/general/keyring.js +0 -336
  164. package/test/general/oid.js +0 -39
  165. package/test/general/openpgp.js +0 -2577
  166. package/test/general/packet.js +0 -950
  167. package/test/general/signature.js +0 -1715
  168. package/test/general/streaming.js +0 -944
  169. package/test/general/testInputs.js +0 -18
  170. package/test/general/util.js +0 -183
  171. package/test/general/wkd.js +0 -48
  172. package/test/general/x25519.js +0 -556
  173. package/test/unittests.js +0 -64
package/src/key/key.js DELETED
@@ -1,888 +0,0 @@
1
- // GPG4Browsers - An OpenPGP implementation in javascript
2
- // Copyright (C) 2011 Recurity Labs GmbH
3
- //
4
- // This library is free software; you can redistribute it and/or
5
- // modify it under the terms of the GNU Lesser General Public
6
- // License as published by the Free Software Foundation; either
7
- // version 3.0 of the License, or (at your option) any later version.
8
- //
9
- // This library is distributed in the hope that it will be useful,
10
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- // Lesser General Public License for more details.
13
- //
14
- // You should have received a copy of the GNU Lesser General Public
15
- // License along with this library; if not, write to the Free Software
16
- // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
-
18
- /**
19
- * @requires encoding/armor
20
- * @requires packet
21
- * @requires enums
22
- * @requires util
23
- * @requires key/User
24
- * @requires key/Subkey
25
- * @module key/Key
26
- */
27
-
28
- import armor from '../encoding/armor';
29
- import packet from '../packet';
30
- import enums from '../enums';
31
- import util from '../util';
32
- import User from './user';
33
- import SubKey from './subkey';
34
- import * as helper from './helper';
35
-
36
- /**
37
- * @class
38
- * @classdesc Class that represents an OpenPGP key. Must contain a primary key.
39
- * Can contain additional subkeys, signatures, user ids, user attributes.
40
- * @param {module:packet.List} packetlist The packets that form this key
41
- * @borrows module:packet.PublicKey#getKeyId as Key#getKeyId
42
- * @borrows module:packet.PublicKey#getFingerprint as Key#getFingerprint
43
- * @borrows module:packet.PublicKey#hasSameFingerprintAs as Key#hasSameFingerprintAs
44
- * @borrows module:packet.PublicKey#getAlgorithmInfo as Key#getAlgorithmInfo
45
- * @borrows module:packet.PublicKey#getCreationTime as Key#getCreationTime
46
- * @borrows module:packet.PublicKey#isDecrypted as Key#isDecrypted
47
- */
48
- export default function Key(packetlist) {
49
- if (!(this instanceof Key)) {
50
- return new Key(packetlist);
51
- }
52
- // same data as in packetlist but in structured form
53
- this.keyPacket = null;
54
- this.revocationSignatures = [];
55
- this.directSignatures = [];
56
- this.users = [];
57
- this.subKeys = [];
58
- this.packetlist2structure(packetlist);
59
- if (!this.keyPacket || !this.users.length) {
60
- throw new Error('Invalid key: need at least key and user ID packet');
61
- }
62
- }
63
-
64
- Object.defineProperty(Key.prototype, 'primaryKey', {
65
- get() {
66
- return this.keyPacket;
67
- },
68
- configurable: true,
69
- enumerable: true
70
- });
71
-
72
- /**
73
- * Transforms packetlist to structured key data
74
- * @param {module:packet.List} packetlist The packets that form a key
75
- */
76
- Key.prototype.packetlist2structure = function(packetlist) {
77
- let user;
78
- let primaryKeyId;
79
- let subKey;
80
- for (let i = 0; i < packetlist.length; i++) {
81
- switch (packetlist[i].tag) {
82
- case enums.packet.publicKey:
83
- case enums.packet.secretKey:
84
- this.keyPacket = packetlist[i];
85
- primaryKeyId = this.getKeyId();
86
- break;
87
- case enums.packet.userid:
88
- case enums.packet.userAttribute:
89
- user = new User(packetlist[i]);
90
- this.users.push(user);
91
- break;
92
- case enums.packet.publicSubkey:
93
- case enums.packet.secretSubkey:
94
- user = null;
95
- subKey = new SubKey(packetlist[i]);
96
- this.subKeys.push(subKey);
97
- break;
98
- case enums.packet.signature:
99
- switch (packetlist[i].signatureType) {
100
- case enums.signature.cert_generic:
101
- case enums.signature.cert_persona:
102
- case enums.signature.cert_casual:
103
- case enums.signature.cert_positive:
104
- if (!user) {
105
- util.print_debug('Dropping certification signatures without preceding user packet');
106
- continue;
107
- }
108
- if (packetlist[i].issuerKeyId.equals(primaryKeyId)) {
109
- user.selfCertifications.push(packetlist[i]);
110
- } else {
111
- user.otherCertifications.push(packetlist[i]);
112
- }
113
- break;
114
- case enums.signature.cert_revocation:
115
- if (user) {
116
- user.revocationSignatures.push(packetlist[i]);
117
- } else {
118
- this.directSignatures.push(packetlist[i]);
119
- }
120
- break;
121
- case enums.signature.key:
122
- this.directSignatures.push(packetlist[i]);
123
- break;
124
- case enums.signature.subkey_binding:
125
- if (!subKey) {
126
- util.print_debug('Dropping subkey binding signature without preceding subkey packet');
127
- continue;
128
- }
129
- subKey.bindingSignatures.push(packetlist[i]);
130
- break;
131
- case enums.signature.key_revocation:
132
- this.revocationSignatures.push(packetlist[i]);
133
- break;
134
- case enums.signature.subkey_revocation:
135
- if (!subKey) {
136
- util.print_debug('Dropping subkey revocation signature without preceding subkey packet');
137
- continue;
138
- }
139
- subKey.revocationSignatures.push(packetlist[i]);
140
- break;
141
- }
142
- break;
143
- }
144
- }
145
- };
146
-
147
- /**
148
- * Transforms structured key data to packetlist
149
- * @returns {module:packet.List} The packets that form a key
150
- */
151
- Key.prototype.toPacketlist = function() {
152
- const packetlist = new packet.List();
153
- packetlist.push(this.keyPacket);
154
- packetlist.concat(this.revocationSignatures);
155
- packetlist.concat(this.directSignatures);
156
- this.users.map(user => packetlist.concat(user.toPacketlist()));
157
- this.subKeys.map(subKey => packetlist.concat(subKey.toPacketlist()));
158
- return packetlist;
159
- };
160
-
161
- /**
162
- * Returns an array containing all public or private subkeys matching keyId;
163
- * If keyId is not present, returns all subkeys.
164
- * @param {type/keyid} keyId
165
- * @returns {Array<module:key~SubKey>}
166
- */
167
- Key.prototype.getSubkeys = function(keyId = null) {
168
- const subKeys = [];
169
- this.subKeys.forEach(subKey => {
170
- if (!keyId || subKey.getKeyId().equals(keyId, true)) {
171
- subKeys.push(subKey);
172
- }
173
- });
174
- return subKeys;
175
- };
176
-
177
- /**
178
- * Returns an array containing all public or private keys matching keyId.
179
- * If keyId is not present, returns all keys starting with the primary key.
180
- * @param {type/keyid} keyId
181
- * @returns {Array<module:key.Key|module:key~SubKey>}
182
- */
183
- Key.prototype.getKeys = function(keyId = null) {
184
- const keys = [];
185
- if (!keyId || this.getKeyId().equals(keyId, true)) {
186
- keys.push(this);
187
- }
188
- return keys.concat(this.getSubkeys(keyId));
189
- };
190
-
191
- /**
192
- * Returns key IDs of all keys
193
- * @returns {Array<module:type/keyid>}
194
- */
195
- Key.prototype.getKeyIds = function() {
196
- return this.getKeys().map(key => key.getKeyId());
197
- };
198
-
199
- /**
200
- * Returns userids
201
- * @returns {Array<string>} array of userids
202
- */
203
- Key.prototype.getUserIds = function() {
204
- return this.users.map(user => {
205
- return user.userId ? user.userId.userid : null;
206
- }).filter(userid => userid !== null);
207
- };
208
-
209
- /**
210
- * Returns true if this is a public key
211
- * @returns {Boolean}
212
- */
213
- Key.prototype.isPublic = function() {
214
- return this.keyPacket.tag === enums.packet.publicKey;
215
- };
216
-
217
- /**
218
- * Returns true if this is a private key
219
- * @returns {Boolean}
220
- */
221
- Key.prototype.isPrivate = function() {
222
- return this.keyPacket.tag === enums.packet.secretKey;
223
- };
224
-
225
- /**
226
- * Returns key as public key (shallow copy)
227
- * @returns {module:key.Key} new public Key
228
- */
229
- Key.prototype.toPublic = function() {
230
- const packetlist = new packet.List();
231
- const keyPackets = this.toPacketlist();
232
- let bytes;
233
- let pubKeyPacket;
234
- let pubSubkeyPacket;
235
- for (let i = 0; i < keyPackets.length; i++) {
236
- switch (keyPackets[i].tag) {
237
- case enums.packet.secretKey:
238
- bytes = keyPackets[i].writePublicKey();
239
- pubKeyPacket = new packet.PublicKey();
240
- pubKeyPacket.read(bytes);
241
- packetlist.push(pubKeyPacket);
242
- break;
243
- case enums.packet.secretSubkey:
244
- bytes = keyPackets[i].writePublicKey();
245
- pubSubkeyPacket = new packet.PublicSubkey();
246
- pubSubkeyPacket.read(bytes);
247
- packetlist.push(pubSubkeyPacket);
248
- break;
249
- default:
250
- packetlist.push(keyPackets[i]);
251
- }
252
- }
253
- return new Key(packetlist);
254
- };
255
-
256
- /**
257
- * Returns ASCII armored text of key
258
- * @returns {ReadableStream<String>} ASCII armor
259
- */
260
- Key.prototype.armor = function() {
261
- const type = this.isPublic() ? enums.armor.public_key : enums.armor.private_key;
262
- return armor.encode(type, this.toPacketlist().write());
263
- };
264
-
265
- /**
266
- * Returns last created key or key by given keyId that is available for signing and verification
267
- * @param {module:type/keyid} keyId, optional
268
- * @param {Date} date (optional) use the given date for verification instead of the current time
269
- * @param {Object} userId, optional user ID
270
- * @returns {Promise<module:key.Key|module:key~SubKey|null>} key or null if no signing key has been found
271
- * @async
272
- */
273
- Key.prototype.getSigningKey = async function (keyId = null, date = new Date(), userId = {}) {
274
- await this.verifyPrimaryKey(date, userId);
275
- const primaryKey = this.keyPacket;
276
- const subKeys = this.subKeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created);
277
- let exception;
278
- for (let i = 0; i < subKeys.length; i++) {
279
- if (!keyId || subKeys[i].getKeyId().equals(keyId)) {
280
- try {
281
- await subKeys[i].verify(primaryKey, date);
282
- const dataToVerify = { key: primaryKey, bind: subKeys[i].keyPacket };
283
- const bindingSignature = await helper.getLatestValidSignature(subKeys[i].bindingSignatures, primaryKey, enums.signature.subkey_binding, dataToVerify, date);
284
- if (
285
- bindingSignature &&
286
- bindingSignature.embeddedSignature &&
287
- helper.isValidSigningKeyPacket(subKeys[i].keyPacket, bindingSignature) &&
288
- await helper.getLatestValidSignature([bindingSignature.embeddedSignature], subKeys[i].keyPacket, enums.signature.key_binding, dataToVerify, date)
289
- ) {
290
- return subKeys[i];
291
- }
292
- } catch (e) {
293
- exception = e;
294
- }
295
- }
296
- }
297
- const primaryUser = await this.getPrimaryUser(date, userId);
298
- if ((!keyId || primaryKey.getKeyId().equals(keyId)) &&
299
- helper.isValidSigningKeyPacket(primaryKey, primaryUser.selfCertification)) {
300
- return this;
301
- }
302
- throw util.wrapError('Could not find valid signing key packet in key ' + this.getKeyId().toHex(), exception);
303
- };
304
-
305
- /**
306
- * Returns last created key or key by given keyId that is available for encryption or decryption
307
- * @param {module:type/keyid} keyId, optional
308
- * @param {Date} date, optional
309
- * @param {String} userId, optional
310
- * @returns {Promise<module:key.Key|module:key~SubKey|null>} key or null if no encryption key has been found
311
- * @async
312
- */
313
- Key.prototype.getEncryptionKey = async function(keyId, date = new Date(), userId = {}) {
314
- await this.verifyPrimaryKey(date, userId);
315
- const primaryKey = this.keyPacket;
316
- // V4: by convention subkeys are preferred for encryption service
317
- const subKeys = this.subKeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created);
318
- let exception;
319
- for (let i = 0; i < subKeys.length; i++) {
320
- if (!keyId || subKeys[i].getKeyId().equals(keyId)) {
321
- try {
322
- await subKeys[i].verify(primaryKey, date);
323
- const dataToVerify = { key: primaryKey, bind: subKeys[i].keyPacket };
324
- const bindingSignature = await helper.getLatestValidSignature(subKeys[i].bindingSignatures, primaryKey, enums.signature.subkey_binding, dataToVerify, date);
325
- if (bindingSignature && helper.isValidEncryptionKeyPacket(subKeys[i].keyPacket, bindingSignature)) {
326
- return subKeys[i];
327
- }
328
- } catch (e) {
329
- exception = e;
330
- }
331
- }
332
- }
333
- // if no valid subkey for encryption, evaluate primary key
334
- const primaryUser = await this.getPrimaryUser(date, userId);
335
- if ((!keyId || primaryKey.getKeyId().equals(keyId)) &&
336
- helper.isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification)) {
337
- return this;
338
- }
339
- throw util.wrapError('Could not find valid encryption key packet in key ' + this.getKeyId().toHex(), exception);
340
- };
341
-
342
- /**
343
- * Returns all keys that are available for decryption, matching the keyId when given
344
- * This is useful to retrieve keys for session key decryption
345
- * @param {module:type/keyid} keyId, optional
346
- * @param {Date} date, optional
347
- * @param {String} userId, optional
348
- * @returns {Promise<Array<module:key.Key|module:key~SubKey>>} array of decryption keys
349
- * @async
350
- */
351
- Key.prototype.getDecryptionKeys = async function(keyId, date = new Date(), userId = {}) {
352
- const primaryKey = this.keyPacket;
353
- const keys = [];
354
- for (let i = 0; i < this.subKeys.length; i++) {
355
- if (!keyId || this.subKeys[i].getKeyId().equals(keyId, true)) {
356
- try {
357
- const dataToVerify = { key: primaryKey, bind: this.subKeys[i].keyPacket };
358
- const bindingSignature = await helper.getLatestValidSignature(this.subKeys[i].bindingSignatures, primaryKey, enums.signature.subkey_binding, dataToVerify, date);
359
- if (bindingSignature && helper.isValidDecryptionKeyPacket(bindingSignature)) {
360
- keys.push(this.subKeys[i]);
361
- }
362
- } catch (e) {}
363
- }
364
- }
365
-
366
- // evaluate primary key
367
- const primaryUser = await this.getPrimaryUser(date, userId);
368
- if ((!keyId || primaryKey.getKeyId().equals(keyId, true)) &&
369
- helper.isValidDecryptionKeyPacket(primaryUser.selfCertification)) {
370
- keys.push(this);
371
- }
372
-
373
- return keys;
374
- };
375
-
376
- /**
377
- * Encrypts all secret key and subkey packets matching keyId
378
- * @param {String|Array<String>} passphrases - if multiple passphrases, then should be in same order as packets each should encrypt
379
- * @param {module:type/keyid} keyId
380
- * @returns {Promise<Array<module:packet.SecretKey|module:packet.SecretSubkey>>}
381
- * @async
382
- */
383
- Key.prototype.encrypt = async function(passphrases, keyId = null) {
384
- if (!this.isPrivate()) {
385
- throw new Error("Nothing to encrypt in a public key");
386
- }
387
-
388
- const keys = this.getKeys(keyId);
389
- passphrases = util.isArray(passphrases) ? passphrases : new Array(keys.length).fill(passphrases);
390
- if (passphrases.length !== keys.length) {
391
- throw new Error("Invalid number of passphrases for key");
392
- }
393
-
394
- return Promise.all(keys.map(async function(key, i) {
395
- const { keyPacket } = key;
396
- await keyPacket.encrypt(passphrases[i]);
397
- keyPacket.clearPrivateParams();
398
- return keyPacket;
399
- }));
400
- };
401
-
402
- /**
403
- * Decrypts all secret key and subkey packets matching keyId
404
- * @param {String|Array<String>} passphrases
405
- * @param {module:type/keyid} keyId
406
- * @returns {Promise<Boolean>} true if all matching key and subkey packets decrypted successfully
407
- * @throws {Error} if any matching key or subkey packets did not decrypt successfully
408
- * @async
409
- */
410
- Key.prototype.decrypt = async function(passphrases, keyId = null) {
411
- if (!this.isPrivate()) {
412
- throw new Error("Nothing to decrypt in a public key");
413
- }
414
- passphrases = util.isArray(passphrases) ? passphrases : [passphrases];
415
-
416
- const results = await Promise.all(this.getKeys(keyId).map(async function(key) {
417
- let decrypted = false;
418
- let error = null;
419
- await Promise.all(passphrases.map(async function(passphrase) {
420
- try {
421
- await key.keyPacket.decrypt(passphrase);
422
- // If we are decrypting a single key packet, we also validate it directly
423
- if (keyId) await key.keyPacket.validate();
424
- decrypted = true;
425
- } catch (e) {
426
- error = e;
427
- }
428
- }));
429
- if (!decrypted) {
430
- throw error;
431
- }
432
- return decrypted;
433
- }));
434
-
435
- if (!keyId) {
436
- // The full key should be decrypted and we can validate it all
437
- await this.validate();
438
- }
439
-
440
- return results.every(result => result === true);
441
- };
442
-
443
- /**
444
- * Check whether the private and public primary key parameters correspond
445
- * Together with verification of binding signatures, this guarantees key integrity
446
- * In case of gnu-dummy primary key, it is enough to validate any signing subkeys
447
- * otherwise all encryption subkeys are validated
448
- * If only gnu-dummy keys are found, we cannot properly validate so we throw an error
449
- * @throws {Error} if validation was not successful and the key cannot be trusted
450
- * @async
451
- */
452
- Key.prototype.validate = async function() {
453
- if (!this.isPrivate()) {
454
- throw new Error("Cannot validate a public key");
455
- }
456
-
457
- let signingKeyPacket;
458
- if (!this.primaryKey.isDummy()) {
459
- signingKeyPacket = this.primaryKey;
460
- } else {
461
- /**
462
- * It is enough to validate any signing keys
463
- * since its binding signatures are also checked
464
- */
465
- const signingKey = await this.getSigningKey(null, null);
466
- // This could again be a dummy key
467
- if (signingKey && !signingKey.keyPacket.isDummy()) {
468
- signingKeyPacket = signingKey.keyPacket;
469
- }
470
- }
471
-
472
- if (signingKeyPacket) {
473
- return signingKeyPacket.validate();
474
- } else {
475
- const keys = this.getKeys();
476
- const allDummies = keys.map(key => key.keyPacket.isDummy()).every(Boolean);
477
- if (allDummies) {
478
- throw new Error("Cannot validate an all-gnu-dummy key");
479
- }
480
-
481
- return Promise.all(keys.map(async key => key.keyPacket.validate()));
482
- }
483
- };
484
-
485
- /**
486
- * Clear private key parameters
487
- */
488
- Key.prototype.clearPrivateParams = function () {
489
- if (!this.isPrivate()) {
490
- throw new Error("Can't clear private parameters of a public key");
491
- }
492
- this.getKeys().forEach(({ keyPacket }) => {
493
- if (keyPacket.isDecrypted()) {
494
- keyPacket.clearPrivateParams();
495
- }
496
- });
497
- };
498
-
499
- /**
500
- * Checks if a signature on a key is revoked
501
- * @param {module:packet.SecretKey|
502
- * @param {module:packet.Signature} signature The signature to verify
503
- * @param {module:packet.PublicSubkey|
504
- * module:packet.SecretSubkey|
505
- * module:packet.PublicKey|
506
- * module:packet.SecretKey} key, optional The key to verify the signature
507
- * @param {Date} date Use the given date instead of the current time
508
- * @returns {Promise<Boolean>} True if the certificate is revoked
509
- * @async
510
- */
511
- Key.prototype.isRevoked = async function(signature, key, date = new Date()) {
512
- return helper.isDataRevoked(
513
- this.keyPacket, enums.signature.key_revocation, { key: this.keyPacket }, this.revocationSignatures, signature, key, date
514
- );
515
- };
516
-
517
- /**
518
- * Verify primary key. Checks for revocation signatures, expiration time
519
- * and valid self signature. Throws if the primary key is invalid.
520
- * @param {Date} date (optional) use the given date for verification instead of the current time
521
- * @param {Object} userId (optional) user ID
522
- * @returns {Promise<true>} The status of the primary key
523
- * @async
524
- */
525
- Key.prototype.verifyPrimaryKey = async function(date = new Date(), userId = {}) {
526
- const primaryKey = this.keyPacket;
527
- // check for key revocation signatures
528
- if (await this.isRevoked(null, null, date)) {
529
- throw new Error('Primary key is revoked');
530
- }
531
- // check for at least one self signature. Self signature of user ID not mandatory
532
- // See {@link https://tools.ietf.org/html/rfc4880#section-11.1}
533
- if (!this.users.some(user => user.userId && user.selfCertifications.length)) {
534
- throw new Error('No self-certifications');
535
- }
536
- // check for valid, unrevoked, unexpired self signature
537
- const { selfCertification } = await this.getPrimaryUser(date, userId);
538
- // check for expiration time
539
- if (helper.isDataExpired(primaryKey, selfCertification, date)) {
540
- throw new Error('Primary key is expired');
541
- }
542
- };
543
-
544
- /**
545
- * Returns the latest date when the key can be used for encrypting, signing, or both, depending on the `capabilities` paramater.
546
- * When `capabilities` is null, defaults to returning the expiry date of the primary key.
547
- * Returns null if `capabilities` is passed and the key does not have the specified capabilities or is revoked or invalid.
548
- * Returns Infinity if the key doesn't expire.
549
- * @param {encrypt|sign|encrypt_sign} capabilities, optional
550
- * @param {module:type/keyid} keyId, optional
551
- * @param {Object} userId, optional user ID
552
- * @returns {Promise<Date | Infinity | null>}
553
- * @async
554
- */
555
- Key.prototype.getExpirationTime = async function(capabilities, keyId, userId) {
556
- const primaryUser = await this.getPrimaryUser(null, userId);
557
- const selfCert = primaryUser.selfCertification;
558
- const keyExpiry = helper.getExpirationTime(this.keyPacket, selfCert);
559
- const sigExpiry = selfCert.getExpirationTime();
560
- let expiry = keyExpiry < sigExpiry ? keyExpiry : sigExpiry;
561
- if (capabilities === 'encrypt' || capabilities === 'encrypt_sign') {
562
- const encryptKey =
563
- await this.getEncryptionKey(keyId, expiry, userId).catch(() => {}) ||
564
- await this.getEncryptionKey(keyId, null, userId).catch(() => {});
565
- if (!encryptKey) return null;
566
- const encryptExpiry = await encryptKey.getExpirationTime(this.keyPacket);
567
- if (encryptExpiry < expiry) expiry = encryptExpiry;
568
- }
569
- if (capabilities === 'sign' || capabilities === 'encrypt_sign') {
570
- const signKey =
571
- await this.getSigningKey(keyId, expiry, userId).catch(() => {}) ||
572
- await this.getSigningKey(keyId, null, userId).catch(() => {});
573
- if (!signKey) return null;
574
- const signExpiry = await signKey.getExpirationTime(this.keyPacket);
575
- if (signExpiry < expiry) expiry = signExpiry;
576
- }
577
- return expiry;
578
- };
579
-
580
- /**
581
- * Returns primary user and most significant (latest valid) self signature
582
- * - if multiple primary users exist, returns the one with the latest self signature
583
- * - otherwise, returns the user with the latest self signature
584
- * @param {Date} date (optional) use the given date for verification instead of the current time
585
- * @param {Object} userId (optional) user ID to get instead of the primary user, if it exists
586
- * @returns {Promise<{user: module:key.User,
587
- * selfCertification: module:packet.Signature}>} The primary user and the self signature
588
- * @async
589
- */
590
- Key.prototype.getPrimaryUser = async function(date = new Date(), userId = {}) {
591
- const primaryKey = this.keyPacket;
592
- const users = [];
593
- let exception;
594
- for (let i = 0; i < this.users.length; i++) {
595
- try {
596
- const user = this.users[i];
597
- if (!user.userId) {
598
- continue;
599
- }
600
- if (
601
- (userId.name !== undefined && user.userId.name !== userId.name) ||
602
- (userId.email !== undefined && user.userId.email !== userId.email) ||
603
- (userId.comment !== undefined && user.userId.comment !== userId.comment)
604
- ) {
605
- throw new Error('Could not find user that matches that user ID');
606
- }
607
- const dataToVerify = { userId: user.userId, key: primaryKey };
608
- const selfCertification = await helper.getLatestValidSignature(user.selfCertifications, primaryKey, enums.signature.cert_generic, dataToVerify, date);
609
- users.push({ index: i, user, selfCertification });
610
- } catch (e) {
611
- exception = e;
612
- }
613
- }
614
- if (!users.length) {
615
- throw exception || new Error('Could not find primary user');
616
- }
617
- await Promise.all(users.map(async function (a) {
618
- return a.user.revoked || a.user.isRevoked(primaryKey, a.selfCertification, null, date);
619
- }));
620
- // sort by primary user flag and signature creation time
621
- const primaryUser = users.sort(function(a, b) {
622
- const A = a.selfCertification;
623
- const B = b.selfCertification;
624
- return B.revoked - A.revoked || A.isPrimaryUserID - B.isPrimaryUserID || A.created - B.created;
625
- }).pop();
626
- const { user, selfCertification: cert } = primaryUser;
627
- if (cert.revoked || await user.isRevoked(primaryKey, cert, null, date)) {
628
- throw new Error('Primary user is revoked');
629
- }
630
- return primaryUser;
631
- };
632
-
633
- /**
634
- * Update key with new components from specified key with same key ID:
635
- * users, subkeys, certificates are merged into the destination key,
636
- * duplicates and expired signatures are ignored.
637
- *
638
- * If the specified key is a private key and the destination key is public,
639
- * the destination key is transformed to a private key.
640
- * @param {module:key.Key} key Source key to merge
641
- * @returns {Promise<undefined>}
642
- * @async
643
- */
644
- Key.prototype.update = async function(key) {
645
- if (!this.hasSameFingerprintAs(key)) {
646
- throw new Error('Key update method: fingerprints of keys not equal');
647
- }
648
- if (this.isPublic() && key.isPrivate()) {
649
- // check for equal subkey packets
650
- const equal = (this.subKeys.length === key.subKeys.length) &&
651
- (this.subKeys.every(destSubKey => {
652
- return key.subKeys.some(srcSubKey => {
653
- return destSubKey.hasSameFingerprintAs(srcSubKey);
654
- });
655
- }));
656
- if (!equal) {
657
- throw new Error('Cannot update public key with private key if subkey mismatch');
658
- }
659
- this.keyPacket = key.keyPacket;
660
- }
661
- // revocation signatures
662
- await helper.mergeSignatures(key, this, 'revocationSignatures', srcRevSig => {
663
- return helper.isDataRevoked(this.keyPacket, enums.signature.key_revocation, this, [srcRevSig], null, key.keyPacket);
664
- });
665
- // direct signatures
666
- await helper.mergeSignatures(key, this, 'directSignatures');
667
- // TODO replace when Promise.some or Promise.any are implemented
668
- // users
669
- await Promise.all(key.users.map(async srcUser => {
670
- let found = false;
671
- await Promise.all(this.users.map(async dstUser => {
672
- if ((srcUser.userId && dstUser.userId &&
673
- (srcUser.userId.userid === dstUser.userId.userid)) ||
674
- (srcUser.userAttribute && (srcUser.userAttribute.equals(dstUser.userAttribute)))) {
675
- await dstUser.update(srcUser, this.keyPacket);
676
- found = true;
677
- }
678
- }));
679
- if (!found) {
680
- this.users.push(srcUser);
681
- }
682
- }));
683
- // TODO replace when Promise.some or Promise.any are implemented
684
- // subkeys
685
- await Promise.all(key.subKeys.map(async srcSubKey => {
686
- let found = false;
687
- await Promise.all(this.subKeys.map(async dstSubKey => {
688
- if (dstSubKey.hasSameFingerprintAs(srcSubKey)) {
689
- await dstSubKey.update(srcSubKey, this.keyPacket);
690
- found = true;
691
- }
692
- }));
693
- if (!found) {
694
- this.subKeys.push(srcSubKey);
695
- }
696
- }));
697
- };
698
-
699
- /**
700
- * Revokes the key
701
- * @param {Object} reasonForRevocation optional, object indicating the reason for revocation
702
- * @param {module:enums.reasonForRevocation} reasonForRevocation.flag optional, flag indicating the reason for revocation
703
- * @param {String} reasonForRevocation.string optional, string explaining the reason for revocation
704
- * @param {Date} date optional, override the creationtime of the revocation signature
705
- * @returns {Promise<module:key.Key>} new key with revocation signature
706
- * @async
707
- */
708
- Key.prototype.revoke = async function({
709
- flag: reasonForRevocationFlag = enums.reasonForRevocation.no_reason,
710
- string: reasonForRevocationString = ''
711
- } = {}, date = new Date()) {
712
- if (this.isPublic()) {
713
- throw new Error('Need private key for revoking');
714
- }
715
- const dataToSign = { key: this.keyPacket };
716
- const key = new Key(this.toPacketlist());
717
- key.revocationSignatures.push(await helper.createSignaturePacket(dataToSign, null, this.keyPacket, {
718
- signatureType: enums.signature.key_revocation,
719
- reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
720
- reasonForRevocationString
721
- }, date));
722
- return key;
723
- };
724
-
725
- /**
726
- * Get revocation certificate from a revoked key.
727
- * (To get a revocation certificate for an unrevoked key, call revoke() first.)
728
- * @param {Date} date Use the given date instead of the current time
729
- * @returns {Promise<String>} armored revocation certificate
730
- * @async
731
- */
732
- Key.prototype.getRevocationCertificate = async function(date = new Date()) {
733
- const dataToVerify = { key: this.keyPacket };
734
- const revocationSignature = await helper.getLatestValidSignature(this.revocationSignatures, this.keyPacket, enums.signature.key_revocation, dataToVerify, date);
735
- const packetlist = new packet.List();
736
- packetlist.push(revocationSignature);
737
- return armor.encode(enums.armor.public_key, packetlist.write(), null, null, 'This is a revocation certificate');
738
- };
739
-
740
- /**
741
- * Applies a revocation certificate to a key
742
- * This adds the first signature packet in the armored text to the key,
743
- * if it is a valid revocation signature.
744
- * @param {String} revocationCertificate armored revocation certificate
745
- * @returns {Promise<module:key.Key>} new revoked key
746
- * @async
747
- */
748
- Key.prototype.applyRevocationCertificate = async function(revocationCertificate) {
749
- const input = await armor.decode(revocationCertificate);
750
- const packetlist = new packet.List();
751
- await packetlist.read(input.data);
752
- const revocationSignature = packetlist.findPacket(enums.packet.signature);
753
- if (!revocationSignature || revocationSignature.signatureType !== enums.signature.key_revocation) {
754
- throw new Error('Could not find revocation signature packet');
755
- }
756
- if (!revocationSignature.issuerKeyId.equals(this.getKeyId())) {
757
- throw new Error('Revocation signature does not match key');
758
- }
759
- if (revocationSignature.isExpired()) {
760
- throw new Error('Revocation signature is expired');
761
- }
762
- try {
763
- await revocationSignature.verify(this.keyPacket, enums.signature.key_revocation, { key: this.keyPacket });
764
- } catch (e) {
765
- throw util.wrapError('Could not verify revocation signature', e);
766
- }
767
- const key = new Key(this.toPacketlist());
768
- key.revocationSignatures.push(revocationSignature);
769
- return key;
770
- };
771
-
772
- /**
773
- * Signs primary user of key
774
- * @param {Array<module:key.Key>} privateKey decrypted private keys for signing
775
- * @param {Date} date (optional) use the given date for verification instead of the current time
776
- * @param {Object} userId (optional) user ID to get instead of the primary user, if it exists
777
- * @returns {Promise<module:key.Key>} new public key with new certificate signature
778
- * @async
779
- */
780
- Key.prototype.signPrimaryUser = async function(privateKeys, date, userId) {
781
- const { index, user } = await this.getPrimaryUser(date, userId);
782
- const userSign = await user.sign(this.keyPacket, privateKeys);
783
- const key = new Key(this.toPacketlist());
784
- key.users[index] = userSign;
785
- return key;
786
- };
787
-
788
- /**
789
- * Signs all users of key
790
- * @param {Array<module:key.Key>} privateKeys decrypted private keys for signing
791
- * @returns {Promise<module:key.Key>} new public key with new certificate signature
792
- * @async
793
- */
794
- Key.prototype.signAllUsers = async function(privateKeys) {
795
- const that = this;
796
- const key = new Key(this.toPacketlist());
797
- key.users = await Promise.all(this.users.map(function(user) {
798
- return user.sign(that.keyPacket, privateKeys);
799
- }));
800
- return key;
801
- };
802
-
803
- /**
804
- * Verifies primary user of key
805
- * - if no arguments are given, verifies the self certificates;
806
- * - otherwise, verifies all certificates signed with given keys.
807
- * @param {Array<module:key.Key>} keys array of keys to verify certificate signatures
808
- * @param {Date} date (optional) use the given date for verification instead of the current time
809
- * @param {Object} userId (optional) user ID to get instead of the primary user, if it exists
810
- * @returns {Promise<Array<{keyid: module:type/keyid,
811
- * valid: Boolean}>>} List of signer's keyid and validity of signature
812
- * @async
813
- */
814
- Key.prototype.verifyPrimaryUser = async function(keys, date, userId) {
815
- const primaryKey = this.keyPacket;
816
- const { user } = await this.getPrimaryUser(date, userId);
817
- const results = keys ? await user.verifyAllCertifications(primaryKey, keys) :
818
- [{ keyid: primaryKey.keyid, valid: await user.verify(primaryKey).catch(() => false) }];
819
- return results;
820
- };
821
-
822
- /**
823
- * Verifies all users of key
824
- * - if no arguments are given, verifies the self certificates;
825
- * - otherwise, verifies all certificates signed with given keys.
826
- * @param {Array<module:key.Key>} keys array of keys to verify certificate signatures
827
- * @returns {Promise<Array<{userid: String,
828
- * keyid: module:type/keyid,
829
- * valid: Boolean}>>} list of userid, signer's keyid and validity of signature
830
- * @async
831
- */
832
- Key.prototype.verifyAllUsers = async function(keys) {
833
- const results = [];
834
- const primaryKey = this.keyPacket;
835
- await Promise.all(this.users.map(async function(user) {
836
- const signatures = keys ? await user.verifyAllCertifications(primaryKey, keys) :
837
- [{ keyid: primaryKey.keyid, valid: await user.verify(primaryKey).catch(() => false) }];
838
- signatures.forEach(signature => {
839
- results.push({
840
- userid: user.userId.userid,
841
- keyid: signature.keyid,
842
- valid: signature.valid
843
- });
844
- });
845
- }));
846
- return results;
847
- };
848
-
849
- /**
850
- * Generates a new OpenPGP subkey, and returns a clone of the Key object with the new subkey added.
851
- * Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the primary key.
852
- * @param {Integer} options.rsaBits number of bits for the key creation.
853
- * @param {Number} [options.keyExpirationTime=0]
854
- * The number of seconds after the key creation time that the key expires
855
- * @param {String} curve (optional) Elliptic curve for ECC keys
856
- * @param {Date} date (optional) Override the creation date of the key and the key signatures
857
- * @param {Boolean} sign (optional) Indicates whether the subkey should sign rather than encrypt. Defaults to false
858
- * @returns {Promise<module:key.Key>}
859
- * @async
860
- */
861
- Key.prototype.addSubkey = async function(options = {}) {
862
- if (!this.isPrivate()) {
863
- throw new Error("Cannot add a subkey to a public key");
864
- }
865
- if (options.passphrase) {
866
- throw new Error("Subkey could not be encrypted here, please encrypt whole key");
867
- }
868
- if (util.getWebCryptoAll() && options.rsaBits < 2048) {
869
- throw new Error('When using webCrypto rsaBits should be 2048 or 4096, found: ' + options.rsaBits);
870
- }
871
- const secretKeyPacket = this.primaryKey;
872
- if (!secretKeyPacket.isDecrypted()) {
873
- throw new Error("Key is not decrypted");
874
- }
875
- const defaultOptions = secretKeyPacket.getAlgorithmInfo();
876
- options = helper.sanitizeKeyOptions(options, defaultOptions);
877
- const keyPacket = await helper.generateSecretSubkey(options);
878
- const bindingSignature = await helper.createBindingSignature(keyPacket, secretKeyPacket, options);
879
- const packetList = this.toPacketlist();
880
- packetList.push(keyPacket);
881
- packetList.push(bindingSignature);
882
- return new Key(packetList);
883
- };
884
-
885
- ['getKeyId', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'isDecrypted', 'hasSameFingerprintAs'].forEach(name => {
886
- Key.prototype[name] =
887
- SubKey.prototype[name];
888
- });