@protontech/openpgp 4.10.6 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +31379 -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 +43947 -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 +43884 -0
- package/dist/openpgp.js +41082 -41563
- 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 +43872 -0
- package/lightweight/package.json +5 -0
- package/openpgp.d.ts +890 -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/signature.js
DELETED
|
@@ -1,782 +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 web-stream-tools
|
|
20
|
-
* @requires packet/packet
|
|
21
|
-
* @requires type/keyid
|
|
22
|
-
* @requires type/mpi
|
|
23
|
-
* @requires crypto
|
|
24
|
-
* @requires enums
|
|
25
|
-
* @requires util
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
import stream from 'web-stream-tools';
|
|
29
|
-
import packet from './packet';
|
|
30
|
-
import type_keyid from '../type/keyid.js';
|
|
31
|
-
import type_mpi from '../type/mpi.js';
|
|
32
|
-
import crypto from '../crypto';
|
|
33
|
-
import enums from '../enums';
|
|
34
|
-
import util from '../util';
|
|
35
|
-
import config from '../config';
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Implementation of the Signature Packet (Tag 2)
|
|
39
|
-
*
|
|
40
|
-
* {@link https://tools.ietf.org/html/rfc4880#section-5.2|RFC4480 5.2}:
|
|
41
|
-
* A Signature packet describes a binding between some public key and
|
|
42
|
-
* some data. The most common signatures are a signature of a file or a
|
|
43
|
-
* block of text, and a signature that is a certification of a User ID.
|
|
44
|
-
* @memberof module:packet
|
|
45
|
-
* @constructor
|
|
46
|
-
* @param {Date} date the creation date of the signature
|
|
47
|
-
*/
|
|
48
|
-
function Signature(date = new Date()) {
|
|
49
|
-
this.tag = enums.packet.signature;
|
|
50
|
-
this.version = 4; // This is set to 5 below if we sign with a V5 key.
|
|
51
|
-
this.signatureType = null;
|
|
52
|
-
this.hashAlgorithm = null;
|
|
53
|
-
this.publicKeyAlgorithm = null;
|
|
54
|
-
|
|
55
|
-
this.signatureData = null;
|
|
56
|
-
this.unhashedSubpackets = [];
|
|
57
|
-
this.signedHashValue = null;
|
|
58
|
-
|
|
59
|
-
this.created = util.normalizeDate(date);
|
|
60
|
-
this.signatureExpirationTime = null;
|
|
61
|
-
this.signatureNeverExpires = true;
|
|
62
|
-
this.exportable = null;
|
|
63
|
-
this.trustLevel = null;
|
|
64
|
-
this.trustAmount = null;
|
|
65
|
-
this.regularExpression = null;
|
|
66
|
-
this.revocable = null;
|
|
67
|
-
this.keyExpirationTime = null;
|
|
68
|
-
this.keyNeverExpires = null;
|
|
69
|
-
this.preferredSymmetricAlgorithms = null;
|
|
70
|
-
this.revocationKeyClass = null;
|
|
71
|
-
this.revocationKeyAlgorithm = null;
|
|
72
|
-
this.revocationKeyFingerprint = null;
|
|
73
|
-
this.issuerKeyId = new type_keyid();
|
|
74
|
-
this.notations = [];
|
|
75
|
-
this.preferredHashAlgorithms = null;
|
|
76
|
-
this.preferredCompressionAlgorithms = null;
|
|
77
|
-
this.keyServerPreferences = null;
|
|
78
|
-
this.preferredKeyServer = null;
|
|
79
|
-
this.isPrimaryUserID = null;
|
|
80
|
-
this.policyURI = null;
|
|
81
|
-
this.keyFlags = null;
|
|
82
|
-
this.signersUserId = null;
|
|
83
|
-
this.reasonForRevocationFlag = null;
|
|
84
|
-
this.reasonForRevocationString = null;
|
|
85
|
-
this.features = null;
|
|
86
|
-
this.signatureTargetPublicKeyAlgorithm = null;
|
|
87
|
-
this.signatureTargetHashAlgorithm = null;
|
|
88
|
-
this.signatureTargetHash = null;
|
|
89
|
-
this.embeddedSignature = null;
|
|
90
|
-
this.issuerKeyVersion = null;
|
|
91
|
-
this.issuerFingerprint = null;
|
|
92
|
-
this.preferredAeadAlgorithms = null;
|
|
93
|
-
|
|
94
|
-
this.verified = null;
|
|
95
|
-
this.revoked = null;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* parsing function for a signature packet (tag 2).
|
|
100
|
-
* @param {String} bytes payload of a tag 2 packet
|
|
101
|
-
* @param {Integer} position position to start reading from the bytes string
|
|
102
|
-
* @param {Integer} len length of the packet or the remaining length of bytes at position
|
|
103
|
-
* @returns {module:packet.Signature} object representation
|
|
104
|
-
*/
|
|
105
|
-
Signature.prototype.read = function (bytes) {
|
|
106
|
-
let i = 0;
|
|
107
|
-
this.version = bytes[i++];
|
|
108
|
-
|
|
109
|
-
if (this.version !== 4 && this.version !== 5) {
|
|
110
|
-
throw new Error('Version ' + this.version + ' of the signature is unsupported.');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
this.signatureType = bytes[i++];
|
|
114
|
-
this.publicKeyAlgorithm = bytes[i++];
|
|
115
|
-
this.hashAlgorithm = bytes[i++];
|
|
116
|
-
|
|
117
|
-
// hashed subpackets
|
|
118
|
-
i += this.read_sub_packets(bytes.subarray(i, bytes.length), true);
|
|
119
|
-
|
|
120
|
-
// A V4 signature hashes the packet body
|
|
121
|
-
// starting from its first field, the version number, through the end
|
|
122
|
-
// of the hashed subpacket data. Thus, the fields hashed are the
|
|
123
|
-
// signature version, the signature type, the public-key algorithm, the
|
|
124
|
-
// hash algorithm, the hashed subpacket length, and the hashed
|
|
125
|
-
// subpacket body.
|
|
126
|
-
this.signatureData = bytes.subarray(0, i);
|
|
127
|
-
|
|
128
|
-
// unhashed subpackets
|
|
129
|
-
i += this.read_sub_packets(bytes.subarray(i, bytes.length), false);
|
|
130
|
-
|
|
131
|
-
// Two-octet field holding left 16 bits of signed hash value.
|
|
132
|
-
this.signedHashValue = bytes.subarray(i, i + 2);
|
|
133
|
-
i += 2;
|
|
134
|
-
|
|
135
|
-
this.signature = bytes.subarray(i, bytes.length);
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
Signature.prototype.write = function () {
|
|
139
|
-
const arr = [];
|
|
140
|
-
arr.push(this.signatureData);
|
|
141
|
-
arr.push(this.write_unhashed_sub_packets());
|
|
142
|
-
arr.push(this.signedHashValue);
|
|
143
|
-
arr.push(stream.clone(this.signature));
|
|
144
|
-
return util.concat(arr);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Signs provided data. This needs to be done prior to serialization.
|
|
149
|
-
* @param {module:packet.SecretKey} key private key used to sign the message.
|
|
150
|
-
* @param {Object} data Contains packets to be signed.
|
|
151
|
-
* @param {Boolean} detached (optional) whether to create a detached signature
|
|
152
|
-
* @param {Boolean} streaming (optional) whether to process data as a stream
|
|
153
|
-
* @returns {Promise<Boolean>}
|
|
154
|
-
* @async
|
|
155
|
-
*/
|
|
156
|
-
Signature.prototype.sign = async function (key, data, detached = false, streaming = false) {
|
|
157
|
-
const signatureType = enums.write(enums.signature, this.signatureType);
|
|
158
|
-
const publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm);
|
|
159
|
-
const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
|
|
160
|
-
|
|
161
|
-
if (key.version === 5) {
|
|
162
|
-
this.version = 5;
|
|
163
|
-
}
|
|
164
|
-
const arr = [new Uint8Array([this.version, signatureType, publicKeyAlgorithm, hashAlgorithm])];
|
|
165
|
-
|
|
166
|
-
this.issuerKeyVersion = key.version;
|
|
167
|
-
this.issuerFingerprint = key.getFingerprintBytes();
|
|
168
|
-
this.issuerKeyId = key.getKeyId();
|
|
169
|
-
|
|
170
|
-
// Add hashed subpackets
|
|
171
|
-
arr.push(this.write_hashed_sub_packets());
|
|
172
|
-
|
|
173
|
-
this.signatureData = util.concat(arr);
|
|
174
|
-
|
|
175
|
-
const toHash = this.toHash(signatureType, data, detached);
|
|
176
|
-
const hash = await this.hash(signatureType, data, toHash, detached);
|
|
177
|
-
|
|
178
|
-
this.signedHashValue = stream.slice(stream.clone(hash), 0, 2);
|
|
179
|
-
const params = key.params;
|
|
180
|
-
const signed = async () => crypto.signature.sign(
|
|
181
|
-
publicKeyAlgorithm, hashAlgorithm, params, toHash, await stream.readToEnd(hash)
|
|
182
|
-
);
|
|
183
|
-
if (streaming) {
|
|
184
|
-
this.signature = stream.fromAsync(signed);
|
|
185
|
-
} else {
|
|
186
|
-
this.signature = await signed();
|
|
187
|
-
|
|
188
|
-
// Store the fact that this signature is valid, e.g. for when we call `await
|
|
189
|
-
// getLatestValidSignature(this.revocationSignatures, key, data)` later.
|
|
190
|
-
// Note that this only holds up if the key and data passed to verify are the
|
|
191
|
-
// same as the ones passed to sign.
|
|
192
|
-
this.verified = true;
|
|
193
|
-
}
|
|
194
|
-
return true;
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Creates Uint8Array of bytes of all subpacket data except Issuer and Embedded Signature subpackets
|
|
199
|
-
* @returns {Uint8Array} subpacket data
|
|
200
|
-
*/
|
|
201
|
-
Signature.prototype.write_hashed_sub_packets = function () {
|
|
202
|
-
const sub = enums.signatureSubpacket;
|
|
203
|
-
const arr = [];
|
|
204
|
-
let bytes;
|
|
205
|
-
if (this.created !== null) {
|
|
206
|
-
arr.push(write_sub_packet(sub.signature_creation_time, util.writeDate(this.created)));
|
|
207
|
-
}
|
|
208
|
-
if (this.signatureExpirationTime !== null) {
|
|
209
|
-
arr.push(write_sub_packet(sub.signature_expiration_time, util.writeNumber(this.signatureExpirationTime, 4)));
|
|
210
|
-
}
|
|
211
|
-
if (this.exportable !== null) {
|
|
212
|
-
arr.push(write_sub_packet(sub.exportable_certification, new Uint8Array([this.exportable ? 1 : 0])));
|
|
213
|
-
}
|
|
214
|
-
if (this.trustLevel !== null) {
|
|
215
|
-
bytes = new Uint8Array([this.trustLevel, this.trustAmount]);
|
|
216
|
-
arr.push(write_sub_packet(sub.trust_signature, bytes));
|
|
217
|
-
}
|
|
218
|
-
if (this.regularExpression !== null) {
|
|
219
|
-
arr.push(write_sub_packet(sub.regular_expression, this.regularExpression));
|
|
220
|
-
}
|
|
221
|
-
if (this.revocable !== null) {
|
|
222
|
-
arr.push(write_sub_packet(sub.revocable, new Uint8Array([this.revocable ? 1 : 0])));
|
|
223
|
-
}
|
|
224
|
-
if (this.keyExpirationTime !== null) {
|
|
225
|
-
arr.push(write_sub_packet(sub.key_expiration_time, util.writeNumber(this.keyExpirationTime, 4)));
|
|
226
|
-
}
|
|
227
|
-
if (this.preferredSymmetricAlgorithms !== null) {
|
|
228
|
-
bytes = util.str_to_Uint8Array(util.Uint8Array_to_str(this.preferredSymmetricAlgorithms));
|
|
229
|
-
arr.push(write_sub_packet(sub.preferred_symmetric_algorithms, bytes));
|
|
230
|
-
}
|
|
231
|
-
if (this.revocationKeyClass !== null) {
|
|
232
|
-
bytes = new Uint8Array([this.revocationKeyClass, this.revocationKeyAlgorithm]);
|
|
233
|
-
bytes = util.concat([bytes, this.revocationKeyFingerprint]);
|
|
234
|
-
arr.push(write_sub_packet(sub.revocation_key, bytes));
|
|
235
|
-
}
|
|
236
|
-
this.notations.forEach(([name, value]) => {
|
|
237
|
-
bytes = [new Uint8Array([0x80, 0, 0, 0])];
|
|
238
|
-
// 2 octets of name length
|
|
239
|
-
bytes.push(util.writeNumber(name.length, 2));
|
|
240
|
-
// 2 octets of value length
|
|
241
|
-
bytes.push(util.writeNumber(value.length, 2));
|
|
242
|
-
bytes.push(util.str_to_Uint8Array(name + value));
|
|
243
|
-
bytes = util.concat(bytes);
|
|
244
|
-
arr.push(write_sub_packet(sub.notation_data, bytes));
|
|
245
|
-
});
|
|
246
|
-
if (this.preferredHashAlgorithms !== null) {
|
|
247
|
-
bytes = util.str_to_Uint8Array(util.Uint8Array_to_str(this.preferredHashAlgorithms));
|
|
248
|
-
arr.push(write_sub_packet(sub.preferred_hash_algorithms, bytes));
|
|
249
|
-
}
|
|
250
|
-
if (this.preferredCompressionAlgorithms !== null) {
|
|
251
|
-
bytes = util.str_to_Uint8Array(util.Uint8Array_to_str(this.preferredCompressionAlgorithms));
|
|
252
|
-
arr.push(write_sub_packet(sub.preferred_compression_algorithms, bytes));
|
|
253
|
-
}
|
|
254
|
-
if (this.keyServerPreferences !== null) {
|
|
255
|
-
bytes = util.str_to_Uint8Array(util.Uint8Array_to_str(this.keyServerPreferences));
|
|
256
|
-
arr.push(write_sub_packet(sub.key_server_preferences, bytes));
|
|
257
|
-
}
|
|
258
|
-
if (this.preferredKeyServer !== null) {
|
|
259
|
-
arr.push(write_sub_packet(sub.preferred_key_server, util.str_to_Uint8Array(this.preferredKeyServer)));
|
|
260
|
-
}
|
|
261
|
-
if (this.isPrimaryUserID !== null) {
|
|
262
|
-
arr.push(write_sub_packet(sub.primary_user_id, new Uint8Array([this.isPrimaryUserID ? 1 : 0])));
|
|
263
|
-
}
|
|
264
|
-
if (this.policyURI !== null) {
|
|
265
|
-
arr.push(write_sub_packet(sub.policy_uri, util.str_to_Uint8Array(this.policyURI)));
|
|
266
|
-
}
|
|
267
|
-
if (this.keyFlags !== null) {
|
|
268
|
-
bytes = util.str_to_Uint8Array(util.Uint8Array_to_str(this.keyFlags));
|
|
269
|
-
arr.push(write_sub_packet(sub.key_flags, bytes));
|
|
270
|
-
}
|
|
271
|
-
if (this.signersUserId !== null) {
|
|
272
|
-
arr.push(write_sub_packet(sub.signers_user_id, util.str_to_Uint8Array(this.signersUserId)));
|
|
273
|
-
}
|
|
274
|
-
if (this.reasonForRevocationFlag !== null) {
|
|
275
|
-
bytes = util.str_to_Uint8Array(String.fromCharCode(this.reasonForRevocationFlag) + this.reasonForRevocationString);
|
|
276
|
-
arr.push(write_sub_packet(sub.reason_for_revocation, bytes));
|
|
277
|
-
}
|
|
278
|
-
if (this.features !== null) {
|
|
279
|
-
bytes = util.str_to_Uint8Array(util.Uint8Array_to_str(this.features));
|
|
280
|
-
arr.push(write_sub_packet(sub.features, bytes));
|
|
281
|
-
}
|
|
282
|
-
if (this.signatureTargetPublicKeyAlgorithm !== null) {
|
|
283
|
-
bytes = [new Uint8Array([this.signatureTargetPublicKeyAlgorithm, this.signatureTargetHashAlgorithm])];
|
|
284
|
-
bytes.push(util.str_to_Uint8Array(this.signatureTargetHash));
|
|
285
|
-
bytes = util.concat(bytes);
|
|
286
|
-
arr.push(write_sub_packet(sub.signature_target, bytes));
|
|
287
|
-
}
|
|
288
|
-
if (this.preferredAeadAlgorithms !== null) {
|
|
289
|
-
bytes = util.str_to_Uint8Array(util.Uint8Array_to_str(this.preferredAeadAlgorithms));
|
|
290
|
-
arr.push(write_sub_packet(sub.preferred_aead_algorithms, bytes));
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const result = util.concat(arr);
|
|
294
|
-
const length = util.writeNumber(result.length, 2);
|
|
295
|
-
|
|
296
|
-
return util.concat([length, result]);
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Creates Uint8Array of bytes of Issuer and Embedded Signature subpackets
|
|
301
|
-
* @returns {Uint8Array} subpacket data
|
|
302
|
-
*/
|
|
303
|
-
Signature.prototype.write_unhashed_sub_packets = function() {
|
|
304
|
-
const sub = enums.signatureSubpacket;
|
|
305
|
-
const arr = [];
|
|
306
|
-
let bytes;
|
|
307
|
-
if (!this.issuerKeyId.isNull() && this.issuerKeyVersion !== 5) {
|
|
308
|
-
// If the version of [the] key is greater than 4, this subpacket
|
|
309
|
-
// MUST NOT be included in the signature.
|
|
310
|
-
arr.push(write_sub_packet(sub.issuer, this.issuerKeyId.write()));
|
|
311
|
-
}
|
|
312
|
-
if (this.embeddedSignature !== null) {
|
|
313
|
-
arr.push(write_sub_packet(sub.embedded_signature, this.embeddedSignature.write()));
|
|
314
|
-
}
|
|
315
|
-
if (this.issuerFingerprint !== null) {
|
|
316
|
-
bytes = [new Uint8Array([this.issuerKeyVersion]), this.issuerFingerprint];
|
|
317
|
-
bytes = util.concat(bytes);
|
|
318
|
-
arr.push(write_sub_packet(sub.issuer_fingerprint, bytes));
|
|
319
|
-
}
|
|
320
|
-
this.unhashedSubpackets.forEach(data => {
|
|
321
|
-
arr.push(packet.writeSimpleLength(data.length));
|
|
322
|
-
arr.push(data);
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
const result = util.concat(arr);
|
|
326
|
-
const length = util.writeNumber(result.length, 2);
|
|
327
|
-
|
|
328
|
-
return util.concat([length, result]);
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Creates a string representation of a sub signature packet
|
|
333
|
-
* @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.1|RFC4880 5.2.3.1}
|
|
334
|
-
* @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.2|RFC4880 5.2.3.2}
|
|
335
|
-
* @param {Integer} type subpacket signature type.
|
|
336
|
-
* @param {String} data data to be included
|
|
337
|
-
* @returns {String} a string-representation of a sub signature packet
|
|
338
|
-
* @private
|
|
339
|
-
*/
|
|
340
|
-
function write_sub_packet(type, data) {
|
|
341
|
-
const arr = [];
|
|
342
|
-
arr.push(packet.writeSimpleLength(data.length + 1));
|
|
343
|
-
arr.push(new Uint8Array([type]));
|
|
344
|
-
arr.push(data);
|
|
345
|
-
return util.concat(arr);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
// V4 signature sub packets
|
|
349
|
-
|
|
350
|
-
Signature.prototype.read_sub_packet = function (bytes, trusted = true) {
|
|
351
|
-
let mypos = 0;
|
|
352
|
-
|
|
353
|
-
const read_array = (prop, bytes) => {
|
|
354
|
-
this[prop] = [];
|
|
355
|
-
|
|
356
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
357
|
-
this[prop].push(bytes[i]);
|
|
358
|
-
}
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
// The leftmost bit denotes a "critical" packet
|
|
362
|
-
const critical = bytes[mypos] & 0x80;
|
|
363
|
-
const type = bytes[mypos] & 0x7F;
|
|
364
|
-
|
|
365
|
-
// GPG puts the Issuer and Signature subpackets in the unhashed area.
|
|
366
|
-
// Tampering with those invalidates the signature, so we can trust them.
|
|
367
|
-
// Ignore all other unhashed subpackets.
|
|
368
|
-
if (!trusted && ![
|
|
369
|
-
enums.signatureSubpacket.issuer,
|
|
370
|
-
enums.signatureSubpacket.issuer_fingerprint,
|
|
371
|
-
enums.signatureSubpacket.embedded_signature
|
|
372
|
-
].includes(type)) {
|
|
373
|
-
this.unhashedSubpackets.push(bytes.subarray(mypos, bytes.length));
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
mypos++;
|
|
378
|
-
|
|
379
|
-
// subpacket type
|
|
380
|
-
switch (type) {
|
|
381
|
-
case 2:
|
|
382
|
-
// Signature Creation Time
|
|
383
|
-
this.created = util.readDate(bytes.subarray(mypos, bytes.length));
|
|
384
|
-
break;
|
|
385
|
-
case 3: {
|
|
386
|
-
// Signature Expiration Time in seconds
|
|
387
|
-
const seconds = util.readNumber(bytes.subarray(mypos, bytes.length));
|
|
388
|
-
|
|
389
|
-
this.signatureNeverExpires = seconds === 0;
|
|
390
|
-
this.signatureExpirationTime = seconds;
|
|
391
|
-
|
|
392
|
-
break;
|
|
393
|
-
}
|
|
394
|
-
case 4:
|
|
395
|
-
// Exportable Certification
|
|
396
|
-
this.exportable = bytes[mypos++] === 1;
|
|
397
|
-
break;
|
|
398
|
-
case 5:
|
|
399
|
-
// Trust Signature
|
|
400
|
-
this.trustLevel = bytes[mypos++];
|
|
401
|
-
this.trustAmount = bytes[mypos++];
|
|
402
|
-
break;
|
|
403
|
-
case 6:
|
|
404
|
-
// Regular Expression
|
|
405
|
-
this.regularExpression = bytes[mypos];
|
|
406
|
-
break;
|
|
407
|
-
case 7:
|
|
408
|
-
// Revocable
|
|
409
|
-
this.revocable = bytes[mypos++] === 1;
|
|
410
|
-
break;
|
|
411
|
-
case 9: {
|
|
412
|
-
// Key Expiration Time in seconds
|
|
413
|
-
const seconds = util.readNumber(bytes.subarray(mypos, bytes.length));
|
|
414
|
-
|
|
415
|
-
this.keyExpirationTime = seconds;
|
|
416
|
-
this.keyNeverExpires = seconds === 0;
|
|
417
|
-
|
|
418
|
-
break;
|
|
419
|
-
}
|
|
420
|
-
case 11:
|
|
421
|
-
// Preferred Symmetric Algorithms
|
|
422
|
-
read_array('preferredSymmetricAlgorithms', bytes.subarray(mypos, bytes.length));
|
|
423
|
-
break;
|
|
424
|
-
case 12:
|
|
425
|
-
// Revocation Key
|
|
426
|
-
// (1 octet of class, 1 octet of public-key algorithm ID, 20
|
|
427
|
-
// octets of
|
|
428
|
-
// fingerprint)
|
|
429
|
-
this.revocationKeyClass = bytes[mypos++];
|
|
430
|
-
this.revocationKeyAlgorithm = bytes[mypos++];
|
|
431
|
-
this.revocationKeyFingerprint = bytes.subarray(mypos, mypos + 20);
|
|
432
|
-
break;
|
|
433
|
-
|
|
434
|
-
case 16:
|
|
435
|
-
// Issuer
|
|
436
|
-
this.issuerKeyId.read(bytes.subarray(mypos, bytes.length));
|
|
437
|
-
break;
|
|
438
|
-
|
|
439
|
-
case 20:
|
|
440
|
-
// Notation Data
|
|
441
|
-
// We don't know how to handle anything but a text flagged data.
|
|
442
|
-
if (bytes[mypos] === 0x80) {
|
|
443
|
-
// We extract key/value tuple from the byte stream.
|
|
444
|
-
mypos += 4;
|
|
445
|
-
const m = util.readNumber(bytes.subarray(mypos, mypos + 2));
|
|
446
|
-
mypos += 2;
|
|
447
|
-
const n = util.readNumber(bytes.subarray(mypos, mypos + 2));
|
|
448
|
-
mypos += 2;
|
|
449
|
-
|
|
450
|
-
const name = util.Uint8Array_to_str(bytes.subarray(mypos, mypos + m));
|
|
451
|
-
const value = util.Uint8Array_to_str(bytes.subarray(mypos + m, mypos + m + n));
|
|
452
|
-
|
|
453
|
-
this.notations.push([name, value]);
|
|
454
|
-
|
|
455
|
-
if (critical && (config.known_notations.indexOf(name) === -1)) {
|
|
456
|
-
throw new Error("Unknown critical notation: " + name);
|
|
457
|
-
}
|
|
458
|
-
} else {
|
|
459
|
-
util.print_debug("Unsupported notation flag " + bytes[mypos]);
|
|
460
|
-
}
|
|
461
|
-
break;
|
|
462
|
-
case 21:
|
|
463
|
-
// Preferred Hash Algorithms
|
|
464
|
-
read_array('preferredHashAlgorithms', bytes.subarray(mypos, bytes.length));
|
|
465
|
-
break;
|
|
466
|
-
case 22:
|
|
467
|
-
// Preferred Compression Algorithms
|
|
468
|
-
read_array('preferredCompressionAlgorithms', bytes.subarray(mypos, bytes.length));
|
|
469
|
-
break;
|
|
470
|
-
case 23:
|
|
471
|
-
// Key Server Preferences
|
|
472
|
-
read_array('keyServerPreferences', bytes.subarray(mypos, bytes.length));
|
|
473
|
-
break;
|
|
474
|
-
case 24:
|
|
475
|
-
// Preferred Key Server
|
|
476
|
-
this.preferredKeyServer = util.Uint8Array_to_str(bytes.subarray(mypos, bytes.length));
|
|
477
|
-
break;
|
|
478
|
-
case 25:
|
|
479
|
-
// Primary User ID
|
|
480
|
-
this.isPrimaryUserID = bytes[mypos++] !== 0;
|
|
481
|
-
break;
|
|
482
|
-
case 26:
|
|
483
|
-
// Policy URI
|
|
484
|
-
this.policyURI = util.Uint8Array_to_str(bytes.subarray(mypos, bytes.length));
|
|
485
|
-
break;
|
|
486
|
-
case 27:
|
|
487
|
-
// Key Flags
|
|
488
|
-
read_array('keyFlags', bytes.subarray(mypos, bytes.length));
|
|
489
|
-
break;
|
|
490
|
-
case 28:
|
|
491
|
-
// Signer's User ID
|
|
492
|
-
this.signersUserId = util.Uint8Array_to_str(bytes.subarray(mypos, bytes.length));
|
|
493
|
-
break;
|
|
494
|
-
case 29:
|
|
495
|
-
// Reason for Revocation
|
|
496
|
-
this.reasonForRevocationFlag = bytes[mypos++];
|
|
497
|
-
this.reasonForRevocationString = util.Uint8Array_to_str(bytes.subarray(mypos, bytes.length));
|
|
498
|
-
break;
|
|
499
|
-
case 30:
|
|
500
|
-
// Features
|
|
501
|
-
read_array('features', bytes.subarray(mypos, bytes.length));
|
|
502
|
-
break;
|
|
503
|
-
case 31: {
|
|
504
|
-
// Signature Target
|
|
505
|
-
// (1 octet public-key algorithm, 1 octet hash algorithm, N octets hash)
|
|
506
|
-
this.signatureTargetPublicKeyAlgorithm = bytes[mypos++];
|
|
507
|
-
this.signatureTargetHashAlgorithm = bytes[mypos++];
|
|
508
|
-
|
|
509
|
-
const len = crypto.getHashByteLength(this.signatureTargetHashAlgorithm);
|
|
510
|
-
|
|
511
|
-
this.signatureTargetHash = util.Uint8Array_to_str(bytes.subarray(mypos, mypos + len));
|
|
512
|
-
break;
|
|
513
|
-
}
|
|
514
|
-
case 32:
|
|
515
|
-
// Embedded Signature
|
|
516
|
-
this.embeddedSignature = new Signature();
|
|
517
|
-
this.embeddedSignature.read(bytes.subarray(mypos, bytes.length));
|
|
518
|
-
break;
|
|
519
|
-
case 33:
|
|
520
|
-
// Issuer Fingerprint
|
|
521
|
-
this.issuerKeyVersion = bytes[mypos++];
|
|
522
|
-
this.issuerFingerprint = bytes.subarray(mypos, bytes.length);
|
|
523
|
-
if (this.issuerKeyVersion === 5) {
|
|
524
|
-
this.issuerKeyId.read(this.issuerFingerprint);
|
|
525
|
-
} else {
|
|
526
|
-
this.issuerKeyId.read(this.issuerFingerprint.subarray(-8));
|
|
527
|
-
}
|
|
528
|
-
break;
|
|
529
|
-
case 34:
|
|
530
|
-
// Preferred AEAD Algorithms
|
|
531
|
-
read_array.call(this, 'preferredAeadAlgorithms', bytes.subarray(mypos, bytes.length));
|
|
532
|
-
break;
|
|
533
|
-
default: {
|
|
534
|
-
const err = new Error("Unknown signature subpacket type " + type + " @:" + mypos);
|
|
535
|
-
if (critical) {
|
|
536
|
-
throw err;
|
|
537
|
-
} else {
|
|
538
|
-
util.print_debug(err);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
Signature.prototype.read_sub_packets = function(bytes, trusted = true) {
|
|
545
|
-
// Two-octet scalar octet count for following subpacket data.
|
|
546
|
-
const subpacket_length = util.readNumber(bytes.subarray(0, 2));
|
|
547
|
-
|
|
548
|
-
let i = 2;
|
|
549
|
-
|
|
550
|
-
// subpacket data set (zero or more subpackets)
|
|
551
|
-
while (i < 2 + subpacket_length) {
|
|
552
|
-
const len = packet.readSimpleLength(bytes.subarray(i, bytes.length));
|
|
553
|
-
i += len.offset;
|
|
554
|
-
|
|
555
|
-
this.read_sub_packet(bytes.subarray(i, i + len.len), trusted);
|
|
556
|
-
|
|
557
|
-
i += len.len;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
return i;
|
|
561
|
-
};
|
|
562
|
-
|
|
563
|
-
// Produces data to produce signature on
|
|
564
|
-
Signature.prototype.toSign = function (type, data) {
|
|
565
|
-
const t = enums.signature;
|
|
566
|
-
|
|
567
|
-
switch (type) {
|
|
568
|
-
case t.binary:
|
|
569
|
-
if (data.text !== null) {
|
|
570
|
-
return util.encode_utf8(data.getText(true));
|
|
571
|
-
}
|
|
572
|
-
return data.getBytes(true);
|
|
573
|
-
|
|
574
|
-
case t.text: {
|
|
575
|
-
const bytes = data.getBytes(true);
|
|
576
|
-
// normalize EOL to \r\n
|
|
577
|
-
return util.canonicalizeEOL(bytes);
|
|
578
|
-
}
|
|
579
|
-
case t.standalone:
|
|
580
|
-
return new Uint8Array(0);
|
|
581
|
-
|
|
582
|
-
case t.cert_generic:
|
|
583
|
-
case t.cert_persona:
|
|
584
|
-
case t.cert_casual:
|
|
585
|
-
case t.cert_positive:
|
|
586
|
-
case t.cert_revocation: {
|
|
587
|
-
let packet;
|
|
588
|
-
let tag;
|
|
589
|
-
|
|
590
|
-
if (data.userId) {
|
|
591
|
-
tag = 0xB4;
|
|
592
|
-
packet = data.userId;
|
|
593
|
-
} else if (data.userAttribute) {
|
|
594
|
-
tag = 0xD1;
|
|
595
|
-
packet = data.userAttribute;
|
|
596
|
-
} else {
|
|
597
|
-
throw new Error('Either a userId or userAttribute packet needs to be ' +
|
|
598
|
-
'supplied for certification.');
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
const bytes = packet.write();
|
|
602
|
-
|
|
603
|
-
return util.concat([this.toSign(t.key, data),
|
|
604
|
-
new Uint8Array([tag]),
|
|
605
|
-
util.writeNumber(bytes.length, 4),
|
|
606
|
-
bytes]);
|
|
607
|
-
}
|
|
608
|
-
case t.subkey_binding:
|
|
609
|
-
case t.subkey_revocation:
|
|
610
|
-
case t.key_binding:
|
|
611
|
-
return util.concat([this.toSign(t.key, data), this.toSign(t.key, {
|
|
612
|
-
key: data.bind
|
|
613
|
-
})]);
|
|
614
|
-
|
|
615
|
-
case t.key:
|
|
616
|
-
if (data.key === undefined) {
|
|
617
|
-
throw new Error('Key packet is required for this signature.');
|
|
618
|
-
}
|
|
619
|
-
return data.key.writeForHash(this.version);
|
|
620
|
-
|
|
621
|
-
case t.key_revocation:
|
|
622
|
-
return this.toSign(t.key, data);
|
|
623
|
-
case t.timestamp:
|
|
624
|
-
return new Uint8Array(0);
|
|
625
|
-
case t.third_party:
|
|
626
|
-
throw new Error('Not implemented');
|
|
627
|
-
default:
|
|
628
|
-
throw new Error('Unknown signature type.');
|
|
629
|
-
}
|
|
630
|
-
};
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
Signature.prototype.calculateTrailer = function (data, detached) {
|
|
634
|
-
let length = 0;
|
|
635
|
-
return stream.transform(stream.clone(this.signatureData), value => {
|
|
636
|
-
length += value.length;
|
|
637
|
-
}, () => {
|
|
638
|
-
const arr = [];
|
|
639
|
-
if (this.version === 5 && (this.signatureType === enums.signature.binary || this.signatureType === enums.signature.text)) {
|
|
640
|
-
if (detached) {
|
|
641
|
-
arr.push(new Uint8Array(6));
|
|
642
|
-
} else {
|
|
643
|
-
arr.push(data.writeHeader());
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
arr.push(new Uint8Array([this.version, 0xFF]));
|
|
647
|
-
if (this.version === 5) {
|
|
648
|
-
arr.push(new Uint8Array(4));
|
|
649
|
-
}
|
|
650
|
-
arr.push(util.writeNumber(length, 4));
|
|
651
|
-
// For v5, this should really be writeNumber(length, 8) rather than the
|
|
652
|
-
// hardcoded 4 zero bytes above
|
|
653
|
-
return util.concat(arr);
|
|
654
|
-
});
|
|
655
|
-
};
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
Signature.prototype.toHash = function(signatureType, data, detached = false) {
|
|
659
|
-
const bytes = this.toSign(signatureType, data);
|
|
660
|
-
|
|
661
|
-
return util.concat([bytes, this.signatureData, this.calculateTrailer(data, detached)]);
|
|
662
|
-
};
|
|
663
|
-
|
|
664
|
-
Signature.prototype.hash = async function(signatureType, data, toHash, detached = false, streaming = true) {
|
|
665
|
-
const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
|
|
666
|
-
if (!toHash) toHash = this.toHash(signatureType, data, detached);
|
|
667
|
-
if (!streaming && util.isStream(toHash)) {
|
|
668
|
-
return stream.fromAsync(async () => this.hash(signatureType, data, await stream.readToEnd(toHash), detached));
|
|
669
|
-
}
|
|
670
|
-
return crypto.hash.digest(hashAlgorithm, toHash);
|
|
671
|
-
};
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
/**
|
|
675
|
-
* verifies the signature packet. Note: not all signature types are implemented
|
|
676
|
-
* @param {module:packet.PublicSubkey|module:packet.PublicKey|
|
|
677
|
-
* module:packet.SecretSubkey|module:packet.SecretKey} key the public key to verify the signature
|
|
678
|
-
* @param {module:enums.signature} signatureType expected signature type
|
|
679
|
-
* @param {String|Object} data data which on the signature applies
|
|
680
|
-
* @param {Boolean} detached (optional) whether to verify a detached signature
|
|
681
|
-
* @returns {Promise<Boolean>} True if message is verified, else false.
|
|
682
|
-
* @async
|
|
683
|
-
*/
|
|
684
|
-
Signature.prototype.verify = async function (key, signatureType, data, detached = false, streaming = false) {
|
|
685
|
-
const publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm);
|
|
686
|
-
const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
|
|
687
|
-
|
|
688
|
-
if (publicKeyAlgorithm !== enums.write(enums.publicKey, key.algorithm)) {
|
|
689
|
-
throw new Error('Public key algorithm used to sign signature does not match issuer key algorithm.');
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
let toHash;
|
|
693
|
-
let hash;
|
|
694
|
-
if (this.hashed) {
|
|
695
|
-
hash = await this.hashed;
|
|
696
|
-
} else {
|
|
697
|
-
toHash = this.toHash(signatureType, data, detached);
|
|
698
|
-
if (!streaming) toHash = await stream.readToEnd(toHash);
|
|
699
|
-
hash = await this.hash(signatureType, data, toHash);
|
|
700
|
-
}
|
|
701
|
-
hash = await stream.readToEnd(hash);
|
|
702
|
-
if (this.signedHashValue[0] !== hash[0] ||
|
|
703
|
-
this.signedHashValue[1] !== hash[1]) {
|
|
704
|
-
throw new Error('Message digest did not match');
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
let mpicount = 0;
|
|
708
|
-
// Algorithm-Specific Fields for RSA signatures:
|
|
709
|
-
// - multiprecision number (MPI) of RSA signature value m**d mod n.
|
|
710
|
-
if (publicKeyAlgorithm > 0 && publicKeyAlgorithm < 4) {
|
|
711
|
-
mpicount = 1;
|
|
712
|
-
|
|
713
|
-
// Algorithm-Specific Fields for DSA, ECDSA, and EdDSA signatures:
|
|
714
|
-
// - MPI of DSA value r.
|
|
715
|
-
// - MPI of DSA value s.
|
|
716
|
-
} else if (publicKeyAlgorithm === enums.publicKey.dsa ||
|
|
717
|
-
publicKeyAlgorithm === enums.publicKey.ecdsa ||
|
|
718
|
-
publicKeyAlgorithm === enums.publicKey.eddsa) {
|
|
719
|
-
mpicount = 2;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
// EdDSA signature parameters are encoded in little-endian format
|
|
723
|
-
// https://tools.ietf.org/html/rfc8032#section-5.1.2
|
|
724
|
-
const endian = publicKeyAlgorithm === enums.publicKey.eddsa ? 'le' : 'be';
|
|
725
|
-
const mpi = [];
|
|
726
|
-
let i = 0;
|
|
727
|
-
this.signature = await stream.readToEnd(this.signature);
|
|
728
|
-
for (let j = 0; j < mpicount; j++) {
|
|
729
|
-
mpi[j] = new type_mpi();
|
|
730
|
-
i += mpi[j].read(this.signature.subarray(i, this.signature.length), endian);
|
|
731
|
-
}
|
|
732
|
-
const verified = await crypto.signature.verify(
|
|
733
|
-
publicKeyAlgorithm, hashAlgorithm, mpi, key.params,
|
|
734
|
-
toHash, hash
|
|
735
|
-
);
|
|
736
|
-
if (!verified) {
|
|
737
|
-
throw new Error('Signature verification failed');
|
|
738
|
-
}
|
|
739
|
-
if (config.reject_hash_algorithms.has(hashAlgorithm)) {
|
|
740
|
-
throw new Error('Insecure hash algorithm: ' + enums.read(enums.hash, hashAlgorithm).toUpperCase());
|
|
741
|
-
}
|
|
742
|
-
if (config.reject_message_hash_algorithms.has(hashAlgorithm) &&
|
|
743
|
-
[enums.signature.binary, enums.signature.text].includes(this.signatureType)) {
|
|
744
|
-
throw new Error('Insecure message hash algorithm: ' + enums.read(enums.hash, hashAlgorithm).toUpperCase());
|
|
745
|
-
}
|
|
746
|
-
if (this.revocationKeyClass !== null) {
|
|
747
|
-
throw new Error('This key is intended to be revoked with an authorized key, which OpenPGP.js does not support.');
|
|
748
|
-
}
|
|
749
|
-
this.verified = true;
|
|
750
|
-
return true;
|
|
751
|
-
};
|
|
752
|
-
|
|
753
|
-
/**
|
|
754
|
-
* Verifies signature expiration date
|
|
755
|
-
* @param {Date} date (optional) use the given date for verification instead of the current time
|
|
756
|
-
* @returns {Boolean} true if expired
|
|
757
|
-
*/
|
|
758
|
-
Signature.prototype.isExpired = function (date = new Date()) {
|
|
759
|
-
const normDate = util.normalizeDate(date);
|
|
760
|
-
if (normDate !== null) {
|
|
761
|
-
const expirationTime = this.getExpirationTime();
|
|
762
|
-
return !(this.created <= normDate && normDate <= expirationTime);
|
|
763
|
-
}
|
|
764
|
-
return false;
|
|
765
|
-
};
|
|
766
|
-
|
|
767
|
-
/**
|
|
768
|
-
* Returns the expiration time of the signature or Infinity if signature does not expire
|
|
769
|
-
* @returns {Date} expiration time
|
|
770
|
-
*/
|
|
771
|
-
Signature.prototype.getExpirationTime = function () {
|
|
772
|
-
return !this.signatureNeverExpires ? new Date(this.created.getTime() + this.signatureExpirationTime * 1000) : Infinity;
|
|
773
|
-
};
|
|
774
|
-
|
|
775
|
-
/**
|
|
776
|
-
* Fix custom types after cloning
|
|
777
|
-
*/
|
|
778
|
-
Signature.prototype.postCloneTypeFix = function() {
|
|
779
|
-
this.issuerKeyId = type_keyid.fromClone(this.issuerKeyId);
|
|
780
|
-
};
|
|
781
|
-
|
|
782
|
-
export default Signature;
|