@protontech/openpgp 4.10.5 → 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 +41080 -41565
  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 -61067
  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 -40024
  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 -224
  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 -363
  88. package/src/key/index.js +0 -32
  89. package/src/key/key.js +0 -890
  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 -156
  109. package/src/packet/public_subkey.js +0 -44
  110. package/src/packet/secret_key.js +0 -448
  111. package/src/packet/secret_subkey.js +0 -41
  112. package/src/packet/signature.js +0 -782
  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 -88
  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 -3402
  163. package/test/general/keyring.js +0 -336
  164. package/test/general/oid.js +0 -39
  165. package/test/general/openpgp.js +0 -2542
  166. package/test/general/packet.js +0 -937
  167. package/test/general/signature.js +0 -1665
  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,890 +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
- await this.verifyPrimaryKey(date, userId);
353
- const primaryKey = this.keyPacket;
354
- const keys = [];
355
- for (let i = 0; i < this.subKeys.length; i++) {
356
- if (!keyId || this.subKeys[i].getKeyId().equals(keyId, true)) {
357
- try {
358
- await this.subKeys[i].verify(primaryKey, date);
359
- const dataToVerify = { key: primaryKey, bind: this.subKeys[i].keyPacket };
360
- const bindingSignature = await helper.getLatestValidSignature(this.subKeys[i].bindingSignatures, primaryKey, enums.signature.subkey_binding, dataToVerify, date);
361
- if (bindingSignature && helper.isValidEncryptionKeyPacket(this.subKeys[i].keyPacket, bindingSignature)) {
362
- keys.push(this.subKeys[i]);
363
- }
364
- } catch (e) {}
365
- }
366
- }
367
-
368
- // evaluate primary key
369
- const primaryUser = await this.getPrimaryUser(date, userId);
370
- if ((!keyId || primaryKey.getKeyId().equals(keyId, true)) &&
371
- helper.isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification)) {
372
- keys.push(this);
373
- }
374
-
375
- return keys;
376
- };
377
-
378
- /**
379
- * Encrypts all secret key and subkey packets matching keyId
380
- * @param {String|Array<String>} passphrases - if multiple passphrases, then should be in same order as packets each should encrypt
381
- * @param {module:type/keyid} keyId
382
- * @returns {Promise<Array<module:packet.SecretKey|module:packet.SecretSubkey>>}
383
- * @async
384
- */
385
- Key.prototype.encrypt = async function(passphrases, keyId = null) {
386
- if (!this.isPrivate()) {
387
- throw new Error("Nothing to encrypt in a public key");
388
- }
389
-
390
- const keys = this.getKeys(keyId);
391
- passphrases = util.isArray(passphrases) ? passphrases : new Array(keys.length).fill(passphrases);
392
- if (passphrases.length !== keys.length) {
393
- throw new Error("Invalid number of passphrases for key");
394
- }
395
-
396
- return Promise.all(keys.map(async function(key, i) {
397
- const { keyPacket } = key;
398
- await keyPacket.encrypt(passphrases[i]);
399
- keyPacket.clearPrivateParams();
400
- return keyPacket;
401
- }));
402
- };
403
-
404
- /**
405
- * Decrypts all secret key and subkey packets matching keyId
406
- * @param {String|Array<String>} passphrases
407
- * @param {module:type/keyid} keyId
408
- * @returns {Promise<Boolean>} true if all matching key and subkey packets decrypted successfully
409
- * @throws {Error} if any matching key or subkey packets did not decrypt successfully
410
- * @async
411
- */
412
- Key.prototype.decrypt = async function(passphrases, keyId = null) {
413
- if (!this.isPrivate()) {
414
- throw new Error("Nothing to decrypt in a public key");
415
- }
416
- passphrases = util.isArray(passphrases) ? passphrases : [passphrases];
417
-
418
- const results = await Promise.all(this.getKeys(keyId).map(async function(key) {
419
- let decrypted = false;
420
- let error = null;
421
- await Promise.all(passphrases.map(async function(passphrase) {
422
- try {
423
- await key.keyPacket.decrypt(passphrase);
424
- // If we are decrypting a single key packet, we also validate it directly
425
- if (keyId) await key.keyPacket.validate();
426
- decrypted = true;
427
- } catch (e) {
428
- error = e;
429
- }
430
- }));
431
- if (!decrypted) {
432
- throw error;
433
- }
434
- return decrypted;
435
- }));
436
-
437
- if (!keyId) {
438
- // The full key should be decrypted and we can validate it all
439
- await this.validate();
440
- }
441
-
442
- return results.every(result => result === true);
443
- };
444
-
445
- /**
446
- * Check whether the private and public primary key parameters correspond
447
- * Together with verification of binding signatures, this guarantees key integrity
448
- * In case of gnu-dummy primary key, it is enough to validate any signing subkeys
449
- * otherwise all encryption subkeys are validated
450
- * If only gnu-dummy keys are found, we cannot properly validate so we throw an error
451
- * @throws {Error} if validation was not successful and the key cannot be trusted
452
- * @async
453
- */
454
- Key.prototype.validate = async function() {
455
- if (!this.isPrivate()) {
456
- throw new Error("Cannot validate a public key");
457
- }
458
-
459
- let signingKeyPacket;
460
- if (!this.keyPacket.isDummy()) {
461
- signingKeyPacket = this.primaryKey;
462
- } else {
463
- /**
464
- * It is enough to validate any signing keys
465
- * since its binding signatures are also checked
466
- */
467
- const signingKey = await this.getSigningKey(null, null);
468
- // This could again be a dummy key
469
- if (signingKey && !signingKey.keyPacket.isDummy()) {
470
- signingKeyPacket = signingKey.keyPacket;
471
- }
472
- }
473
-
474
- if (signingKeyPacket) {
475
- return signingKeyPacket.validate();
476
- } else {
477
- const keys = this.getKeys();
478
- const allDummies = keys.map(key => key.keyPacket.isDummy()).every(Boolean);
479
- if (allDummies) {
480
- throw new Error("Cannot validate an all-gnu-dummy key");
481
- }
482
-
483
- return Promise.all(keys.map(async key => key.keyPacket.validate()));
484
- }
485
- };
486
-
487
- /**
488
- * Clear private key parameters
489
- */
490
- Key.prototype.clearPrivateParams = function () {
491
- if (!this.isPrivate()) {
492
- throw new Error("Can't clear private parameters of a public key");
493
- }
494
- this.getKeys().forEach(({ keyPacket }) => {
495
- if (keyPacket.isDecrypted()) {
496
- keyPacket.clearPrivateParams();
497
- }
498
- });
499
- };
500
-
501
- /**
502
- * Checks if a signature on a key is revoked
503
- * @param {module:packet.SecretKey|
504
- * @param {module:packet.Signature} signature The signature to verify
505
- * @param {module:packet.PublicSubkey|
506
- * module:packet.SecretSubkey|
507
- * module:packet.PublicKey|
508
- * module:packet.SecretKey} key, optional The key to verify the signature
509
- * @param {Date} date Use the given date instead of the current time
510
- * @returns {Promise<Boolean>} True if the certificate is revoked
511
- * @async
512
- */
513
- Key.prototype.isRevoked = async function(signature, key, date = new Date()) {
514
- return helper.isDataRevoked(
515
- this.keyPacket, enums.signature.key_revocation, { key: this.keyPacket }, this.revocationSignatures, signature, key, date
516
- );
517
- };
518
-
519
- /**
520
- * Verify primary key. Checks for revocation signatures, expiration time
521
- * and valid self signature. Throws if the primary key is invalid.
522
- * @param {Date} date (optional) use the given date for verification instead of the current time
523
- * @param {Object} userId (optional) user ID
524
- * @returns {Promise<true>} The status of the primary key
525
- * @async
526
- */
527
- Key.prototype.verifyPrimaryKey = async function(date = new Date(), userId = {}) {
528
- const primaryKey = this.keyPacket;
529
- // check for key revocation signatures
530
- if (await this.isRevoked(null, null, date)) {
531
- throw new Error('Primary key is revoked');
532
- }
533
- // check for at least one self signature. Self signature of user ID not mandatory
534
- // See {@link https://tools.ietf.org/html/rfc4880#section-11.1}
535
- if (!this.users.some(user => user.userId && user.selfCertifications.length)) {
536
- throw new Error('No self-certifications');
537
- }
538
- // check for valid, unrevoked, unexpired self signature
539
- const { selfCertification } = await this.getPrimaryUser(date, userId);
540
- // check for expiration time
541
- if (helper.isDataExpired(primaryKey, selfCertification, date)) {
542
- throw new Error('Primary key is expired');
543
- }
544
- };
545
-
546
- /**
547
- * Returns the latest date when the key can be used for encrypting, signing, or both, depending on the `capabilities` paramater.
548
- * When `capabilities` is null, defaults to returning the expiry date of the primary key.
549
- * Returns null if `capabilities` is passed and the key does not have the specified capabilities or is revoked or invalid.
550
- * Returns Infinity if the key doesn't expire.
551
- * @param {encrypt|sign|encrypt_sign} capabilities, optional
552
- * @param {module:type/keyid} keyId, optional
553
- * @param {Object} userId, optional user ID
554
- * @returns {Promise<Date | Infinity | null>}
555
- * @async
556
- */
557
- Key.prototype.getExpirationTime = async function(capabilities, keyId, userId) {
558
- const primaryUser = await this.getPrimaryUser(null, userId);
559
- const selfCert = primaryUser.selfCertification;
560
- const keyExpiry = helper.getExpirationTime(this.keyPacket, selfCert);
561
- const sigExpiry = selfCert.getExpirationTime();
562
- let expiry = keyExpiry < sigExpiry ? keyExpiry : sigExpiry;
563
- if (capabilities === 'encrypt' || capabilities === 'encrypt_sign') {
564
- const encryptKey =
565
- await this.getEncryptionKey(keyId, expiry, userId).catch(() => {}) ||
566
- await this.getEncryptionKey(keyId, null, userId).catch(() => {});
567
- if (!encryptKey) return null;
568
- const encryptExpiry = await encryptKey.getExpirationTime(this.keyPacket);
569
- if (encryptExpiry < expiry) expiry = encryptExpiry;
570
- }
571
- if (capabilities === 'sign' || capabilities === 'encrypt_sign') {
572
- const signKey =
573
- await this.getSigningKey(keyId, expiry, userId).catch(() => {}) ||
574
- await this.getSigningKey(keyId, null, userId).catch(() => {});
575
- if (!signKey) return null;
576
- const signExpiry = await signKey.getExpirationTime(this.keyPacket);
577
- if (signExpiry < expiry) expiry = signExpiry;
578
- }
579
- return expiry;
580
- };
581
-
582
- /**
583
- * Returns primary user and most significant (latest valid) self signature
584
- * - if multiple primary users exist, returns the one with the latest self signature
585
- * - otherwise, returns the user with the latest self signature
586
- * @param {Date} date (optional) use the given date for verification instead of the current time
587
- * @param {Object} userId (optional) user ID to get instead of the primary user, if it exists
588
- * @returns {Promise<{user: module:key.User,
589
- * selfCertification: module:packet.Signature}>} The primary user and the self signature
590
- * @async
591
- */
592
- Key.prototype.getPrimaryUser = async function(date = new Date(), userId = {}) {
593
- const primaryKey = this.keyPacket;
594
- const users = [];
595
- let exception;
596
- for (let i = 0; i < this.users.length; i++) {
597
- try {
598
- const user = this.users[i];
599
- if (!user.userId) {
600
- continue;
601
- }
602
- if (
603
- (userId.name !== undefined && user.userId.name !== userId.name) ||
604
- (userId.email !== undefined && user.userId.email !== userId.email) ||
605
- (userId.comment !== undefined && user.userId.comment !== userId.comment)
606
- ) {
607
- throw new Error('Could not find user that matches that user ID');
608
- }
609
- const dataToVerify = { userId: user.userId, key: primaryKey };
610
- const selfCertification = await helper.getLatestValidSignature(user.selfCertifications, primaryKey, enums.signature.cert_generic, dataToVerify, date);
611
- users.push({ index: i, user, selfCertification });
612
- } catch (e) {
613
- exception = e;
614
- }
615
- }
616
- if (!users.length) {
617
- throw exception || new Error('Could not find primary user');
618
- }
619
- await Promise.all(users.map(async function (a) {
620
- return a.user.revoked || a.user.isRevoked(primaryKey, a.selfCertification, null, date);
621
- }));
622
- // sort by primary user flag and signature creation time
623
- const primaryUser = users.sort(function(a, b) {
624
- const A = a.selfCertification;
625
- const B = b.selfCertification;
626
- return B.revoked - A.revoked || A.isPrimaryUserID - B.isPrimaryUserID || A.created - B.created;
627
- }).pop();
628
- const { user, selfCertification: cert } = primaryUser;
629
- if (cert.revoked || await user.isRevoked(primaryKey, cert, null, date)) {
630
- throw new Error('Primary user is revoked');
631
- }
632
- return primaryUser;
633
- };
634
-
635
- /**
636
- * Update key with new components from specified key with same key ID:
637
- * users, subkeys, certificates are merged into the destination key,
638
- * duplicates and expired signatures are ignored.
639
- *
640
- * If the specified key is a private key and the destination key is public,
641
- * the destination key is transformed to a private key.
642
- * @param {module:key.Key} key Source key to merge
643
- * @returns {Promise<undefined>}
644
- * @async
645
- */
646
- Key.prototype.update = async function(key) {
647
- if (!this.hasSameFingerprintAs(key)) {
648
- throw new Error('Key update method: fingerprints of keys not equal');
649
- }
650
- if (this.isPublic() && key.isPrivate()) {
651
- // check for equal subkey packets
652
- const equal = (this.subKeys.length === key.subKeys.length) &&
653
- (this.subKeys.every(destSubKey => {
654
- return key.subKeys.some(srcSubKey => {
655
- return destSubKey.hasSameFingerprintAs(srcSubKey);
656
- });
657
- }));
658
- if (!equal) {
659
- throw new Error('Cannot update public key with private key if subkey mismatch');
660
- }
661
- this.keyPacket = key.keyPacket;
662
- }
663
- // revocation signatures
664
- await helper.mergeSignatures(key, this, 'revocationSignatures', srcRevSig => {
665
- return helper.isDataRevoked(this.keyPacket, enums.signature.key_revocation, this, [srcRevSig], null, key.keyPacket);
666
- });
667
- // direct signatures
668
- await helper.mergeSignatures(key, this, 'directSignatures');
669
- // TODO replace when Promise.some or Promise.any are implemented
670
- // users
671
- await Promise.all(key.users.map(async srcUser => {
672
- let found = false;
673
- await Promise.all(this.users.map(async dstUser => {
674
- if ((srcUser.userId && dstUser.userId &&
675
- (srcUser.userId.userid === dstUser.userId.userid)) ||
676
- (srcUser.userAttribute && (srcUser.userAttribute.equals(dstUser.userAttribute)))) {
677
- await dstUser.update(srcUser, this.keyPacket);
678
- found = true;
679
- }
680
- }));
681
- if (!found) {
682
- this.users.push(srcUser);
683
- }
684
- }));
685
- // TODO replace when Promise.some or Promise.any are implemented
686
- // subkeys
687
- await Promise.all(key.subKeys.map(async srcSubKey => {
688
- let found = false;
689
- await Promise.all(this.subKeys.map(async dstSubKey => {
690
- if (dstSubKey.hasSameFingerprintAs(srcSubKey)) {
691
- await dstSubKey.update(srcSubKey, this.keyPacket);
692
- found = true;
693
- }
694
- }));
695
- if (!found) {
696
- this.subKeys.push(srcSubKey);
697
- }
698
- }));
699
- };
700
-
701
- /**
702
- * Revokes the key
703
- * @param {Object} reasonForRevocation optional, object indicating the reason for revocation
704
- * @param {module:enums.reasonForRevocation} reasonForRevocation.flag optional, flag indicating the reason for revocation
705
- * @param {String} reasonForRevocation.string optional, string explaining the reason for revocation
706
- * @param {Date} date optional, override the creationtime of the revocation signature
707
- * @returns {Promise<module:key.Key>} new key with revocation signature
708
- * @async
709
- */
710
- Key.prototype.revoke = async function({
711
- flag: reasonForRevocationFlag = enums.reasonForRevocation.no_reason,
712
- string: reasonForRevocationString = ''
713
- } = {}, date = new Date()) {
714
- if (this.isPublic()) {
715
- throw new Error('Need private key for revoking');
716
- }
717
- const dataToSign = { key: this.keyPacket };
718
- const key = new Key(this.toPacketlist());
719
- key.revocationSignatures.push(await helper.createSignaturePacket(dataToSign, null, this.keyPacket, {
720
- signatureType: enums.signature.key_revocation,
721
- reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
722
- reasonForRevocationString
723
- }, date));
724
- return key;
725
- };
726
-
727
- /**
728
- * Get revocation certificate from a revoked key.
729
- * (To get a revocation certificate for an unrevoked key, call revoke() first.)
730
- * @param {Date} date Use the given date instead of the current time
731
- * @returns {Promise<String>} armored revocation certificate
732
- * @async
733
- */
734
- Key.prototype.getRevocationCertificate = async function(date = new Date()) {
735
- const dataToVerify = { key: this.keyPacket };
736
- const revocationSignature = await helper.getLatestValidSignature(this.revocationSignatures, this.keyPacket, enums.signature.key_revocation, dataToVerify, date);
737
- const packetlist = new packet.List();
738
- packetlist.push(revocationSignature);
739
- return armor.encode(enums.armor.public_key, packetlist.write(), null, null, 'This is a revocation certificate');
740
- };
741
-
742
- /**
743
- * Applies a revocation certificate to a key
744
- * This adds the first signature packet in the armored text to the key,
745
- * if it is a valid revocation signature.
746
- * @param {String} revocationCertificate armored revocation certificate
747
- * @returns {Promise<module:key.Key>} new revoked key
748
- * @async
749
- */
750
- Key.prototype.applyRevocationCertificate = async function(revocationCertificate) {
751
- const input = await armor.decode(revocationCertificate);
752
- const packetlist = new packet.List();
753
- await packetlist.read(input.data);
754
- const revocationSignature = packetlist.findPacket(enums.packet.signature);
755
- if (!revocationSignature || revocationSignature.signatureType !== enums.signature.key_revocation) {
756
- throw new Error('Could not find revocation signature packet');
757
- }
758
- if (!revocationSignature.issuerKeyId.equals(this.getKeyId())) {
759
- throw new Error('Revocation signature does not match key');
760
- }
761
- if (revocationSignature.isExpired()) {
762
- throw new Error('Revocation signature is expired');
763
- }
764
- try {
765
- await revocationSignature.verify(this.keyPacket, enums.signature.key_revocation, { key: this.keyPacket });
766
- } catch (e) {
767
- throw util.wrapError('Could not verify revocation signature', e);
768
- }
769
- const key = new Key(this.toPacketlist());
770
- key.revocationSignatures.push(revocationSignature);
771
- return key;
772
- };
773
-
774
- /**
775
- * Signs primary user of key
776
- * @param {Array<module:key.Key>} privateKey decrypted private keys for signing
777
- * @param {Date} date (optional) use the given date for verification instead of the current time
778
- * @param {Object} userId (optional) user ID to get instead of the primary user, if it exists
779
- * @returns {Promise<module:key.Key>} new public key with new certificate signature
780
- * @async
781
- */
782
- Key.prototype.signPrimaryUser = async function(privateKeys, date, userId) {
783
- const { index, user } = await this.getPrimaryUser(date, userId);
784
- const userSign = await user.sign(this.keyPacket, privateKeys);
785
- const key = new Key(this.toPacketlist());
786
- key.users[index] = userSign;
787
- return key;
788
- };
789
-
790
- /**
791
- * Signs all users of key
792
- * @param {Array<module:key.Key>} privateKeys decrypted private keys for signing
793
- * @returns {Promise<module:key.Key>} new public key with new certificate signature
794
- * @async
795
- */
796
- Key.prototype.signAllUsers = async function(privateKeys) {
797
- const that = this;
798
- const key = new Key(this.toPacketlist());
799
- key.users = await Promise.all(this.users.map(function(user) {
800
- return user.sign(that.keyPacket, privateKeys);
801
- }));
802
- return key;
803
- };
804
-
805
- /**
806
- * Verifies primary user of key
807
- * - if no arguments are given, verifies the self certificates;
808
- * - otherwise, verifies all certificates signed with given keys.
809
- * @param {Array<module:key.Key>} keys array of keys to verify certificate signatures
810
- * @param {Date} date (optional) use the given date for verification instead of the current time
811
- * @param {Object} userId (optional) user ID to get instead of the primary user, if it exists
812
- * @returns {Promise<Array<{keyid: module:type/keyid,
813
- * valid: Boolean}>>} List of signer's keyid and validity of signature
814
- * @async
815
- */
816
- Key.prototype.verifyPrimaryUser = async function(keys, date, userId) {
817
- const primaryKey = this.keyPacket;
818
- const { user } = await this.getPrimaryUser(date, userId);
819
- const results = keys ? await user.verifyAllCertifications(primaryKey, keys) :
820
- [{ keyid: primaryKey.keyid, valid: await user.verify(primaryKey).catch(() => false) }];
821
- return results;
822
- };
823
-
824
- /**
825
- * Verifies all users of key
826
- * - if no arguments are given, verifies the self certificates;
827
- * - otherwise, verifies all certificates signed with given keys.
828
- * @param {Array<module:key.Key>} keys array of keys to verify certificate signatures
829
- * @returns {Promise<Array<{userid: String,
830
- * keyid: module:type/keyid,
831
- * valid: Boolean}>>} list of userid, signer's keyid and validity of signature
832
- * @async
833
- */
834
- Key.prototype.verifyAllUsers = async function(keys) {
835
- const results = [];
836
- const primaryKey = this.keyPacket;
837
- await Promise.all(this.users.map(async function(user) {
838
- const signatures = keys ? await user.verifyAllCertifications(primaryKey, keys) :
839
- [{ keyid: primaryKey.keyid, valid: await user.verify(primaryKey).catch(() => false) }];
840
- signatures.forEach(signature => {
841
- results.push({
842
- userid: user.userId.userid,
843
- keyid: signature.keyid,
844
- valid: signature.valid
845
- });
846
- });
847
- }));
848
- return results;
849
- };
850
-
851
- /**
852
- * Generates a new OpenPGP subkey, and returns a clone of the Key object with the new subkey added.
853
- * Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the primary key.
854
- * @param {Integer} options.rsaBits number of bits for the key creation.
855
- * @param {Number} [options.keyExpirationTime=0]
856
- * The number of seconds after the key creation time that the key expires
857
- * @param {String} curve (optional) Elliptic curve for ECC keys
858
- * @param {Date} date (optional) Override the creation date of the key and the key signatures
859
- * @param {Boolean} sign (optional) Indicates whether the subkey should sign rather than encrypt. Defaults to false
860
- * @returns {Promise<module:key.Key>}
861
- * @async
862
- */
863
- Key.prototype.addSubkey = async function(options = {}) {
864
- if (!this.isPrivate()) {
865
- throw new Error("Cannot add a subkey to a public key");
866
- }
867
- if (options.passphrase) {
868
- throw new Error("Subkey could not be encrypted here, please encrypt whole key");
869
- }
870
- if (util.getWebCryptoAll() && options.rsaBits < 2048) {
871
- throw new Error('When using webCrypto rsaBits should be 2048 or 4096, found: ' + options.rsaBits);
872
- }
873
- const secretKeyPacket = this.primaryKey;
874
- if (!secretKeyPacket.isDecrypted()) {
875
- throw new Error("Key is not decrypted");
876
- }
877
- const defaultOptions = secretKeyPacket.getAlgorithmInfo();
878
- options = helper.sanitizeKeyOptions(options, defaultOptions);
879
- const keyPacket = await helper.generateSecretSubkey(options);
880
- const bindingSignature = await helper.createBindingSignature(keyPacket, secretKeyPacket, options);
881
- const packetList = this.toPacketlist();
882
- packetList.push(keyPacket);
883
- packetList.push(bindingSignature);
884
- return new Key(packetList);
885
- };
886
-
887
- ['getKeyId', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'isDecrypted', 'hasSameFingerprintAs'].forEach(name => {
888
- Key.prototype[name] =
889
- SubKey.prototype[name];
890
- });