@it-enterprise/digital-signature 1.1.7 → 1.2.2
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 +468 -229
- 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,15 +136,17 @@ export default class DigitalSignature {
|
|
|
78
136
|
* @param {number} type
|
|
79
137
|
*/
|
|
80
138
|
async setLibraryType(type) {
|
|
81
|
-
if (this._euSign) {
|
|
82
|
-
await this._euSign.ResetPrivateKey();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
139
|
switch (type) {
|
|
86
140
|
case DigitalSignatureKeyType.Token:
|
|
141
|
+
if (this._euSign === this._euSignKeyMedia && await this._euSign.IsInitialized()) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
87
144
|
this._euSign = this._euSignKeyMedia;
|
|
88
145
|
break;
|
|
89
146
|
default:
|
|
147
|
+
if (this._euSign === this._euSignFile) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
90
150
|
this._euSign = this._euSignFile;
|
|
91
151
|
break;
|
|
92
152
|
}
|
|
@@ -104,7 +164,6 @@ export default class DigitalSignature {
|
|
|
104
164
|
* @returns {Promise<number>} Текущий тип библиотеки
|
|
105
165
|
*/
|
|
106
166
|
async initialise() {
|
|
107
|
-
|
|
108
167
|
if (!this._glSign) {
|
|
109
168
|
this._glSign = await Promise.resolve(this._settingsProvider.getGlSign());
|
|
110
169
|
}
|
|
@@ -187,23 +246,35 @@ export default class DigitalSignature {
|
|
|
187
246
|
}
|
|
188
247
|
|
|
189
248
|
if (!this._euSettings) {
|
|
190
|
-
|
|
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
|
+
}
|
|
191
262
|
|
|
192
263
|
this._euSettings = {
|
|
193
|
-
language: this.
|
|
264
|
+
language: this._language,
|
|
194
265
|
encoding: "UTF-16LE",
|
|
195
266
|
httpProxyServiceURL: this._settings.httpProxyServiceURL,
|
|
196
267
|
directAccess: true,
|
|
197
268
|
CAs: certificates.CAs,
|
|
198
269
|
CACertificates: certificates.CACertificates,
|
|
199
|
-
|
|
200
|
-
KSPs: this._KSPs,
|
|
270
|
+
KSPs: this.KSPs,
|
|
201
271
|
allowedKeyMediaTypes: [
|
|
202
272
|
"е.ключ BIFIT iToken",
|
|
203
273
|
"криптомод. ІІТ Гряда-61",
|
|
204
|
-
"криптомод. ІІТ Гряда-301",
|
|
205
274
|
"е.ключ ІІТ Алмаз-1К",
|
|
275
|
+
"е.ключ ІІТ Алмаз-1К (Bluetooth)",
|
|
206
276
|
"е.ключ ІІТ Кристал-1",
|
|
277
|
+
"криптомод. ІІТ Гряда-301",
|
|
207
278
|
"ID-карта громадянина (БЕН)",
|
|
208
279
|
"е.ключ ІІТ Алмаз-1К (PKCS#11)",
|
|
209
280
|
"е.ключ ІІТ Кристал-1 (PKCS#11)",
|
|
@@ -243,6 +314,7 @@ export default class DigitalSignature {
|
|
|
243
314
|
if (euSign === this._euSignKeyMedia && !await this._euSignFile.IsInitialized()) {
|
|
244
315
|
this._euSignFile.SetRuntimeParameter(EndUserConstants.EU_SIGN_TYPE_PARAMETER, EndUserConstants.EndUserSignType.CAdES_X_Long);
|
|
245
316
|
}
|
|
317
|
+
|
|
246
318
|
return this.getLibraryType();
|
|
247
319
|
}
|
|
248
320
|
|
|
@@ -256,35 +328,93 @@ export default class DigitalSignature {
|
|
|
256
328
|
|
|
257
329
|
/**
|
|
258
330
|
* Получить список подключённых устройств
|
|
259
|
-
* @returns {Promise<Array<EndUserKeyMedia>>}
|
|
331
|
+
* @returns {Promise<Array<EndUserKeyMedia>>} Список подключённых устройств
|
|
260
332
|
*/
|
|
261
333
|
async getKeyMedias() {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
return this._euSign.GetKeyMedias();
|
|
334
|
+
await this.setLibraryType(DigitalSignatureKeyType.Token);
|
|
335
|
+
return this._euSignKeyMedia.GetKeyMedias();
|
|
266
336
|
}
|
|
267
337
|
|
|
338
|
+
/**
|
|
339
|
+
* Считать ключ по параметрам
|
|
340
|
+
* @param {PrivateKeyInfo} keyInfo - Параметры ключа
|
|
341
|
+
*/
|
|
342
|
+
async readPrivateKeyByInfo(keyInfo) {
|
|
343
|
+
if (!keyInfo) {
|
|
344
|
+
throw {
|
|
345
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
346
|
+
message: this._resourses.BadParameter + " keyInfo"
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
await this.setLibraryType(keyInfo.keyType);
|
|
351
|
+
switch (keyInfo.keyType) {
|
|
352
|
+
case DigitalSignatureKeyType.File:
|
|
353
|
+
return await this.readFileKey(keyInfo.privateKey, keyInfo.password, keyInfo.certificates);
|
|
354
|
+
case DigitalSignatureKeyType.Token:
|
|
355
|
+
return await this.readHardwareKey(keyInfo.keyMedia, keyInfo.certificates);
|
|
356
|
+
case DigitalSignatureKeyType.KSP:
|
|
357
|
+
return await this.readPrivateKeyKSP(keyInfo.ksp, keyInfo.kspUserId, false);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
268
361
|
/**
|
|
269
362
|
* Считать аппаратный ключ
|
|
270
363
|
* @param {EndUserKeyMedia} keyMedia - Параметры аппаратного ключа
|
|
271
364
|
* @param {Array<Uint8Array>?} certs - Сертификаты ключа (при необходимости)
|
|
272
365
|
*/
|
|
273
366
|
async readHardwareKey(keyMedia, certs) {
|
|
274
|
-
|
|
275
|
-
|
|
367
|
+
await this.setLibraryType(DigitalSignatureKeyType.Token);
|
|
368
|
+
|
|
369
|
+
if (!keyMedia) {
|
|
370
|
+
throw {
|
|
371
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
372
|
+
message: this._resourses.BadParameter + " keyMedia"
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
if (!keyMedia.password) {
|
|
376
|
+
throw {
|
|
377
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
378
|
+
message: this._resourses.PasswordNotSet
|
|
379
|
+
};
|
|
276
380
|
}
|
|
381
|
+
|
|
277
382
|
if (Array.isArray(certs)) {
|
|
278
383
|
certs = await Promise.all(certs.map(cert => cert instanceof File || cert instanceof Blob ? readFile(cert) : cert));
|
|
279
384
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
const ownerInfo = await this._euSign.ReadPrivateKey(keyMedia, certs, this._selectedIssuerCN);
|
|
388
|
+
this._readedKey = new HardwarePrivateKeyInfo(
|
|
389
|
+
DigitalSignatureKeyType.Token,
|
|
390
|
+
ownerInfo,
|
|
391
|
+
await this._euSign.GetOwnCertificates(),
|
|
392
|
+
keyMedia
|
|
393
|
+
);
|
|
394
|
+
return this._readedKey;
|
|
395
|
+
} catch (error) {
|
|
396
|
+
if (error && error.code === EndUserError.EU_ERROR_CERT_NOT_FOUND) {
|
|
397
|
+
if (!this._selectedIssuerCN) {
|
|
398
|
+
throw {
|
|
399
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
400
|
+
message: this._resourses.ReadPrivateKeyCAAutoDetectError
|
|
401
|
+
};
|
|
402
|
+
} else if (this._selectedIssuerCN) {
|
|
403
|
+
if (!this._selectedCA.cmpAddress) {
|
|
404
|
+
throw {
|
|
405
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
406
|
+
message: format(this._resourses.ReadPrivateKeyNeedCertificateError, this._selectedIssuerCN)
|
|
407
|
+
};
|
|
408
|
+
} else {
|
|
409
|
+
throw {
|
|
410
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
411
|
+
message: format(this._resourses.ReadPrivateKeyInvalidCAError, this._selectedIssuerCN)
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
throw error;
|
|
417
|
+
}
|
|
288
418
|
}
|
|
289
419
|
|
|
290
420
|
/**
|
|
@@ -294,26 +424,60 @@ export default class DigitalSignature {
|
|
|
294
424
|
* @param {Array<Uint8Array|File>?} certs - Сертификаты ключа (при необходимости)
|
|
295
425
|
*/
|
|
296
426
|
async readFileKey(privateKey, password, certs) {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
427
|
+
await this.setLibraryType(DigitalSignatureKeyType.File);
|
|
428
|
+
|
|
429
|
+
if (!privateKey) {
|
|
430
|
+
throw {
|
|
431
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
432
|
+
message: this._resourses.BadParameter + " keyMedia"
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
if (!password) {
|
|
436
|
+
throw {
|
|
437
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
438
|
+
message: this._resourses.PasswordNotSet
|
|
439
|
+
};
|
|
300
440
|
}
|
|
441
|
+
|
|
301
442
|
if (privateKey instanceof File || privateKey instanceof Blob) {
|
|
302
|
-
keyName = privateKey.name;
|
|
303
443
|
privateKey = await readFile(privateKey);
|
|
304
444
|
}
|
|
305
445
|
if (Array.isArray(certs)) {
|
|
306
446
|
certs = await Promise.all(certs.map(cert => cert instanceof File || cert instanceof Blob ? readFile(cert) : cert));
|
|
307
447
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
448
|
+
try {
|
|
449
|
+
const ownerInfo = await this._euSign.ReadPrivateKeyBinary(privateKey, password, certs, this._selectedIssuerCN);
|
|
450
|
+
this._readedKey = new FilePrivateKeyInfo(
|
|
451
|
+
DigitalSignatureKeyType.File,
|
|
452
|
+
ownerInfo,
|
|
453
|
+
await this._euSign.GetOwnCertificates(),
|
|
454
|
+
privateKey,
|
|
455
|
+
password
|
|
456
|
+
);
|
|
457
|
+
return this._readedKey;
|
|
458
|
+
} catch (error) {
|
|
459
|
+
if (error && error.code === EndUserError.EU_ERROR_CERT_NOT_FOUND) {
|
|
460
|
+
if (!this._selectedIssuerCN) {
|
|
461
|
+
throw {
|
|
462
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
463
|
+
message: this._resourses.ReadPrivateKeyCAAutoDetectError
|
|
464
|
+
};
|
|
465
|
+
} else if (this._selectedIssuerCN) {
|
|
466
|
+
if (!this._selectedCA.cmpAddress) {
|
|
467
|
+
throw {
|
|
468
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
469
|
+
message: format(this._resourses.ReadPrivateKeyNeedCertificateError, this._selectedIssuerCN)
|
|
470
|
+
};
|
|
471
|
+
} else {
|
|
472
|
+
throw {
|
|
473
|
+
code: EndUserError.EU_ERROR_CERT_NOT_FOUND,
|
|
474
|
+
message: format(this._resourses.ReadPrivateKeyInvalidCAError, this._selectedIssuerCN)
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
throw error;
|
|
480
|
+
}
|
|
317
481
|
}
|
|
318
482
|
|
|
319
483
|
/**
|
|
@@ -322,9 +486,8 @@ export default class DigitalSignature {
|
|
|
322
486
|
* @returns {Promise<EndUserJKSPrivateKeyInfo[]>}
|
|
323
487
|
*/
|
|
324
488
|
async getJKSPrivateKeys(jks) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
489
|
+
await this.setLibraryType(DigitalSignatureKeyType.File);
|
|
490
|
+
|
|
328
491
|
if (jks instanceof File || jks instanceof Blob) {
|
|
329
492
|
jks = await readFile(jks);
|
|
330
493
|
}
|
|
@@ -340,56 +503,44 @@ export default class DigitalSignature {
|
|
|
340
503
|
}
|
|
341
504
|
|
|
342
505
|
/**
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
506
|
+
* Считать ключ с DepositSign
|
|
507
|
+
* @param {string} userId - Идентификатор пользователя
|
|
508
|
+
* @param {boolean?} getCerts - Получать информацию о ключе пользователя. Это приведёт к дополнительному запросу на подписание
|
|
509
|
+
*/
|
|
347
510
|
async readPrivateKeyDepositsign(userId, getCerts = false) {
|
|
348
|
-
return await this.readPrivateKeyKSP(userId, this.
|
|
511
|
+
return await this.readPrivateKeyKSP(userId, this._KSPs.depositsign, getCerts);
|
|
349
512
|
}
|
|
350
513
|
|
|
351
514
|
/**
|
|
352
515
|
* Считать ключ с Дiя
|
|
353
516
|
* @param {boolean?} getCerts - Получать информацию о ключе пользователя. Это приведёт к дополнительному запросу на подписание
|
|
354
517
|
*/
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
if (sessionStorage[diia] != "+") {
|
|
358
|
-
try {
|
|
359
|
-
sessionStorage[diia] = await downloadData(new URL(this.KSPs[1].address).origin + "/diia");
|
|
360
|
-
} catch {
|
|
361
|
-
throw {
|
|
362
|
-
message: this._resourses.DiiaError + `<a target="_blank" href="${window.origin}">${window.origin}</a></li><ul>`
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return await this.readPrivateKeyKSP(null, this.KSPs[1], getCerts);
|
|
518
|
+
async readPrivateKeyDiia(getCerts = false) {
|
|
519
|
+
return await this.readPrivateKeyKSP(null, this.KSPs.diia, getCerts);
|
|
368
520
|
}
|
|
369
521
|
|
|
370
522
|
/**
|
|
371
523
|
* Считать ключ с облачного провайдера
|
|
372
|
-
* @param {
|
|
373
|
-
* @param {string
|
|
524
|
+
* @param {KSPSettings} ksp - Идентификатор облачного провайдера
|
|
525
|
+
* @param {string?} userId - Идентификатор пользователя
|
|
374
526
|
* @param {boolean?} getCerts - Получать информацию о ключе пользователя. Это приведёт к дополнительному запросу на подписание
|
|
375
|
-
* @param {number?} keyType - Тип ключа
|
|
376
527
|
*/
|
|
377
|
-
async readPrivateKeyKSP(
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
if (this._euSign != this._euSignFile) {
|
|
383
|
-
await this.setLibraryType(keyType);
|
|
528
|
+
async readPrivateKeyKSP(ksp, userId, getCerts = false) {
|
|
529
|
+
await this.setLibraryType(DigitalSignatureKeyType.KSP);
|
|
530
|
+
|
|
531
|
+
if (ksp.ksp === EndUserConstants.EU_KSP_DIIA) {
|
|
532
|
+
await this._diiaCheckAccess();
|
|
384
533
|
}
|
|
385
|
-
|
|
534
|
+
|
|
535
|
+
const ownerInfo = await this._euSign.ReadPrivateKeyKSP(userId, ksp.name, getCerts);
|
|
386
536
|
if (getCerts && !ownerInfo) {
|
|
387
537
|
throw {
|
|
538
|
+
code: EndUserError.EU_ERROR_KEY_MEDIAS_READ_FAILED,
|
|
388
539
|
message: this._resourses.PrivateKeyNotReaded
|
|
389
540
|
};
|
|
390
541
|
}
|
|
391
542
|
this._readedKey = new KspPrivateKeyInfo(
|
|
392
|
-
|
|
543
|
+
DigitalSignatureKeyType.KSP,
|
|
393
544
|
ownerInfo,
|
|
394
545
|
getCerts ? await this._euSign.GetOwnCertificates() : [],
|
|
395
546
|
userId,
|
|
@@ -419,7 +570,7 @@ export default class DigitalSignature {
|
|
|
419
570
|
* @returns {KSPSettings[]} Список поддержирживаемых облачных провайдеров
|
|
420
571
|
*/
|
|
421
572
|
get KSPs() {
|
|
422
|
-
return this._KSPs;
|
|
573
|
+
return this._KSPs.asArray();
|
|
423
574
|
}
|
|
424
575
|
|
|
425
576
|
/**
|
|
@@ -427,16 +578,18 @@ export default class DigitalSignature {
|
|
|
427
578
|
* @returns {Promise<boolean>} считан ли ключ
|
|
428
579
|
*/
|
|
429
580
|
async isPrivateKeyReaded() {
|
|
430
|
-
|
|
581
|
+
try {
|
|
582
|
+
return !!this._readedKey && await this._euSign.IsPrivateKeyReaded();
|
|
583
|
+
} catch {
|
|
584
|
+
return false;
|
|
585
|
+
}
|
|
431
586
|
}
|
|
432
587
|
|
|
433
588
|
/**
|
|
434
589
|
* Очистить считанный ключ
|
|
435
590
|
*/
|
|
436
591
|
async resetPrivateKey() {
|
|
437
|
-
await
|
|
438
|
-
this._euSign.ResetPrivateKey()
|
|
439
|
-
]);
|
|
592
|
+
await this._euSign.ResetPrivateKey();
|
|
440
593
|
this._readedKey = null;
|
|
441
594
|
}
|
|
442
595
|
|
|
@@ -445,7 +598,7 @@ export default class DigitalSignature {
|
|
|
445
598
|
* @returns {Promise<Array<CASettings>>}
|
|
446
599
|
*/
|
|
447
600
|
async getCAs() {
|
|
448
|
-
return await this.
|
|
601
|
+
return await this._euSignFile.GetCAs();
|
|
449
602
|
}
|
|
450
603
|
|
|
451
604
|
/**
|
|
@@ -469,49 +622,78 @@ export default class DigitalSignature {
|
|
|
469
622
|
|
|
470
623
|
/**
|
|
471
624
|
* Подписать данные
|
|
472
|
-
* @param {Uint8Array | string |
|
|
473
|
-
* @param {
|
|
625
|
+
* @param {Uint8Array | string | NamedData | Array<Uint8Array | string | NamedData>} data - Данные для подписи. Можно передавать данные в массиве для наложения нескольких подписей за раз
|
|
626
|
+
* @param {EndUserSignContainerInfo?} signType - Тип подписи
|
|
474
627
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байтов. По умолчанию подпись возвращается в виде строки в base64
|
|
475
628
|
*/
|
|
476
|
-
async signData(data,
|
|
477
|
-
if (
|
|
478
|
-
|
|
629
|
+
async signData(data, signType, asByteArray) {
|
|
630
|
+
if (signType === true) {
|
|
631
|
+
// Обратная совместимость. Если передать в параметре значение true, дожна создаться подпись CAdES Enveloped (внутренняя)
|
|
632
|
+
signType = new EndUserSignContainerInfo();
|
|
633
|
+
signType.type = EndUserConstants.EndUserSignContainerType.CAdES;
|
|
634
|
+
signType.subType = EndUserConstants.EndUserCAdESType.Enveloped;
|
|
635
|
+
} else if (typeof signType != "object") {
|
|
636
|
+
// По умолчанию создаётся подпись CAdES Detached
|
|
637
|
+
signType = new EndUserSignContainerInfo();
|
|
638
|
+
signType.type = EndUserConstants.EndUserSignContainerType.CAdES;
|
|
639
|
+
signType.subType = EndUserConstants.EndUserCAdESType.Detached;
|
|
479
640
|
}
|
|
480
641
|
if (typeof asByteArray !== "boolean") {
|
|
481
642
|
asByteArray = false;
|
|
482
643
|
}
|
|
483
|
-
|
|
644
|
+
|
|
645
|
+
if (this.readedKey.keyType === DigitalSignatureKeyType.KSP && signType.type !== EndUserConstants.EndUserSignContainerType.CAdES) {
|
|
646
|
+
throw {
|
|
647
|
+
code: EndUserError.EU_ERROR_NOT_SUPPORTED,
|
|
648
|
+
message: this._resourses.KSPSignFormatError
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
if (signType.type === EndUserConstants.EndUserSignContainerType.ASiC) {
|
|
653
|
+
const signLevel = signType.asicSignType === EndUserConstants.EndUserASiCSignType.CAdES ? EndUserConstants.EndUserSignType.CAdES_X_Long : EndUserConstants.EndUserXAdESSignLevel.B_LT;
|
|
654
|
+
return await this._euSign.ASiCSignData(this._readedKey.getSignAlgo(), signType.subType, signType.asicSignType, signLevel, data, !asByteArray);
|
|
655
|
+
} else if (signType.type === EndUserConstants.EndUserSignContainerType.XAdES) {
|
|
656
|
+
let returnArray = true;
|
|
657
|
+
if (!Array.isArray(data)) {
|
|
658
|
+
data = [data];
|
|
659
|
+
returnArray = false;
|
|
660
|
+
}
|
|
661
|
+
data = data.map((e, i) => !e.name && !e.val ? { name: "data" + i, val: e } : e);
|
|
662
|
+
const signs = [];
|
|
663
|
+
for (let i = 0; i < data.length; i++) {
|
|
664
|
+
const result = await this._euSign.XAdESSignData(this._readedKey.getSignAlgo(), signType.subType, EndUserConstants.EndUserXAdESSignLevel.B_LT, data[i], !asByteArray);
|
|
665
|
+
signs[i] = result;
|
|
666
|
+
}
|
|
667
|
+
return returnArray ? signs : signs[0];
|
|
668
|
+
} else if (signType.type === EndUserConstants.EndUserSignContainerType.PAdES) {
|
|
669
|
+
return await this._euSign.PDFSignData(this._readedKey.getSignAlgo(), data, EndUserConstants.EndUserPAdESSignLevel.B_T, !asByteArray);
|
|
670
|
+
} else if (signType.type === EndUserConstants.EndUserSignContainerType.CAdES) {
|
|
671
|
+
if (signType.subType === EndUserConstants.EndUserCAdESType.Detached) {
|
|
672
|
+
const hash = await this._euSign.HashData(this._readedKey.getHashAlgo(), data, !asByteArray);
|
|
673
|
+
return await this._euSign.SignHash(this._readedKey.getSignAlgo(), hash, true, !asByteArray);
|
|
674
|
+
} else {
|
|
675
|
+
return await this._euSign.SignDataEx(this._readedKey.getSignAlgo(), data, false, true, !asByteArray);
|
|
676
|
+
}
|
|
677
|
+
} else {
|
|
678
|
+
throw {
|
|
679
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
680
|
+
message: this._resourses.BadSignatureType
|
|
681
|
+
};
|
|
682
|
+
}
|
|
484
683
|
}
|
|
485
684
|
|
|
486
685
|
/**
|
|
487
686
|
* Подписать файл
|
|
488
|
-
* @param {string |
|
|
489
|
-
* @param {
|
|
687
|
+
* @param {string | NamedData | Array<string | NamedData>} fileUrl - Ссылка на загрузку файла. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
|
|
688
|
+
* @param {EndUserSignContainerInfo?} signType - Тип подписи
|
|
490
689
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
|
|
491
690
|
*/
|
|
492
|
-
async signFile(fileUrl,
|
|
493
|
-
|
|
494
|
-
internal = false;
|
|
495
|
-
}
|
|
496
|
-
if (typeof asByteArray !== "boolean") {
|
|
497
|
-
asByteArray = false;
|
|
498
|
-
}
|
|
499
|
-
const isNamedData = Array.isArray(fileUrl) && fileUrl.every(url => typeof url === "object") || typeof fileUrl === "object";
|
|
500
|
-
let data;
|
|
501
|
-
if (Array.isArray(fileUrl)) {
|
|
502
|
-
data = await Promise.all(fileUrl.map(function(url) {
|
|
503
|
-
const downloadedData = downloadData(isNamedData ? url.val : url, "binary");
|
|
504
|
-
return isNamedData ? {name: url.name, val: downloadedData} : downloadedData;
|
|
505
|
-
}));
|
|
506
|
-
} else {
|
|
507
|
-
const downloadedData = await downloadData(isNamedData ? fileUrl.val : fileUrl, "binary");
|
|
508
|
-
data = isNamedData ? {name: fileUrl.name, val: downloadedData} : downloadedData;
|
|
509
|
-
}
|
|
510
|
-
return await this.signData(data, internal, asByteArray);
|
|
691
|
+
async signFile(fileUrl, signType, asByteArray) {
|
|
692
|
+
return await downloadAndSignFiles(fileUrl, async (data) => await this.signData(data, signType, asByteArray));
|
|
511
693
|
}
|
|
512
694
|
|
|
513
695
|
/**
|
|
514
|
-
* Подписать хеш
|
|
696
|
+
* Подписать хеш подписью CAdES Detached
|
|
515
697
|
* @param {Uint8Array | string | NamedData | Array<Uint8Array | string> | NamedData} hash - Хеш файла. Можно передавать несколько хешей в массиве для наложения нескольких подписей за раз
|
|
516
698
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
|
|
517
699
|
*/
|
|
@@ -523,38 +705,57 @@ export default class DigitalSignature {
|
|
|
523
705
|
}
|
|
524
706
|
|
|
525
707
|
/**
|
|
526
|
-
* Подписать хеш из файла
|
|
708
|
+
* Подписать хеш из файла подписью CAdES Detached
|
|
527
709
|
* @param {string | NamedData | Array<string | NamedData>} hashUrl - Ссылка на скачивание хеша. Можно передавать несколько ссылок в массиве для наложения нескольких подписей за раз
|
|
528
710
|
* @param {boolean?} asByteArray - Возвращать подпись в виде массива байт. По умолчанию подпись возвращается в виде строки в base64
|
|
529
711
|
*/
|
|
530
712
|
async signFileHash(hashUrl, asByteArray) {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
}));
|
|
541
|
-
} else {
|
|
542
|
-
const downloadedData = await downloadData(hashUrl, "binary");
|
|
543
|
-
hash = isNamedData ? {name: hashUrl.name, val: downloadedData} : downloadedData;
|
|
544
|
-
}
|
|
545
|
-
return await this.signHash(hash, asByteArray);
|
|
713
|
+
return await downloadAndSignFiles(hashUrl, async (hash) => await this.signHash(hash, asByteArray));
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Получить данные о типе подписи
|
|
718
|
+
* @param {string | Uint8Array} sign - Подпись
|
|
719
|
+
*/
|
|
720
|
+
async getSignContainerInfo(sign) {
|
|
721
|
+
return await this._euSign.GetSignContainerInfo(sign);
|
|
546
722
|
}
|
|
547
723
|
|
|
548
724
|
/**
|
|
549
|
-
* Проверить
|
|
725
|
+
* Проверить подпись (Соответствие подписанных данных не проверяется)
|
|
550
726
|
* @param {Uint8Array | string} data - Подписанные данные
|
|
551
727
|
* @param {Uint8Array | string} sign - Подпись
|
|
552
728
|
* @param {number?} signIndex - Номер подписи. -1 что бы проверить все подписи
|
|
553
729
|
*/
|
|
554
730
|
async verifyData(data, sign, signIndex) {
|
|
555
731
|
if (!Number.isInteger(signIndex)) {
|
|
556
|
-
signIndex =
|
|
732
|
+
signIndex = -1;
|
|
557
733
|
}
|
|
734
|
+
const signContainerInfo = await this._euSign.GetSignContainerInfo(sign.val || sign);
|
|
735
|
+
|
|
736
|
+
if (signContainerInfo.type === EndUserConstants.EndUserSignContainerType.ASiC) {
|
|
737
|
+
return await this._euSign.ASiCVerifyData(sign, signIndex);
|
|
738
|
+
} else if (signContainerInfo.type === EndUserConstants.EndUserSignContainerType.PAdES) {
|
|
739
|
+
return await this._euSign.PDFVerifyData(sign, signIndex);
|
|
740
|
+
} else if (signContainerInfo.type === EndUserConstants.EndUserSignContainerType.XAdES) {
|
|
741
|
+
return await this._euSign.XAdESVerifyData(data, sign.val || sign, signIndex);
|
|
742
|
+
} else if (signContainerInfo.type === EndUserConstants.EndUserSignContainerType.CAdES) {
|
|
743
|
+
if (signContainerInfo.subType === EndUserConstants.EndUserCAdESType.Detached) {
|
|
744
|
+
if (!data) {
|
|
745
|
+
throw {
|
|
746
|
+
code: EndUserError.EU_ERROR_BAD_PARAMETER,
|
|
747
|
+
message: this._resourses.BadParameter + " data"
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
const signerInfo = await this._euSign.GetSigner(sign, signIndex, false);
|
|
751
|
+
const hashAlgo = signAlgoToHashAlgo((Array.isArray(signerInfo) ? signerInfo[0] : signerInfo).infoEx.publicKeyType);
|
|
752
|
+
const hash = await this._euSign.HashData(hashAlgo, data);
|
|
753
|
+
return await this._euSign.VerifyHash(hash.val || hash, sign.val || sign, signIndex);
|
|
754
|
+
} else {
|
|
755
|
+
return await this._euSign.VerifyDataInternal(sign.val || sign, signIndex);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
558
759
|
return await this._euSign.VerifyData(data, sign, signIndex);
|
|
559
760
|
}
|
|
560
761
|
|
|
@@ -578,10 +779,7 @@ export default class DigitalSignature {
|
|
|
578
779
|
* @param {number?} signIndex - Номер подписи. -1 что бы проверить все подписи
|
|
579
780
|
*/
|
|
580
781
|
async verifyDataInternal(sign, signIndex) {
|
|
581
|
-
|
|
582
|
-
signIndex = 0;
|
|
583
|
-
}
|
|
584
|
-
return await this._euSign.VerifyDataInternal(sign, signIndex);
|
|
782
|
+
return await this.verifyData(null, sign, signIndex);
|
|
585
783
|
}
|
|
586
784
|
|
|
587
785
|
/**
|
|
@@ -595,20 +793,20 @@ export default class DigitalSignature {
|
|
|
595
793
|
}
|
|
596
794
|
|
|
597
795
|
/**
|
|
598
|
-
* Проверить подпись хеша
|
|
796
|
+
* Проверить подпись хеша (Только CAdES Detached)
|
|
599
797
|
* @param {Uint8Array | string} hash - Хеш подписанного файла
|
|
600
798
|
* @param {Uint8Array | string} sign - Подпись
|
|
601
799
|
* @param {number?} signIndex - Номер подписи. -1 что бы проверить все подписи
|
|
602
800
|
*/
|
|
603
801
|
async verifyHash(hash, sign, signIndex) {
|
|
604
802
|
if (!Number.isInteger(signIndex)) {
|
|
605
|
-
signIndex =
|
|
803
|
+
signIndex = -1;
|
|
606
804
|
}
|
|
607
|
-
return await this._euSign.VerifyHash(hash, sign, signIndex);
|
|
805
|
+
return await this._euSign.VerifyHash(hash.val || hash, sign.val || sign, signIndex);
|
|
608
806
|
}
|
|
609
807
|
|
|
610
808
|
/**
|
|
611
|
-
* Проверить подпись хеша из файла
|
|
809
|
+
* Проверить подпись хеша из файла (Только CAdES Detached)
|
|
612
810
|
* @param {string} hashUrl - Ссылка на загрузку файла
|
|
613
811
|
* @param {string} signUrl - Ссылка на загрузку подписи
|
|
614
812
|
* @param {number?} signIndex - Номер подписи. -1 что бы проверить все подписи
|
|
@@ -623,62 +821,57 @@ export default class DigitalSignature {
|
|
|
623
821
|
|
|
624
822
|
/**
|
|
625
823
|
* Выполнить подписание данных с проверкой подписи
|
|
626
|
-
* @param {Uint8Array | string | NamedData} data - данные для
|
|
627
|
-
* @param {
|
|
628
|
-
*/
|
|
629
|
-
async signDataEx(data,
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
824
|
+
* @param {Uint8Array | string | NamedData | Array<Uint8Array | string | NamedData>} data - Данные для подписи. Можно передавать данные в массиве для наложения нескольких подписей за раз
|
|
825
|
+
* @param {EndUserSignContainerInfo?} signType - Тип подписи
|
|
826
|
+
*/
|
|
827
|
+
async signDataEx(data, signType) {
|
|
828
|
+
const signs = await this.signData(data, signType);
|
|
829
|
+
|
|
830
|
+
if (Array.isArray(data)) {
|
|
831
|
+
const result = [];
|
|
832
|
+
for (let i = 0; i < signs.length; i++) {
|
|
833
|
+
const sign = signs[i];
|
|
834
|
+
let signInfo = await this.verifyData(data[i].val || data[i], sign.val || sign);
|
|
835
|
+
if (Array.isArray(signInfo)) {
|
|
836
|
+
signInfo = signInfo[signInfo.length - 1];
|
|
837
|
+
}
|
|
838
|
+
result[i] = {
|
|
839
|
+
Success: true,
|
|
840
|
+
Sign: sign.val || sign,
|
|
841
|
+
SignatureInfo: {
|
|
842
|
+
Success: true,
|
|
843
|
+
DateTimeStr: signInfo.timeInfo.time,
|
|
844
|
+
Signer: signInfo.ownerInfo.subjCN,
|
|
845
|
+
OwnerInfo: signInfo.ownerInfo
|
|
846
|
+
}
|
|
847
|
+
};
|
|
640
848
|
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
Sign: isNamedData ? signature.val : signature,
|
|
647
|
-
SignatureInfo: {
|
|
648
|
-
Success: true,
|
|
649
|
-
DateTimeStr: signatureInfo.timeInfo.time,
|
|
650
|
-
Signer: signatureInfo.ownerInfo.subjCN,
|
|
651
|
-
OwnerInfo: signatureInfo.ownerInfo
|
|
849
|
+
return result;
|
|
850
|
+
} else {
|
|
851
|
+
let signInfo = await this.verifyData(data.val || data, signs.val || signs);
|
|
852
|
+
if (Array.isArray(signInfo)) {
|
|
853
|
+
signInfo = signInfo[signInfo.length - 1];
|
|
652
854
|
}
|
|
653
|
-
|
|
855
|
+
return {
|
|
856
|
+
Success: true,
|
|
857
|
+
Sign: signs.val || signs,
|
|
858
|
+
SignatureInfo: {
|
|
859
|
+
Success: true,
|
|
860
|
+
DateTimeStr: signInfo.timeInfo.time,
|
|
861
|
+
Signer: signInfo.ownerInfo.subjCN,
|
|
862
|
+
OwnerInfo: signInfo.ownerInfo
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
}
|
|
654
866
|
}
|
|
655
867
|
|
|
656
868
|
/**
|
|
657
869
|
* Выполнить подписание с проверкой подписи
|
|
658
|
-
* @param {string | NamedData} fileUrl - ссылка на загрузку файла для подписания
|
|
659
|
-
* @param {
|
|
660
|
-
*/
|
|
661
|
-
async signFileEx(fileUrl,
|
|
662
|
-
|
|
663
|
-
let data = await downloadData(isNamedData ? fileUrl.val : fileUrl, "binary");
|
|
664
|
-
if(!hash) {
|
|
665
|
-
data = await this._euSign.HashData(this._readedKey.getHashAlgo(), data, false);
|
|
666
|
-
if(isNamedData) {
|
|
667
|
-
data = {name: fileUrl.name, val: data};
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
const signature = await this.signHash(data);
|
|
671
|
-
const signatureInfo = await this.verifyHash(isNamedData ? data.val : data, isNamedData ? signature.val : signature);
|
|
672
|
-
return {
|
|
673
|
-
Success: true,
|
|
674
|
-
Sign: isNamedData ? signature.val : signature,
|
|
675
|
-
SignatureInfo: {
|
|
676
|
-
Success: true,
|
|
677
|
-
DateTimeStr: signatureInfo.timeInfo.time,
|
|
678
|
-
Signer: signatureInfo.ownerInfo.subjCN,
|
|
679
|
-
OwnerInfo: signatureInfo.ownerInfo
|
|
680
|
-
}
|
|
681
|
-
};
|
|
870
|
+
* @param {string | NamedData | Array<string> | Array<NamedData>} fileUrl - ссылка на загрузку файла для подписания
|
|
871
|
+
* @param {EndUserSignContainerInfo?} signType - Тип подписи
|
|
872
|
+
*/
|
|
873
|
+
async signFileEx(fileUrl, signType) {
|
|
874
|
+
return await downloadAndSignFiles(fileUrl, async (data) => await this.signDataEx(data, signType));
|
|
682
875
|
}
|
|
683
876
|
|
|
684
877
|
/**
|
|
@@ -686,19 +879,44 @@ export default class DigitalSignature {
|
|
|
686
879
|
* @param {string | NamedData} hash - хеш для подписания
|
|
687
880
|
*/
|
|
688
881
|
async signHashEx(hash) {
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
882
|
+
const signs = await this.signHash(hash);
|
|
883
|
+
|
|
884
|
+
if (Array.isArray(hash)) {
|
|
885
|
+
const result = [];
|
|
886
|
+
for (let i = 0; i < signs.length; i++) {
|
|
887
|
+
const sign = signs[i];
|
|
888
|
+
let signInfo = await this.verifyHash(hash[i].val || hash[i], sign.val || sign);
|
|
889
|
+
if (Array.isArray(signInfo)) {
|
|
890
|
+
signInfo = signInfo[signInfo.length - 1];
|
|
891
|
+
}
|
|
892
|
+
result[i] = {
|
|
893
|
+
Success: true,
|
|
894
|
+
Sign: sign.val || sign,
|
|
895
|
+
SignatureInfo: {
|
|
896
|
+
Success: true,
|
|
897
|
+
DateTimeStr: signInfo.timeInfo.time,
|
|
898
|
+
Signer: signInfo.ownerInfo.subjCN,
|
|
899
|
+
OwnerInfo: signInfo.ownerInfo
|
|
900
|
+
}
|
|
901
|
+
};
|
|
700
902
|
}
|
|
701
|
-
|
|
903
|
+
return result;
|
|
904
|
+
} else {
|
|
905
|
+
let signInfo = await this.verifyHash(hash.val || hash, signs.val || signs);
|
|
906
|
+
if (Array.isArray(signInfo)) {
|
|
907
|
+
signInfo = signInfo[signInfo.length - 1];
|
|
908
|
+
}
|
|
909
|
+
return {
|
|
910
|
+
Success: true,
|
|
911
|
+
Sign: signs.val || signs,
|
|
912
|
+
SignatureInfo: {
|
|
913
|
+
Success: true,
|
|
914
|
+
DateTimeStr: signInfo.timeInfo.time,
|
|
915
|
+
Signer: signInfo.ownerInfo.subjCN,
|
|
916
|
+
OwnerInfo: signInfo.ownerInfo
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
}
|
|
702
920
|
}
|
|
703
921
|
|
|
704
922
|
/**
|
|
@@ -759,18 +977,18 @@ export default class DigitalSignature {
|
|
|
759
977
|
* @param {boolean} toLocalStorage - Будет ли ключ сохранён после закрытия вкладки
|
|
760
978
|
*/
|
|
761
979
|
async storePrivateKeyInfo(privateKeyInfo, toLocalStorage) {
|
|
762
|
-
if(privateKeyInfo.ksp &&
|
|
980
|
+
if (privateKeyInfo.ksp && privateKeyInfo.ksp.needQRCode) {
|
|
763
981
|
return;
|
|
764
982
|
}
|
|
765
983
|
|
|
766
984
|
const storage = toLocalStorage ? localStorage : sessionStorage;
|
|
767
985
|
const keys = await this.getStoredPrivateKeyInfo();
|
|
768
986
|
|
|
769
|
-
if(keys.length == 0 || keys.filter(key => key.id == privateKeyInfo.id).length < 1) {
|
|
987
|
+
if (keys.length == 0 || keys.filter(key => key.id == privateKeyInfo.id).length < 1) {
|
|
770
988
|
const keys = await this.getPrivateKeyInfoFromStorage(toLocalStorage);
|
|
771
989
|
keys.push(privateKeyInfo);
|
|
772
990
|
const data = await this._euSignFile.ProtectDataByPassword(JSON.stringify(keys), "", true);
|
|
773
|
-
storage[this._userId +
|
|
991
|
+
storage[this._userId + PRIVATE_KEY_INFO] = data;
|
|
774
992
|
}
|
|
775
993
|
}
|
|
776
994
|
|
|
@@ -787,27 +1005,27 @@ export default class DigitalSignature {
|
|
|
787
1005
|
|
|
788
1006
|
async getPrivateKeyInfoFromStorage(fromLocalStorage, keyType) {
|
|
789
1007
|
const storage = fromLocalStorage ? localStorage : sessionStorage;
|
|
790
|
-
const storedKeys = storage[this._userId +
|
|
1008
|
+
const storedKeys = storage[this._userId + PRIVATE_KEY_INFO];
|
|
791
1009
|
|
|
792
1010
|
let ls;
|
|
793
1011
|
const result = [];
|
|
794
|
-
if(!storedKeys) {
|
|
1012
|
+
if (!storedKeys) {
|
|
795
1013
|
return result;
|
|
796
1014
|
}
|
|
797
1015
|
const data = await this._euSignFile.UnprotectDataByPassword(storedKeys, "", true);
|
|
798
|
-
try{
|
|
1016
|
+
try {
|
|
799
1017
|
ls = JSON.parse(data);
|
|
800
|
-
if(keyType >= 0) {
|
|
1018
|
+
if (keyType >= 0) {
|
|
801
1019
|
ls = ls.filter(key => key.keyType == keyType);
|
|
802
1020
|
}
|
|
803
1021
|
}
|
|
804
|
-
catch{
|
|
1022
|
+
catch {
|
|
805
1023
|
ls = [];
|
|
806
1024
|
}
|
|
807
1025
|
|
|
808
1026
|
ls.forEach(key => {
|
|
809
1027
|
const password = key.password;
|
|
810
|
-
if(key.keyType == DigitalSignatureKeyType.File) {
|
|
1028
|
+
if (key.keyType == DigitalSignatureKeyType.File) {
|
|
811
1029
|
key.privateKey = new Uint8Array(Object.assign(new Array(), key.privateKey));
|
|
812
1030
|
key = new FilePrivateKeyInfo(key.keyType, key.ownerInfo, key.certificates, key.privateKey, key.password);
|
|
813
1031
|
}
|
|
@@ -834,22 +1052,22 @@ export default class DigitalSignature {
|
|
|
834
1052
|
* Удалить сохранённые ключи
|
|
835
1053
|
* @param {string} keyId - Идентификатор ключа
|
|
836
1054
|
*/
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
localStorage.removeItem(this._userId +
|
|
840
|
-
sessionStorage.removeItem(this._userId +
|
|
1055
|
+
async removeStoredPrivateKeyInfo(keyId) {
|
|
1056
|
+
if (keyId === undefined) {
|
|
1057
|
+
localStorage.removeItem(this._userId + PRIVATE_KEY_INFO);
|
|
1058
|
+
sessionStorage.removeItem(this._userId + PRIVATE_KEY_INFO);
|
|
841
1059
|
}
|
|
842
|
-
else{
|
|
1060
|
+
else {
|
|
843
1061
|
const localStoredKeys = await this.getPrivateKeyInfoFromStorage(true);
|
|
844
1062
|
const sessionStoredKeys = await this.getPrivateKeyInfoFromStorage(false);
|
|
845
1063
|
const storage = localStoredKeys.filter(item => item.id == keyId).length > 0 ? localStorage : sessionStorage;
|
|
846
1064
|
const keys = storage == localStorage ? localStoredKeys : sessionStoredKeys;
|
|
847
1065
|
const keyIndex = keys.findIndex((element) => element.id == keyId);
|
|
848
1066
|
|
|
849
|
-
if(keyIndex > -1) {
|
|
1067
|
+
if (keyIndex > -1) {
|
|
850
1068
|
keys.splice(keyIndex, 1);
|
|
851
1069
|
const data = await this._euSignFile.ProtectDataByPassword(JSON.stringify(keys), "", true);
|
|
852
|
-
storage[this._userId +
|
|
1070
|
+
storage[this._userId + PRIVATE_KEY_INFO] = data;
|
|
853
1071
|
}
|
|
854
1072
|
}
|
|
855
1073
|
}
|
|
@@ -858,11 +1076,11 @@ export default class DigitalSignature {
|
|
|
858
1076
|
* Получить предпочитаемый тип ключа
|
|
859
1077
|
*/
|
|
860
1078
|
get _preferredKeyType () {
|
|
861
|
-
const keyType = parseInt(localStorage[this._userId +
|
|
1079
|
+
const keyType = parseInt(localStorage[this._userId + PRIVATE_KEY_TYPE]);
|
|
862
1080
|
if (typeof keyType === "number" && keyType > -1) {
|
|
863
1081
|
return keyType;
|
|
864
1082
|
} else {
|
|
865
|
-
localStorage[this._userId +
|
|
1083
|
+
localStorage[this._userId + PRIVATE_KEY_TYPE] = DigitalSignatureKeyType.File;
|
|
866
1084
|
return DigitalSignatureKeyType.File;
|
|
867
1085
|
}
|
|
868
1086
|
}
|
|
@@ -873,15 +1091,36 @@ export default class DigitalSignature {
|
|
|
873
1091
|
*/
|
|
874
1092
|
set _preferredKeyType (keyType) {
|
|
875
1093
|
if (typeof keyType === "number" && keyType > -1) {
|
|
876
|
-
localStorage[this._userId +
|
|
1094
|
+
localStorage[this._userId + PRIVATE_KEY_TYPE] = keyType;
|
|
877
1095
|
}
|
|
878
1096
|
}
|
|
879
1097
|
|
|
880
1098
|
get _resourses() {
|
|
881
|
-
return Resourses[this.
|
|
1099
|
+
return Resourses[this._language];
|
|
882
1100
|
}
|
|
883
1101
|
|
|
884
1102
|
get _userId () {
|
|
885
|
-
return typeof this.
|
|
1103
|
+
return typeof this._settingsProvider.userId === "function" ? this._settingsProvider.userId() : this._settingsProvider.userId;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
get _language () {
|
|
1107
|
+
return typeof this._settingsProvider.language === "function" ? this._settingsProvider.language() : this._settingsProvider.language;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Проверка доступности Дiя
|
|
1112
|
+
*/
|
|
1113
|
+
async _diiaCheckAccess() {
|
|
1114
|
+
const diia = "DIIA";
|
|
1115
|
+
if (sessionStorage[diia] != "+") {
|
|
1116
|
+
try {
|
|
1117
|
+
sessionStorage[diia] = await downloadData(new URL(this._KSPs.diia.address).origin + "/diia");
|
|
1118
|
+
} catch {
|
|
1119
|
+
throw {
|
|
1120
|
+
code: EndUserError.EU_ERROR_TRANSMIT_REQUEST,
|
|
1121
|
+
message: this._resourses.DiiaError + `<a target="_blank" href="${window.origin}">${window.origin}</a></li><ul>`
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
886
1125
|
}
|
|
887
1126
|
}
|