@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.
- package/README.md +311 -239
- package/dist/lightweight/bn.interface.min.mjs +3 -0
- package/dist/lightweight/bn.interface.min.mjs.map +1 -0
- package/dist/lightweight/bn.interface.mjs +340 -0
- package/dist/lightweight/bn.min.mjs +3 -0
- package/dist/lightweight/bn.min.mjs.map +1 -0
- package/dist/lightweight/bn.mjs +3434 -0
- package/dist/lightweight/elliptic.min.mjs +3 -0
- package/dist/lightweight/elliptic.min.mjs.map +1 -0
- package/dist/lightweight/elliptic.mjs +4313 -0
- package/dist/lightweight/openpgp.min.mjs +3 -0
- package/dist/lightweight/openpgp.min.mjs.map +1 -0
- package/dist/lightweight/openpgp.mjs +31375 -0
- package/dist/lightweight/ponyfill.es6.min.mjs +3 -0
- package/dist/lightweight/ponyfill.es6.min.mjs.map +1 -0
- package/dist/lightweight/ponyfill.es6.mjs +3831 -0
- package/dist/lightweight/web-streams-adapter.min.mjs +17 -0
- package/dist/lightweight/web-streams-adapter.min.mjs.map +1 -0
- package/dist/lightweight/web-streams-adapter.mjs +561 -0
- package/dist/node/openpgp.js +43943 -0
- package/dist/node/openpgp.min.js +17 -0
- package/dist/node/openpgp.min.js.map +1 -0
- package/dist/node/openpgp.min.mjs +17 -0
- package/dist/node/openpgp.min.mjs.map +1 -0
- package/dist/node/openpgp.mjs +43880 -0
- package/dist/openpgp.js +41080 -41565
- package/dist/openpgp.min.js +17 -2
- package/dist/openpgp.min.js.map +1 -0
- package/dist/openpgp.min.mjs +17 -0
- package/dist/openpgp.min.mjs.map +1 -0
- package/dist/openpgp.mjs +43868 -0
- package/lightweight/package.json +5 -0
- package/openpgp.d.ts +889 -0
- package/package.json +63 -57
- package/dist/compat/openpgp.js +0 -61067
- package/dist/compat/openpgp.min.js +0 -2
- package/dist/compat/openpgp.worker.js +0 -173
- package/dist/compat/openpgp.worker.min.js +0 -2
- package/dist/lightweight/elliptic.min.js +0 -5
- package/dist/lightweight/openpgp.js +0 -40024
- package/dist/lightweight/openpgp.min.js +0 -2
- package/dist/lightweight/openpgp.worker.js +0 -173
- package/dist/lightweight/openpgp.worker.min.js +0 -2
- package/dist/openpgp.worker.js +0 -173
- package/dist/openpgp.worker.min.js +0 -2
- package/src/cleartext.js +0 -220
- package/src/config/config.js +0 -224
- package/src/config/index.js +0 -7
- package/src/config/localStorage.js +0 -35
- package/src/crypto/aes_kw.js +0 -153
- package/src/crypto/cfb.js +0 -169
- package/src/crypto/cipher/aes.js +0 -27
- package/src/crypto/cipher/blowfish.js +0 -398
- package/src/crypto/cipher/cast5.js +0 -610
- package/src/crypto/cipher/des.js +0 -476
- package/src/crypto/cipher/index.js +0 -91
- package/src/crypto/cipher/twofish.js +0 -346
- package/src/crypto/cmac.js +0 -98
- package/src/crypto/crypto.js +0 -394
- package/src/crypto/eax.js +0 -172
- package/src/crypto/gcm.js +0 -141
- package/src/crypto/hash/index.js +0 -163
- package/src/crypto/hash/md5.js +0 -205
- package/src/crypto/index.js +0 -57
- package/src/crypto/ocb.js +0 -274
- package/src/crypto/pkcs1.js +0 -170
- package/src/crypto/pkcs5.js +0 -55
- package/src/crypto/public_key/dsa.js +0 -188
- package/src/crypto/public_key/elgamal.js +0 -137
- package/src/crypto/public_key/elliptic/curves.js +0 -385
- package/src/crypto/public_key/elliptic/ecdh.js +0 -414
- package/src/crypto/public_key/elliptic/ecdsa.js +0 -348
- package/src/crypto/public_key/elliptic/eddsa.js +0 -119
- package/src/crypto/public_key/elliptic/index.js +0 -34
- package/src/crypto/public_key/elliptic/indutnyKey.js +0 -85
- package/src/crypto/public_key/index.js +0 -28
- package/src/crypto/public_key/prime.js +0 -275
- package/src/crypto/public_key/rsa.js +0 -597
- package/src/crypto/random.js +0 -145
- package/src/crypto/signature.js +0 -137
- package/src/encoding/armor.js +0 -433
- package/src/encoding/base64.js +0 -96
- package/src/enums.js +0 -493
- package/src/hkp.js +0 -89
- package/src/index.js +0 -161
- package/src/key/factory.js +0 -326
- package/src/key/helper.js +0 -363
- package/src/key/index.js +0 -32
- package/src/key/key.js +0 -890
- package/src/key/subkey.js +0 -187
- package/src/key/user.js +0 -230
- package/src/keyring/index.js +0 -12
- package/src/keyring/keyring.js +0 -229
- package/src/keyring/localstore.js +0 -119
- package/src/lightweight_helper.js +0 -26
- package/src/message.js +0 -825
- package/src/openpgp.js +0 -717
- package/src/packet/all_packets.js +0 -116
- package/src/packet/clone.js +0 -189
- package/src/packet/compressed.js +0 -194
- package/src/packet/index.js +0 -20
- package/src/packet/literal.js +0 -168
- package/src/packet/marker.js +0 -62
- package/src/packet/one_pass_signature.js +0 -156
- package/src/packet/packet.js +0 -300
- package/src/packet/packetlist.js +0 -232
- package/src/packet/public_key.js +0 -280
- package/src/packet/public_key_encrypted_session_key.js +0 -156
- package/src/packet/public_subkey.js +0 -44
- package/src/packet/secret_key.js +0 -448
- package/src/packet/secret_subkey.js +0 -41
- package/src/packet/signature.js +0 -782
- package/src/packet/sym_encrypted_aead_protected.js +0 -189
- package/src/packet/sym_encrypted_integrity_protected.js +0 -139
- package/src/packet/sym_encrypted_session_key.js +0 -204
- package/src/packet/symmetrically_encrypted.js +0 -118
- package/src/packet/trust.js +0 -35
- package/src/packet/user_attribute.js +0 -94
- package/src/packet/userid.js +0 -87
- package/src/polyfills.js +0 -64
- package/src/signature.js +0 -73
- package/src/type/ecdh_symkey.js +0 -69
- package/src/type/kdf_params.js +0 -114
- package/src/type/keyid.js +0 -110
- package/src/type/mpi.js +0 -138
- package/src/type/oid.js +0 -110
- package/src/type/s2k.js +0 -203
- package/src/util.js +0 -836
- package/src/wkd.js +0 -88
- package/src/worker/async_proxy.js +0 -190
- package/src/worker/worker.js +0 -167
- package/test/crypto/aes_kw.js +0 -57
- package/test/crypto/cipher/aes.js +0 -86
- package/test/crypto/cipher/blowfish.js +0 -58
- package/test/crypto/cipher/cast5.js +0 -25
- package/test/crypto/cipher/des.js +0 -143
- package/test/crypto/cipher/index.js +0 -7
- package/test/crypto/cipher/twofish.js +0 -71
- package/test/crypto/crypto.js +0 -383
- package/test/crypto/eax.js +0 -150
- package/test/crypto/ecdh.js +0 -359
- package/test/crypto/elliptic.js +0 -251
- package/test/crypto/elliptic_data.js +0 -102
- package/test/crypto/hash/index.js +0 -5
- package/test/crypto/hash/md5.js +0 -16
- package/test/crypto/hash/ripemd.js +0 -14
- package/test/crypto/hash/sha.js +0 -20
- package/test/crypto/index.js +0 -14
- package/test/crypto/ocb.js +0 -183
- package/test/crypto/pkcs5.js +0 -39
- package/test/crypto/random.js +0 -79
- package/test/crypto/rsa.js +0 -180
- package/test/crypto/validate.js +0 -387
- package/test/general/armor.js +0 -408
- package/test/general/brainpool.js +0 -360
- package/test/general/decompression.js +0 -60
- package/test/general/ecc_nist.js +0 -115
- package/test/general/ecc_secp256k1.js +0 -242
- package/test/general/forwarding.js +0 -43
- package/test/general/hkp.js +0 -165
- package/test/general/index.js +0 -20
- package/test/general/key.js +0 -3402
- package/test/general/keyring.js +0 -336
- package/test/general/oid.js +0 -39
- package/test/general/openpgp.js +0 -2542
- package/test/general/packet.js +0 -937
- package/test/general/signature.js +0 -1665
- package/test/general/streaming.js +0 -944
- package/test/general/testInputs.js +0 -18
- package/test/general/util.js +0 -183
- package/test/general/wkd.js +0 -48
- package/test/general/x25519.js +0 -556
- package/test/unittests.js +0 -64
package/src/packet/secret_key.js
DELETED
|
@@ -1,448 +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 packet/public_key
|
|
20
|
-
* @requires type/keyid
|
|
21
|
-
* @requires type/s2k
|
|
22
|
-
* @requires crypto
|
|
23
|
-
* @requires enums
|
|
24
|
-
* @requires util
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
import PublicKey from './public_key';
|
|
28
|
-
import type_keyid from '../type/keyid.js';
|
|
29
|
-
import type_s2k from '../type/s2k';
|
|
30
|
-
import crypto from '../crypto';
|
|
31
|
-
import enums from '../enums';
|
|
32
|
-
import util from '../util';
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* A Secret-Key packet contains all the information that is found in a
|
|
36
|
-
* Public-Key packet, including the public-key material, but also
|
|
37
|
-
* includes the secret-key material after all the public-key fields.
|
|
38
|
-
* @memberof module:packet
|
|
39
|
-
* @constructor
|
|
40
|
-
* @extends module:packet.PublicKey
|
|
41
|
-
*/
|
|
42
|
-
function SecretKey(date = new Date()) {
|
|
43
|
-
PublicKey.call(this, date);
|
|
44
|
-
/**
|
|
45
|
-
* Packet type
|
|
46
|
-
* @type {module:enums.packet}
|
|
47
|
-
*/
|
|
48
|
-
this.tag = enums.packet.secretKey;
|
|
49
|
-
/**
|
|
50
|
-
* Secret-key data
|
|
51
|
-
*/
|
|
52
|
-
this.keyMaterial = null;
|
|
53
|
-
/**
|
|
54
|
-
* Indicates whether secret-key data is encrypted. `this.isEncrypted === false` means data is available in decrypted form.
|
|
55
|
-
*/
|
|
56
|
-
this.isEncrypted = null;
|
|
57
|
-
/**
|
|
58
|
-
* S2K usage
|
|
59
|
-
* @type {Integer}
|
|
60
|
-
*/
|
|
61
|
-
this.s2k_usage = 0;
|
|
62
|
-
/**
|
|
63
|
-
* S2K object
|
|
64
|
-
* @type {type/s2k}
|
|
65
|
-
*/
|
|
66
|
-
this.s2k = null;
|
|
67
|
-
/**
|
|
68
|
-
* Symmetric algorithm
|
|
69
|
-
* @type {String}
|
|
70
|
-
*/
|
|
71
|
-
this.symmetric = null;
|
|
72
|
-
/**
|
|
73
|
-
* AEAD algorithm
|
|
74
|
-
* @type {String}
|
|
75
|
-
*/
|
|
76
|
-
this.aead = null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
SecretKey.prototype = new PublicKey();
|
|
80
|
-
SecretKey.prototype.constructor = SecretKey;
|
|
81
|
-
|
|
82
|
-
// Helper function
|
|
83
|
-
|
|
84
|
-
function parse_cleartext_params(cleartext, algorithm) {
|
|
85
|
-
const algo = enums.write(enums.publicKey, algorithm);
|
|
86
|
-
const types = crypto.getPrivKeyParamTypes(algo);
|
|
87
|
-
const params = crypto.constructParams(types);
|
|
88
|
-
let p = 0;
|
|
89
|
-
|
|
90
|
-
for (let i = 0; i < types.length && p < cleartext.length; i++) {
|
|
91
|
-
p += params[i].read(cleartext.subarray(p, cleartext.length));
|
|
92
|
-
if (p > cleartext.length) {
|
|
93
|
-
throw new Error('Error reading param @:' + p);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return params;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function write_cleartext_params(params, algorithm) {
|
|
101
|
-
const arr = [];
|
|
102
|
-
const algo = enums.write(enums.publicKey, algorithm);
|
|
103
|
-
const numPublicParams = crypto.getPubKeyParamTypes(algo).length;
|
|
104
|
-
|
|
105
|
-
for (let i = numPublicParams; i < params.length; i++) {
|
|
106
|
-
arr.push(params[i].write());
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return util.concatUint8Array(arr);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// 5.5.3. Secret-Key Packet Formats
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Internal parser for private keys as specified in
|
|
117
|
-
* {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.5.3|RFC4880bis-04 section 5.5.3}
|
|
118
|
-
* @param {String} bytes Input string to read the packet from
|
|
119
|
-
*/
|
|
120
|
-
SecretKey.prototype.read = function (bytes) {
|
|
121
|
-
// - A Public-Key or Public-Subkey packet, as described above.
|
|
122
|
-
let i = this.readPublicKey(bytes);
|
|
123
|
-
|
|
124
|
-
// - One octet indicating string-to-key usage conventions. Zero
|
|
125
|
-
// indicates that the secret-key data is not encrypted. 255 or 254
|
|
126
|
-
// indicates that a string-to-key specifier is being given. Any
|
|
127
|
-
// other value is a symmetric-key encryption algorithm identifier.
|
|
128
|
-
this.s2k_usage = bytes[i++];
|
|
129
|
-
|
|
130
|
-
// - Only for a version 5 packet, a one-octet scalar octet count of
|
|
131
|
-
// the next 4 optional fields.
|
|
132
|
-
if (this.version === 5) {
|
|
133
|
-
i++;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
|
|
137
|
-
// one-octet symmetric encryption algorithm.
|
|
138
|
-
if (this.s2k_usage === 255 || this.s2k_usage === 254 || this.s2k_usage === 253) {
|
|
139
|
-
this.symmetric = bytes[i++];
|
|
140
|
-
this.symmetric = enums.read(enums.symmetric, this.symmetric);
|
|
141
|
-
|
|
142
|
-
// - [Optional] If string-to-key usage octet was 253, a one-octet
|
|
143
|
-
// AEAD algorithm.
|
|
144
|
-
if (this.s2k_usage === 253) {
|
|
145
|
-
this.aead = bytes[i++];
|
|
146
|
-
this.aead = enums.read(enums.aead, this.aead);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
|
|
150
|
-
// string-to-key specifier. The length of the string-to-key
|
|
151
|
-
// specifier is implied by its type, as described above.
|
|
152
|
-
this.s2k = new type_s2k();
|
|
153
|
-
i += this.s2k.read(bytes.subarray(i, bytes.length));
|
|
154
|
-
|
|
155
|
-
if (this.s2k.type === 'gnu-dummy') {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
} else if (this.s2k_usage) {
|
|
159
|
-
this.symmetric = this.s2k_usage;
|
|
160
|
-
this.symmetric = enums.read(enums.symmetric, this.symmetric);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// - [Optional] If secret data is encrypted (string-to-key usage octet
|
|
164
|
-
// not zero), an Initial Vector (IV) of the same length as the
|
|
165
|
-
// cipher's block size.
|
|
166
|
-
if (this.s2k_usage) {
|
|
167
|
-
this.iv = bytes.subarray(
|
|
168
|
-
i,
|
|
169
|
-
i + crypto.cipher[this.symmetric].blockSize
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
i += this.iv.length;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// - Only for a version 5 packet, a four-octet scalar octet count for
|
|
176
|
-
// the following key material.
|
|
177
|
-
if (this.version === 5) {
|
|
178
|
-
i += 4;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// - Plain or encrypted multiprecision integers comprising the secret
|
|
182
|
-
// key data. These algorithm-specific fields are as described
|
|
183
|
-
// below.
|
|
184
|
-
this.keyMaterial = bytes.subarray(i);
|
|
185
|
-
this.isEncrypted = !!this.s2k_usage;
|
|
186
|
-
|
|
187
|
-
if (!this.isEncrypted) {
|
|
188
|
-
const cleartext = this.keyMaterial.subarray(0, -2);
|
|
189
|
-
if (!util.equalsUint8Array(util.write_checksum(cleartext), this.keyMaterial.subarray(-2))) {
|
|
190
|
-
throw new Error('Key checksum mismatch');
|
|
191
|
-
}
|
|
192
|
-
const privParams = parse_cleartext_params(cleartext, this.algorithm);
|
|
193
|
-
this.params = this.params.concat(privParams);
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Creates an OpenPGP key packet for the given key.
|
|
199
|
-
* @returns {String} A string of bytes containing the secret key OpenPGP packet
|
|
200
|
-
*/
|
|
201
|
-
SecretKey.prototype.write = function () {
|
|
202
|
-
const arr = [this.writePublicKey()];
|
|
203
|
-
|
|
204
|
-
arr.push(new Uint8Array([this.s2k_usage]));
|
|
205
|
-
|
|
206
|
-
const optionalFieldsArr = [];
|
|
207
|
-
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
|
|
208
|
-
// one- octet symmetric encryption algorithm.
|
|
209
|
-
if (this.s2k_usage === 255 || this.s2k_usage === 254 || this.s2k_usage === 253) {
|
|
210
|
-
optionalFieldsArr.push(enums.write(enums.symmetric, this.symmetric));
|
|
211
|
-
|
|
212
|
-
// - [Optional] If string-to-key usage octet was 253, a one-octet
|
|
213
|
-
// AEAD algorithm.
|
|
214
|
-
if (this.s2k_usage === 253) {
|
|
215
|
-
optionalFieldsArr.push(enums.write(enums.aead, this.aead));
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
|
|
219
|
-
// string-to-key specifier. The length of the string-to-key
|
|
220
|
-
// specifier is implied by its type, as described above.
|
|
221
|
-
optionalFieldsArr.push(...this.s2k.write());
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// - [Optional] If secret data is encrypted (string-to-key usage octet
|
|
225
|
-
// not zero), an Initial Vector (IV) of the same length as the
|
|
226
|
-
// cipher's block size.
|
|
227
|
-
if (this.s2k_usage && this.s2k.type !== 'gnu-dummy') {
|
|
228
|
-
optionalFieldsArr.push(...this.iv);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if (this.version === 5) {
|
|
232
|
-
arr.push(new Uint8Array([optionalFieldsArr.length]));
|
|
233
|
-
}
|
|
234
|
-
arr.push(new Uint8Array(optionalFieldsArr));
|
|
235
|
-
|
|
236
|
-
if (!this.isDummy()) {
|
|
237
|
-
if (!this.s2k_usage) {
|
|
238
|
-
const cleartextParams = write_cleartext_params(this.params, this.algorithm);
|
|
239
|
-
this.keyMaterial = util.concatUint8Array([
|
|
240
|
-
cleartextParams,
|
|
241
|
-
util.write_checksum(cleartextParams)
|
|
242
|
-
]);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (this.version === 5) {
|
|
246
|
-
arr.push(util.writeNumber(this.keyMaterial.length, 4));
|
|
247
|
-
}
|
|
248
|
-
arr.push(this.keyMaterial);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return util.concatUint8Array(arr);
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Check whether secret-key data is available in decrypted form. Returns null for public keys.
|
|
256
|
-
* @returns {Boolean|null}
|
|
257
|
-
*/
|
|
258
|
-
SecretKey.prototype.isDecrypted = function() {
|
|
259
|
-
return this.isEncrypted === false;
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Check whether this is a gnu-dummy key
|
|
264
|
-
* @returns {Boolean}
|
|
265
|
-
*/
|
|
266
|
-
SecretKey.prototype.isDummy = function() {
|
|
267
|
-
return !!(this.s2k && this.s2k.type === 'gnu-dummy');
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Encrypt the payload. By default, we use aes256 and iterated, salted string
|
|
272
|
-
* to key specifier. If the key is in a decrypted state (isEncrypted === false)
|
|
273
|
-
* and the passphrase is empty or undefined, the key will be set as not encrypted.
|
|
274
|
-
* This can be used to remove passphrase protection after calling decrypt().
|
|
275
|
-
* @param {String} passphrase
|
|
276
|
-
* @returns {Promise<Boolean>}
|
|
277
|
-
* @async
|
|
278
|
-
*/
|
|
279
|
-
SecretKey.prototype.encrypt = async function (passphrase) {
|
|
280
|
-
if (this.isDummy()) {
|
|
281
|
-
return false;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (!this.isDecrypted()) {
|
|
285
|
-
throw new Error('Key packet is already encrypted');
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
if (this.isDecrypted() && !passphrase) {
|
|
289
|
-
this.s2k_usage = 0;
|
|
290
|
-
return false;
|
|
291
|
-
} else if (!passphrase) {
|
|
292
|
-
throw new Error('The key must be decrypted before removing passphrase protection.');
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
this.s2k = new type_s2k();
|
|
296
|
-
this.s2k.salt = await crypto.random.getRandomBytes(8);
|
|
297
|
-
const cleartext = write_cleartext_params(this.params, this.algorithm);
|
|
298
|
-
this.symmetric = 'aes256';
|
|
299
|
-
const key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric);
|
|
300
|
-
const blockLen = crypto.cipher[this.symmetric].blockSize;
|
|
301
|
-
this.iv = await crypto.random.getRandomBytes(blockLen);
|
|
302
|
-
|
|
303
|
-
if (this.version === 5) {
|
|
304
|
-
this.s2k_usage = 253;
|
|
305
|
-
this.aead = 'eax';
|
|
306
|
-
const mode = crypto[this.aead];
|
|
307
|
-
const modeInstance = await mode(this.symmetric, key);
|
|
308
|
-
this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), new Uint8Array());
|
|
309
|
-
} else {
|
|
310
|
-
this.s2k_usage = 254;
|
|
311
|
-
this.keyMaterial = await crypto.cfb.encrypt(this.symmetric, key, util.concatUint8Array([
|
|
312
|
-
cleartext,
|
|
313
|
-
await crypto.hash.sha1(cleartext)
|
|
314
|
-
]), this.iv);
|
|
315
|
-
}
|
|
316
|
-
return true;
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
async function produceEncryptionKey(s2k, passphrase, algorithm) {
|
|
320
|
-
return s2k.produce_key(
|
|
321
|
-
passphrase,
|
|
322
|
-
crypto.cipher[algorithm].keySize
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Decrypts the private key params which are needed to use the key.
|
|
328
|
-
* {@link module:packet.SecretKey.isDecrypted} should be false, as
|
|
329
|
-
* otherwise calls to this function will throw an error.
|
|
330
|
-
* @param {String} passphrase The passphrase for this private key as string
|
|
331
|
-
* @returns {Promise<Boolean>}
|
|
332
|
-
* @async
|
|
333
|
-
*/
|
|
334
|
-
SecretKey.prototype.decrypt = async function (passphrase) {
|
|
335
|
-
if (this.isDummy()) {
|
|
336
|
-
this.isEncrypted = false;
|
|
337
|
-
return false;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (this.isDecrypted()) {
|
|
341
|
-
throw new Error('Key packet is already decrypted.');
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
let key;
|
|
345
|
-
if (this.s2k_usage === 254 || this.s2k_usage === 253) {
|
|
346
|
-
key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric);
|
|
347
|
-
} else if (this.s2k_usage === 255) {
|
|
348
|
-
throw new Error('Encrypted private key is authenticated using an insecure two-byte hash');
|
|
349
|
-
} else {
|
|
350
|
-
throw new Error('Private key is encrypted using an insecure S2K function: unsalted MD5');
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
let cleartext;
|
|
354
|
-
if (this.s2k_usage === 253) {
|
|
355
|
-
const mode = crypto[this.aead];
|
|
356
|
-
try {
|
|
357
|
-
const modeInstance = await mode(this.symmetric, key);
|
|
358
|
-
cleartext = await modeInstance.decrypt(this.keyMaterial, this.iv.subarray(0, mode.ivLength), new Uint8Array());
|
|
359
|
-
} catch (err) {
|
|
360
|
-
if (err.message === 'Authentication tag mismatch') {
|
|
361
|
-
throw new Error('Incorrect key passphrase: ' + err.message);
|
|
362
|
-
}
|
|
363
|
-
throw err;
|
|
364
|
-
}
|
|
365
|
-
} else {
|
|
366
|
-
const cleartextWithHash = await crypto.cfb.decrypt(this.symmetric, key, this.keyMaterial, this.iv);
|
|
367
|
-
|
|
368
|
-
cleartext = cleartextWithHash.subarray(0, -20);
|
|
369
|
-
const hash = await crypto.hash.sha1(cleartext);
|
|
370
|
-
|
|
371
|
-
if (!util.equalsUint8Array(hash, cleartextWithHash.subarray(-20))) {
|
|
372
|
-
throw new Error('Incorrect key passphrase');
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const privParams = parse_cleartext_params(cleartext, this.algorithm);
|
|
377
|
-
this.params = this.params.concat(privParams);
|
|
378
|
-
this.isEncrypted = false;
|
|
379
|
-
this.keyMaterial = null;
|
|
380
|
-
this.s2k_usage = 0;
|
|
381
|
-
|
|
382
|
-
return true;
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
SecretKey.prototype.generate = async function (bits, curve) {
|
|
386
|
-
const algo = enums.write(enums.publicKey, this.algorithm);
|
|
387
|
-
this.params = await crypto.generateParams(algo, bits, curve);
|
|
388
|
-
this.isEncrypted = false;
|
|
389
|
-
};
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* Checks that the key parameters are consistent
|
|
393
|
-
* @throws {Error} if validation was not successful
|
|
394
|
-
* @async
|
|
395
|
-
*/
|
|
396
|
-
SecretKey.prototype.validate = async function () {
|
|
397
|
-
if (this.isDummy()) {
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
if (!this.isDecrypted()) {
|
|
402
|
-
throw new Error('Key is not decrypted');
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
const algo = enums.write(enums.publicKey, this.algorithm);
|
|
406
|
-
const validParams = await crypto.validateParams(algo, this.params);
|
|
407
|
-
if (!validParams) {
|
|
408
|
-
throw new Error('Key is invalid');
|
|
409
|
-
}
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Clear private key parameters
|
|
414
|
-
*/
|
|
415
|
-
SecretKey.prototype.clearPrivateParams = function () {
|
|
416
|
-
if (this.s2k && this.s2k.type === 'gnu-dummy') {
|
|
417
|
-
this.isEncrypted = true;
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
const algo = enums.write(enums.publicKey, this.algorithm);
|
|
422
|
-
const publicParamCount = crypto.getPubKeyParamTypes(algo).length;
|
|
423
|
-
this.params.slice(publicParamCount).forEach(param => {
|
|
424
|
-
param.data.fill(0);
|
|
425
|
-
});
|
|
426
|
-
this.params.length = publicParamCount;
|
|
427
|
-
this.isEncrypted = true;
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Fix custom types after cloning
|
|
432
|
-
*/
|
|
433
|
-
SecretKey.prototype.postCloneTypeFix = function() {
|
|
434
|
-
const algo = enums.write(enums.publicKey, this.algorithm);
|
|
435
|
-
const types = [].concat(crypto.getPubKeyParamTypes(algo), crypto.getPrivKeyParamTypes(algo));
|
|
436
|
-
for (let i = 0; i < this.params.length; i++) {
|
|
437
|
-
const param = this.params[i];
|
|
438
|
-
this.params[i] = types[i].fromClone(param);
|
|
439
|
-
}
|
|
440
|
-
if (this.keyid) {
|
|
441
|
-
this.keyid = type_keyid.fromClone(this.keyid);
|
|
442
|
-
}
|
|
443
|
-
if (this.s2k) {
|
|
444
|
-
this.s2k = type_s2k.fromClone(this.s2k);
|
|
445
|
-
}
|
|
446
|
-
};
|
|
447
|
-
|
|
448
|
-
export default SecretKey;
|
|
@@ -1,41 +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 packet/secret_key
|
|
20
|
-
* @requires enums
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import SecretKey from './secret_key';
|
|
24
|
-
import enums from '../enums';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* A Secret-Subkey packet (tag 7) is the subkey analog of the Secret
|
|
28
|
-
* Key packet and has exactly the same format.
|
|
29
|
-
* @memberof module:packet
|
|
30
|
-
* @constructor
|
|
31
|
-
* @extends module:packet.SecretKey
|
|
32
|
-
*/
|
|
33
|
-
function SecretSubkey(date = new Date()) {
|
|
34
|
-
SecretKey.call(this, date);
|
|
35
|
-
this.tag = enums.packet.secretSubkey;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
SecretSubkey.prototype = new SecretKey();
|
|
39
|
-
SecretSubkey.prototype.constructor = SecretSubkey;
|
|
40
|
-
|
|
41
|
-
export default SecretSubkey;
|