@it-enterprise/digital-signature 1.1.6 → 1.2.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/.eslintrc.js +1 -4
- package/euscp/EndUserConstants.d.ts +44 -22
- package/euscp/EndUserSettings.d.ts +3 -1
- package/euscp/EndUserSignContainerInfo.d.ts +10 -0
- package/euscp/EndUserSignInfo.d.ts +2 -0
- package/euscp/euscp.d.ts +29 -4
- package/euscp/euscp.js +8 -8
- package/package.json +2 -1
- package/readme.md +300 -110
- package/src/DigitalSignature.js +444 -235
- package/src/Models.js +89 -118
- package/src/Resourses.json +30 -3
- package/src/Utils.js +57 -1
package/src/DigitalSignature.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { EndUser, EndUserConstants, EndUserProxySettings, EndUserError, KSPSettings, EndUserCertificate, EndUserKeyMedia } from "../euscp/euscp";
|
|
1
|
+
import { EndUser, EndUserConstants, EndUserProxySettings, EndUserError, KSPSettings, EndUserCertificate, EndUserKeyMedia, EndUserSignContainerInfo } from "../euscp/euscp";
|
|
2
2
|
import { DigitalSignatureKeyType, PrivateKeyInfo, FilePrivateKeyInfo, HardwarePrivateKeyInfo, KspPrivateKeyInfo } from "./Models";
|
|
3
|
-
import { downloadData, readFile } from "./Utils";
|
|
3
|
+
import { downloadAndSignFiles, downloadData, format, readFile, signAlgoToHashAlgo } from "./Utils";
|
|
4
4
|
import Resourses from "./Resourses.json";
|
|
5
5
|
import GlSign from "./GlSign";
|
|
6
6
|
|
|
7
|
+
const PRIVATE_KEY_TYPE = "PKType";
|
|
8
|
+
const PRIVATE_KEY_INFO = "PKInfo";
|
|
9
|
+
|
|
7
10
|
export default class DigitalSignature {
|
|
8
11
|
/**
|
|
9
12
|
* @param {DigitalSignatureSettings} settingsProvider
|
|
@@ -33,30 +36,85 @@ export default class DigitalSignature {
|
|
|
33
36
|
depositsign.ksp = EndUserConstants.EU_KSP_IIT;
|
|
34
37
|
depositsign.address = "https://depositsign.com/api/v1/it-enterprise/sign-server";
|
|
35
38
|
depositsign.directAccess = true;
|
|
39
|
+
depositsign.needQRCode = false;
|
|
36
40
|
|
|
37
41
|
const diia = new KSPSettings();
|
|
38
|
-
diia.name = "
|
|
42
|
+
diia.name = "Дія.Підпис";
|
|
39
43
|
diia.ksp = EndUserConstants.EU_KSP_DIIA;
|
|
40
44
|
diia.directAccess = true;
|
|
41
|
-
diia.mobileAppName = "
|
|
45
|
+
diia.mobileAppName = "Дія";
|
|
42
46
|
diia.address = "https://diia-sign.it.ua/KSPSign";
|
|
43
47
|
diia.systemId = "diia-sign-it-ent";
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
diia.needQRCode = true;
|
|
49
|
+
|
|
50
|
+
const smartId = new KSPSettings();
|
|
51
|
+
smartId.name = "Приватбанк - хмарний підпис \"SmartID\"";
|
|
52
|
+
smartId.ksp = EndUserConstants.EU_KSP_PB;
|
|
53
|
+
smartId.directAccess = true;
|
|
54
|
+
smartId.mobileAppName = "Приват24";
|
|
55
|
+
smartId.address = "https://acsk.privatbank.ua/cloud/api/back/";
|
|
56
|
+
smartId.clientIdPrefix = "IEIS_";
|
|
57
|
+
smartId.confirmationURL = "https://www.privat24.ua/rd/kep";
|
|
58
|
+
smartId.needQRCode = true;
|
|
59
|
+
|
|
60
|
+
const vchasno = new KSPSettings();
|
|
61
|
+
vchasno.name = "Вчасно - хмарний підпис";
|
|
62
|
+
vchasno.ksp = EndUserConstants.EU_KSP_IIT;
|
|
63
|
+
vchasno.address = "https://cs.vchasno.ua/ss/";
|
|
64
|
+
vchasno.directAccess = true;
|
|
65
|
+
vchasno.needQRCode = false;
|
|
66
|
+
|
|
67
|
+
const cloudKey = new KSPSettings();
|
|
68
|
+
cloudKey.name = "ТОВ «ЦСК «Україна» - хмарний підпис CloudKey";
|
|
69
|
+
cloudKey.ksp = EndUserConstants.EU_KSP_PB;
|
|
70
|
+
cloudKey.directAccess = true;
|
|
71
|
+
cloudKey.mobileAppName = "CloudKey";
|
|
72
|
+
cloudKey.address = "https://sid.uakey.com.ua/smartid/iit/";
|
|
73
|
+
cloudKey.clientIdPrefix = "DIIA_2";
|
|
74
|
+
cloudKey.confirmationURL = "https://sid.uakey.com.ua/kep?hash=rd/kep";
|
|
75
|
+
cloudKey.needQRCode = true;
|
|
76
|
+
|
|
77
|
+
const esign = new KSPSettings();
|
|
78
|
+
esign.name = "ESign - хмарний підпис";
|
|
79
|
+
esign.ksp = EndUserConstants.EU_KSP_IIT;
|
|
80
|
+
esign.address = "https://cabinet.e-life.com.ua/api/EDG/Sign";
|
|
81
|
+
esign.directAccess = true;
|
|
82
|
+
esign.needQRCode = false;
|
|
83
|
+
|
|
84
|
+
const idd = new KSPSettings();
|
|
85
|
+
idd.name = "ІДД ДПС - хмарний підпис";
|
|
86
|
+
idd.ksp = EndUserConstants.EU_KSP_IIT;
|
|
87
|
+
idd.address = "https://smart-sign.tax.gov.ua/";
|
|
88
|
+
idd.port = "443";
|
|
89
|
+
idd.directAccess = true;
|
|
90
|
+
idd.clientIdType = 1;
|
|
91
|
+
idd.needQRCode = false;
|
|
92
|
+
|
|
93
|
+
this._KSPs = {
|
|
94
|
+
depositsign,
|
|
95
|
+
diia,
|
|
96
|
+
smartId,
|
|
97
|
+
vchasno,
|
|
98
|
+
cloudKey,
|
|
99
|
+
esign,
|
|
100
|
+
idd,
|
|
101
|
+
asArray: function() {
|
|
102
|
+
return [
|
|
103
|
+
depositsign,
|
|
104
|
+
diia,
|
|
105
|
+
smartId,
|
|
106
|
+
vchasno,
|
|
107
|
+
cloudKey,
|
|
108
|
+
esign,
|
|
109
|
+
idd
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
};
|
|
47
113
|
|
|
48
114
|
/** @type {PrivateKeyInfo} */
|
|
49
115
|
this._readedKey = null;
|
|
50
116
|
}
|
|
51
117
|
|
|
52
|
-
get PRIVATE_KEY_TYPE() {
|
|
53
|
-
return "_PrivateKeyType";
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
get PRIVATE_KEY_INFO() {
|
|
57
|
-
return "_PrivateKeyInfo";
|
|
58
|
-
}
|
|
59
|
-
|
|
60
118
|
/**
|
|
61
119
|
* Считанный приватный ключ
|
|
62
120
|
* @type {PrivateKeyInfo}
|
|
@@ -78,21 +136,24 @@ export default class DigitalSignature {
|
|
|
78
136
|
* @param {number} type
|
|
79
137
|
*/
|
|
80
138
|
async setLibraryType(type) {
|
|
81
|
-
|
|
82
|
-
if (this._euSign) {
|
|
83
|
-
await this._euSign.ResetPrivateKey();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
139
|
switch (type) {
|
|
87
140
|
case DigitalSignatureKeyType.Token:
|
|
141
|
+
if (this._euSign === this._euSignKeyMedia) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
88
144
|
this._euSign = this._euSignKeyMedia;
|
|
89
145
|
break;
|
|
90
146
|
default:
|
|
147
|
+
if (this._euSign === this._euSignFile) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
91
150
|
this._euSign = this._euSignFile;
|
|
92
151
|
break;
|
|
93
152
|
}
|
|
94
153
|
|
|
95
|
-
|
|
154
|
+
if (type != null && type != undefined) {
|
|
155
|
+
this._preferredKeyType = type;
|
|
156
|
+
}
|
|
96
157
|
|
|
97
158
|
await this.initialise();
|
|
98
159
|
this.keyType = type;
|
|
@@ -103,7 +164,6 @@ export default class DigitalSignature {
|
|
|
103
164
|
* @returns {Promise<number>} Текущий тип библиотеки
|
|
104
165
|
*/
|
|
105
166
|
async initialise() {
|
|
106
|
-
|
|
107
167
|
if (!this._glSign) {
|
|
108
168
|
this._glSign = await Promise.resolve(this._settingsProvider.getGlSign());
|
|
109
169
|
}
|
|
@@ -185,38 +245,55 @@ export default class DigitalSignature {
|
|
|
185
245
|
return this.getLibraryType();
|
|
186
246
|
}
|
|
187
247
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
"криптомод. ІІТ Гряда-301",
|
|
203
|
-
"е.ключ ІІТ Алмаз-1К",
|
|
204
|
-
"е.ключ ІІТ Кристал-1",
|
|
205
|
-
"ID-карта громадянина (БЕН)",
|
|
206
|
-
"е.ключ ІІТ Алмаз-1К (PKCS#11)",
|
|
207
|
-
"е.ключ ІІТ Кристал-1 (PKCS#11)",
|
|
208
|
-
"е.ключ чи смарт-карта Avest (PKCS#11)",
|
|
209
|
-
"е.ключ Ефіт Key (PKCS#11)",
|
|
210
|
-
"е.ключ чи смарт-карта Автор (PKCS#11)",
|
|
211
|
-
"е.ключ чи смарт-карта Автор 338 (PKCS#11)",
|
|
212
|
-
"смарт-карта Техноконс. TEllipse3 (PKCS#11)",
|
|
213
|
-
"смарт-карта Техноконс. TEllipse",
|
|
214
|
-
"смарт-карта Техноконс. TEllipse2/3",
|
|
215
|
-
"е.ключ SafeNet iKey (PKCS#11, RSA)"
|
|
216
|
-
]
|
|
217
|
-
};
|
|
248
|
+
if (!this._euSettings) {
|
|
249
|
+
let certificates;
|
|
250
|
+
try {
|
|
251
|
+
certificates = await this._settings.certificatesProvider.loadCertificates();
|
|
252
|
+
} catch (error) {
|
|
253
|
+
if (error && error.code === EndUserError.EU_ERROR_DOWNLOAD_FILE) {
|
|
254
|
+
throw {
|
|
255
|
+
code: EndUserError.EU_ERROR_DOWNLOAD_FILE,
|
|
256
|
+
message: this._resourses.DownloadingRootCertificatesError
|
|
257
|
+
};
|
|
258
|
+
} else {
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
218
262
|
|
|
219
|
-
|
|
263
|
+
this._euSettings = {
|
|
264
|
+
language: this._language,
|
|
265
|
+
encoding: "UTF-16LE",
|
|
266
|
+
httpProxyServiceURL: this._settings.httpProxyServiceURL,
|
|
267
|
+
directAccess: true,
|
|
268
|
+
CAs: certificates.CAs,
|
|
269
|
+
CACertificates: certificates.CACertificates,
|
|
270
|
+
KSPs: this.KSPs,
|
|
271
|
+
allowedKeyMediaTypes: [
|
|
272
|
+
"е.ключ BIFIT iToken",
|
|
273
|
+
"криптомод. ІІТ Гряда-61",
|
|
274
|
+
"е.ключ ІІТ Алмаз-1К",
|
|
275
|
+
"е.ключ ІІТ Алмаз-1К (Bluetooth)",
|
|
276
|
+
"е.ключ ІІТ Кристал-1",
|
|
277
|
+
"криптомод. ІІТ Гряда-301",
|
|
278
|
+
"ID-карта громадянина (БЕН)",
|
|
279
|
+
"е.ключ ІІТ Алмаз-1К (PKCS#11)",
|
|
280
|
+
"е.ключ ІІТ Кристал-1 (PKCS#11)",
|
|
281
|
+
"е.ключ чи смарт-карта Avest (PKCS#11)",
|
|
282
|
+
"е.ключ Ефіт Key (PKCS#11)",
|
|
283
|
+
"е.ключ чи смарт-карта Автор (PKCS#11)",
|
|
284
|
+
"е.ключ чи смарт-карта Автор 338 (PKCS#11)",
|
|
285
|
+
"смарт-карта Техноконс. TEllipse3 (PKCS#11)",
|
|
286
|
+
"смарт-карта Техноконс. TEllipse",
|
|
287
|
+
"смарт-карта Техноконс. TEllipse2/3",
|
|
288
|
+
"е.ключ SafeNet iKey (PKCS#11, RSA)"
|
|
289
|
+
]
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
await euSign.Initialize(this._euSettings);
|
|
294
|
+
if (euSign === this._euSignKeyMedia && !await this._euSignFile.IsInitialized()) {
|
|
295
|
+
this._euSignFile.Initialize(this._euSettings);
|
|
296
|
+
}
|
|
220
297
|
if (this._glSign.ApplyProxySettings) {
|
|
221
298
|
const { UseProxy, ProxyAddress, ProxyPort, ProxyUser, ProxyPassword } = this._glSign;
|
|
222
299
|
const proxy = new EndUserProxySettings();
|
|
@@ -228,9 +305,15 @@ export default class DigitalSignature {
|
|
|
228
305
|
proxy.password = ProxyPassword;
|
|
229
306
|
proxy.savePassword = true;
|
|
230
307
|
await euSign.SetProxySettings(proxy);
|
|
308
|
+
if (euSign === this._euSignKeyMedia && !await this._euSignFile.IsInitialized()) {
|
|
309
|
+
this._euSignFile.SetProxySettings(proxy);
|
|
310
|
+
}
|
|
231
311
|
}
|
|
232
312
|
|
|
233
313
|
await euSign.SetRuntimeParameter(EndUserConstants.EU_SIGN_TYPE_PARAMETER, EndUserConstants.EndUserSignType.CAdES_X_Long);
|
|
314
|
+
if (euSign === this._euSignKeyMedia && !await this._euSignFile.IsInitialized()) {
|
|
315
|
+
this._euSignFile.SetRuntimeParameter(EndUserConstants.EU_SIGN_TYPE_PARAMETER, EndUserConstants.EndUserSignType.CAdES_X_Long);
|
|
316
|
+
}
|
|
234
317
|
|
|
235
318
|
return this.getLibraryType();
|
|
236
319
|
}
|
|
@@ -245,13 +328,11 @@ export default class DigitalSignature {
|
|
|
245
328
|
|
|
246
329
|
/**
|
|
247
330
|
* Получить список подключённых устройств
|
|
248
|
-
* @returns {Promise<Array<EndUserKeyMedia>>}
|
|
331
|
+
* @returns {Promise<Array<EndUserKeyMedia>>} Список подключённых устройств
|
|
249
332
|
*/
|
|
250
333
|
async getKeyMedias() {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
return this._euSign.GetKeyMedias();
|
|
334
|
+
await this.setLibraryType(DigitalSignatureKeyType.Token);
|
|
335
|
+
return this._euSignKeyMedia.GetKeyMedias();
|
|
255
336
|
}
|
|
256
337
|
|
|
257
338
|
/**
|
|
@@ -260,20 +341,57 @@ export default class DigitalSignature {
|
|
|
260
341
|
* @param {Array<Uint8Array>?} certs - Сертификаты ключа (при необходимости)
|
|
261
342
|
*/
|
|
262
343
|
async readHardwareKey(keyMedia, certs) {
|
|
263
|
-
|
|
264
|
-
|
|
344
|
+
await this.setLibraryType(DigitalSignatureKeyType.Token);
|
|
345
|
+
|
|
346
|
+
if (!keyMedia) {
|
|
347
|
+
throw {
|
|
348
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
349
|
+
message: this._resourses.BadParameter + " keyMedia"
|
|
350
|
+
};
|
|
265
351
|
}
|
|
352
|
+
if (!keyMedia.password) {
|
|
353
|
+
throw {
|
|
354
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
355
|
+
message: this._resourses.PasswordNotSet
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
266
359
|
if (Array.isArray(certs)) {
|
|
267
360
|
certs = await Promise.all(certs.map(cert => cert instanceof File || cert instanceof Blob ? readFile(cert) : cert));
|
|
268
361
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
362
|
+
|
|
363
|
+
try {
|
|
364
|
+
const ownerInfo = await this._euSign.ReadPrivateKey(keyMedia, certs, this._selectedIssuerCN);
|
|
365
|
+
this._readedKey = new HardwarePrivateKeyInfo(
|
|
366
|
+
DigitalSignatureKeyType.Token,
|
|
367
|
+
ownerInfo,
|
|
368
|
+
await this._euSign.GetOwnCertificates(),
|
|
369
|
+
keyMedia
|
|
370
|
+
);
|
|
371
|
+
return this._readedKey;
|
|
372
|
+
} catch (error) {
|
|
373
|
+
if (error && error.code === EndUserError.EU_ERROR_CERT_NOT_FOUND) {
|
|
374
|
+
if (!this._selectedIssuerCN) {
|
|
375
|
+
throw {
|
|
376
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
377
|
+
message: this._resourses.ReadPrivateKeyCAAutoDetectError
|
|
378
|
+
};
|
|
379
|
+
} else if (this._selectedIssuerCN) {
|
|
380
|
+
if (!this._selectedCA.cmpAddress) {
|
|
381
|
+
throw {
|
|
382
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
383
|
+
message: format(this._resourses.ReadPrivateKeyNeedCertificateError, this._selectedIssuerCN)
|
|
384
|
+
};
|
|
385
|
+
} else {
|
|
386
|
+
throw {
|
|
387
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
388
|
+
message: format(this._resourses.ReadPrivateKeyInvalidCAError, this._selectedIssuerCN)
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
throw error;
|
|
394
|
+
}
|
|
277
395
|
}
|
|
278
396
|
|
|
279
397
|
/**
|
|
@@ -283,26 +401,60 @@ export default class DigitalSignature {
|
|
|
283
401
|
* @param {Array<Uint8Array|File>?} certs - Сертификаты ключа (при необходимости)
|
|
284
402
|
*/
|
|
285
403
|
async readFileKey(privateKey, password, certs) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
404
|
+
await this.setLibraryType(DigitalSignatureKeyType.File);
|
|
405
|
+
|
|
406
|
+
if (!privateKey) {
|
|
407
|
+
throw {
|
|
408
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
409
|
+
message: this._resourses.BadParameter + " keyMedia"
|
|
410
|
+
};
|
|
289
411
|
}
|
|
412
|
+
if (!password) {
|
|
413
|
+
throw {
|
|
414
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
415
|
+
message: this._resourses.PasswordNotSet
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
|
|
290
419
|
if (privateKey instanceof File || privateKey instanceof Blob) {
|
|
291
|
-
keyName = privateKey.name;
|
|
292
420
|
privateKey = await readFile(privateKey);
|
|
293
421
|
}
|
|
294
422
|
if (Array.isArray(certs)) {
|
|
295
423
|
certs = await Promise.all(certs.map(cert => cert instanceof File || cert instanceof Blob ? readFile(cert) : cert));
|
|
296
424
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
425
|
+
try {
|
|
426
|
+
const ownerInfo = await this._euSign.ReadPrivateKeyBinary(privateKey, password, certs, this._selectedIssuerCN);
|
|
427
|
+
this._readedKey = new FilePrivateKeyInfo(
|
|
428
|
+
DigitalSignatureKeyType.File,
|
|
429
|
+
ownerInfo,
|
|
430
|
+
await this._euSign.GetOwnCertificates(),
|
|
431
|
+
privateKey,
|
|
432
|
+
password
|
|
433
|
+
);
|
|
434
|
+
return this._readedKey;
|
|
435
|
+
} catch (error) {
|
|
436
|
+
if (error && error.code === EndUserError.EU_ERROR_CERT_NOT_FOUND) {
|
|
437
|
+
if (!this._selectedIssuerCN) {
|
|
438
|
+
throw {
|
|
439
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
440
|
+
message: this._resourses.ReadPrivateKeyCAAutoDetectError
|
|
441
|
+
};
|
|
442
|
+
} else if (this._selectedIssuerCN) {
|
|
443
|
+
if (!this._selectedCA.cmpAddress) {
|
|
444
|
+
throw {
|
|
445
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
446
|
+
message: format(this._resourses.ReadPrivateKeyNeedCertificateError, this._selectedIssuerCN)
|
|
447
|
+
};
|
|
448
|
+
} else {
|
|
449
|
+
throw {
|
|
450
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
451
|
+
message: format(this._resourses.ReadPrivateKeyInvalidCAError, this._selectedIssuerCN)
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
throw error;
|
|
457
|
+
}
|
|
306
458
|
}
|
|
307
459
|
|
|
308
460
|
/**
|
|
@@ -311,9 +463,8 @@ export default class DigitalSignature {
|
|
|
311
463
|
* @returns {Promise<EndUserJKSPrivateKeyInfo[]>}
|
|
312
464
|
*/
|
|
313
465
|
async getJKSPrivateKeys(jks) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
466
|
+
await this.setLibraryType(DigitalSignatureKeyType.File);
|
|
467
|
+
|
|
317
468
|
if (jks instanceof File || jks instanceof Blob) {
|
|
318
469
|
jks = await readFile(jks);
|
|
319
470
|
}
|
|
@@ -329,49 +480,39 @@ export default class DigitalSignature {
|
|
|
329
480
|
}
|
|
330
481
|
|
|
331
482
|
/**
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
483
|
+
* Считать ключ с DepositSign
|
|
484
|
+
* @param {string} userId - Идентификатор пользователя
|
|
485
|
+
* @param {boolean?} getCerts - Получать информацию о ключе пользователя. Это приведёт к дополнительному запросу на подписание
|
|
486
|
+
*/
|
|
336
487
|
async readPrivateKeyDepositsign(userId, getCerts = false) {
|
|
337
|
-
return await this.readPrivateKeyKSP(userId, this.
|
|
488
|
+
return await this.readPrivateKeyKSP(userId, this._KSPs.depositsign, getCerts);
|
|
338
489
|
}
|
|
339
490
|
|
|
340
491
|
/**
|
|
341
492
|
* Считать ключ с Дiя
|
|
342
493
|
* @param {boolean?} getCerts - Получать информацию о ключе пользователя. Это приведёт к дополнительному запросу на подписание
|
|
343
494
|
*/
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if (sessionStorage[diia] != "+") {
|
|
347
|
-
try {
|
|
348
|
-
sessionStorage[diia] = await downloadData("https://diia-sign.it.ua/diia/");
|
|
349
|
-
} catch {
|
|
350
|
-
throw {
|
|
351
|
-
message: this._resourses.DiiaError + `<a target="_blank" href="${window.origin}">${window.origin}</a></li><ul>`
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
return await this.readPrivateKeyKSP(null, this.KSPs[1], getCerts);
|
|
495
|
+
async readPrivateKeyDiia(getCerts = false) {
|
|
496
|
+
return await this.readPrivateKeyKSP(null, this.KSPs.diia, getCerts);
|
|
357
497
|
}
|
|
358
498
|
|
|
359
499
|
/**
|
|
360
500
|
* Считать ключ с облачного провайдера
|
|
361
|
-
* @param {
|
|
362
|
-
* @param {string
|
|
501
|
+
* @param {KSPSettings} ksp - Идентификатор облачного провайдера
|
|
502
|
+
* @param {string?} userId - Идентификатор пользователя
|
|
363
503
|
* @param {boolean?} getCerts - Получать информацию о ключе пользователя. Это приведёт к дополнительному запросу на подписание
|
|
364
504
|
*/
|
|
365
|
-
async readPrivateKeyKSP(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
ksp = ksp.name;
|
|
505
|
+
async readPrivateKeyKSP(ksp, userId, getCerts = false) {
|
|
506
|
+
await this.setLibraryType(DigitalSignatureKeyType.KSP);
|
|
507
|
+
|
|
508
|
+
if (ksp.ksp === EndUserConstants.EU_KSP_DIIA) {
|
|
509
|
+
await this._diiaCheckAccess();
|
|
371
510
|
}
|
|
372
|
-
|
|
511
|
+
|
|
512
|
+
const ownerInfo = await this._euSign.ReadPrivateKeyKSP(userId, ksp.name, getCerts);
|
|
373
513
|
if (getCerts && !ownerInfo) {
|
|
374
514
|
throw {
|
|
515
|
+
code: EndUserError.EU_ERROR_KEY_MEDIAS_READ_FAILED,
|
|
375
516
|
message: this._resourses.PrivateKeyNotReaded
|
|
376
517
|
};
|
|
377
518
|
}
|
|
@@ -395,11 +536,7 @@ export default class DigitalSignature {
|
|
|
395
536
|
* @param {authenticationCallback} event - Коллбэк. Вызывается при запросе на подписание.
|
|
396
537
|
*/
|
|
397
538
|
async addConfirmKSPOperationEventListener(event) {
|
|
398
|
-
|
|
399
|
-
await this.setLibraryType(DigitalSignatureKeyType.KSP);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
await this._euSign.AddEventListener(EndUserConstants.EndUserEventType.ConfirmKSPOperation, function(data) {
|
|
539
|
+
await this._euSignFile.AddEventListener(EndUserConstants.EndUserEventType.ConfirmKSPOperation, function(data) {
|
|
403
540
|
data.qrCode = "data:image/bmp;base64," + data.qrCode;
|
|
404
541
|
event(data);
|
|
405
542
|
});
|
|
@@ -410,7 +547,7 @@ export default class DigitalSignature {
|
|
|
410
547
|
* @returns {KSPSettings[]} Список поддержирживаемых облачных провайдеров
|
|
411
548
|
*/
|
|
412
549
|
get KSPs() {
|
|
413
|
-
return this._KSPs;
|
|
550
|
+
return this._KSPs.asArray();
|
|
414
551
|
}
|
|
415
552
|
|
|
416
553
|
/**
|
|
@@ -418,16 +555,18 @@ export default class DigitalSignature {
|
|
|
418
555
|
* @returns {Promise<boolean>} считан ли ключ
|
|
419
556
|
*/
|
|
420
557
|
async isPrivateKeyReaded() {
|
|
421
|
-
|
|
558
|
+
try {
|
|
559
|
+
return !!this._readedKey && await this._euSign.IsPrivateKeyReaded();
|
|
560
|
+
} catch {
|
|
561
|
+
return false;
|
|
562
|
+
}
|
|
422
563
|
}
|
|
423
564
|
|
|
424
565
|
/**
|
|
425
566
|
* Очистить считанный ключ
|
|
426
567
|
*/
|
|
427
568
|
async resetPrivateKey() {
|
|
428
|
-
await
|
|
429
|
-
this._euSign.ResetPrivateKey()
|
|
430
|
-
]);
|
|
569
|
+
await this._euSign.ResetPrivateKey();
|
|
431
570
|
this._readedKey = null;
|
|
432
571
|
}
|
|
433
572
|
|
|
@@ -436,7 +575,7 @@ export default class DigitalSignature {
|
|
|
436
575
|
* @returns {Promise<Array<CASettings>>}
|
|
437
576
|
*/
|
|
438
577
|
async getCAs() {
|
|
439
|
-
return await this.
|
|
578
|
+
return await this._euSignFile.GetCAs();
|
|
440
579
|
}
|
|
441
580
|
|
|
442
581
|
/**
|
|
@@ -460,49 +599,78 @@ export default class DigitalSignature {
|
|
|
460
599
|
|
|
461
600
|
/**
|
|
462
601
|
* Подписать данные
|
|
463
|
-
* @param {Uint8Array | string |
|
|
464
|
-
* @param {
|
|
602
|
+
* @param {Uint8Array | string | NamedData | Array<Uint8Array | string | NamedData>} data - Данные для подписи. Можно передавать данные в массиве для наложения нескольких подписей за раз
|
|
603
|
+
* @param {EndUserSignContainerInfo?} signType - Тип подписи
|
|
465
604
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байтов. По умолчанию подпись возвращается в виде строки в base64
|
|
466
605
|
*/
|
|
467
|
-
async signData(data,
|
|
468
|
-
if (
|
|
469
|
-
|
|
606
|
+
async signData(data, signType, asByteArray) {
|
|
607
|
+
if (signType === true) {
|
|
608
|
+
// Обратная совместимость. Если передать в параметре значение true, дожна создаться подпись CAdES Enveloped (внутренняя)
|
|
609
|
+
signType = new EndUserSignContainerInfo();
|
|
610
|
+
signType.type = EndUserConstants.EndUserSignContainerType.CAdES;
|
|
611
|
+
signType.subType = EndUserConstants.EndUserCAdESType.Enveloped;
|
|
612
|
+
} else if (typeof signType != "object") {
|
|
613
|
+
// По умолчанию создаётся подпись CAdES Detached
|
|
614
|
+
signType = new EndUserSignContainerInfo();
|
|
615
|
+
signType.type = EndUserConstants.EndUserSignContainerType.CAdES;
|
|
616
|
+
signType.subType = EndUserConstants.EndUserCAdESType.Detached;
|
|
470
617
|
}
|
|
471
618
|
if (typeof asByteArray !== "boolean") {
|
|
472
619
|
asByteArray = false;
|
|
473
620
|
}
|
|
474
|
-
|
|
621
|
+
|
|
622
|
+
if (this.readedKey.keyType === DigitalSignatureKeyType.KSP && signType.type !== EndUserConstants.EndUserSignContainerType.CAdES) {
|
|
623
|
+
throw {
|
|
624
|
+
code: EndUserError.EU_ERROR_NOT_SUPPORTED,
|
|
625
|
+
message: this._resourses.KSPSignFormatError
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
if (signType.type === EndUserConstants.EndUserSignContainerType.ASiC) {
|
|
630
|
+
const signLevel = signType.asicSignType === EndUserConstants.EndUserASiCSignType.CAdES ? EndUserConstants.EndUserSignType.CAdES_X_Long : EndUserConstants.EndUserXAdESSignLevel.B_LT;
|
|
631
|
+
return await this._euSign.ASiCSignData(this._readedKey.getSignAlgo(), signType.subType, signType.asicSignType, signLevel, data, !asByteArray);
|
|
632
|
+
} else if (signType.type === EndUserConstants.EndUserSignContainerType.XAdES) {
|
|
633
|
+
let returnArray = true;
|
|
634
|
+
if (!Array.isArray(data)) {
|
|
635
|
+
data = [data];
|
|
636
|
+
returnArray = false;
|
|
637
|
+
}
|
|
638
|
+
data = data.map((e, i) => !e.name && !e.val ? { name: "data" + i, val: e } : e);
|
|
639
|
+
const signs = [];
|
|
640
|
+
for (let i = 0; i < data.length; i++) {
|
|
641
|
+
const result = await this._euSign.XAdESSignData(this._readedKey.getSignAlgo(), signType.subType, EndUserConstants.EndUserXAdESSignLevel.B_LT, data[i], !asByteArray);
|
|
642
|
+
signs[i] = result;
|
|
643
|
+
}
|
|
644
|
+
return returnArray ? signs : signs[0];
|
|
645
|
+
} else if (signType.type === EndUserConstants.EndUserSignContainerType.PAdES) {
|
|
646
|
+
return await this._euSign.PDFSignData(this._readedKey.getSignAlgo(), data, EndUserConstants.EndUserPAdESSignLevel.B_T, !asByteArray);
|
|
647
|
+
} else if (signType.type === EndUserConstants.EndUserSignContainerType.CAdES) {
|
|
648
|
+
if (signType.subType === EndUserConstants.EndUserCAdESType.Detached) {
|
|
649
|
+
const hash = await this._euSign.HashData(this._readedKey.getHashAlgo(), data, !asByteArray);
|
|
650
|
+
return await this._euSign.SignHash(this._readedKey.getSignAlgo(), hash, true, !asByteArray);
|
|
651
|
+
} else {
|
|
652
|
+
return await this._euSign.SignDataEx(this._readedKey.getSignAlgo(), data, false, true, !asByteArray);
|
|
653
|
+
}
|
|
654
|
+
} else {
|
|
655
|
+
throw {
|
|
656
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
657
|
+
message: this._resourses.BadSignatureType
|
|
658
|
+
};
|
|
659
|
+
}
|
|
475
660
|
}
|
|
476
661
|
|
|
477
662
|
/**
|
|
478
663
|
* Подписать файл
|
|
479
|
-
* @param {string |
|
|
480
|
-
* @param {
|
|
664
|
+
* @param {string | NamedData | Array<string | NamedData>} fileUrl - Ссылка на загрузку файла. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
|
|
665
|
+
* @param {EndUserSignContainerInfo?} signType - Тип подписи
|
|
481
666
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
|
|
482
667
|
*/
|
|
483
|
-
async signFile(fileUrl,
|
|
484
|
-
|
|
485
|
-
internal = false;
|
|
486
|
-
}
|
|
487
|
-
if (typeof asByteArray !== "boolean") {
|
|
488
|
-
asByteArray = false;
|
|
489
|
-
}
|
|
490
|
-
const isNamedData = Array.isArray(fileUrl) && fileUrl.every(url => typeof url === "object") || typeof fileUrl === "object";
|
|
491
|
-
let data;
|
|
492
|
-
if (Array.isArray(fileUrl)) {
|
|
493
|
-
data = await Promise.all(fileUrl.map(function(url) {
|
|
494
|
-
const downloadedData = downloadData(isNamedData ? url.val : url, "binary");
|
|
495
|
-
return isNamedData ? {name: url.name, val: downloadedData} : downloadedData;
|
|
496
|
-
}));
|
|
497
|
-
} else {
|
|
498
|
-
const downloadedData = await downloadData(isNamedData ? fileUrl.val : fileUrl, "binary");
|
|
499
|
-
data = isNamedData ? {name: fileUrl.name, val: downloadedData} : downloadedData;
|
|
500
|
-
}
|
|
501
|
-
return await this.signData(data, internal, asByteArray);
|
|
668
|
+
async signFile(fileUrl, signType, asByteArray) {
|
|
669
|
+
return await downloadAndSignFiles(fileUrl, async (data) => await this.signData(data, signType, asByteArray));
|
|
502
670
|
}
|
|
503
671
|
|
|
504
672
|
/**
|
|
505
|
-
* Подписать хеш
|
|
673
|
+
* Подписать хеш подписью CAdES Detached
|
|
506
674
|
* @param {Uint8Array | string | NamedData | Array<Uint8Array | string> | NamedData} hash - Хеш файла. Можно передавать несколько хешей в массиве для наложения нескольких подписей за раз
|
|
507
675
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
|
|
508
676
|
*/
|
|
@@ -514,38 +682,57 @@ export default class DigitalSignature {
|
|
|
514
682
|
}
|
|
515
683
|
|
|
516
684
|
/**
|
|
517
|
-
* Подписать хеш из файла
|
|
685
|
+
* Подписать хеш из файла подписью CAdES Detached
|
|
518
686
|
* @param {string | NamedData | Array<string | NamedData>} hashUrl - Ссылка на скачивание хеша. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
|
|
519
687
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
|
|
520
688
|
*/
|
|
521
689
|
async signFileHash(hashUrl, asByteArray) {
|
|
522
|
-
|
|
523
|
-
asByteArray = false;
|
|
524
|
-
}
|
|
525
|
-
const isNamedData = Array.isArray(hashUrl) && hashUrl.every(url => typeof url === "object") || typeof hashUrl === "object";
|
|
526
|
-
let hash;
|
|
527
|
-
if (Array.isArray(hashUrl)) {
|
|
528
|
-
hash = await Promise.all(hashUrl.map(function(url) {
|
|
529
|
-
const downloadedData = downloadData(isNamedData ? url.val : url, "binary");
|
|
530
|
-
return isNamedData ? {name: url.name, val: downloadedData} : downloadedData;
|
|
531
|
-
}));
|
|
532
|
-
} else {
|
|
533
|
-
const downloadedData = await downloadData(hashUrl, "binary");
|
|
534
|
-
hash = isNamedData ? {name: hashUrl.name, val: downloadedData} : downloadedData;
|
|
535
|
-
}
|
|
536
|
-
return await this.signHash(hash, asByteArray);
|
|
690
|
+
return await downloadAndSignFiles(hashUrl, async (hash) => await this.signHash(hash, asByteArray));
|
|
537
691
|
}
|
|
538
692
|
|
|
539
693
|
/**
|
|
540
|
-
*
|
|
694
|
+
* Получить данные о типе подписи
|
|
695
|
+
* @param {string | Uint8Array} sign - Подпись
|
|
696
|
+
*/
|
|
697
|
+
async getSignContainerInfo(sign) {
|
|
698
|
+
return await this._euSign.GetSignContainerInfo(sign);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Проверить подпись (Соответствие подписанных данных не проверяется)
|
|
541
703
|
* @param {Uint8Array | string} data - Подписанные данные
|
|
542
704
|
* @param {Uint8Array | string} sign - Подпись
|
|
543
705
|
* @param {number?} signIndex - Номер подписи. -1 что бы проверить все подписи
|
|
544
706
|
*/
|
|
545
707
|
async verifyData(data, sign, signIndex) {
|
|
546
708
|
if (!Number.isInteger(signIndex)) {
|
|
547
|
-
signIndex =
|
|
709
|
+
signIndex = -1;
|
|
548
710
|
}
|
|
711
|
+
const signContainerInfo = await this._euSign.GetSignContainerInfo(sign.val || sign);
|
|
712
|
+
|
|
713
|
+
if (signContainerInfo.type === EndUserConstants.EndUserSignContainerType.ASiC) {
|
|
714
|
+
return await this._euSign.ASiCVerifyData(sign, signIndex);
|
|
715
|
+
} else if (signContainerInfo.type === EndUserConstants.EndUserSignContainerType.PAdES) {
|
|
716
|
+
return await this._euSign.PDFVerifyData(sign, signIndex);
|
|
717
|
+
} else if (signContainerInfo.type === EndUserConstants.EndUserSignContainerType.XAdES) {
|
|
718
|
+
return await this._euSign.XAdESVerifyData(data, sign.val || sign, signIndex);
|
|
719
|
+
} else if (signContainerInfo.type === EndUserConstants.EndUserSignContainerType.CAdES) {
|
|
720
|
+
if (signContainerInfo.subType === EndUserConstants.EndUserCAdESType.Detached) {
|
|
721
|
+
if (!data) {
|
|
722
|
+
throw {
|
|
723
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
724
|
+
message: this._resourses.BadParameter + " data"
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
const signerInfo = await this._euSign.GetSigner(sign, signIndex, false);
|
|
728
|
+
const hashAlgo = signAlgoToHashAlgo((Array.isArray(signerInfo) ? signerInfo[0] : signerInfo).infoEx.publicKeyType);
|
|
729
|
+
const hash = await this._euSign.HashData(hashAlgo, data);
|
|
730
|
+
return await this._euSign.VerifyHash(hash.val || hash, sign.val || sign, signIndex);
|
|
731
|
+
} else {
|
|
732
|
+
return await this._euSign.VerifyDataInternal(sign.val || sign, signIndex);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
549
736
|
return await this._euSign.VerifyData(data, sign, signIndex);
|
|
550
737
|
}
|
|
551
738
|
|
|
@@ -569,10 +756,7 @@ export default class DigitalSignature {
|
|
|
569
756
|
* @param {number?} signIndex - Номер подписи. -1 что бы проверить все подписи
|
|
570
757
|
*/
|
|
571
758
|
async verifyDataInternal(sign, signIndex) {
|
|
572
|
-
|
|
573
|
-
signIndex = 0;
|
|
574
|
-
}
|
|
575
|
-
return await this._euSign.VerifyDataInternal(sign, signIndex);
|
|
759
|
+
return await this.verifyData(null, sign, signIndex);
|
|
576
760
|
}
|
|
577
761
|
|
|
578
762
|
/**
|
|
@@ -586,7 +770,7 @@ export default class DigitalSignature {
|
|
|
586
770
|
}
|
|
587
771
|
|
|
588
772
|
/**
|
|
589
|
-
* Проверить подпись хеша
|
|
773
|
+
* Проверить подпись хеша (Только CAdES Detached)
|
|
590
774
|
* @param {Uint8Array | string} hash - Хеш подписанного файла
|
|
591
775
|
* @param {Uint8Array | string} sign - Подпись
|
|
592
776
|
* @param {number?} signIndex - Номер подписи. -1 что бы проверить все подписи
|
|
@@ -599,7 +783,7 @@ export default class DigitalSignature {
|
|
|
599
783
|
}
|
|
600
784
|
|
|
601
785
|
/**
|
|
602
|
-
* Проверить подпись хеша из файла
|
|
786
|
+
* Проверить подпись хеша из файла (Только CAdES Detached)
|
|
603
787
|
* @param {string} hashUrl - Ссылка на загрузку файла
|
|
604
788
|
* @param {string} signUrl - Ссылка на загрузку подписи
|
|
605
789
|
* @param {number?} signIndex - Номер подписи. -1 что бы проверить все подписи
|
|
@@ -614,34 +798,48 @@ export default class DigitalSignature {
|
|
|
614
798
|
|
|
615
799
|
/**
|
|
616
800
|
* Выполнить подписание данных с проверкой подписи
|
|
617
|
-
* @param {Uint8Array | string | NamedData} data - данные для
|
|
618
|
-
* @param {
|
|
619
|
-
*/
|
|
620
|
-
async signDataEx(data,
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
801
|
+
* @param {Uint8Array | string | NamedData | Array<Uint8Array | string | NamedData>} data - Данные для подписи. Можно передавать данные в массиве для наложения нескольких подписей за раз
|
|
802
|
+
* @param {EndUserSignContainerInfo?} signType - Тип подписи
|
|
803
|
+
*/
|
|
804
|
+
async signDataEx(data, signType) {
|
|
805
|
+
const signs = await this.signData(data, signType);
|
|
806
|
+
|
|
807
|
+
if (Array.isArray(data)) {
|
|
808
|
+
const result = [];
|
|
809
|
+
for (let i = 0; i < signs.length; i++) {
|
|
810
|
+
const sign = signs[i];
|
|
811
|
+
let signInfo = await this.verifyData(data[i], sign);
|
|
812
|
+
if (Array.isArray(signInfo)) {
|
|
813
|
+
signInfo = signInfo[signInfo.length - 1];
|
|
814
|
+
}
|
|
815
|
+
result[i] = {
|
|
816
|
+
Success: true,
|
|
817
|
+
Sign: sign.val || sign,
|
|
818
|
+
SignatureInfo: {
|
|
819
|
+
Success: true,
|
|
820
|
+
DateTimeStr: signInfo.timeInfo.time,
|
|
821
|
+
Signer: signInfo.ownerInfo.subjCN,
|
|
822
|
+
OwnerInfo: signInfo.ownerInfo
|
|
823
|
+
}
|
|
824
|
+
};
|
|
631
825
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
Sign: isNamedData ? signature.val : signature,
|
|
638
|
-
SignatureInfo: {
|
|
639
|
-
Success: true,
|
|
640
|
-
DateTimeStr: signatureInfo.timeInfo.time,
|
|
641
|
-
Signer: signatureInfo.ownerInfo.subjCN,
|
|
642
|
-
OwnerInfo: signatureInfo.ownerInfo
|
|
826
|
+
return result;
|
|
827
|
+
} else {
|
|
828
|
+
let signInfo = await this.verifyData(data, signs);
|
|
829
|
+
if (Array.isArray(signInfo)) {
|
|
830
|
+
signInfo = signInfo[signInfo.length - 1];
|
|
643
831
|
}
|
|
644
|
-
|
|
832
|
+
return {
|
|
833
|
+
Success: true,
|
|
834
|
+
Sign: signs.val || signs,
|
|
835
|
+
SignatureInfo: {
|
|
836
|
+
Success: true,
|
|
837
|
+
DateTimeStr: signInfo.timeInfo.time,
|
|
838
|
+
Signer: signInfo.ownerInfo.subjCN,
|
|
839
|
+
OwnerInfo: signInfo.ownerInfo
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
}
|
|
645
843
|
}
|
|
646
844
|
|
|
647
845
|
/**
|
|
@@ -652,24 +850,14 @@ export default class DigitalSignature {
|
|
|
652
850
|
async signFileEx(fileUrl, hash) {
|
|
653
851
|
const isNamedData = typeof fileUrl === "object";
|
|
654
852
|
let data = await downloadData(isNamedData ? fileUrl.val : fileUrl, "binary");
|
|
655
|
-
if(
|
|
656
|
-
data =
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
853
|
+
if (isNamedData) {
|
|
854
|
+
data = {name: fileUrl.name, val: data};
|
|
855
|
+
}
|
|
856
|
+
if (hash) {
|
|
857
|
+
return await this.signHashEx(data);
|
|
858
|
+
} else {
|
|
859
|
+
return await this.signDataEx(data, false);
|
|
660
860
|
}
|
|
661
|
-
const signature = await this.signHash(data);
|
|
662
|
-
const signatureInfo = await this.verifyHash(isNamedData ? data.val : data, isNamedData ? signature.val : signature);
|
|
663
|
-
return {
|
|
664
|
-
Success: true,
|
|
665
|
-
Sign: isNamedData ? signature.val : signature,
|
|
666
|
-
SignatureInfo: {
|
|
667
|
-
Success: true,
|
|
668
|
-
DateTimeStr: signatureInfo.timeInfo.time,
|
|
669
|
-
Signer: signatureInfo.ownerInfo.subjCN,
|
|
670
|
-
OwnerInfo: signatureInfo.ownerInfo
|
|
671
|
-
}
|
|
672
|
-
};
|
|
673
861
|
}
|
|
674
862
|
|
|
675
863
|
/**
|
|
@@ -750,18 +938,18 @@ export default class DigitalSignature {
|
|
|
750
938
|
* @param {boolean} toLocalStorage - Будет ли ключ сохранён после закрытия вкладки
|
|
751
939
|
*/
|
|
752
940
|
async storePrivateKeyInfo(privateKeyInfo, toLocalStorage) {
|
|
753
|
-
if(privateKeyInfo.ksp &&
|
|
941
|
+
if (privateKeyInfo.ksp && privateKeyInfo.ksp.needQrcode) {
|
|
754
942
|
return;
|
|
755
943
|
}
|
|
756
944
|
|
|
757
945
|
const storage = toLocalStorage ? localStorage : sessionStorage;
|
|
758
946
|
const keys = await this.getStoredPrivateKeyInfo();
|
|
759
947
|
|
|
760
|
-
if(keys.length == 0 || keys.filter(key => key.id == privateKeyInfo.id).length < 1) {
|
|
948
|
+
if (keys.length == 0 || keys.filter(key => key.id == privateKeyInfo.id).length < 1) {
|
|
761
949
|
const keys = await this.getPrivateKeyInfoFromStorage(toLocalStorage);
|
|
762
950
|
keys.push(privateKeyInfo);
|
|
763
951
|
const data = await this._euSignFile.ProtectDataByPassword(JSON.stringify(keys), "", true);
|
|
764
|
-
storage[this._userId +
|
|
952
|
+
storage[this._userId + PRIVATE_KEY_INFO] = data;
|
|
765
953
|
}
|
|
766
954
|
}
|
|
767
955
|
|
|
@@ -778,27 +966,27 @@ export default class DigitalSignature {
|
|
|
778
966
|
|
|
779
967
|
async getPrivateKeyInfoFromStorage(fromLocalStorage, keyType) {
|
|
780
968
|
const storage = fromLocalStorage ? localStorage : sessionStorage;
|
|
781
|
-
const storedKeys = storage[this._userId +
|
|
969
|
+
const storedKeys = storage[this._userId + PRIVATE_KEY_INFO];
|
|
782
970
|
|
|
783
971
|
let ls;
|
|
784
972
|
const result = [];
|
|
785
|
-
if(!storedKeys) {
|
|
973
|
+
if (!storedKeys) {
|
|
786
974
|
return result;
|
|
787
975
|
}
|
|
788
976
|
const data = await this._euSignFile.UnprotectDataByPassword(storedKeys, "", true);
|
|
789
|
-
try{
|
|
977
|
+
try {
|
|
790
978
|
ls = JSON.parse(data);
|
|
791
|
-
if(keyType >= 0) {
|
|
979
|
+
if (keyType >= 0) {
|
|
792
980
|
ls = ls.filter(key => key.keyType == keyType);
|
|
793
981
|
}
|
|
794
982
|
}
|
|
795
|
-
catch{
|
|
983
|
+
catch {
|
|
796
984
|
ls = [];
|
|
797
985
|
}
|
|
798
986
|
|
|
799
987
|
ls.forEach(key => {
|
|
800
988
|
const password = key.password;
|
|
801
|
-
if(key.keyType == DigitalSignatureKeyType.File) {
|
|
989
|
+
if (key.keyType == DigitalSignatureKeyType.File) {
|
|
802
990
|
key.privateKey = new Uint8Array(Object.assign(new Array(), key.privateKey));
|
|
803
991
|
key = new FilePrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.privateKey, key.password);
|
|
804
992
|
}
|
|
@@ -825,19 +1013,19 @@ export default class DigitalSignature {
|
|
|
825
1013
|
* Удалить сохранённые ключи
|
|
826
1014
|
* @param {string} keyId - Идентификатор ключа
|
|
827
1015
|
*/
|
|
828
|
-
|
|
829
|
-
|
|
1016
|
+
async removeStoredPrivateKeyInfo(keyId) {
|
|
1017
|
+
if (keyId === undefined) {
|
|
830
1018
|
localStorage.removeItem(this._userId + this.PRIVATE_KEY_INFO);
|
|
831
1019
|
sessionStorage.removeItem(this._userId + this.PRIVATE_KEY_INFO);
|
|
832
1020
|
}
|
|
833
|
-
else{
|
|
1021
|
+
else {
|
|
834
1022
|
const localStoredKeys = await this.getPrivateKeyInfoFromStorage(true);
|
|
835
1023
|
const sessionStoredKeys = await this.getPrivateKeyInfoFromStorage(false);
|
|
836
1024
|
const storage = localStoredKeys.filter(item => item.id == keyId).length > 0 ? localStorage : sessionStorage;
|
|
837
1025
|
const keys = storage == localStorage ? localStoredKeys : sessionStoredKeys;
|
|
838
1026
|
const keyIndex = keys.findIndex((element) => element.id == keyId);
|
|
839
1027
|
|
|
840
|
-
if(keyIndex > -1) {
|
|
1028
|
+
if (keyIndex > -1) {
|
|
841
1029
|
keys.splice(keyIndex, 1);
|
|
842
1030
|
const data = await this._euSignFile.ProtectDataByPassword(JSON.stringify(keys), "", true);
|
|
843
1031
|
storage[this._userId + this.PRIVATE_KEY_INFO] = data;
|
|
@@ -849,11 +1037,11 @@ export default class DigitalSignature {
|
|
|
849
1037
|
* Получить предпочитаемый тип ключа
|
|
850
1038
|
*/
|
|
851
1039
|
get _preferredKeyType () {
|
|
852
|
-
const keyType = parseInt(localStorage[this._userId +
|
|
1040
|
+
const keyType = parseInt(localStorage[this._userId + PRIVATE_KEY_TYPE]);
|
|
853
1041
|
if (typeof keyType === "number" && keyType > -1) {
|
|
854
1042
|
return keyType;
|
|
855
1043
|
} else {
|
|
856
|
-
localStorage[this._userId +
|
|
1044
|
+
localStorage[this._userId + PRIVATE_KEY_TYPE] = DigitalSignatureKeyType.File;
|
|
857
1045
|
return DigitalSignatureKeyType.File;
|
|
858
1046
|
}
|
|
859
1047
|
}
|
|
@@ -864,15 +1052,36 @@ export default class DigitalSignature {
|
|
|
864
1052
|
*/
|
|
865
1053
|
set _preferredKeyType (keyType) {
|
|
866
1054
|
if (typeof keyType === "number" && keyType > -1) {
|
|
867
|
-
localStorage[this._userId +
|
|
1055
|
+
localStorage[this._userId + PRIVATE_KEY_TYPE] = keyType;
|
|
868
1056
|
}
|
|
869
1057
|
}
|
|
870
1058
|
|
|
871
1059
|
get _resourses() {
|
|
872
|
-
return Resourses[this.
|
|
1060
|
+
return Resourses[this._language];
|
|
873
1061
|
}
|
|
874
1062
|
|
|
875
1063
|
get _userId () {
|
|
876
|
-
return typeof this.
|
|
1064
|
+
return typeof this._settingsProvider.userId === "function" ? this._settingsProvider.userId() : this._settingsProvider.userId;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
get _language () {
|
|
1068
|
+
return typeof this._settingsProvider.language === "function" ? this._settingsProvider.language() : this._settingsProvider.language;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* Проверка доступности Дiя
|
|
1073
|
+
*/
|
|
1074
|
+
async _diiaCheckAccess() {
|
|
1075
|
+
const diia = "DIIA";
|
|
1076
|
+
if (sessionStorage[diia] != "+") {
|
|
1077
|
+
try {
|
|
1078
|
+
sessionStorage[diia] = await downloadData(new URL(this._KSPs.diia.address).origin + "/diia");
|
|
1079
|
+
} catch {
|
|
1080
|
+
throw {
|
|
1081
|
+
code: EndUserError.EU_ERROR_TRANSMIT_REQUEST,
|
|
1082
|
+
message: this._resourses.DiiaError + `<a target="_blank" href="${window.origin}">${window.origin}</a></li><ul>`
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
877
1086
|
}
|
|
878
1087
|
}
|