From 6d6ac62a0acf831a624eb057ef73da087e0d940d Mon Sep 17 00:00:00 2001 From: Vitalii Goma Date: Tue, 17 Jan 2017 13:22:49 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D0=BE=D0=BD=D0=B0?= =?UTF-8?q?=D1=87=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BC=D0=B8=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + README.md | 17 + dist/1.crypto-pro.js | 1624 ++++++++++++++++++++++++++++++++++++++ dist/1.crypto-pro.js.map | 1 + dist/2.crypto-pro.js | 1600 +++++++++++++++++++++++++++++++++++++ dist/2.crypto-pro.js.map | 1 + dist/crypto-pro.js | 845 ++++++++++++++++++++ dist/crypto-pro.js.map | 1 + example/index.html | 27 + package.json | 29 + src/apiAsync.js | 545 +++++++++++++ src/apiSync.js | 520 ++++++++++++ src/cades.js | 635 +++++++++++++++ src/common.js | 278 +++++++ src/constants.js | 139 ++++ src/index.js | 103 +++ src/oids.js | 44 ++ webpack.config.js | 11 + 18 files changed, 6422 insertions(+) create mode 100644 .gitignore create mode 100755 README.md create mode 100644 dist/1.crypto-pro.js create mode 100644 dist/1.crypto-pro.js.map create mode 100644 dist/2.crypto-pro.js create mode 100644 dist/2.crypto-pro.js.map create mode 100644 dist/crypto-pro.js create mode 100644 dist/crypto-pro.js.map create mode 100755 example/index.html create mode 100644 package.json create mode 100755 src/apiAsync.js create mode 100755 src/apiSync.js create mode 100755 src/cades.js create mode 100755 src/common.js create mode 100755 src/constants.js create mode 100755 src/index.js create mode 100755 src/oids.js create mode 100755 webpack.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c564040 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +node_modules/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100755 index 0000000..197df86 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +## CryptoPro + +Единое, асинхронное API для взаимодействия с КриптоПРО ЭЦП Browser Plug-In (IE8+) + +``` js +CryptoService.call('getCertsList').then(function (certList) { + console.log(certList); +}); +``` + +Для работы с библиотекой, хост, с которого работает скрипт необходимо добавить +в доверенные узлы с помощью настроек КриптоПРО ЭЦП Browser Plug-In. + +Полифиллы необходимо подключать самостоятельно. + +### License +Licensed as MIT. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. diff --git a/dist/1.crypto-pro.js b/dist/1.crypto-pro.js new file mode 100644 index 0000000..ec778e2 --- /dev/null +++ b/dist/1.crypto-pro.js @@ -0,0 +1,1624 @@ +webpackJsonpCryptoPro([1],[ +/* 0 */, +/* 1 */, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + var cryptoCommon = __webpack_require__(3), + cryptoConstants = __webpack_require__(7), + + _certProto = { + /** + * Проверяет, валиден ли сертификат + * */ + isValid: function isValid() { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + cadesplugin.async_spawn(function* () { + var result; + + try { + result = yield cert.IsValid(); + result = yield result.Result; + } catch (err) { + reject('Ошибка при проверке сертификата: ', err.message); + return; + } + + resolve(result); + }); + }); + }, + + /** + * Достает указанное свойство у сертификата + * */ + getProp: function (propName) { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + cadesplugin.async_spawn(function* () { + var result; + + try { + result = yield cert[propName]; + } catch (err) { + reject('Ошибка при обращении к свойству сертификата: ', err.message); + return; + } + + resolve(result); + }); + }); + }, + + /** + * Экспорт base64 представления сертификата пользователя + * */ + exportBase64: function exportBase64() { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + cadesplugin.async_spawn(function* () { + var base64; + + try { + base64 = yield cert.Export(0); + } catch (err) { + reject('Ошибка при экспорте сертификата: ', err.message); + return; + } + + resolve(base64); + }); + }); + }, + + /** + * Возвращает информацию об алгоритме + * */ + getAlgorithm: function getAlgorithm() { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + cadesplugin.async_spawn(function* () { + var result = {}, + algorithm; + + try { + algorithm = yield cert.PublicKey(); + algorithm = yield algorithm.Algorithm; + + result.algorithm = yield algorithm.FriendlyName; + result.oid = yield algorithm.Value; + } catch (err) { + reject('Ошибка при получении алгоритма: ', err.message); + return; + } + + resolve(result); + }); + }); + }, + + /** + * Разбирает SubjectName сертификата по тэгам + * */ + getOwnerInfo: function getOwnerInfo() { + return getCertInfo.call(this, cryptoCommon.subjectNameTagsTranslations, 'SubjectName'); + }, + + /** + * Разбирает IssuerName сертификата по тэгам + * */ + getIssuerInfo: function getIssuerInfo() { + return getCertInfo.call(this, cryptoCommon.issuerNameTagsTranslations, 'IssuerName'); + }, + + /** + * Получение OID сертификата + * + * @returns {Array} Возвращает массив OID (улучшенного ключа) + * */ + getExtendedKeyUsage: function getExtendedKeyUsage() { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + cadesplugin.async_spawn(function* () { + var OIDS = [], + count, + item; + + try { + count = yield cert.ExtendedKeyUsage(); + count = yield count.EKUs; + count = yield count.Count; + + if (count > 0) { + while (count > 0) { + item = yield cert.ExtendedKeyUsage(); + item = yield item.EKUs; + item = yield item.Item(count); + item = yield item.OID; + + OIDS.push(item); + + count--; + } + } + } catch (err) { + reject('Ошибка при получении ОИД\'ов: ', err.message); + return; + } + + resolve(OIDS); + }); + }); + }, + + getDecodedExtendedKeyUsage: cryptoCommon.getDecodedExtendedKeyUsage, + + hasExtendedKeyUsage: cryptoCommon.hasExtendedKeyUsage + }, + + _certListCache; + + /** + * Проверяет корректность настроек ЭП на машине + * */ + function isValidEDSSettings() { + return new Promise(function (resolve, reject) { + cadesplugin.async_spawn(function* () { + var result; + + try { + result = yield cadesplugin.CreateObjectAsync('CAdESCOM.About'); + } catch (error) { + reject('Настройки ЭП на данной машине не верны'); + } + + resolve(); + }); + }); + } + + /** + * Получить сертификат в формате cades по хэшу + * */ + function getCadesCert(hash) { + return new Promise(function (resolve, reject) { + cadesplugin.async_spawn(function* () { + var oStore = yield cadesplugin.CreateObjectAsync('CAdESCOM.Store'), + certs, + certCnt, + cert; + + if (!oStore) { + reject('Не удалось получить доступ к хранилищу сертификатов'); + return; + } + + // Открываем хранилище + try { + yield oStore.Open( + cadesplugin.CAPICOM_CURRENT_USER_STORE, + cadesplugin.CAPICOM_MY_STORE, + cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED + ); + } catch (err) { + reject('Ошибка при открытии хранилища: ' + err.message); + return; + } + + // Получаем доступ к сертификатам + try { + certs = yield oStore.Certificates; + certCnt = yield certs.Count; + } catch (err) { + reject('Ошибка получения списка сертификатов: ' + err.message); + return; + } + + if (!certCnt) { + reject('Нет доступных сертификатов'); + return; + } + + // Получаем сертификат по хэшу + try { + certs = yield certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH, hash); + + if (certs.Count) { + cert = yield certs.Item(1); + } else { + throw new Error('Нет доступных сертификатов'); + } + } catch (err) { + reject('Не удалось получить сертификат по хэшу: ' + err.message); + return; + } + + oStore.Close(); + + resolve(cert); + }); + }); + } + + /** + * Разбирает информацию сертификата по тэгам + * */ + function getCertInfo(tags, propName) { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + cadesplugin.async_spawn(function* () { + var propInfo; + + try { + propInfo = yield cert[propName]; + } catch (err) { + reject('Ошибка при извлечении данных из сертификата: ', err.message); + return; + } + + resolve(cryptoCommon.parseCertInfo(tags, propInfo)); + }); + }); + } + + /** + * Возвращает список сертификатов, доступных в системе + * + * @param {Boolean} [resetCache=false] -- нужно ли сбросить кэш списка сертификатов + * @returns {Promise} -- со списком сертификатов {Array} + * */ + function getCertsList(resetCache) { + return new Promise(function (resolve, reject) { + if (!resetCache && _certListCache) { + resolve(_certListCache); + return; + } + + cadesplugin.async_spawn(function* () { + var oStore = yield cadesplugin.CreateObjectAsync('CAdESCOM.Store'), + result = [], + certs, + count, + item; + + // Открываем хранилище + try { + yield oStore.Open( + cadesplugin.CAPICOM_CURRENT_USER_STORE, + cadesplugin.CAPICOM_MY_STORE, + cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED + ); + } catch (err) { + reject('Ошибка при открытии хранилища: ' + err.message); + return; + } + + // Получаем доступ к сертификатам + try { + certs = yield oStore.Certificates; + + if (certs) { + certs = yield certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID); + /** + * Не рассматриваются сертификаты, в которых отсутствует закрытый ключ + * или не действительны на данный момент + * */ + certs = yield certs.Find( + cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY, + cryptoConstants.PropId.CAPICOM_PROPID_KEY_PROV_INFO + ); + + count = yield certs.Count; + } + } catch (err) { + reject('Ошибка получения списка сертификатов: ' + err.message); + return; + } + + if (!count) { + reject('Нет доступных сертификатов'); + return; + } + + try { + while (count) { + item = yield certs.Item(count); + + result.push(Object.assign(Object.create(_certProto), { + _cert: yield item, + thumbprint: yield item.Thumbprint, + subjectName: yield item.SubjectName, + issuerName: yield item.IssuerName, + validFrom: yield item.ValidFromDate, + validTo: yield item.ValidToDate + })); + + count--; + } + } catch (err) { + reject('Ошибка обработки сертификатов: ' + err.message); + return; + } + + oStore.Close(); + + _certListCache = cryptoCommon.prepareCertsInfo(result); + + resolve(_certListCache); + }); + }); + } + + /** + * Получить сертификат по хэшу + * */ + function getCert(hash) { + return new Promise(function (resolve, reject) { + if (!hash) { + reject('Хэш не указан'); + return; + } + + getCertsList().then(function (list) { + var foundCert; + + list.some(function (cert) { + if (hash === cert.thumbprint) { + foundCert = cert; + return true; + } + }); + + if (foundCert) { + resolve(foundCert); + } else { + reject('Сертификат с хэшем: "' + hash + '" не найден'); + } + }, reject); + }); + } + + /** + * Создает подпись base64 строки по hash'у сертификата + * + * @param {String} hash -- fingerprint (thumbprint) сертификата + * @param {String} dataBase64 -- строковые данные в формате base64 + * @param {String} signType -- тип подписи открепленная (true) / присоединенная (false) (default: false) + * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String} + * */ + function signData(hash, dataBase64, signType) { + return new Promise(function (resolve, reject) { + getCadesCert(hash).then(function (cert) { + cadesplugin.async_spawn(function* () { + var clientTime = new Date(), + oAttrs = yield cadesplugin.CreateObjectAsync('CADESCOM.CPAttribute'), + oSignedData = yield cadesplugin.CreateObjectAsync('CAdESCOM.CadesSignedData'), + oSigner = yield cadesplugin.CreateObjectAsync('CAdESCOM.CPSigner'), + attrs, + signature; + + clientTime = cryptoCommon.getDateObj(clientTime); + + try { + yield oAttrs.propset_Name(cryptoConstants.Time.AUTHENTICATED_ATTRIBUTE_SIGNING_TIME); + yield oAttrs.propset_Value(clientTime); + } catch (err) { + reject('Ошибка при установке данных подписи: ' + err.message); + return; + } + + // Задаем настройки для подписи + try { + yield oSigner.propset_Certificate(cert); + attrs = yield oSigner.AuthenticatedAttributes2; + yield attrs.Add(oAttrs); + yield oSignedData.propset_ContentEncoding(cadesplugin.CADESCOM_BASE64_TO_BINARY); + yield oSignedData.propset_Content(dataBase64); + yield oSigner.propset_Options(cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY); + } catch (err) { + reject('Не удалось установить настройки для подписи: ' + err.message); + return; + } + + try { + signature = yield oSignedData.SignCades( + oSigner, + cadesplugin.CADESCOM_CADES_BES, + Boolean(signType) + ); + } catch (err) { + reject('Не удалось создать подпись: ' + err.message); + return; + } + + resolve(signature); + }); + }); + }); + } + + /** + * Создает подпись XML строки по hash'у сертификата + * + * @param {String} hash -- fingerprint (thumbprint) сертификата + * @param {String} dataXML -- данные в формате XML + * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String} + * */ + function signDataXML(hash, dataXML) { + return new Promise(function (resolve, reject) { + getCadesCert(hash).then(function (cert) { + cadesplugin.async_spawn(function* () { + var oSigner = yield cadesplugin.CreateObjectAsync('CAdESCOM.CPSigner'), + signerXML = yield cadesplugin.CreateObjectAsync('CAdESCOM.SignedXML'), + cnts = cryptoConstants, + signature; + + // Задаем настройки для подписи + try { + yield oSigner.propset_Certificate(cert); + // Добавляем данные для подписи + yield signerXML.propset_Content(dataXML); + // Устанавливаем тип подписи + yield signerXML.propset_SignatureType(cnts.SignatureType.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED); + // Устанавливаем алгоритм подписи + yield signerXML.propset_SignatureMethod(cnts.GostXmlDSigUrls.XmlDsigGost3410Url); + // Устанавливаем алгоритм хэширования + yield signerXML.propset_DigestMethod(cnts.GostXmlDSigUrls.XmlDsigGost3411Url); + } catch (err) { + reject('Не удалось установить настройки для подписи: ' + err.message); + return; + } + + try { + signature = yield signerXML.Sign(oSigner); + } catch (err) { + reject('Не удалось создать подпись: ' + err.message); + return; + } + + resolve(signature); + }); + }); + }); + } + + /** + * Возвращает информацию о версии CSP и плагина + * */ + function getSystemInfo() { + var sysInfo = cryptoCommon.getEnvInfo(); + + return new Promise(function (resolve, reject) { + cadesplugin.async_spawn(function* () { + var e; + + try { + e = yield cadesplugin.CreateObjectAsync('CAdESCOM.About'); + + sysInfo.cadesVersion = yield e.PluginVersion; + // Возможен вызов в ранних версиях в виде sysInfo.cspVersion = yield e.CSPVersion('', 75); + sysInfo.cspVersion = yield e.CSPVersion(); + + if (!sysInfo.cadesVersion) { + sysInfo.cadesVersion = yield e.Version; + } + + sysInfo.cadesVersion = yield sysInfo.cadesVersion.toString(); + sysInfo.cspVersion = yield sysInfo.cspVersion.toString(); + + resolve(sysInfo); + } catch (err) { + reject('Ошибка при получении информации о системе: ', err.message); + } + }); + }); + } + + /** + * Promise обертка для синхронного вызова проверки версии CSP + * */ + function isValidCSPVersion(version) { + return new Promise(function (resolve) { + resolve(cryptoCommon.isValidCSPVersion(version)); + }); + } + + /** + * Promise обертка для синхронного вызова проверки версии плагина + * */ + function isValidCadesVersion(version) { + return new Promise(function (resolve) { + resolve(cryptoCommon.isValidCadesVersion(version)); + }); + } + + module.exports = { + isValidEDSSettings: isValidEDSSettings, + getCertsList: getCertsList, + getCert: getCert, + signData: signData, + signDataXML: signDataXML, + getSystemInfo: getSystemInfo, + isValidCSPVersion: isValidCSPVersion, + isValidCadesVersion: isValidCadesVersion + }; + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + var bowser = __webpack_require__(4); + var oids = __webpack_require__(6); + + var subjectNameTagsTranslations = [ + {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'}, + {possibleNames: ['CN'], translation: 'Владелец'}, + {possibleNames: ['SN'], translation: 'Фамилия'}, + {possibleNames: ['G'], translation: 'Имя Отчество'}, + {possibleNames: ['C'], translation: 'Страна'}, + {possibleNames: ['S'], translation: 'Регион'}, + {possibleNames: ['STREET'], translation: 'Адрес'}, + {possibleNames: ['O'], translation: 'Компания'}, + {possibleNames: ['OU'], translation: 'Отдел/подразделение'}, + {possibleNames: ['T'], translation: 'Должность'}, + {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'}, + {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'}, + {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'}, + {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'}, + {possibleNames: ['E'], translation: 'Email'}, + {possibleNames: ['L'], translation: 'Город'} + ], + + issuerNameTagsTranslations = [ + {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'}, + {possibleNames: ['CN'], translation: 'Удостоверяющий центр'}, + {possibleNames: ['S'], translation: 'Регион'}, + {possibleNames: ['C'], translation: 'Страна'}, + {possibleNames: ['STREET'], translation: 'Адрес'}, + {possibleNames: ['O'], translation: 'Компания'}, + {possibleNames: ['OU'], translation: 'Тип'}, + {possibleNames: ['T'], translation: 'Должность'}, + {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'}, + {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'}, + {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'}, + {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'}, + {possibleNames: ['E'], translation: 'Email'}, + {possibleNames: ['L'], translation: 'Город'} + ]; + + /** + * Парсит информацию из строки с информацией о сертификате + * */ + function parseCertInfo(tags, infoString) { + /** + * Пример входной строки: + * + + T=Генеральный директор, UnstructuredName="INN=7811514257/KPP=781101001/OGRN=1127847087884", + STREET="Крыленко, д.3, лит.Б", CN=Король Анатолий Евгеньевич, G=Анатолий Евгеньевич, SN=Король, + OU=Администрация, O="ООО ""Аксиома""", L=Санкт-Петербург, S=78 г. Санкт-Петербург, C=RU, E=korol@sferasro.ru, + INN=007811514257, OGRN=1127847087884, SNILS=11617693460 + + * */ + var result = infoString.match(/([а-яА-Яa-zA-Z0-9\.]+)=(?:("[^"]+?")|(.+?))(?:,|$)/g); + + if (result) { + result = result.map(function (group) { + /** + * Пример входной строки: + * + + UnstructuredName="INN=7811514257/KPP=781101001/OGRN=1127847087884", + + * */ + var parts = group.match(/^([а-яА-Яa-zA-Z0-9\.]+)=(.+?),?$/), + title = parts && parts[1], + descr = parts && parts[2], + translated = false, + oidTitle; + + // Если тайтл содержит ОИД, пытаемся расшифровать + if (/^OID./.test(title)) { + oidTitle = title.match(/^OID\.(.*)/); + + if (oidTitle && oidTitle[1]) { + oidTitle = oids[oidTitle[1]]; + + if (oidTitle) { + title = oidTitle; + } + } + } + + // Вырезаем лишние кавычки + descr = descr.replace(/^"(.*)"/, '$1'); + descr = descr.replace(/"{2}/g, '"'); + + tags.some(function (tag) { + return tag.possibleNames.some(function (possible) { + var match = possible === title; + + if (match) { + title = tag.translation; + translated = true; + } + + return match; + }); + }); + + return { + title: title, + descr: descr, + translated: translated + }; + }); + } + + return result; + } + + /** + * Возвращает дату в формате (dd.mm.yyyy hh:mm:ss) из строки, формата, используемого плагином cryptoPro + * */ + function getReadableDate(date) { + date = new Date(date); + + return ([ + date.getDate(), + date.getMonth() + 1, + date.getFullYear() + ].join('.') + ' ' + [ + date.getHours(), + date.getMinutes(), + date.getSeconds() + ].join(':')).replace(/\b(\d)\b/g, '0$1'); + } + + /** + * Преобразует дату для IE + * */ + function getDateObj(dateObj) { + return bowser.msie ? dateObj.getVarDate() : dateObj; + } + + /** + * Подготавливает информацию о сертификатах + * */ + function prepareCertsInfo(items) { + return items.map(function (c) { + c.name = c.subjectName.match(/CN=(.+?),/); + + // Удалось ли вытащить Common Name + if (c.name && c.name[1]) { + c.name = c.name[1]; + } + + c.validFrom = getReadableDate(c.validFrom); + c.validTo = getReadableDate(c.validTo); + + c.label = c.name + ' (до ' + c.validTo + ')'; + + return c; + }); + } + + /** + * Возвращает расшифрованные ОИД'ы + * */ + function getDecodedExtendedKeyUsage() { + var that = this; + + return new Promise(function (resolve) { + that.getExtendedKeyUsage().then(function (certOids) { + resolve(certOids.reduce(function (oidsLst, oid) { + oid = { + id: oid, + descr: oids[oid] || null + }; + + if (oid.descr) { + oidsLst.unshift(oid); + } else { + oidsLst.push(oid); + } + + return oidsLst; + }, [])); + }); + }); + } + + /** + * Проверка наличия ОИД'а(ОИД'ов) у сертификата + * + * @param {String|Array} oids - ОИД'ы для проверки + * @returns {Promise} с отложенным результатом типа {Boolean} + * */ + function hasExtendedKeyUsage(oids) { + var that = this; + + return new Promise(function (resolve) { + that.getExtendedKeyUsage().then(function (certOids) { + var result; + + if (Array.isArray(oids)) { + result = oids.every(function (oidToCheck) { + return certOids.some(function (certOid) { + return certOid === oidToCheck; + }); + }); + } else { + result = certOids.some(function (certOid) { + return certOid === oids; + }); + } + + resolve(result); + }); + }); + } + + /** + * Выводит информацию о системе пользователя + * */ + function getEnvInfo() { + var parsed = bowser._detect(navigator.userAgent), + info = { + browserName: parsed.name, + browserVersion: parsed.version + }; + + if (parsed.mac) { + info.os = 'Mac'; + } else if (parsed.windows) { + info.os = 'Windows'; + } else if (parsed.linux) { + info.os = 'Linux'; + } + + return info; + } + + /** + * Подходящая ли версия CSP + * */ + function isValidCSPVersion(version) { + version = version.match(/\d+?\b(?:\.\d+)?/); + + return version >= 3.6; + } + + /** + * Подходящая ли версия cades плагина + * */ + function isValidCadesVersion(version) { + version = version.split('.').reduce(function (verInfo, number, i) { + if (i === 0) { + verInfo.major = number; + } else if (i === 1) { + verInfo.minor = number; + } else if (i === 2) { + verInfo.patch = number; + } + + return verInfo; + }, {}); + + if (version.major < 2) { + return false; + } + + return version.patch >= 12438; + } + + module.exports = { + subjectNameTagsTranslations: subjectNameTagsTranslations, + issuerNameTagsTranslations: issuerNameTagsTranslations, + parseCertInfo: parseCertInfo, + getReadableDate: getReadableDate, + getDateObj: getDateObj, + prepareCertsInfo: prepareCertsInfo, + getDecodedExtendedKeyUsage: getDecodedExtendedKeyUsage, + hasExtendedKeyUsage: hasExtendedKeyUsage, + getEnvInfo: getEnvInfo, + isValidCSPVersion: isValidCSPVersion, + isValidCadesVersion: isValidCadesVersion + }; + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + /*! + * Bowser - a browser detector + * https://github.com/ded/bowser + * MIT License | (c) Dustin Diaz 2015 + */ + + !function (root, name, definition) { + if (typeof module != 'undefined' && module.exports) module.exports = definition() + else if (true) __webpack_require__(5)(name, definition) + else root[name] = definition() + }(this, 'bowser', function () { + /** + * See useragents.js for examples of navigator.userAgent + */ + + var t = true + + function detect(ua) { + + function getFirstMatch(regex) { + var match = ua.match(regex); + return (match && match.length > 1 && match[1]) || ''; + } + + function getSecondMatch(regex) { + var match = ua.match(regex); + return (match && match.length > 1 && match[2]) || ''; + } + + var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase() + , likeAndroid = /like android/i.test(ua) + , android = !likeAndroid && /android/i.test(ua) + , nexusMobile = /nexus\s*[0-6]\s*/i.test(ua) + , nexusTablet = !nexusMobile && /nexus\s*[0-9]+/i.test(ua) + , chromeos = /CrOS/.test(ua) + , silk = /silk/i.test(ua) + , sailfish = /sailfish/i.test(ua) + , tizen = /tizen/i.test(ua) + , webos = /(web|hpw)os/i.test(ua) + , windowsphone = /windows phone/i.test(ua) + , samsungBrowser = /SamsungBrowser/i.test(ua) + , windows = !windowsphone && /windows/i.test(ua) + , mac = !iosdevice && !silk && /macintosh/i.test(ua) + , linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua) + , edgeVersion = getFirstMatch(/edge\/(\d+(\.\d+)?)/i) + , versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i) + , tablet = /tablet/i.test(ua) + , mobile = !tablet && /[^-]mobi/i.test(ua) + , xbox = /xbox/i.test(ua) + , result + + if (/opera/i.test(ua)) { + // an old Opera + result = { + name: 'Opera' + , opera: t + , version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\s\/](\d+(\.\d+)?)/i) + } + } else if (/opr|opios/i.test(ua)) { + // a new Opera + result = { + name: 'Opera' + , opera: t + , version: getFirstMatch(/(?:opr|opios)[\s\/](\d+(\.\d+)?)/i) || versionIdentifier + } + } + else if (/SamsungBrowser/i.test(ua)) { + result = { + name: 'Samsung Internet for Android' + , samsungBrowser: t + , version: versionIdentifier || getFirstMatch(/(?:SamsungBrowser)[\s\/](\d+(\.\d+)?)/i) + } + } + else if (/coast/i.test(ua)) { + result = { + name: 'Opera Coast' + , coast: t + , version: versionIdentifier || getFirstMatch(/(?:coast)[\s\/](\d+(\.\d+)?)/i) + } + } + else if (/yabrowser/i.test(ua)) { + result = { + name: 'Yandex Browser' + , yandexbrowser: t + , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i) + } + } + else if (/ucbrowser/i.test(ua)) { + result = { + name: 'UC Browser' + , ucbrowser: t + , version: getFirstMatch(/(?:ucbrowser)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (/mxios/i.test(ua)) { + result = { + name: 'Maxthon' + , maxthon: t + , version: getFirstMatch(/(?:mxios)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (/epiphany/i.test(ua)) { + result = { + name: 'Epiphany' + , epiphany: t + , version: getFirstMatch(/(?:epiphany)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (/puffin/i.test(ua)) { + result = { + name: 'Puffin' + , puffin: t + , version: getFirstMatch(/(?:puffin)[\s\/](\d+(?:\.\d+)?)/i) + } + } + else if (/sleipnir/i.test(ua)) { + result = { + name: 'Sleipnir' + , sleipnir: t + , version: getFirstMatch(/(?:sleipnir)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (/k-meleon/i.test(ua)) { + result = { + name: 'K-Meleon' + , kMeleon: t + , version: getFirstMatch(/(?:k-meleon)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (windowsphone) { + result = { + name: 'Windows Phone' + , windowsphone: t + } + if (edgeVersion) { + result.msedge = t + result.version = edgeVersion + } + else { + result.msie = t + result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i) + } + } + else if (/msie|trident/i.test(ua)) { + result = { + name: 'Internet Explorer' + , msie: t + , version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i) + } + } else if (chromeos) { + result = { + name: 'Chrome' + , chromeos: t + , chromeBook: t + , chrome: t + , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) + } + } else if (/chrome.+? edge/i.test(ua)) { + result = { + name: 'Microsoft Edge' + , msedge: t + , version: edgeVersion + } + } + else if (/vivaldi/i.test(ua)) { + result = { + name: 'Vivaldi' + , vivaldi: t + , version: getFirstMatch(/vivaldi\/(\d+(\.\d+)?)/i) || versionIdentifier + } + } + else if (sailfish) { + result = { + name: 'Sailfish' + , sailfish: t + , version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i) + } + } + else if (/seamonkey\//i.test(ua)) { + result = { + name: 'SeaMonkey' + , seamonkey: t + , version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i) + } + } + else if (/firefox|iceweasel|fxios/i.test(ua)) { + result = { + name: 'Firefox' + , firefox: t + , version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \/](\d+(\.\d+)?)/i) + } + if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) { + result.firefoxos = t + } + } + else if (silk) { + result = { + name: 'Amazon Silk' + , silk: t + , version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i) + } + } + else if (/phantom/i.test(ua)) { + result = { + name: 'PhantomJS' + , phantom: t + , version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i) + } + } + else if (/slimerjs/i.test(ua)) { + result = { + name: 'SlimerJS' + , slimer: t + , version: getFirstMatch(/slimerjs\/(\d+(\.\d+)?)/i) + } + } + else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) { + result = { + name: 'BlackBerry' + , blackberry: t + , version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i) + } + } + else if (webos) { + result = { + name: 'WebOS' + , webos: t + , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i) + }; + /touchpad\//i.test(ua) && (result.touchpad = t) + } + else if (/bada/i.test(ua)) { + result = { + name: 'Bada' + , bada: t + , version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i) + }; + } + else if (tizen) { + result = { + name: 'Tizen' + , tizen: t + , version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier + }; + } + else if (/qupzilla/i.test(ua)) { + result = { + name: 'QupZilla' + , qupzilla: t + , version: getFirstMatch(/(?:qupzilla)[\s\/](\d+(?:\.\d+)+)/i) || versionIdentifier + } + } + else if (/chromium/i.test(ua)) { + result = { + name: 'Chromium' + , chromium: t + , version: getFirstMatch(/(?:chromium)[\s\/](\d+(?:\.\d+)?)/i) || versionIdentifier + } + } + else if (/chrome|crios|crmo/i.test(ua)) { + result = { + name: 'Chrome' + , chrome: t + , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) + } + } + else if (android) { + result = { + name: 'Android' + , version: versionIdentifier + } + } + else if (/safari|applewebkit/i.test(ua)) { + result = { + name: 'Safari' + , safari: t + } + if (versionIdentifier) { + result.version = versionIdentifier + } + } + else if (iosdevice) { + result = { + name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod' + } + // WTF: version is not part of user agent in web apps + if (versionIdentifier) { + result.version = versionIdentifier + } + } + else if(/googlebot/i.test(ua)) { + result = { + name: 'Googlebot' + , googlebot: t + , version: getFirstMatch(/googlebot\/(\d+(\.\d+))/i) || versionIdentifier + } + } + else { + result = { + name: getFirstMatch(/^(.*)\/(.*) /), + version: getSecondMatch(/^(.*)\/(.*) /) + }; + } + + // set webkit or gecko flag for browsers based on these engines + if (!result.msedge && /(apple)?webkit/i.test(ua)) { + if (/(apple)?webkit\/537\.36/i.test(ua)) { + result.name = result.name || "Blink" + result.blink = t + } else { + result.name = result.name || "Webkit" + result.webkit = t + } + if (!result.version && versionIdentifier) { + result.version = versionIdentifier + } + } else if (!result.opera && /gecko\//i.test(ua)) { + result.name = result.name || "Gecko" + result.gecko = t + result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i) + } + + // set OS flags for platforms that have multiple browsers + if (!result.windowsphone && !result.msedge && (android || result.silk)) { + result.android = t + } else if (!result.windowsphone && !result.msedge && iosdevice) { + result[iosdevice] = t + result.ios = t + } else if (mac) { + result.mac = t + } else if (xbox) { + result.xbox = t + } else if (windows) { + result.windows = t + } else if (linux) { + result.linux = t + } + + // OS version extraction + var osVersion = ''; + if (result.windowsphone) { + osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i); + } else if (iosdevice) { + osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i); + osVersion = osVersion.replace(/[_\s]/g, '.'); + } else if (android) { + osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i); + } else if (result.webos) { + osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i); + } else if (result.blackberry) { + osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i); + } else if (result.bada) { + osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i); + } else if (result.tizen) { + osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i); + } + if (osVersion) { + result.osversion = osVersion; + } + + // device type extraction + var osMajorVersion = osVersion.split('.')[0]; + if ( + tablet + || nexusTablet + || iosdevice == 'ipad' + || (android && (osMajorVersion == 3 || (osMajorVersion >= 4 && !mobile))) + || result.silk + ) { + result.tablet = t + } else if ( + mobile + || iosdevice == 'iphone' + || iosdevice == 'ipod' + || android + || nexusMobile + || result.blackberry + || result.webos + || result.bada + ) { + result.mobile = t + } + + // Graded Browser Support + // http://developer.yahoo.com/yui/articles/gbs + if (result.msedge || + (result.msie && result.version >= 10) || + (result.yandexbrowser && result.version >= 15) || + (result.vivaldi && result.version >= 1.0) || + (result.chrome && result.version >= 20) || + (result.samsungBrowser && result.version >= 4) || + (result.firefox && result.version >= 20.0) || + (result.safari && result.version >= 6) || + (result.opera && result.version >= 10.0) || + (result.ios && result.osversion && result.osversion.split(".")[0] >= 6) || + (result.blackberry && result.version >= 10.1) + || (result.chromium && result.version >= 20) + ) { + result.a = t; + } + else if ((result.msie && result.version < 10) || + (result.chrome && result.version < 20) || + (result.firefox && result.version < 20.0) || + (result.safari && result.version < 6) || + (result.opera && result.version < 10.0) || + (result.ios && result.osversion && result.osversion.split(".")[0] < 6) + || (result.chromium && result.version < 20) + ) { + result.c = t + } else result.x = t + + return result + } + + var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent || '' : '') + + bowser.test = function (browserList) { + for (var i = 0; i < browserList.length; ++i) { + var browserItem = browserList[i]; + if (typeof browserItem=== 'string') { + if (browserItem in bowser) { + return true; + } + } + } + return false; + } + + /** + * Get version precisions count + * + * @example + * getVersionPrecision("1.10.3") // 3 + * + * @param {string} version + * @return {number} + */ + function getVersionPrecision(version) { + return version.split(".").length; + } + + /** + * Array::map polyfill + * + * @param {Array} arr + * @param {Function} iterator + * @return {Array} + */ + function map(arr, iterator) { + var result = [], i; + if (Array.prototype.map) { + return Array.prototype.map.call(arr, iterator); + } + for (i = 0; i < arr.length; i++) { + result.push(iterator(arr[i])); + } + return result; + } + + /** + * Calculate browser version weight + * + * @example + * compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1 + * compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1 + * compareVersions(['1.10.2.1', '1.10.2.1']); // 0 + * compareVersions(['1.10.2.1', '1.0800.2']); // -1 + * + * @param {Array} versions versions to compare + * @return {Number} comparison result + */ + function compareVersions(versions) { + // 1) get common precision for both versions, for example for "10.0" and "9" it should be 2 + var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1])); + var chunks = map(versions, function (version) { + var delta = precision - getVersionPrecision(version); + + // 2) "9" -> "9.0" (for precision = 2) + version = version + new Array(delta + 1).join(".0"); + + // 3) "9.0" -> ["000000000"", "000000009"] + return map(version.split("."), function (chunk) { + return new Array(20 - chunk.length).join("0") + chunk; + }).reverse(); + }); + + // iterate in reverse order by reversed chunks array + while (--precision >= 0) { + // 4) compare: "000000009" > "000000010" = false (but "9" > "10" = true) + if (chunks[0][precision] > chunks[1][precision]) { + return 1; + } + else if (chunks[0][precision] === chunks[1][precision]) { + if (precision === 0) { + // all version chunks are same + return 0; + } + } + else { + return -1; + } + } + } + + /** + * Check if browser is unsupported + * + * @example + * bowser.isUnsupportedBrowser({ + * msie: "10", + * firefox: "23", + * chrome: "29", + * safari: "5.1", + * opera: "16", + * phantom: "534" + * }); + * + * @param {Object} minVersions map of minimal version to browser + * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map + * @param {String} [ua] user agent string + * @return {Boolean} + */ + function isUnsupportedBrowser(minVersions, strictMode, ua) { + var _bowser = bowser; + + // make strictMode param optional with ua param usage + if (typeof strictMode === 'string') { + ua = strictMode; + strictMode = void(0); + } + + if (strictMode === void(0)) { + strictMode = false; + } + if (ua) { + _bowser = detect(ua); + } + + var version = "" + _bowser.version; + for (var browser in minVersions) { + if (minVersions.hasOwnProperty(browser)) { + if (_bowser[browser]) { + if (typeof minVersions[browser] !== 'string') { + throw new Error('Browser version in the minVersion map should be a string: ' + browser + ': ' + String(minVersions)); + } + + // browser version and min supported version. + return compareVersions([version, minVersions[browser]]) < 0; + } + } + } + + return strictMode; // not found + } + + /** + * Check if browser is supported + * + * @param {Object} minVersions map of minimal version to browser + * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map + * @param {String} [ua] user agent string + * @return {Boolean} + */ + function check(minVersions, strictMode, ua) { + return !isUnsupportedBrowser(minVersions, strictMode, ua); + } + + bowser.isUnsupportedBrowser = isUnsupportedBrowser; + bowser.compareVersions = compareVersions; + bowser.check = check; + + /* + * Set our detect method to the main bowser object so we can + * reuse it to test other user agents. + * This is needed to implement future tests. + */ + bowser._detect = detect; + + return bowser + }); + + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + + module.exports = function() { throw new Error("define cannot be used indirect"); }; + + +/***/ }, +/* 6 */ +/***/ function(module, exports) { + + module.exports = { + '1.2.840.113549.1.9.2': 'Неструктурированное имя', + '1.2.643.3.141.1.1': 'РНС ФСС', + '1.2.643.3.141.1.2': 'КП ФСС', + '1.2.643.3.131.1.1': 'ИНН', + '1.3.6.1.5.5.7.3.2': 'Проверка подлинности клиента', + '1.3.6.1.5.5.7.3.4': 'Защищенная электронная почта', + '1.2.643.3.8.100.1': 'Сертификат типа "ekey-ГОСТ"', + '1.2.643.3.8.100.1.1': 'Общее использование в системах ИОК без права заверения финансовых документов', + '1.2.643.3.8.100.1.2': 'Передача отчетности по ТКС', + '1.2.643.3.8.100.1.3': 'Оформление взаимных обязательств, соглашений, договоров, актов и т.п.', + '1.2.643.3.8.100.1.4': 'Внутрикорпоративный документооборот', + '1.2.643.3.8.100.1.5': 'Использование в системах электронной торговли', + '1.2.643.3.8.100.1.6': 'Использование в торгово-закупочной системе "ЭЛЕКТРА"', + '1.2.643.6.2.1.7.2': 'Использование физическим лицом в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских прав и обязанностей в отношении инвестиционных паев паевых инвестиционных фондов, в том числе отношения, связанные с учетом и/или фиксацией прав на инвестиционные паи паевых инвестиционных фондов', + '1.2.643.6.2.1.7.1': 'Использование единоличным исполнительным органом юридического лица или уполномоченными представителями юридического лица в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских и иных прав и обязанностей в сфере негосударственного пенсионного обеспечения, негосударственного пенсионного страхования, в сфере деятельности паевых инвестиционных фондов, акционерных инвестиционных фондов, профессиональных участников рынка ценных бумаг, а также связанной с обслуживанием указанной деятельности услуг кредитных и иных организаций', + '1.3.6.1.4.1.29919.21': 'Использование в системе Портал государственных закупок Ростовской области "Рефери".', + '1.2.643.3.2.100.65.13.11': 'Использование в системе АИС "Госзакупки" Сахалинской области.', + '1.2.643.3.8.100.1.7': 'Использование в системе Портал государственных закупок Ставропольского края.', + '1.2.643.3.8.100.1.8': 'Использование в Единой системе электронной торговли B2B-Center и B2G.', + '1.2.643.3.8.100.1.9': 'Для участия в электронных торгах и подписания государственного контракта в электронной площадке ОАО «ЕЭТП» уполномоченными лицами участников размещения государственного или муниципального заказа', + '1.2.643.3.8.100.1.10': 'Для участия в электронных торгах и подписания государственного контракта в информационных системах Тендерного комитета города Москвы уполномоченными лицами участников размещения государственного заказа города Москвы', + '1.2.643.3.8.100.1.11': 'Подписание электронных документов в автоматизированной информационной системе размещения государственного и муниципального заказа Саратовской области', + '1.2.643.3.8.100.1.12': 'Использование в системе государственного заказа Иркутской области', + '1.2.643.3.8.100.1.13': 'Использование в электронной торговой площадке агентства государственного заказа Красноярского края', + '1.3.6.1.4.1.24138.1.1.8.1': 'Обеспечение юридической значимости в Системе "Электронная Торговая Площадка"', + '1.2.643.3.8.100.1.14': 'Использование в электронной торговой площадке "Тендер"', + '1.2.643.6.3': 'Использование в электронных торговых системах и в программном обеспечении, связанным с обменом электронных сообщений', + '1.2.643.2.2.34.6': 'Пользователь Центра Регистрации', + '1.2.643.2.39.1.1': 'Использование в программных продуктах системы "1С:Предприятие 8"', + '1.2.643.5.1.24.2.1.3': 'Формирование документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя', + '1.2.643.5.1.24.2.1.3.1': 'Формирование кадастровым инженером документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя', + '1.2.643.5.1.24.2.2.2': 'Формирование документов как результата оказания услуги со стороны органов регистрации прав', + '1.2.643.5.1.24.2.2.3': 'Формирование документов для получения государственных услуг в сфере государственной регистрации прав на недвижимое имущество и сделок с ним со стороны заявителя', + '1.2.643.6.3.1.1': 'Использование на электронных площадок отобранных для проведения аукционах в электронной форме', + '1.2.643.6.3.1.2.1': 'Тип участника - Юридическое лицо', + '1.2.643.6.3.1.2.2': 'Тип участника - Физическое лицо', + '1.2.643.6.3.1.2.3': 'Тип участника - Индивидуальный предприниматель', + '1.2.643.6.3.1.3.1': 'Участник размещения заказа', + '1.2.643.6.3.1.4.1': 'Администратор организации', + '1.2.643.6.3.1.4.2': 'Уполномоченный специалист', + '1.2.643.6.3.1.4.3': 'Специалист с правом подписи контракта', + '1.3.643.3.8.100.15': 'Использование в ЭТП "uTender"' + }; + +/***/ }, +/* 7 */ +/***/ function(module, exports) { + + module.exports = { + // CAPICOM_STORE_LOCATION enumeration + StoreLocation: { + CAPICOM_MEMORY_STORE: 0, + CAPICOM_LOCAL_MACHINE_STORE: 1, + CAPICOM_CURRENT_USER_STORE: 2, + CAPICOM_ACTIVE_DIRECTORY_USER_STORE: 3, + CAPICOM_SMART_CARD_USER_STORE: 4 + }, + // CAPICOM_STORE_OPEN_MODE enumeration + StoreOpenMode: { + CAPICOM_STORE_OPEN_READ_ONLY: 0, + CAPICOM_STORE_OPEN_READ_WRITE: 1, + CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED: 2, + CAPICOM_STORE_OPEN_EXISTING_ONLY: 128, + CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED: 256 + }, + // CAPICOM_CERTIFICATE_FIND_TYPE enumeration + CertFindType: { + CAPICOM_CERTIFICATE_FIND_SHA1_HASH: 0, + CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME: 1, + CAPICOM_CERTIFICATE_FIND_ISSUER_NAME: 2, + CAPICOM_CERTIFICATE_FIND_ROOT_NAME: 3, + CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME: 4, + CAPICOM_CERTIFICATE_FIND_EXTENSION: 5, + CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY: 6, + CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY: 7, + CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY: 8, + CAPICOM_CERTIFICATE_FIND_TIME_VALID: 9, + CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID: 10, + CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED: 11, + CAPICOM_CERTIFICATE_FIND_KEY_USAGE: 12 + }, + Time: { + AUTHENTICATED_ATTRIBUTE_SIGNING_TIME: 0 + }, + Check: { + CHECK_NONE: 0, + CHECK_TRUSTED_ROOT: 1, + CHECK_TIME_VALIDITY: 2, + CHECK_SIGNATURE_VALIDITY: 4, + CHECK_ONLINE_REVOCATION_STATUS: 8, + CHECK_OFFLINE_REVOCATION_STATUS: 16, + TRUST_IS_NOT_TIME_VALID: 1, + TRUST_IS_NOT_TIME_NESTED: 2, + TRUST_IS_REVOKED: 4, + TRUST_IS_NOT_SIGNATURE_VALID: 8, + TRUST_IS_NOT_VALID_FOR_USAGE: 16, + TRUST_IS_UNTRUSTED_ROOT: 32, + TRUST_REVOCATION_STATUS_UNKNOWN: 64, + TRUST_IS_CYCLIC: 128, + TRUST_IS_PARTIAL_CHAIN: 65536, + TRUST_CTL_IS_NOT_TIME_VALID: 131072, + TRUST_CTL_IS_NOT_SIGNATURE_VALID: 262144, + TRUST_CTL_IS_NOT_VALID_FOR_USAGE: 524288, + }, + // CAPICOM_PROPID enumeration + PropId: { + CAPICOM_PROPID_UNKNOWN: 0, + CAPICOM_PROPID_KEY_PROV_HANDLE: 1, + CAPICOM_PROPID_KEY_PROV_INFO: 2, + CAPICOM_PROPID_SHA1_HASH: 3, + CAPICOM_PROPID_HASH_PROP: 3, + CAPICOM_PROPID_MD5_HASH: 4, + CAPICOM_PROPID_KEY_CONTEXT: 5, + CAPICOM_PROPID_KEY_SPEC: 6, + CAPICOM_PROPID_IE30_RESERVED: 7, + CAPICOM_PROPID_PUBKEY_HASH_RESERVED: 8, + CAPICOM_PROPID_ENHKEY_USAGE: 9, + CAPICOM_PROPID_CTL_USAGE: 9, + CAPICOM_PROPID_NEXT_UPDATE_LOCATION: 10, + CAPICOM_PROPID_FRIENDLY_NAME: 11, + CAPICOM_PROPID_PVK_FILE: 12, + CAPICOM_PROPID_DESCRIPTION: 13, + CAPICOM_PROPID_ACCESS_STATE: 14, + CAPICOM_PROPID_SIGNATURE_HASH: 15, + CAPICOM_PROPID_SMART_CARD_DATA: 16, + CAPICOM_PROPID_EFS: 17, + CAPICOM_PROPID_FORTEZZA_DATA: 18, + CAPICOM_PROPID_ARCHIVED: 19, + CAPICOM_PROPID_KEY_IDENTIFIER: 20, + CAPICOM_PROPID_AUTO_ENROLL: 21, + CAPICOM_PROPID_PUBKEY_ALG_PARA: 22, + CAPICOM_PROPID_CROSS_CERT_DIST_POINTS: 23, + CAPICOM_PROPID_ISSUER_PUBLIC_KEY_MD5_HASH: 24, + CAPICOM_PROPID_SUBJECT_PUBLIC_KEY_MD5_HASH: 25, + CAPICOM_PROPID_ENROLLMENT: 26, + CAPICOM_PROPID_DATE_STAMP: 27, + CAPICOM_PROPID_ISSUER_SERIAL_NUMBER_MD5_HASH: 28, + CAPICOM_PROPID_SUBJECT_NAME_MD5_HASH: 29, + CAPICOM_PROPID_EXTENDED_ERROR_INFO: 30, + CAPICOM_PROPID_RENEWAL: 64, + CAPICOM_PROPID_ARCHIVED_KEY_HASH: 65, + CAPICOM_PROPID_FIRST_RESERVED: 66, + CAPICOM_PROPID_LAST_RESERVED: 0x00007FFF, + CAPICOM_PROPID_FIRST_USER: 0x00008000, + CAPICOM_PROPID_LAST_USER: 0x0000FFFF + }, + // CADESCOM_XML_SIGNATURE_TYPE enumeration + SignatureType: { + CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED: 0, + CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING: 1, + CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE: 2 + }, + // CADESCOM_HASH_ALGORITHM enumeration + HashAlgorithm: { + CADESCOM_HASH_ALGORITHM_CP_GOST_3411: 100, + CADESCOM_HASH_ALGORITHM_MD2: 1, + CADESCOM_HASH_ALGORITHM_MD4: 2, + CADESCOM_HASH_ALGORITHM_MD5: 3, + CADESCOM_HASH_ALGORITHM_SHA_256: 4, + CADESCOM_HASH_ALGORITHM_SHA_384: 5, + CADESCOM_HASH_ALGORITHM_SHA_512: 6, + CADESCOM_HASH_ALGORITHM_SHA1: 0 + }, + CadesType: { + CADESCOM_CADES_DEFAULT: 0, + CADESCOM_CADES_BES: 1, + CADESCOM_CADES_X_LONG_TYPE_1: 0x5d + }, + ContentEncoding: { + CADESCOM_BASE64_TO_BINARY: 0x01, + CADESCOM_STRING_TO_UCS2LE: 0x00 + }, + StoreNames: { + CAPICOM_MY_STORE: 'My' + }, + Chain: { + CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT: 0, + CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN: 1, + CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY: 2 + }, + GostXmlDSigUrls: { + XmlDsigGost3410Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411', + XmlDsigGost3411Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411', + XmlDsigGost3410UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411', + XmlDsigGost3411UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr3411' + } + }; + +/***/ } +]); +//# sourceMappingURL=1.crypto-pro.js.map \ No newline at end of file diff --git a/dist/1.crypto-pro.js.map b/dist/1.crypto-pro.js.map new file mode 100644 index 0000000..9d13f40 --- /dev/null +++ b/dist/1.crypto-pro.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///./apiAsync.js","webpack:///./common.js","webpack:///../~/bowser/bowser.js","webpack:///../~/webpack/buildin/amd-define.js","webpack:///./oids.js","webpack:///./constants.js"],"names":[],"mappings":";;;;;;AAAA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;;AAEA;AACA,kBAAiB;AACjB,cAAa;AACb,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;;AAEA;AACA,kBAAiB;AACjB,cAAa;AACb,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;;AAEA;AACA,kBAAiB;AACjB,cAAa;AACb,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,oCAAmC;AACnC;;AAEA;AACA;AACA;;AAEA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;;AAEA;AACA,kBAAiB;AACjB,cAAa;AACb,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,sBAAqB,MAAM;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,sBAAqB;AACrB;AACA;AACA;;AAEA;AACA,kBAAiB;AACjB,cAAa;AACb,UAAS;;AAET;;AAEA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;;AAEA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,kBAAiB;AACjB;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,cAAa,QAAQ,6BAA6B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;;AAErB;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa,QAAQ,wDAAwD;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA,cAAa;AACb,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa,QAAQ,wDAAwD;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA,cAAa;AACb,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;AChiBA;AACA;;AAEA;AACA,UAAS,4EAA4E;AACrF,UAAS,+CAA+C;AACxD,UAAS,8CAA8C;AACvD,UAAS,kDAAkD;AAC3D,UAAS,4CAA4C;AACrD,UAAS,4CAA4C;AACrD,UAAS,gDAAgD;AACzD,UAAS,8CAA8C;AACvD,UAAS,0DAA0D;AACnE,UAAS,+CAA+C;AACxD,UAAS,qDAAqD;AAC9D,UAAS,2DAA2D;AACpE,UAAS,wDAAwD;AACjE,UAAS,kDAAkD;AAC3D,UAAS,2CAA2C;AACpD,UAAS;AACT;;AAEA;AACA,UAAS,4EAA4E;AACrF,UAAS,2DAA2D;AACpE,UAAS,4CAA4C;AACrD,UAAS,4CAA4C;AACrD,UAAS,gDAAgD;AACzD,UAAS,8CAA8C;AACvD,UAAS,0CAA0C;AACnD,UAAS,+CAA+C;AACxD,UAAS,qDAAqD;AAC9D,UAAS,2DAA2D;AACpE,UAAS,wDAAwD;AACjE,UAAS,kDAAkD;AAC3D,UAAS,2CAA2C;AACpD,UAAS;AACT;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sCAAqC,EAAE;;AAEvC;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,kBAAiB;AACjB,cAAa;;AAEb;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kBAAiB;AACjB;AACA;;AAEA;AACA,cAAa;AACb,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA,YAAW,aAAa;AACxB,cAAa,QAAQ,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,sBAAqB;AACrB,kBAAiB;AACjB,cAAa;AACb;AACA;AACA,kBAAiB;AACjB;;AAEA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;;AAEA;AACA,MAAK,IAAI;;AAET;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACrRA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA,oBAAmB,wBAAwB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc,OAAO;AACrB,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAc,MAAM;AACpB,eAAc,SAAS;AACvB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,gBAAgB;AAC/B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,sDAAqD;AACrD,mDAAkD;AAClD,mDAAkD;AAClD;AACA,eAAc,cAAc;AAC5B,eAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA,eAAc,OAAO;AACrB,eAAc,QAAQ;AACtB,eAAc,OAAO;AACrB,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,uBAAsB;AACtB;;AAEA;AACA;AACA;AACA,eAAc,OAAO;AACrB,eAAc,QAAQ;AACtB,eAAc,OAAO;AACrB,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,EAAC;;;;;;;ACnkBD,8BAA6B,mDAAmD;;;;;;;ACAhF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,G","file":"1.crypto-pro.js","sourcesContent":["var cryptoCommon = require('./common'),\n cryptoConstants = require('./constants'),\n\n _certProto = {\n /**\n * Проверяет, валиден ли сертификат\n * */\n isValid: function isValid() {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n cadesplugin.async_spawn(function* () {\n var result;\n\n try {\n result = yield cert.IsValid();\n result = yield result.Result;\n } catch (err) {\n reject('Ошибка при проверке сертификата: ', err.message);\n return;\n }\n\n resolve(result);\n });\n });\n },\n\n /**\n * Достает указанное свойство у сертификата\n * */\n getProp: function (propName) {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n cadesplugin.async_spawn(function* () {\n var result;\n\n try {\n result = yield cert[propName];\n } catch (err) {\n reject('Ошибка при обращении к свойству сертификата: ', err.message);\n return;\n }\n\n resolve(result);\n });\n });\n },\n\n /**\n * Экспорт base64 представления сертификата пользователя\n * */\n exportBase64: function exportBase64() {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n cadesplugin.async_spawn(function* () {\n var base64;\n\n try {\n base64 = yield cert.Export(0);\n } catch (err) {\n reject('Ошибка при экспорте сертификата: ', err.message);\n return;\n }\n\n resolve(base64);\n });\n });\n },\n\n /**\n * Возвращает информацию об алгоритме\n * */\n getAlgorithm: function getAlgorithm() {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n cadesplugin.async_spawn(function* () {\n var result = {},\n algorithm;\n\n try {\n algorithm = yield cert.PublicKey();\n algorithm = yield algorithm.Algorithm;\n\n result.algorithm = yield algorithm.FriendlyName;\n result.oid = yield algorithm.Value;\n } catch (err) {\n reject('Ошибка при получении алгоритма: ', err.message);\n return;\n }\n\n resolve(result);\n });\n });\n },\n\n /**\n * Разбирает SubjectName сертификата по тэгам\n * */\n getOwnerInfo: function getOwnerInfo() {\n return getCertInfo.call(this, cryptoCommon.subjectNameTagsTranslations, 'SubjectName');\n },\n\n /**\n * Разбирает IssuerName сертификата по тэгам\n * */\n getIssuerInfo: function getIssuerInfo() {\n return getCertInfo.call(this, cryptoCommon.issuerNameTagsTranslations, 'IssuerName');\n },\n\n /**\n * Получение OID сертификата\n *\n * @returns {Array} Возвращает массив OID (улучшенного ключа)\n * */\n getExtendedKeyUsage: function getExtendedKeyUsage() {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n cadesplugin.async_spawn(function* () {\n var OIDS = [],\n count,\n item;\n\n try {\n count = yield cert.ExtendedKeyUsage();\n count = yield count.EKUs;\n count = yield count.Count;\n\n if (count > 0) {\n while (count > 0) {\n item = yield cert.ExtendedKeyUsage();\n item = yield item.EKUs;\n item = yield item.Item(count);\n item = yield item.OID;\n\n OIDS.push(item);\n\n count--;\n }\n }\n } catch (err) {\n reject('Ошибка при получении ОИД\\'ов: ', err.message);\n return;\n }\n\n resolve(OIDS);\n });\n });\n },\n\n getDecodedExtendedKeyUsage: cryptoCommon.getDecodedExtendedKeyUsage,\n\n hasExtendedKeyUsage: cryptoCommon.hasExtendedKeyUsage\n },\n\n _certListCache;\n\n/**\n * Проверяет корректность настроек ЭП на машине\n * */\nfunction isValidEDSSettings() {\n return new Promise(function (resolve, reject) {\n cadesplugin.async_spawn(function* () {\n var result;\n\n try {\n result = yield cadesplugin.CreateObjectAsync('CAdESCOM.About');\n } catch (error) {\n reject('Настройки ЭП на данной машине не верны');\n }\n\n resolve();\n });\n });\n}\n\n/**\n * Получить сертификат в формате cades по хэшу\n * */\nfunction getCadesCert(hash) {\n return new Promise(function (resolve, reject) {\n cadesplugin.async_spawn(function* () {\n var oStore = yield cadesplugin.CreateObjectAsync('CAdESCOM.Store'),\n certs,\n certCnt,\n cert;\n\n if (!oStore) {\n reject('Не удалось получить доступ к хранилищу сертификатов');\n return;\n }\n\n // Открываем хранилище\n try {\n yield oStore.Open(\n cadesplugin.CAPICOM_CURRENT_USER_STORE,\n cadesplugin.CAPICOM_MY_STORE,\n cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED\n );\n } catch (err) {\n reject('Ошибка при открытии хранилища: ' + err.message);\n return;\n }\n\n // Получаем доступ к сертификатам\n try {\n certs = yield oStore.Certificates;\n certCnt = yield certs.Count;\n } catch (err) {\n reject('Ошибка получения списка сертификатов: ' + err.message);\n return;\n }\n\n if (!certCnt) {\n reject('Нет доступных сертификатов');\n return;\n }\n\n // Получаем сертификат по хэшу\n try {\n certs = yield certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH, hash);\n\n if (certs.Count) {\n cert = yield certs.Item(1);\n } else {\n throw new Error('Нет доступных сертификатов');\n }\n } catch (err) {\n reject('Не удалось получить сертификат по хэшу: ' + err.message);\n return;\n }\n\n oStore.Close();\n\n resolve(cert);\n });\n });\n}\n\n/**\n * Разбирает информацию сертификата по тэгам\n * */\nfunction getCertInfo(tags, propName) {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n cadesplugin.async_spawn(function* () {\n var propInfo;\n\n try {\n propInfo = yield cert[propName];\n } catch (err) {\n reject('Ошибка при извлечении данных из сертификата: ', err.message);\n return;\n }\n\n resolve(cryptoCommon.parseCertInfo(tags, propInfo));\n });\n });\n}\n\n/**\n * Возвращает список сертификатов, доступных в системе\n *\n * @param {Boolean} [resetCache=false] -- нужно ли сбросить кэш списка сертификатов\n * @returns {Promise} -- со списком сертификатов {Array}\n * */\nfunction getCertsList(resetCache) {\n return new Promise(function (resolve, reject) {\n if (!resetCache && _certListCache) {\n resolve(_certListCache);\n return;\n }\n\n cadesplugin.async_spawn(function* () {\n var oStore = yield cadesplugin.CreateObjectAsync('CAdESCOM.Store'),\n result = [],\n certs,\n count,\n item;\n\n // Открываем хранилище\n try {\n yield oStore.Open(\n cadesplugin.CAPICOM_CURRENT_USER_STORE,\n cadesplugin.CAPICOM_MY_STORE,\n cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED\n );\n } catch (err) {\n reject('Ошибка при открытии хранилища: ' + err.message);\n return;\n }\n\n // Получаем доступ к сертификатам\n try {\n certs = yield oStore.Certificates;\n\n if (certs) {\n certs = yield certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID);\n /**\n * Не рассматриваются сертификаты, в которых отсутствует закрытый ключ\n * или не действительны на данный момент\n * */\n certs = yield certs.Find(\n cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY,\n cryptoConstants.PropId.CAPICOM_PROPID_KEY_PROV_INFO\n );\n\n count = yield certs.Count;\n }\n } catch (err) {\n reject('Ошибка получения списка сертификатов: ' + err.message);\n return;\n }\n\n if (!count) {\n reject('Нет доступных сертификатов');\n return;\n }\n\n try {\n while (count) {\n item = yield certs.Item(count);\n\n result.push(Object.assign(Object.create(_certProto), {\n _cert: yield item,\n thumbprint: yield item.Thumbprint,\n subjectName: yield item.SubjectName,\n issuerName: yield item.IssuerName,\n validFrom: yield item.ValidFromDate,\n validTo: yield item.ValidToDate\n }));\n\n count--;\n }\n } catch (err) {\n reject('Ошибка обработки сертификатов: ' + err.message);\n return;\n }\n\n oStore.Close();\n\n _certListCache = cryptoCommon.prepareCertsInfo(result);\n\n resolve(_certListCache);\n });\n });\n}\n\n/**\n * Получить сертификат по хэшу\n * */\nfunction getCert(hash) {\n return new Promise(function (resolve, reject) {\n if (!hash) {\n reject('Хэш не указан');\n return;\n }\n\n getCertsList().then(function (list) {\n var foundCert;\n\n list.some(function (cert) {\n if (hash === cert.thumbprint) {\n foundCert = cert;\n return true;\n }\n });\n\n if (foundCert) {\n resolve(foundCert);\n } else {\n reject('Сертификат с хэшем: \"' + hash + '\" не найден');\n }\n }, reject);\n });\n}\n\n/**\n * Создает подпись base64 строки по hash'у сертификата\n *\n * @param {String} hash -- fingerprint (thumbprint) сертификата\n * @param {String} dataBase64 -- строковые данные в формате base64\n * @param {String} signType -- тип подписи открепленная (true) / присоединенная (false) (default: false)\n * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String}\n * */\nfunction signData(hash, dataBase64, signType) {\n return new Promise(function (resolve, reject) {\n getCadesCert(hash).then(function (cert) {\n cadesplugin.async_spawn(function* () {\n var clientTime = new Date(),\n oAttrs = yield cadesplugin.CreateObjectAsync('CADESCOM.CPAttribute'),\n oSignedData = yield cadesplugin.CreateObjectAsync('CAdESCOM.CadesSignedData'),\n oSigner = yield cadesplugin.CreateObjectAsync('CAdESCOM.CPSigner'),\n attrs,\n signature;\n\n clientTime = cryptoCommon.getDateObj(clientTime);\n\n try {\n yield oAttrs.propset_Name(cryptoConstants.Time.AUTHENTICATED_ATTRIBUTE_SIGNING_TIME);\n yield oAttrs.propset_Value(clientTime);\n } catch (err) {\n reject('Ошибка при установке данных подписи: ' + err.message);\n return;\n }\n\n // Задаем настройки для подписи\n try {\n yield oSigner.propset_Certificate(cert);\n attrs = yield oSigner.AuthenticatedAttributes2;\n yield attrs.Add(oAttrs);\n yield oSignedData.propset_ContentEncoding(cadesplugin.CADESCOM_BASE64_TO_BINARY);\n yield oSignedData.propset_Content(dataBase64);\n yield oSigner.propset_Options(cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY);\n } catch (err) {\n reject('Не удалось установить настройки для подписи: ' + err.message);\n return;\n }\n\n try {\n signature = yield oSignedData.SignCades(\n oSigner,\n cadesplugin.CADESCOM_CADES_BES,\n Boolean(signType)\n );\n } catch (err) {\n reject('Не удалось создать подпись: ' + err.message);\n return;\n }\n\n resolve(signature);\n });\n });\n });\n}\n\n/**\n * Создает подпись XML строки по hash'у сертификата\n *\n * @param {String} hash -- fingerprint (thumbprint) сертификата\n * @param {String} dataXML -- данные в формате XML\n * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String}\n * */\nfunction signDataXML(hash, dataXML) {\n return new Promise(function (resolve, reject) {\n getCadesCert(hash).then(function (cert) {\n cadesplugin.async_spawn(function* () {\n var oSigner = yield cadesplugin.CreateObjectAsync('CAdESCOM.CPSigner'),\n signerXML = yield cadesplugin.CreateObjectAsync('CAdESCOM.SignedXML'),\n cnts = cryptoConstants,\n signature;\n\n // Задаем настройки для подписи\n try {\n yield oSigner.propset_Certificate(cert);\n // Добавляем данные для подписи\n yield signerXML.propset_Content(dataXML);\n // Устанавливаем тип подписи\n yield signerXML.propset_SignatureType(cnts.SignatureType.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED);\n // Устанавливаем алгоритм подписи\n yield signerXML.propset_SignatureMethod(cnts.GostXmlDSigUrls.XmlDsigGost3410Url);\n // Устанавливаем алгоритм хэширования\n yield signerXML.propset_DigestMethod(cnts.GostXmlDSigUrls.XmlDsigGost3411Url);\n } catch (err) {\n reject('Не удалось установить настройки для подписи: ' + err.message);\n return;\n }\n\n try {\n signature = yield signerXML.Sign(oSigner);\n } catch (err) {\n reject('Не удалось создать подпись: ' + err.message);\n return;\n }\n\n resolve(signature);\n });\n });\n });\n}\n\n/**\n * Возвращает информацию о версии CSP и плагина\n * */\nfunction getSystemInfo() {\n var sysInfo = cryptoCommon.getEnvInfo();\n\n return new Promise(function (resolve, reject) {\n cadesplugin.async_spawn(function* () {\n var e;\n\n try {\n e = yield cadesplugin.CreateObjectAsync('CAdESCOM.About');\n\n sysInfo.cadesVersion = yield e.PluginVersion;\n // Возможен вызов в ранних версиях в виде sysInfo.cspVersion = yield e.CSPVersion('', 75);\n sysInfo.cspVersion = yield e.CSPVersion();\n\n if (!sysInfo.cadesVersion) {\n sysInfo.cadesVersion = yield e.Version;\n }\n\n sysInfo.cadesVersion = yield sysInfo.cadesVersion.toString();\n sysInfo.cspVersion = yield sysInfo.cspVersion.toString();\n\n resolve(sysInfo);\n } catch (err) {\n reject('Ошибка при получении информации о системе: ', err.message);\n }\n });\n });\n}\n\n/**\n * Promise обертка для синхронного вызова проверки версии CSP\n * */\nfunction isValidCSPVersion(version) {\n return new Promise(function (resolve) {\n resolve(cryptoCommon.isValidCSPVersion(version));\n });\n}\n\n/**\n * Promise обертка для синхронного вызова проверки версии плагина\n * */\nfunction isValidCadesVersion(version) {\n return new Promise(function (resolve) {\n resolve(cryptoCommon.isValidCadesVersion(version));\n });\n}\n\nmodule.exports = {\n isValidEDSSettings: isValidEDSSettings,\n getCertsList: getCertsList,\n getCert: getCert,\n signData: signData,\n signDataXML: signDataXML,\n getSystemInfo: getSystemInfo,\n isValidCSPVersion: isValidCSPVersion,\n isValidCadesVersion: isValidCadesVersion\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./apiAsync.js\n ** module id = 2\n ** module chunks = 1\n **/","var bowser = require('bowser/bowser');\nvar oids = require('./oids');\n\nvar subjectNameTagsTranslations = [\n {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'},\n {possibleNames: ['CN'], translation: 'Владелец'},\n {possibleNames: ['SN'], translation: 'Фамилия'},\n {possibleNames: ['G'], translation: 'Имя Отчество'},\n {possibleNames: ['C'], translation: 'Страна'},\n {possibleNames: ['S'], translation: 'Регион'},\n {possibleNames: ['STREET'], translation: 'Адрес'},\n {possibleNames: ['O'], translation: 'Компания'},\n {possibleNames: ['OU'], translation: 'Отдел/подразделение'},\n {possibleNames: ['T'], translation: 'Должность'},\n {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'},\n {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'},\n {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'},\n {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'},\n {possibleNames: ['E'], translation: 'Email'},\n {possibleNames: ['L'], translation: 'Город'}\n ],\n\n issuerNameTagsTranslations = [\n {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'},\n {possibleNames: ['CN'], translation: 'Удостоверяющий центр'},\n {possibleNames: ['S'], translation: 'Регион'},\n {possibleNames: ['C'], translation: 'Страна'},\n {possibleNames: ['STREET'], translation: 'Адрес'},\n {possibleNames: ['O'], translation: 'Компания'},\n {possibleNames: ['OU'], translation: 'Тип'},\n {possibleNames: ['T'], translation: 'Должность'},\n {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'},\n {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'},\n {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'},\n {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'},\n {possibleNames: ['E'], translation: 'Email'},\n {possibleNames: ['L'], translation: 'Город'}\n ];\n\n/**\n * Парсит информацию из строки с информацией о сертификате\n * */\nfunction parseCertInfo(tags, infoString) {\n /**\n * Пример входной строки:\n *\n\n T=Генеральный директор, UnstructuredName=\"INN=7811514257/KPP=781101001/OGRN=1127847087884\",\n STREET=\"Крыленко, д.3, лит.Б\", CN=Король Анатолий Евгеньевич, G=Анатолий Евгеньевич, SN=Король,\n OU=Администрация, O=\"ООО \"\"Аксиома\"\"\", L=Санкт-Петербург, S=78 г. Санкт-Петербург, C=RU, E=korol@sferasro.ru,\n INN=007811514257, OGRN=1127847087884, SNILS=11617693460\n\n * */\n var result = infoString.match(/([а-яА-Яa-zA-Z0-9\\.]+)=(?:(\"[^\"]+?\")|(.+?))(?:,|$)/g);\n\n if (result) {\n result = result.map(function (group) {\n /**\n * Пример входной строки:\n *\n\n UnstructuredName=\"INN=7811514257/KPP=781101001/OGRN=1127847087884\",\n\n * */\n var parts = group.match(/^([а-яА-Яa-zA-Z0-9\\.]+)=(.+?),?$/),\n title = parts && parts[1],\n descr = parts && parts[2],\n translated = false,\n oidTitle;\n\n // Если тайтл содержит ОИД, пытаемся расшифровать\n if (/^OID./.test(title)) {\n oidTitle = title.match(/^OID\\.(.*)/);\n\n if (oidTitle && oidTitle[1]) {\n oidTitle = oids[oidTitle[1]];\n\n if (oidTitle) {\n title = oidTitle;\n }\n }\n }\n\n // Вырезаем лишние кавычки\n descr = descr.replace(/^\"(.*)\"/, '$1');\n descr = descr.replace(/\"{2}/g, '\"');\n\n tags.some(function (tag) {\n return tag.possibleNames.some(function (possible) {\n var match = possible === title;\n\n if (match) {\n title = tag.translation;\n translated = true;\n }\n\n return match;\n });\n });\n\n return {\n title: title,\n descr: descr,\n translated: translated\n };\n });\n }\n\n return result;\n}\n\n/**\n * Возвращает дату в формате (dd.mm.yyyy hh:mm:ss) из строки, формата, используемого плагином cryptoPro\n * */\nfunction getReadableDate(date) {\n date = new Date(date);\n\n return ([\n date.getDate(),\n date.getMonth() + 1,\n date.getFullYear()\n ].join('.') + ' ' + [\n date.getHours(),\n date.getMinutes(),\n date.getSeconds()\n ].join(':')).replace(/\\b(\\d)\\b/g, '0$1');\n}\n\n/**\n * Преобразует дату для IE\n * */\nfunction getDateObj(dateObj) {\n return bowser.msie ? dateObj.getVarDate() : dateObj;\n}\n\n/**\n * Подготавливает информацию о сертификатах\n * */\nfunction prepareCertsInfo(items) {\n return items.map(function (c) {\n c.name = c.subjectName.match(/CN=(.+?),/);\n\n // Удалось ли вытащить Common Name\n if (c.name && c.name[1]) {\n c.name = c.name[1];\n }\n\n c.validFrom = getReadableDate(c.validFrom);\n c.validTo = getReadableDate(c.validTo);\n\n c.label = c.name + ' (до ' + c.validTo + ')';\n\n return c;\n });\n}\n\n/**\n * Возвращает расшифрованные ОИД'ы\n * */\nfunction getDecodedExtendedKeyUsage() {\n var that = this;\n\n return new Promise(function (resolve) {\n that.getExtendedKeyUsage().then(function (certOids) {\n resolve(certOids.reduce(function (oidsLst, oid) {\n oid = {\n id: oid,\n descr: oids[oid] || null\n };\n\n if (oid.descr) {\n oidsLst.unshift(oid);\n } else {\n oidsLst.push(oid);\n }\n\n return oidsLst;\n }, []));\n });\n });\n}\n\n/**\n * Проверка наличия ОИД'а(ОИД'ов) у сертификата\n *\n * @param {String|Array} oids - ОИД'ы для проверки\n * @returns {Promise} с отложенным результатом типа {Boolean}\n * */\nfunction hasExtendedKeyUsage(oids) {\n var that = this;\n\n return new Promise(function (resolve) {\n that.getExtendedKeyUsage().then(function (certOids) {\n var result;\n\n if (Array.isArray(oids)) {\n result = oids.every(function (oidToCheck) {\n return certOids.some(function (certOid) {\n return certOid === oidToCheck;\n });\n });\n } else {\n result = certOids.some(function (certOid) {\n return certOid === oids;\n });\n }\n\n resolve(result);\n });\n });\n}\n\n/**\n * Выводит информацию о системе пользователя\n * */\nfunction getEnvInfo() {\n var parsed = bowser._detect(navigator.userAgent),\n info = {\n browserName: parsed.name,\n browserVersion: parsed.version\n };\n\n if (parsed.mac) {\n info.os = 'Mac';\n } else if (parsed.windows) {\n info.os = 'Windows';\n } else if (parsed.linux) {\n info.os = 'Linux';\n }\n\n return info;\n}\n\n/**\n * Подходящая ли версия CSP\n * */\nfunction isValidCSPVersion(version) {\n version = version.match(/\\d+?\\b(?:\\.\\d+)?/);\n\n return version >= 3.6;\n}\n\n/**\n * Подходящая ли версия cades плагина\n * */\nfunction isValidCadesVersion(version) {\n version = version.split('.').reduce(function (verInfo, number, i) {\n if (i === 0) {\n verInfo.major = number;\n } else if (i === 1) {\n verInfo.minor = number;\n } else if (i === 2) {\n verInfo.patch = number;\n }\n\n return verInfo;\n }, {});\n\n if (version.major < 2) {\n return false;\n }\n\n return version.patch >= 12438;\n}\n\nmodule.exports = {\n subjectNameTagsTranslations: subjectNameTagsTranslations,\n issuerNameTagsTranslations: issuerNameTagsTranslations,\n parseCertInfo: parseCertInfo,\n getReadableDate: getReadableDate,\n getDateObj: getDateObj,\n prepareCertsInfo: prepareCertsInfo,\n getDecodedExtendedKeyUsage: getDecodedExtendedKeyUsage,\n hasExtendedKeyUsage: hasExtendedKeyUsage,\n getEnvInfo: getEnvInfo,\n isValidCSPVersion: isValidCSPVersion,\n isValidCadesVersion: isValidCadesVersion\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./common.js\n ** module id = 3\n ** module chunks = 1 2\n **/","/*!\n * Bowser - a browser detector\n * https://github.com/ded/bowser\n * MIT License | (c) Dustin Diaz 2015\n */\n\n!function (root, name, definition) {\n if (typeof module != 'undefined' && module.exports) module.exports = definition()\n else if (typeof define == 'function' && define.amd) define(name, definition)\n else root[name] = definition()\n}(this, 'bowser', function () {\n /**\n * See useragents.js for examples of navigator.userAgent\n */\n\n var t = true\n\n function detect(ua) {\n\n function getFirstMatch(regex) {\n var match = ua.match(regex);\n return (match && match.length > 1 && match[1]) || '';\n }\n\n function getSecondMatch(regex) {\n var match = ua.match(regex);\n return (match && match.length > 1 && match[2]) || '';\n }\n\n var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()\n , likeAndroid = /like android/i.test(ua)\n , android = !likeAndroid && /android/i.test(ua)\n , nexusMobile = /nexus\\s*[0-6]\\s*/i.test(ua)\n , nexusTablet = !nexusMobile && /nexus\\s*[0-9]+/i.test(ua)\n , chromeos = /CrOS/.test(ua)\n , silk = /silk/i.test(ua)\n , sailfish = /sailfish/i.test(ua)\n , tizen = /tizen/i.test(ua)\n , webos = /(web|hpw)os/i.test(ua)\n , windowsphone = /windows phone/i.test(ua)\n , samsungBrowser = /SamsungBrowser/i.test(ua)\n , windows = !windowsphone && /windows/i.test(ua)\n , mac = !iosdevice && !silk && /macintosh/i.test(ua)\n , linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua)\n , edgeVersion = getFirstMatch(/edge\\/(\\d+(\\.\\d+)?)/i)\n , versionIdentifier = getFirstMatch(/version\\/(\\d+(\\.\\d+)?)/i)\n , tablet = /tablet/i.test(ua)\n , mobile = !tablet && /[^-]mobi/i.test(ua)\n , xbox = /xbox/i.test(ua)\n , result\n\n if (/opera/i.test(ua)) {\n // an old Opera\n result = {\n name: 'Opera'\n , opera: t\n , version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n } else if (/opr|opios/i.test(ua)) {\n // a new Opera\n result = {\n name: 'Opera'\n , opera: t\n , version: getFirstMatch(/(?:opr|opios)[\\s\\/](\\d+(\\.\\d+)?)/i) || versionIdentifier\n }\n }\n else if (/SamsungBrowser/i.test(ua)) {\n result = {\n name: 'Samsung Internet for Android'\n , samsungBrowser: t\n , version: versionIdentifier || getFirstMatch(/(?:SamsungBrowser)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/coast/i.test(ua)) {\n result = {\n name: 'Opera Coast'\n , coast: t\n , version: versionIdentifier || getFirstMatch(/(?:coast)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/yabrowser/i.test(ua)) {\n result = {\n name: 'Yandex Browser'\n , yandexbrowser: t\n , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/ucbrowser/i.test(ua)) {\n result = {\n name: 'UC Browser'\n , ucbrowser: t\n , version: getFirstMatch(/(?:ucbrowser)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/mxios/i.test(ua)) {\n result = {\n name: 'Maxthon'\n , maxthon: t\n , version: getFirstMatch(/(?:mxios)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/epiphany/i.test(ua)) {\n result = {\n name: 'Epiphany'\n , epiphany: t\n , version: getFirstMatch(/(?:epiphany)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/puffin/i.test(ua)) {\n result = {\n name: 'Puffin'\n , puffin: t\n , version: getFirstMatch(/(?:puffin)[\\s\\/](\\d+(?:\\.\\d+)?)/i)\n }\n }\n else if (/sleipnir/i.test(ua)) {\n result = {\n name: 'Sleipnir'\n , sleipnir: t\n , version: getFirstMatch(/(?:sleipnir)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/k-meleon/i.test(ua)) {\n result = {\n name: 'K-Meleon'\n , kMeleon: t\n , version: getFirstMatch(/(?:k-meleon)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (windowsphone) {\n result = {\n name: 'Windows Phone'\n , windowsphone: t\n }\n if (edgeVersion) {\n result.msedge = t\n result.version = edgeVersion\n }\n else {\n result.msie = t\n result.version = getFirstMatch(/iemobile\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/msie|trident/i.test(ua)) {\n result = {\n name: 'Internet Explorer'\n , msie: t\n , version: getFirstMatch(/(?:msie |rv:)(\\d+(\\.\\d+)?)/i)\n }\n } else if (chromeos) {\n result = {\n name: 'Chrome'\n , chromeos: t\n , chromeBook: t\n , chrome: t\n , version: getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.\\d+)?)/i)\n }\n } else if (/chrome.+? edge/i.test(ua)) {\n result = {\n name: 'Microsoft Edge'\n , msedge: t\n , version: edgeVersion\n }\n }\n else if (/vivaldi/i.test(ua)) {\n result = {\n name: 'Vivaldi'\n , vivaldi: t\n , version: getFirstMatch(/vivaldi\\/(\\d+(\\.\\d+)?)/i) || versionIdentifier\n }\n }\n else if (sailfish) {\n result = {\n name: 'Sailfish'\n , sailfish: t\n , version: getFirstMatch(/sailfish\\s?browser\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/seamonkey\\//i.test(ua)) {\n result = {\n name: 'SeaMonkey'\n , seamonkey: t\n , version: getFirstMatch(/seamonkey\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/firefox|iceweasel|fxios/i.test(ua)) {\n result = {\n name: 'Firefox'\n , firefox: t\n , version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \\/](\\d+(\\.\\d+)?)/i)\n }\n if (/\\((mobile|tablet);[^\\)]*rv:[\\d\\.]+\\)/i.test(ua)) {\n result.firefoxos = t\n }\n }\n else if (silk) {\n result = {\n name: 'Amazon Silk'\n , silk: t\n , version : getFirstMatch(/silk\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/phantom/i.test(ua)) {\n result = {\n name: 'PhantomJS'\n , phantom: t\n , version: getFirstMatch(/phantomjs\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/slimerjs/i.test(ua)) {\n result = {\n name: 'SlimerJS'\n , slimer: t\n , version: getFirstMatch(/slimerjs\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/blackberry|\\bbb\\d+/i.test(ua) || /rim\\stablet/i.test(ua)) {\n result = {\n name: 'BlackBerry'\n , blackberry: t\n , version: versionIdentifier || getFirstMatch(/blackberry[\\d]+\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (webos) {\n result = {\n name: 'WebOS'\n , webos: t\n , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\\/(\\d+(\\.\\d+)?)/i)\n };\n /touchpad\\//i.test(ua) && (result.touchpad = t)\n }\n else if (/bada/i.test(ua)) {\n result = {\n name: 'Bada'\n , bada: t\n , version: getFirstMatch(/dolfin\\/(\\d+(\\.\\d+)?)/i)\n };\n }\n else if (tizen) {\n result = {\n name: 'Tizen'\n , tizen: t\n , version: getFirstMatch(/(?:tizen\\s?)?browser\\/(\\d+(\\.\\d+)?)/i) || versionIdentifier\n };\n }\n else if (/qupzilla/i.test(ua)) {\n result = {\n name: 'QupZilla'\n , qupzilla: t\n , version: getFirstMatch(/(?:qupzilla)[\\s\\/](\\d+(?:\\.\\d+)+)/i) || versionIdentifier\n }\n }\n else if (/chromium/i.test(ua)) {\n result = {\n name: 'Chromium'\n , chromium: t\n , version: getFirstMatch(/(?:chromium)[\\s\\/](\\d+(?:\\.\\d+)?)/i) || versionIdentifier\n }\n }\n else if (/chrome|crios|crmo/i.test(ua)) {\n result = {\n name: 'Chrome'\n , chrome: t\n , version: getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (android) {\n result = {\n name: 'Android'\n , version: versionIdentifier\n }\n }\n else if (/safari|applewebkit/i.test(ua)) {\n result = {\n name: 'Safari'\n , safari: t\n }\n if (versionIdentifier) {\n result.version = versionIdentifier\n }\n }\n else if (iosdevice) {\n result = {\n name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod'\n }\n // WTF: version is not part of user agent in web apps\n if (versionIdentifier) {\n result.version = versionIdentifier\n }\n }\n else if(/googlebot/i.test(ua)) {\n result = {\n name: 'Googlebot'\n , googlebot: t\n , version: getFirstMatch(/googlebot\\/(\\d+(\\.\\d+))/i) || versionIdentifier\n }\n }\n else {\n result = {\n name: getFirstMatch(/^(.*)\\/(.*) /),\n version: getSecondMatch(/^(.*)\\/(.*) /)\n };\n }\n\n // set webkit or gecko flag for browsers based on these engines\n if (!result.msedge && /(apple)?webkit/i.test(ua)) {\n if (/(apple)?webkit\\/537\\.36/i.test(ua)) {\n result.name = result.name || \"Blink\"\n result.blink = t\n } else {\n result.name = result.name || \"Webkit\"\n result.webkit = t\n }\n if (!result.version && versionIdentifier) {\n result.version = versionIdentifier\n }\n } else if (!result.opera && /gecko\\//i.test(ua)) {\n result.name = result.name || \"Gecko\"\n result.gecko = t\n result.version = result.version || getFirstMatch(/gecko\\/(\\d+(\\.\\d+)?)/i)\n }\n\n // set OS flags for platforms that have multiple browsers\n if (!result.windowsphone && !result.msedge && (android || result.silk)) {\n result.android = t\n } else if (!result.windowsphone && !result.msedge && iosdevice) {\n result[iosdevice] = t\n result.ios = t\n } else if (mac) {\n result.mac = t\n } else if (xbox) {\n result.xbox = t\n } else if (windows) {\n result.windows = t\n } else if (linux) {\n result.linux = t\n }\n\n // OS version extraction\n var osVersion = '';\n if (result.windowsphone) {\n osVersion = getFirstMatch(/windows phone (?:os)?\\s?(\\d+(\\.\\d+)*)/i);\n } else if (iosdevice) {\n osVersion = getFirstMatch(/os (\\d+([_\\s]\\d+)*) like mac os x/i);\n osVersion = osVersion.replace(/[_\\s]/g, '.');\n } else if (android) {\n osVersion = getFirstMatch(/android[ \\/-](\\d+(\\.\\d+)*)/i);\n } else if (result.webos) {\n osVersion = getFirstMatch(/(?:web|hpw)os\\/(\\d+(\\.\\d+)*)/i);\n } else if (result.blackberry) {\n osVersion = getFirstMatch(/rim\\stablet\\sos\\s(\\d+(\\.\\d+)*)/i);\n } else if (result.bada) {\n osVersion = getFirstMatch(/bada\\/(\\d+(\\.\\d+)*)/i);\n } else if (result.tizen) {\n osVersion = getFirstMatch(/tizen[\\/\\s](\\d+(\\.\\d+)*)/i);\n }\n if (osVersion) {\n result.osversion = osVersion;\n }\n\n // device type extraction\n var osMajorVersion = osVersion.split('.')[0];\n if (\n tablet\n || nexusTablet\n || iosdevice == 'ipad'\n || (android && (osMajorVersion == 3 || (osMajorVersion >= 4 && !mobile)))\n || result.silk\n ) {\n result.tablet = t\n } else if (\n mobile\n || iosdevice == 'iphone'\n || iosdevice == 'ipod'\n || android\n || nexusMobile\n || result.blackberry\n || result.webos\n || result.bada\n ) {\n result.mobile = t\n }\n\n // Graded Browser Support\n // http://developer.yahoo.com/yui/articles/gbs\n if (result.msedge ||\n (result.msie && result.version >= 10) ||\n (result.yandexbrowser && result.version >= 15) ||\n\t\t (result.vivaldi && result.version >= 1.0) ||\n (result.chrome && result.version >= 20) ||\n (result.samsungBrowser && result.version >= 4) ||\n (result.firefox && result.version >= 20.0) ||\n (result.safari && result.version >= 6) ||\n (result.opera && result.version >= 10.0) ||\n (result.ios && result.osversion && result.osversion.split(\".\")[0] >= 6) ||\n (result.blackberry && result.version >= 10.1)\n || (result.chromium && result.version >= 20)\n ) {\n result.a = t;\n }\n else if ((result.msie && result.version < 10) ||\n (result.chrome && result.version < 20) ||\n (result.firefox && result.version < 20.0) ||\n (result.safari && result.version < 6) ||\n (result.opera && result.version < 10.0) ||\n (result.ios && result.osversion && result.osversion.split(\".\")[0] < 6)\n || (result.chromium && result.version < 20)\n ) {\n result.c = t\n } else result.x = t\n\n return result\n }\n\n var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent || '' : '')\n\n bowser.test = function (browserList) {\n for (var i = 0; i < browserList.length; ++i) {\n var browserItem = browserList[i];\n if (typeof browserItem=== 'string') {\n if (browserItem in bowser) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Get version precisions count\n *\n * @example\n * getVersionPrecision(\"1.10.3\") // 3\n *\n * @param {string} version\n * @return {number}\n */\n function getVersionPrecision(version) {\n return version.split(\".\").length;\n }\n\n /**\n * Array::map polyfill\n *\n * @param {Array} arr\n * @param {Function} iterator\n * @return {Array}\n */\n function map(arr, iterator) {\n var result = [], i;\n if (Array.prototype.map) {\n return Array.prototype.map.call(arr, iterator);\n }\n for (i = 0; i < arr.length; i++) {\n result.push(iterator(arr[i]));\n }\n return result;\n }\n\n /**\n * Calculate browser version weight\n *\n * @example\n * compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1\n * compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1\n * compareVersions(['1.10.2.1', '1.10.2.1']); // 0\n * compareVersions(['1.10.2.1', '1.0800.2']); // -1\n *\n * @param {Array} versions versions to compare\n * @return {Number} comparison result\n */\n function compareVersions(versions) {\n // 1) get common precision for both versions, for example for \"10.0\" and \"9\" it should be 2\n var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1]));\n var chunks = map(versions, function (version) {\n var delta = precision - getVersionPrecision(version);\n\n // 2) \"9\" -> \"9.0\" (for precision = 2)\n version = version + new Array(delta + 1).join(\".0\");\n\n // 3) \"9.0\" -> [\"000000000\"\", \"000000009\"]\n return map(version.split(\".\"), function (chunk) {\n return new Array(20 - chunk.length).join(\"0\") + chunk;\n }).reverse();\n });\n\n // iterate in reverse order by reversed chunks array\n while (--precision >= 0) {\n // 4) compare: \"000000009\" > \"000000010\" = false (but \"9\" > \"10\" = true)\n if (chunks[0][precision] > chunks[1][precision]) {\n return 1;\n }\n else if (chunks[0][precision] === chunks[1][precision]) {\n if (precision === 0) {\n // all version chunks are same\n return 0;\n }\n }\n else {\n return -1;\n }\n }\n }\n\n /**\n * Check if browser is unsupported\n *\n * @example\n * bowser.isUnsupportedBrowser({\n * msie: \"10\",\n * firefox: \"23\",\n * chrome: \"29\",\n * safari: \"5.1\",\n * opera: \"16\",\n * phantom: \"534\"\n * });\n *\n * @param {Object} minVersions map of minimal version to browser\n * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map\n * @param {String} [ua] user agent string\n * @return {Boolean}\n */\n function isUnsupportedBrowser(minVersions, strictMode, ua) {\n var _bowser = bowser;\n\n // make strictMode param optional with ua param usage\n if (typeof strictMode === 'string') {\n ua = strictMode;\n strictMode = void(0);\n }\n\n if (strictMode === void(0)) {\n strictMode = false;\n }\n if (ua) {\n _bowser = detect(ua);\n }\n\n var version = \"\" + _bowser.version;\n for (var browser in minVersions) {\n if (minVersions.hasOwnProperty(browser)) {\n if (_bowser[browser]) {\n if (typeof minVersions[browser] !== 'string') {\n throw new Error('Browser version in the minVersion map should be a string: ' + browser + ': ' + String(minVersions));\n }\n\n // browser version and min supported version.\n return compareVersions([version, minVersions[browser]]) < 0;\n }\n }\n }\n\n return strictMode; // not found\n }\n\n /**\n * Check if browser is supported\n *\n * @param {Object} minVersions map of minimal version to browser\n * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map\n * @param {String} [ua] user agent string\n * @return {Boolean}\n */\n function check(minVersions, strictMode, ua) {\n return !isUnsupportedBrowser(minVersions, strictMode, ua);\n }\n\n bowser.isUnsupportedBrowser = isUnsupportedBrowser;\n bowser.compareVersions = compareVersions;\n bowser.check = check;\n\n /*\n * Set our detect method to the main bowser object so we can\n * reuse it to test other user agents.\n * This is needed to implement future tests.\n */\n bowser._detect = detect;\n\n return bowser\n});\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ../~/bowser/bowser.js\n ** module id = 4\n ** module chunks = 1 2\n **/","module.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ../~/webpack/buildin/amd-define.js\n ** module id = 5\n ** module chunks = 1 2\n **/","module.exports = {\n '1.2.840.113549.1.9.2': 'Неструктурированное имя',\n '1.2.643.3.141.1.1': 'РНС ФСС',\n '1.2.643.3.141.1.2': 'КП ФСС',\n '1.2.643.3.131.1.1': 'ИНН',\n '1.3.6.1.5.5.7.3.2': 'Проверка подлинности клиента',\n '1.3.6.1.5.5.7.3.4': 'Защищенная электронная почта',\n '1.2.643.3.8.100.1': 'Сертификат типа \"ekey-ГОСТ\"',\n '1.2.643.3.8.100.1.1': 'Общее использование в системах ИОК без права заверения финансовых документов',\n '1.2.643.3.8.100.1.2': 'Передача отчетности по ТКС',\n '1.2.643.3.8.100.1.3': 'Оформление взаимных обязательств, соглашений, договоров, актов и т.п.',\n '1.2.643.3.8.100.1.4': 'Внутрикорпоративный документооборот',\n '1.2.643.3.8.100.1.5': 'Использование в системах электронной торговли',\n '1.2.643.3.8.100.1.6': 'Использование в торгово-закупочной системе \"ЭЛЕКТРА\"',\n '1.2.643.6.2.1.7.2': 'Использование физическим лицом в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских прав и обязанностей в отношении инвестиционных паев паевых инвестиционных фондов, в том числе отношения, связанные с учетом и/или фиксацией прав на инвестиционные паи паевых инвестиционных фондов',\n '1.2.643.6.2.1.7.1': 'Использование единоличным исполнительным органом юридического лица или уполномоченными представителями юридического лица в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских и иных прав и обязанностей в сфере негосударственного пенсионного обеспечения, негосударственного пенсионного страхования, в сфере деятельности паевых инвестиционных фондов, акционерных инвестиционных фондов, профессиональных участников рынка ценных бумаг, а также связанной с обслуживанием указанной деятельности услуг кредитных и иных организаций',\n '1.3.6.1.4.1.29919.21': 'Использование в системе Портал государственных закупок Ростовской области \"Рефери\".',\n '1.2.643.3.2.100.65.13.11': 'Использование в системе АИС \"Госзакупки\" Сахалинской области.',\n '1.2.643.3.8.100.1.7': 'Использование в системе Портал государственных закупок Ставропольского края.',\n '1.2.643.3.8.100.1.8': 'Использование в Единой системе электронной торговли B2B-Center и B2G.',\n '1.2.643.3.8.100.1.9': 'Для участия в электронных торгах и подписания государственного контракта в электронной площадке ОАО «ЕЭТП» уполномоченными лицами участников размещения государственного или муниципального заказа',\n '1.2.643.3.8.100.1.10': 'Для участия в электронных торгах и подписания государственного контракта в информационных системах Тендерного комитета города Москвы уполномоченными лицами участников размещения государственного заказа города Москвы',\n '1.2.643.3.8.100.1.11': 'Подписание электронных документов в автоматизированной информационной системе размещения государственного и муниципального заказа Саратовской области',\n '1.2.643.3.8.100.1.12': 'Использование в системе государственного заказа Иркутской области',\n '1.2.643.3.8.100.1.13': 'Использование в электронной торговой площадке агентства государственного заказа Красноярского края',\n '1.3.6.1.4.1.24138.1.1.8.1': 'Обеспечение юридической значимости в Системе \"Электронная Торговая Площадка\"',\n '1.2.643.3.8.100.1.14': 'Использование в электронной торговой площадке \"Тендер\"',\n '1.2.643.6.3': 'Использование в электронных торговых системах и в программном обеспечении, связанным с обменом электронных сообщений',\n '1.2.643.2.2.34.6': 'Пользователь Центра Регистрации',\n '1.2.643.2.39.1.1': 'Использование в программных продуктах системы \"1С:Предприятие 8\"',\n '1.2.643.5.1.24.2.1.3': 'Формирование документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя',\n '1.2.643.5.1.24.2.1.3.1': 'Формирование кадастровым инженером документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя',\n '1.2.643.5.1.24.2.2.2': 'Формирование документов как результата оказания услуги со стороны органов регистрации прав',\n '1.2.643.5.1.24.2.2.3': 'Формирование документов для получения государственных услуг в сфере государственной регистрации прав на недвижимое имущество и сделок с ним со стороны заявителя',\n '1.2.643.6.3.1.1': 'Использование на электронных площадок отобранных для проведения аукционах в электронной форме',\n '1.2.643.6.3.1.2.1': 'Тип участника - Юридическое лицо',\n '1.2.643.6.3.1.2.2': 'Тип участника - Физическое лицо',\n '1.2.643.6.3.1.2.3': 'Тип участника - Индивидуальный предприниматель',\n '1.2.643.6.3.1.3.1': 'Участник размещения заказа',\n '1.2.643.6.3.1.4.1': 'Администратор организации',\n '1.2.643.6.3.1.4.2': 'Уполномоченный специалист',\n '1.2.643.6.3.1.4.3': 'Специалист с правом подписи контракта',\n '1.3.643.3.8.100.15': 'Использование в ЭТП \"uTender\"'\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./oids.js\n ** module id = 6\n ** module chunks = 1 2\n **/","module.exports = {\n // CAPICOM_STORE_LOCATION enumeration\n StoreLocation: {\n CAPICOM_MEMORY_STORE: 0,\n CAPICOM_LOCAL_MACHINE_STORE: 1,\n CAPICOM_CURRENT_USER_STORE: 2,\n CAPICOM_ACTIVE_DIRECTORY_USER_STORE: 3,\n CAPICOM_SMART_CARD_USER_STORE: 4\n },\n // CAPICOM_STORE_OPEN_MODE enumeration\n StoreOpenMode: {\n CAPICOM_STORE_OPEN_READ_ONLY: 0,\n CAPICOM_STORE_OPEN_READ_WRITE: 1,\n CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED: 2,\n CAPICOM_STORE_OPEN_EXISTING_ONLY: 128,\n CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED: 256\n },\n // CAPICOM_CERTIFICATE_FIND_TYPE enumeration\n CertFindType: {\n CAPICOM_CERTIFICATE_FIND_SHA1_HASH: 0,\n CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME: 1,\n CAPICOM_CERTIFICATE_FIND_ISSUER_NAME: 2,\n CAPICOM_CERTIFICATE_FIND_ROOT_NAME: 3,\n CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME: 4,\n CAPICOM_CERTIFICATE_FIND_EXTENSION: 5,\n CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY: 6,\n CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY: 7,\n CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY: 8,\n CAPICOM_CERTIFICATE_FIND_TIME_VALID: 9,\n CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID: 10,\n CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED: 11,\n CAPICOM_CERTIFICATE_FIND_KEY_USAGE: 12\n },\n Time: {\n AUTHENTICATED_ATTRIBUTE_SIGNING_TIME: 0\n },\n Check: {\n CHECK_NONE: 0,\n CHECK_TRUSTED_ROOT: 1,\n CHECK_TIME_VALIDITY: 2,\n CHECK_SIGNATURE_VALIDITY: 4,\n CHECK_ONLINE_REVOCATION_STATUS: 8,\n CHECK_OFFLINE_REVOCATION_STATUS: 16,\n TRUST_IS_NOT_TIME_VALID: 1,\n TRUST_IS_NOT_TIME_NESTED: 2,\n TRUST_IS_REVOKED: 4,\n TRUST_IS_NOT_SIGNATURE_VALID: 8,\n TRUST_IS_NOT_VALID_FOR_USAGE: 16,\n TRUST_IS_UNTRUSTED_ROOT: 32,\n TRUST_REVOCATION_STATUS_UNKNOWN: 64,\n TRUST_IS_CYCLIC: 128,\n TRUST_IS_PARTIAL_CHAIN: 65536,\n TRUST_CTL_IS_NOT_TIME_VALID: 131072,\n TRUST_CTL_IS_NOT_SIGNATURE_VALID: 262144,\n TRUST_CTL_IS_NOT_VALID_FOR_USAGE: 524288,\n },\n // CAPICOM_PROPID enumeration\n PropId: {\n CAPICOM_PROPID_UNKNOWN: 0,\n CAPICOM_PROPID_KEY_PROV_HANDLE: 1,\n CAPICOM_PROPID_KEY_PROV_INFO: 2,\n CAPICOM_PROPID_SHA1_HASH: 3,\n CAPICOM_PROPID_HASH_PROP: 3,\n CAPICOM_PROPID_MD5_HASH: 4,\n CAPICOM_PROPID_KEY_CONTEXT: 5,\n CAPICOM_PROPID_KEY_SPEC: 6,\n CAPICOM_PROPID_IE30_RESERVED: 7,\n CAPICOM_PROPID_PUBKEY_HASH_RESERVED: 8,\n CAPICOM_PROPID_ENHKEY_USAGE: 9,\n CAPICOM_PROPID_CTL_USAGE: 9,\n CAPICOM_PROPID_NEXT_UPDATE_LOCATION: 10,\n CAPICOM_PROPID_FRIENDLY_NAME: 11,\n CAPICOM_PROPID_PVK_FILE: 12,\n CAPICOM_PROPID_DESCRIPTION: 13,\n CAPICOM_PROPID_ACCESS_STATE: 14,\n CAPICOM_PROPID_SIGNATURE_HASH: 15,\n CAPICOM_PROPID_SMART_CARD_DATA: 16,\n CAPICOM_PROPID_EFS: 17,\n CAPICOM_PROPID_FORTEZZA_DATA: 18,\n CAPICOM_PROPID_ARCHIVED: 19,\n CAPICOM_PROPID_KEY_IDENTIFIER: 20,\n CAPICOM_PROPID_AUTO_ENROLL: 21,\n CAPICOM_PROPID_PUBKEY_ALG_PARA: 22,\n CAPICOM_PROPID_CROSS_CERT_DIST_POINTS: 23,\n CAPICOM_PROPID_ISSUER_PUBLIC_KEY_MD5_HASH: 24,\n CAPICOM_PROPID_SUBJECT_PUBLIC_KEY_MD5_HASH: 25,\n CAPICOM_PROPID_ENROLLMENT: 26,\n CAPICOM_PROPID_DATE_STAMP: 27,\n CAPICOM_PROPID_ISSUER_SERIAL_NUMBER_MD5_HASH: 28,\n CAPICOM_PROPID_SUBJECT_NAME_MD5_HASH: 29,\n CAPICOM_PROPID_EXTENDED_ERROR_INFO: 30,\n CAPICOM_PROPID_RENEWAL: 64,\n CAPICOM_PROPID_ARCHIVED_KEY_HASH: 65,\n CAPICOM_PROPID_FIRST_RESERVED: 66,\n CAPICOM_PROPID_LAST_RESERVED: 0x00007FFF,\n CAPICOM_PROPID_FIRST_USER: 0x00008000,\n CAPICOM_PROPID_LAST_USER: 0x0000FFFF\n },\n // CADESCOM_XML_SIGNATURE_TYPE enumeration\n SignatureType: {\n CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED: 0,\n CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING: 1,\n CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE: 2\n },\n // CADESCOM_HASH_ALGORITHM enumeration\n HashAlgorithm: {\n CADESCOM_HASH_ALGORITHM_CP_GOST_3411: 100,\n CADESCOM_HASH_ALGORITHM_MD2: 1,\n CADESCOM_HASH_ALGORITHM_MD4: 2,\n CADESCOM_HASH_ALGORITHM_MD5: 3,\n CADESCOM_HASH_ALGORITHM_SHA_256: 4,\n CADESCOM_HASH_ALGORITHM_SHA_384: 5,\n CADESCOM_HASH_ALGORITHM_SHA_512: 6,\n CADESCOM_HASH_ALGORITHM_SHA1: 0\n },\n CadesType: {\n CADESCOM_CADES_DEFAULT: 0,\n CADESCOM_CADES_BES: 1,\n CADESCOM_CADES_X_LONG_TYPE_1: 0x5d\n },\n ContentEncoding: {\n CADESCOM_BASE64_TO_BINARY: 0x01,\n CADESCOM_STRING_TO_UCS2LE: 0x00\n },\n StoreNames: {\n CAPICOM_MY_STORE: 'My'\n },\n Chain: {\n CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT: 0,\n CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN: 1,\n CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY: 2\n },\n GostXmlDSigUrls: {\n XmlDsigGost3410Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411',\n XmlDsigGost3411Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411',\n XmlDsigGost3410UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411',\n XmlDsigGost3411UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr3411'\n }\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./constants.js\n ** module id = 7\n ** module chunks = 1 2\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/2.crypto-pro.js b/dist/2.crypto-pro.js new file mode 100644 index 0000000..f86f0be --- /dev/null +++ b/dist/2.crypto-pro.js @@ -0,0 +1,1600 @@ +webpackJsonpCryptoPro([2],[ +/* 0 */, +/* 1 */, +/* 2 */, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + var bowser = __webpack_require__(4); + var oids = __webpack_require__(6); + + var subjectNameTagsTranslations = [ + {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'}, + {possibleNames: ['CN'], translation: 'Владелец'}, + {possibleNames: ['SN'], translation: 'Фамилия'}, + {possibleNames: ['G'], translation: 'Имя Отчество'}, + {possibleNames: ['C'], translation: 'Страна'}, + {possibleNames: ['S'], translation: 'Регион'}, + {possibleNames: ['STREET'], translation: 'Адрес'}, + {possibleNames: ['O'], translation: 'Компания'}, + {possibleNames: ['OU'], translation: 'Отдел/подразделение'}, + {possibleNames: ['T'], translation: 'Должность'}, + {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'}, + {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'}, + {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'}, + {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'}, + {possibleNames: ['E'], translation: 'Email'}, + {possibleNames: ['L'], translation: 'Город'} + ], + + issuerNameTagsTranslations = [ + {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'}, + {possibleNames: ['CN'], translation: 'Удостоверяющий центр'}, + {possibleNames: ['S'], translation: 'Регион'}, + {possibleNames: ['C'], translation: 'Страна'}, + {possibleNames: ['STREET'], translation: 'Адрес'}, + {possibleNames: ['O'], translation: 'Компания'}, + {possibleNames: ['OU'], translation: 'Тип'}, + {possibleNames: ['T'], translation: 'Должность'}, + {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'}, + {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'}, + {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'}, + {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'}, + {possibleNames: ['E'], translation: 'Email'}, + {possibleNames: ['L'], translation: 'Город'} + ]; + + /** + * Парсит информацию из строки с информацией о сертификате + * */ + function parseCertInfo(tags, infoString) { + /** + * Пример входной строки: + * + + T=Генеральный директор, UnstructuredName="INN=7811514257/KPP=781101001/OGRN=1127847087884", + STREET="Крыленко, д.3, лит.Б", CN=Король Анатолий Евгеньевич, G=Анатолий Евгеньевич, SN=Король, + OU=Администрация, O="ООО ""Аксиома""", L=Санкт-Петербург, S=78 г. Санкт-Петербург, C=RU, E=korol@sferasro.ru, + INN=007811514257, OGRN=1127847087884, SNILS=11617693460 + + * */ + var result = infoString.match(/([а-яА-Яa-zA-Z0-9\.]+)=(?:("[^"]+?")|(.+?))(?:,|$)/g); + + if (result) { + result = result.map(function (group) { + /** + * Пример входной строки: + * + + UnstructuredName="INN=7811514257/KPP=781101001/OGRN=1127847087884", + + * */ + var parts = group.match(/^([а-яА-Яa-zA-Z0-9\.]+)=(.+?),?$/), + title = parts && parts[1], + descr = parts && parts[2], + translated = false, + oidTitle; + + // Если тайтл содержит ОИД, пытаемся расшифровать + if (/^OID./.test(title)) { + oidTitle = title.match(/^OID\.(.*)/); + + if (oidTitle && oidTitle[1]) { + oidTitle = oids[oidTitle[1]]; + + if (oidTitle) { + title = oidTitle; + } + } + } + + // Вырезаем лишние кавычки + descr = descr.replace(/^"(.*)"/, '$1'); + descr = descr.replace(/"{2}/g, '"'); + + tags.some(function (tag) { + return tag.possibleNames.some(function (possible) { + var match = possible === title; + + if (match) { + title = tag.translation; + translated = true; + } + + return match; + }); + }); + + return { + title: title, + descr: descr, + translated: translated + }; + }); + } + + return result; + } + + /** + * Возвращает дату в формате (dd.mm.yyyy hh:mm:ss) из строки, формата, используемого плагином cryptoPro + * */ + function getReadableDate(date) { + date = new Date(date); + + return ([ + date.getDate(), + date.getMonth() + 1, + date.getFullYear() + ].join('.') + ' ' + [ + date.getHours(), + date.getMinutes(), + date.getSeconds() + ].join(':')).replace(/\b(\d)\b/g, '0$1'); + } + + /** + * Преобразует дату для IE + * */ + function getDateObj(dateObj) { + return bowser.msie ? dateObj.getVarDate() : dateObj; + } + + /** + * Подготавливает информацию о сертификатах + * */ + function prepareCertsInfo(items) { + return items.map(function (c) { + c.name = c.subjectName.match(/CN=(.+?),/); + + // Удалось ли вытащить Common Name + if (c.name && c.name[1]) { + c.name = c.name[1]; + } + + c.validFrom = getReadableDate(c.validFrom); + c.validTo = getReadableDate(c.validTo); + + c.label = c.name + ' (до ' + c.validTo + ')'; + + return c; + }); + } + + /** + * Возвращает расшифрованные ОИД'ы + * */ + function getDecodedExtendedKeyUsage() { + var that = this; + + return new Promise(function (resolve) { + that.getExtendedKeyUsage().then(function (certOids) { + resolve(certOids.reduce(function (oidsLst, oid) { + oid = { + id: oid, + descr: oids[oid] || null + }; + + if (oid.descr) { + oidsLst.unshift(oid); + } else { + oidsLst.push(oid); + } + + return oidsLst; + }, [])); + }); + }); + } + + /** + * Проверка наличия ОИД'а(ОИД'ов) у сертификата + * + * @param {String|Array} oids - ОИД'ы для проверки + * @returns {Promise} с отложенным результатом типа {Boolean} + * */ + function hasExtendedKeyUsage(oids) { + var that = this; + + return new Promise(function (resolve) { + that.getExtendedKeyUsage().then(function (certOids) { + var result; + + if (Array.isArray(oids)) { + result = oids.every(function (oidToCheck) { + return certOids.some(function (certOid) { + return certOid === oidToCheck; + }); + }); + } else { + result = certOids.some(function (certOid) { + return certOid === oids; + }); + } + + resolve(result); + }); + }); + } + + /** + * Выводит информацию о системе пользователя + * */ + function getEnvInfo() { + var parsed = bowser._detect(navigator.userAgent), + info = { + browserName: parsed.name, + browserVersion: parsed.version + }; + + if (parsed.mac) { + info.os = 'Mac'; + } else if (parsed.windows) { + info.os = 'Windows'; + } else if (parsed.linux) { + info.os = 'Linux'; + } + + return info; + } + + /** + * Подходящая ли версия CSP + * */ + function isValidCSPVersion(version) { + version = version.match(/\d+?\b(?:\.\d+)?/); + + return version >= 3.6; + } + + /** + * Подходящая ли версия cades плагина + * */ + function isValidCadesVersion(version) { + version = version.split('.').reduce(function (verInfo, number, i) { + if (i === 0) { + verInfo.major = number; + } else if (i === 1) { + verInfo.minor = number; + } else if (i === 2) { + verInfo.patch = number; + } + + return verInfo; + }, {}); + + if (version.major < 2) { + return false; + } + + return version.patch >= 12438; + } + + module.exports = { + subjectNameTagsTranslations: subjectNameTagsTranslations, + issuerNameTagsTranslations: issuerNameTagsTranslations, + parseCertInfo: parseCertInfo, + getReadableDate: getReadableDate, + getDateObj: getDateObj, + prepareCertsInfo: prepareCertsInfo, + getDecodedExtendedKeyUsage: getDecodedExtendedKeyUsage, + hasExtendedKeyUsage: hasExtendedKeyUsage, + getEnvInfo: getEnvInfo, + isValidCSPVersion: isValidCSPVersion, + isValidCadesVersion: isValidCadesVersion + }; + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + /*! + * Bowser - a browser detector + * https://github.com/ded/bowser + * MIT License | (c) Dustin Diaz 2015 + */ + + !function (root, name, definition) { + if (typeof module != 'undefined' && module.exports) module.exports = definition() + else if (true) __webpack_require__(5)(name, definition) + else root[name] = definition() + }(this, 'bowser', function () { + /** + * See useragents.js for examples of navigator.userAgent + */ + + var t = true + + function detect(ua) { + + function getFirstMatch(regex) { + var match = ua.match(regex); + return (match && match.length > 1 && match[1]) || ''; + } + + function getSecondMatch(regex) { + var match = ua.match(regex); + return (match && match.length > 1 && match[2]) || ''; + } + + var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase() + , likeAndroid = /like android/i.test(ua) + , android = !likeAndroid && /android/i.test(ua) + , nexusMobile = /nexus\s*[0-6]\s*/i.test(ua) + , nexusTablet = !nexusMobile && /nexus\s*[0-9]+/i.test(ua) + , chromeos = /CrOS/.test(ua) + , silk = /silk/i.test(ua) + , sailfish = /sailfish/i.test(ua) + , tizen = /tizen/i.test(ua) + , webos = /(web|hpw)os/i.test(ua) + , windowsphone = /windows phone/i.test(ua) + , samsungBrowser = /SamsungBrowser/i.test(ua) + , windows = !windowsphone && /windows/i.test(ua) + , mac = !iosdevice && !silk && /macintosh/i.test(ua) + , linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua) + , edgeVersion = getFirstMatch(/edge\/(\d+(\.\d+)?)/i) + , versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i) + , tablet = /tablet/i.test(ua) + , mobile = !tablet && /[^-]mobi/i.test(ua) + , xbox = /xbox/i.test(ua) + , result + + if (/opera/i.test(ua)) { + // an old Opera + result = { + name: 'Opera' + , opera: t + , version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\s\/](\d+(\.\d+)?)/i) + } + } else if (/opr|opios/i.test(ua)) { + // a new Opera + result = { + name: 'Opera' + , opera: t + , version: getFirstMatch(/(?:opr|opios)[\s\/](\d+(\.\d+)?)/i) || versionIdentifier + } + } + else if (/SamsungBrowser/i.test(ua)) { + result = { + name: 'Samsung Internet for Android' + , samsungBrowser: t + , version: versionIdentifier || getFirstMatch(/(?:SamsungBrowser)[\s\/](\d+(\.\d+)?)/i) + } + } + else if (/coast/i.test(ua)) { + result = { + name: 'Opera Coast' + , coast: t + , version: versionIdentifier || getFirstMatch(/(?:coast)[\s\/](\d+(\.\d+)?)/i) + } + } + else if (/yabrowser/i.test(ua)) { + result = { + name: 'Yandex Browser' + , yandexbrowser: t + , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i) + } + } + else if (/ucbrowser/i.test(ua)) { + result = { + name: 'UC Browser' + , ucbrowser: t + , version: getFirstMatch(/(?:ucbrowser)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (/mxios/i.test(ua)) { + result = { + name: 'Maxthon' + , maxthon: t + , version: getFirstMatch(/(?:mxios)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (/epiphany/i.test(ua)) { + result = { + name: 'Epiphany' + , epiphany: t + , version: getFirstMatch(/(?:epiphany)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (/puffin/i.test(ua)) { + result = { + name: 'Puffin' + , puffin: t + , version: getFirstMatch(/(?:puffin)[\s\/](\d+(?:\.\d+)?)/i) + } + } + else if (/sleipnir/i.test(ua)) { + result = { + name: 'Sleipnir' + , sleipnir: t + , version: getFirstMatch(/(?:sleipnir)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (/k-meleon/i.test(ua)) { + result = { + name: 'K-Meleon' + , kMeleon: t + , version: getFirstMatch(/(?:k-meleon)[\s\/](\d+(?:\.\d+)+)/i) + } + } + else if (windowsphone) { + result = { + name: 'Windows Phone' + , windowsphone: t + } + if (edgeVersion) { + result.msedge = t + result.version = edgeVersion + } + else { + result.msie = t + result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i) + } + } + else if (/msie|trident/i.test(ua)) { + result = { + name: 'Internet Explorer' + , msie: t + , version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i) + } + } else if (chromeos) { + result = { + name: 'Chrome' + , chromeos: t + , chromeBook: t + , chrome: t + , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) + } + } else if (/chrome.+? edge/i.test(ua)) { + result = { + name: 'Microsoft Edge' + , msedge: t + , version: edgeVersion + } + } + else if (/vivaldi/i.test(ua)) { + result = { + name: 'Vivaldi' + , vivaldi: t + , version: getFirstMatch(/vivaldi\/(\d+(\.\d+)?)/i) || versionIdentifier + } + } + else if (sailfish) { + result = { + name: 'Sailfish' + , sailfish: t + , version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i) + } + } + else if (/seamonkey\//i.test(ua)) { + result = { + name: 'SeaMonkey' + , seamonkey: t + , version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i) + } + } + else if (/firefox|iceweasel|fxios/i.test(ua)) { + result = { + name: 'Firefox' + , firefox: t + , version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \/](\d+(\.\d+)?)/i) + } + if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) { + result.firefoxos = t + } + } + else if (silk) { + result = { + name: 'Amazon Silk' + , silk: t + , version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i) + } + } + else if (/phantom/i.test(ua)) { + result = { + name: 'PhantomJS' + , phantom: t + , version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i) + } + } + else if (/slimerjs/i.test(ua)) { + result = { + name: 'SlimerJS' + , slimer: t + , version: getFirstMatch(/slimerjs\/(\d+(\.\d+)?)/i) + } + } + else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) { + result = { + name: 'BlackBerry' + , blackberry: t + , version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i) + } + } + else if (webos) { + result = { + name: 'WebOS' + , webos: t + , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i) + }; + /touchpad\//i.test(ua) && (result.touchpad = t) + } + else if (/bada/i.test(ua)) { + result = { + name: 'Bada' + , bada: t + , version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i) + }; + } + else if (tizen) { + result = { + name: 'Tizen' + , tizen: t + , version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier + }; + } + else if (/qupzilla/i.test(ua)) { + result = { + name: 'QupZilla' + , qupzilla: t + , version: getFirstMatch(/(?:qupzilla)[\s\/](\d+(?:\.\d+)+)/i) || versionIdentifier + } + } + else if (/chromium/i.test(ua)) { + result = { + name: 'Chromium' + , chromium: t + , version: getFirstMatch(/(?:chromium)[\s\/](\d+(?:\.\d+)?)/i) || versionIdentifier + } + } + else if (/chrome|crios|crmo/i.test(ua)) { + result = { + name: 'Chrome' + , chrome: t + , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) + } + } + else if (android) { + result = { + name: 'Android' + , version: versionIdentifier + } + } + else if (/safari|applewebkit/i.test(ua)) { + result = { + name: 'Safari' + , safari: t + } + if (versionIdentifier) { + result.version = versionIdentifier + } + } + else if (iosdevice) { + result = { + name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod' + } + // WTF: version is not part of user agent in web apps + if (versionIdentifier) { + result.version = versionIdentifier + } + } + else if(/googlebot/i.test(ua)) { + result = { + name: 'Googlebot' + , googlebot: t + , version: getFirstMatch(/googlebot\/(\d+(\.\d+))/i) || versionIdentifier + } + } + else { + result = { + name: getFirstMatch(/^(.*)\/(.*) /), + version: getSecondMatch(/^(.*)\/(.*) /) + }; + } + + // set webkit or gecko flag for browsers based on these engines + if (!result.msedge && /(apple)?webkit/i.test(ua)) { + if (/(apple)?webkit\/537\.36/i.test(ua)) { + result.name = result.name || "Blink" + result.blink = t + } else { + result.name = result.name || "Webkit" + result.webkit = t + } + if (!result.version && versionIdentifier) { + result.version = versionIdentifier + } + } else if (!result.opera && /gecko\//i.test(ua)) { + result.name = result.name || "Gecko" + result.gecko = t + result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i) + } + + // set OS flags for platforms that have multiple browsers + if (!result.windowsphone && !result.msedge && (android || result.silk)) { + result.android = t + } else if (!result.windowsphone && !result.msedge && iosdevice) { + result[iosdevice] = t + result.ios = t + } else if (mac) { + result.mac = t + } else if (xbox) { + result.xbox = t + } else if (windows) { + result.windows = t + } else if (linux) { + result.linux = t + } + + // OS version extraction + var osVersion = ''; + if (result.windowsphone) { + osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i); + } else if (iosdevice) { + osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i); + osVersion = osVersion.replace(/[_\s]/g, '.'); + } else if (android) { + osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i); + } else if (result.webos) { + osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i); + } else if (result.blackberry) { + osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i); + } else if (result.bada) { + osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i); + } else if (result.tizen) { + osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i); + } + if (osVersion) { + result.osversion = osVersion; + } + + // device type extraction + var osMajorVersion = osVersion.split('.')[0]; + if ( + tablet + || nexusTablet + || iosdevice == 'ipad' + || (android && (osMajorVersion == 3 || (osMajorVersion >= 4 && !mobile))) + || result.silk + ) { + result.tablet = t + } else if ( + mobile + || iosdevice == 'iphone' + || iosdevice == 'ipod' + || android + || nexusMobile + || result.blackberry + || result.webos + || result.bada + ) { + result.mobile = t + } + + // Graded Browser Support + // http://developer.yahoo.com/yui/articles/gbs + if (result.msedge || + (result.msie && result.version >= 10) || + (result.yandexbrowser && result.version >= 15) || + (result.vivaldi && result.version >= 1.0) || + (result.chrome && result.version >= 20) || + (result.samsungBrowser && result.version >= 4) || + (result.firefox && result.version >= 20.0) || + (result.safari && result.version >= 6) || + (result.opera && result.version >= 10.0) || + (result.ios && result.osversion && result.osversion.split(".")[0] >= 6) || + (result.blackberry && result.version >= 10.1) + || (result.chromium && result.version >= 20) + ) { + result.a = t; + } + else if ((result.msie && result.version < 10) || + (result.chrome && result.version < 20) || + (result.firefox && result.version < 20.0) || + (result.safari && result.version < 6) || + (result.opera && result.version < 10.0) || + (result.ios && result.osversion && result.osversion.split(".")[0] < 6) + || (result.chromium && result.version < 20) + ) { + result.c = t + } else result.x = t + + return result + } + + var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent || '' : '') + + bowser.test = function (browserList) { + for (var i = 0; i < browserList.length; ++i) { + var browserItem = browserList[i]; + if (typeof browserItem=== 'string') { + if (browserItem in bowser) { + return true; + } + } + } + return false; + } + + /** + * Get version precisions count + * + * @example + * getVersionPrecision("1.10.3") // 3 + * + * @param {string} version + * @return {number} + */ + function getVersionPrecision(version) { + return version.split(".").length; + } + + /** + * Array::map polyfill + * + * @param {Array} arr + * @param {Function} iterator + * @return {Array} + */ + function map(arr, iterator) { + var result = [], i; + if (Array.prototype.map) { + return Array.prototype.map.call(arr, iterator); + } + for (i = 0; i < arr.length; i++) { + result.push(iterator(arr[i])); + } + return result; + } + + /** + * Calculate browser version weight + * + * @example + * compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1 + * compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1 + * compareVersions(['1.10.2.1', '1.10.2.1']); // 0 + * compareVersions(['1.10.2.1', '1.0800.2']); // -1 + * + * @param {Array} versions versions to compare + * @return {Number} comparison result + */ + function compareVersions(versions) { + // 1) get common precision for both versions, for example for "10.0" and "9" it should be 2 + var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1])); + var chunks = map(versions, function (version) { + var delta = precision - getVersionPrecision(version); + + // 2) "9" -> "9.0" (for precision = 2) + version = version + new Array(delta + 1).join(".0"); + + // 3) "9.0" -> ["000000000"", "000000009"] + return map(version.split("."), function (chunk) { + return new Array(20 - chunk.length).join("0") + chunk; + }).reverse(); + }); + + // iterate in reverse order by reversed chunks array + while (--precision >= 0) { + // 4) compare: "000000009" > "000000010" = false (but "9" > "10" = true) + if (chunks[0][precision] > chunks[1][precision]) { + return 1; + } + else if (chunks[0][precision] === chunks[1][precision]) { + if (precision === 0) { + // all version chunks are same + return 0; + } + } + else { + return -1; + } + } + } + + /** + * Check if browser is unsupported + * + * @example + * bowser.isUnsupportedBrowser({ + * msie: "10", + * firefox: "23", + * chrome: "29", + * safari: "5.1", + * opera: "16", + * phantom: "534" + * }); + * + * @param {Object} minVersions map of minimal version to browser + * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map + * @param {String} [ua] user agent string + * @return {Boolean} + */ + function isUnsupportedBrowser(minVersions, strictMode, ua) { + var _bowser = bowser; + + // make strictMode param optional with ua param usage + if (typeof strictMode === 'string') { + ua = strictMode; + strictMode = void(0); + } + + if (strictMode === void(0)) { + strictMode = false; + } + if (ua) { + _bowser = detect(ua); + } + + var version = "" + _bowser.version; + for (var browser in minVersions) { + if (minVersions.hasOwnProperty(browser)) { + if (_bowser[browser]) { + if (typeof minVersions[browser] !== 'string') { + throw new Error('Browser version in the minVersion map should be a string: ' + browser + ': ' + String(minVersions)); + } + + // browser version and min supported version. + return compareVersions([version, minVersions[browser]]) < 0; + } + } + } + + return strictMode; // not found + } + + /** + * Check if browser is supported + * + * @param {Object} minVersions map of minimal version to browser + * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map + * @param {String} [ua] user agent string + * @return {Boolean} + */ + function check(minVersions, strictMode, ua) { + return !isUnsupportedBrowser(minVersions, strictMode, ua); + } + + bowser.isUnsupportedBrowser = isUnsupportedBrowser; + bowser.compareVersions = compareVersions; + bowser.check = check; + + /* + * Set our detect method to the main bowser object so we can + * reuse it to test other user agents. + * This is needed to implement future tests. + */ + bowser._detect = detect; + + return bowser + }); + + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + + module.exports = function() { throw new Error("define cannot be used indirect"); }; + + +/***/ }, +/* 6 */ +/***/ function(module, exports) { + + module.exports = { + '1.2.840.113549.1.9.2': 'Неструктурированное имя', + '1.2.643.3.141.1.1': 'РНС ФСС', + '1.2.643.3.141.1.2': 'КП ФСС', + '1.2.643.3.131.1.1': 'ИНН', + '1.3.6.1.5.5.7.3.2': 'Проверка подлинности клиента', + '1.3.6.1.5.5.7.3.4': 'Защищенная электронная почта', + '1.2.643.3.8.100.1': 'Сертификат типа "ekey-ГОСТ"', + '1.2.643.3.8.100.1.1': 'Общее использование в системах ИОК без права заверения финансовых документов', + '1.2.643.3.8.100.1.2': 'Передача отчетности по ТКС', + '1.2.643.3.8.100.1.3': 'Оформление взаимных обязательств, соглашений, договоров, актов и т.п.', + '1.2.643.3.8.100.1.4': 'Внутрикорпоративный документооборот', + '1.2.643.3.8.100.1.5': 'Использование в системах электронной торговли', + '1.2.643.3.8.100.1.6': 'Использование в торгово-закупочной системе "ЭЛЕКТРА"', + '1.2.643.6.2.1.7.2': 'Использование физическим лицом в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских прав и обязанностей в отношении инвестиционных паев паевых инвестиционных фондов, в том числе отношения, связанные с учетом и/или фиксацией прав на инвестиционные паи паевых инвестиционных фондов', + '1.2.643.6.2.1.7.1': 'Использование единоличным исполнительным органом юридического лица или уполномоченными представителями юридического лица в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских и иных прав и обязанностей в сфере негосударственного пенсионного обеспечения, негосударственного пенсионного страхования, в сфере деятельности паевых инвестиционных фондов, акционерных инвестиционных фондов, профессиональных участников рынка ценных бумаг, а также связанной с обслуживанием указанной деятельности услуг кредитных и иных организаций', + '1.3.6.1.4.1.29919.21': 'Использование в системе Портал государственных закупок Ростовской области "Рефери".', + '1.2.643.3.2.100.65.13.11': 'Использование в системе АИС "Госзакупки" Сахалинской области.', + '1.2.643.3.8.100.1.7': 'Использование в системе Портал государственных закупок Ставропольского края.', + '1.2.643.3.8.100.1.8': 'Использование в Единой системе электронной торговли B2B-Center и B2G.', + '1.2.643.3.8.100.1.9': 'Для участия в электронных торгах и подписания государственного контракта в электронной площадке ОАО «ЕЭТП» уполномоченными лицами участников размещения государственного или муниципального заказа', + '1.2.643.3.8.100.1.10': 'Для участия в электронных торгах и подписания государственного контракта в информационных системах Тендерного комитета города Москвы уполномоченными лицами участников размещения государственного заказа города Москвы', + '1.2.643.3.8.100.1.11': 'Подписание электронных документов в автоматизированной информационной системе размещения государственного и муниципального заказа Саратовской области', + '1.2.643.3.8.100.1.12': 'Использование в системе государственного заказа Иркутской области', + '1.2.643.3.8.100.1.13': 'Использование в электронной торговой площадке агентства государственного заказа Красноярского края', + '1.3.6.1.4.1.24138.1.1.8.1': 'Обеспечение юридической значимости в Системе "Электронная Торговая Площадка"', + '1.2.643.3.8.100.1.14': 'Использование в электронной торговой площадке "Тендер"', + '1.2.643.6.3': 'Использование в электронных торговых системах и в программном обеспечении, связанным с обменом электронных сообщений', + '1.2.643.2.2.34.6': 'Пользователь Центра Регистрации', + '1.2.643.2.39.1.1': 'Использование в программных продуктах системы "1С:Предприятие 8"', + '1.2.643.5.1.24.2.1.3': 'Формирование документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя', + '1.2.643.5.1.24.2.1.3.1': 'Формирование кадастровым инженером документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя', + '1.2.643.5.1.24.2.2.2': 'Формирование документов как результата оказания услуги со стороны органов регистрации прав', + '1.2.643.5.1.24.2.2.3': 'Формирование документов для получения государственных услуг в сфере государственной регистрации прав на недвижимое имущество и сделок с ним со стороны заявителя', + '1.2.643.6.3.1.1': 'Использование на электронных площадок отобранных для проведения аукционах в электронной форме', + '1.2.643.6.3.1.2.1': 'Тип участника - Юридическое лицо', + '1.2.643.6.3.1.2.2': 'Тип участника - Физическое лицо', + '1.2.643.6.3.1.2.3': 'Тип участника - Индивидуальный предприниматель', + '1.2.643.6.3.1.3.1': 'Участник размещения заказа', + '1.2.643.6.3.1.4.1': 'Администратор организации', + '1.2.643.6.3.1.4.2': 'Уполномоченный специалист', + '1.2.643.6.3.1.4.3': 'Специалист с правом подписи контракта', + '1.3.643.3.8.100.15': 'Использование в ЭТП "uTender"' + }; + +/***/ }, +/* 7 */ +/***/ function(module, exports) { + + module.exports = { + // CAPICOM_STORE_LOCATION enumeration + StoreLocation: { + CAPICOM_MEMORY_STORE: 0, + CAPICOM_LOCAL_MACHINE_STORE: 1, + CAPICOM_CURRENT_USER_STORE: 2, + CAPICOM_ACTIVE_DIRECTORY_USER_STORE: 3, + CAPICOM_SMART_CARD_USER_STORE: 4 + }, + // CAPICOM_STORE_OPEN_MODE enumeration + StoreOpenMode: { + CAPICOM_STORE_OPEN_READ_ONLY: 0, + CAPICOM_STORE_OPEN_READ_WRITE: 1, + CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED: 2, + CAPICOM_STORE_OPEN_EXISTING_ONLY: 128, + CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED: 256 + }, + // CAPICOM_CERTIFICATE_FIND_TYPE enumeration + CertFindType: { + CAPICOM_CERTIFICATE_FIND_SHA1_HASH: 0, + CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME: 1, + CAPICOM_CERTIFICATE_FIND_ISSUER_NAME: 2, + CAPICOM_CERTIFICATE_FIND_ROOT_NAME: 3, + CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME: 4, + CAPICOM_CERTIFICATE_FIND_EXTENSION: 5, + CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY: 6, + CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY: 7, + CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY: 8, + CAPICOM_CERTIFICATE_FIND_TIME_VALID: 9, + CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID: 10, + CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED: 11, + CAPICOM_CERTIFICATE_FIND_KEY_USAGE: 12 + }, + Time: { + AUTHENTICATED_ATTRIBUTE_SIGNING_TIME: 0 + }, + Check: { + CHECK_NONE: 0, + CHECK_TRUSTED_ROOT: 1, + CHECK_TIME_VALIDITY: 2, + CHECK_SIGNATURE_VALIDITY: 4, + CHECK_ONLINE_REVOCATION_STATUS: 8, + CHECK_OFFLINE_REVOCATION_STATUS: 16, + TRUST_IS_NOT_TIME_VALID: 1, + TRUST_IS_NOT_TIME_NESTED: 2, + TRUST_IS_REVOKED: 4, + TRUST_IS_NOT_SIGNATURE_VALID: 8, + TRUST_IS_NOT_VALID_FOR_USAGE: 16, + TRUST_IS_UNTRUSTED_ROOT: 32, + TRUST_REVOCATION_STATUS_UNKNOWN: 64, + TRUST_IS_CYCLIC: 128, + TRUST_IS_PARTIAL_CHAIN: 65536, + TRUST_CTL_IS_NOT_TIME_VALID: 131072, + TRUST_CTL_IS_NOT_SIGNATURE_VALID: 262144, + TRUST_CTL_IS_NOT_VALID_FOR_USAGE: 524288, + }, + // CAPICOM_PROPID enumeration + PropId: { + CAPICOM_PROPID_UNKNOWN: 0, + CAPICOM_PROPID_KEY_PROV_HANDLE: 1, + CAPICOM_PROPID_KEY_PROV_INFO: 2, + CAPICOM_PROPID_SHA1_HASH: 3, + CAPICOM_PROPID_HASH_PROP: 3, + CAPICOM_PROPID_MD5_HASH: 4, + CAPICOM_PROPID_KEY_CONTEXT: 5, + CAPICOM_PROPID_KEY_SPEC: 6, + CAPICOM_PROPID_IE30_RESERVED: 7, + CAPICOM_PROPID_PUBKEY_HASH_RESERVED: 8, + CAPICOM_PROPID_ENHKEY_USAGE: 9, + CAPICOM_PROPID_CTL_USAGE: 9, + CAPICOM_PROPID_NEXT_UPDATE_LOCATION: 10, + CAPICOM_PROPID_FRIENDLY_NAME: 11, + CAPICOM_PROPID_PVK_FILE: 12, + CAPICOM_PROPID_DESCRIPTION: 13, + CAPICOM_PROPID_ACCESS_STATE: 14, + CAPICOM_PROPID_SIGNATURE_HASH: 15, + CAPICOM_PROPID_SMART_CARD_DATA: 16, + CAPICOM_PROPID_EFS: 17, + CAPICOM_PROPID_FORTEZZA_DATA: 18, + CAPICOM_PROPID_ARCHIVED: 19, + CAPICOM_PROPID_KEY_IDENTIFIER: 20, + CAPICOM_PROPID_AUTO_ENROLL: 21, + CAPICOM_PROPID_PUBKEY_ALG_PARA: 22, + CAPICOM_PROPID_CROSS_CERT_DIST_POINTS: 23, + CAPICOM_PROPID_ISSUER_PUBLIC_KEY_MD5_HASH: 24, + CAPICOM_PROPID_SUBJECT_PUBLIC_KEY_MD5_HASH: 25, + CAPICOM_PROPID_ENROLLMENT: 26, + CAPICOM_PROPID_DATE_STAMP: 27, + CAPICOM_PROPID_ISSUER_SERIAL_NUMBER_MD5_HASH: 28, + CAPICOM_PROPID_SUBJECT_NAME_MD5_HASH: 29, + CAPICOM_PROPID_EXTENDED_ERROR_INFO: 30, + CAPICOM_PROPID_RENEWAL: 64, + CAPICOM_PROPID_ARCHIVED_KEY_HASH: 65, + CAPICOM_PROPID_FIRST_RESERVED: 66, + CAPICOM_PROPID_LAST_RESERVED: 0x00007FFF, + CAPICOM_PROPID_FIRST_USER: 0x00008000, + CAPICOM_PROPID_LAST_USER: 0x0000FFFF + }, + // CADESCOM_XML_SIGNATURE_TYPE enumeration + SignatureType: { + CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED: 0, + CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING: 1, + CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE: 2 + }, + // CADESCOM_HASH_ALGORITHM enumeration + HashAlgorithm: { + CADESCOM_HASH_ALGORITHM_CP_GOST_3411: 100, + CADESCOM_HASH_ALGORITHM_MD2: 1, + CADESCOM_HASH_ALGORITHM_MD4: 2, + CADESCOM_HASH_ALGORITHM_MD5: 3, + CADESCOM_HASH_ALGORITHM_SHA_256: 4, + CADESCOM_HASH_ALGORITHM_SHA_384: 5, + CADESCOM_HASH_ALGORITHM_SHA_512: 6, + CADESCOM_HASH_ALGORITHM_SHA1: 0 + }, + CadesType: { + CADESCOM_CADES_DEFAULT: 0, + CADESCOM_CADES_BES: 1, + CADESCOM_CADES_X_LONG_TYPE_1: 0x5d + }, + ContentEncoding: { + CADESCOM_BASE64_TO_BINARY: 0x01, + CADESCOM_STRING_TO_UCS2LE: 0x00 + }, + StoreNames: { + CAPICOM_MY_STORE: 'My' + }, + Chain: { + CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT: 0, + CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN: 1, + CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY: 2 + }, + GostXmlDSigUrls: { + XmlDsigGost3410Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411', + XmlDsigGost3411Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411', + XmlDsigGost3410UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411', + XmlDsigGost3411UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr3411' + } + }; + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { + + var cryptoCommon = __webpack_require__(3), + cryptoConstants = __webpack_require__(7), + + _certProto = { + /** + * Проверяет, валиден ли сертификат + * */ + isValid: function isValid() { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + var result; + + try { + result = cert.IsValid(); + result = result.Result; + } catch (err) { + reject('Ошибка при проверке сертификата: ', err.message); + return; + } + + resolve(result); + }); + }, + + /** + * Достает указанное свойство у сертификата + * */ + getProp: function (propName) { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + var result; + + try { + result = cert[propName]; + } catch (err) { + reject('Ошибка при обращении к свойству сертификата: ', err.message); + return; + } + + resolve(result); + }); + }, + + /** + * Экспорт base64 представления сертификата пользователя + * */ + exportBase64: function exportBase64() { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + var base64; + + try { + base64 = cert.Export(0); + } catch (err) { + reject('Ошибка при экспорте сертификата: ', err.message); + return; + } + + resolve(base64); + }); + }, + + /** + * Возвращает информацию об алгоритме + * */ + getAlgorithm: function getAlgorithm() { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + var result = {}, + algorithm; + + try { + algorithm = cert.PublicKey(); + algorithm = algorithm.Algorithm; + + result.algorithm = algorithm.FriendlyName; + result.oid = algorithm.Value; + } catch (err) { + reject('Ошибка при получении алгоритма: ', err.message); + return; + } + + resolve(result); + }); + }, + + /** + * Разбирает SubjectName сертификата по тэгам + * */ + getOwnerInfo: function getOwnerInfo() { + return getCertInfo.call(this, cryptoCommon.subjectNameTagsTranslations, 'SubjectName'); + }, + + /** + * Разбирает IssuerName сертификата по тэгам + * */ + getIssuerInfo: function getIssuerInfo() { + return getCertInfo.call(this, cryptoCommon.issuerNameTagsTranslations, 'IssuerName'); + }, + + /** + * Получение OID сертификата + * Возвращает массив OID (улучшенного ключа) + * */ + getExtendedKeyUsage: function getExtendedKeyUsage() { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + var OIDS = [], + count, + item; + + try { + count = cert.ExtendedKeyUsage(); + count = count.EKUs; + count = count.Count; + + if (count > 0) { + while (count > 0) { + item = cert.ExtendedKeyUsage(); + item = item.EKUs; + item = item.Item(count); + item = item.OID; + + OIDS.push(item); + + count--; + } + } + } catch (err) { + reject('Ошибка при получении ОИД\'ов: ', err.message); + return; + } + + resolve(OIDS); + }); + }, + + getDecodedExtendedKeyUsage: cryptoCommon.getDecodedExtendedKeyUsage, + + hasExtendedKeyUsage: cryptoCommon.hasExtendedKeyUsage + }, + + _certListCache; + + /** + * Проверяет корректность настроек ЭП на машине + * */ + function isValidEDSSettings() { + return new Promise(function (resolve, reject) { + var result; + + try { + result = cadesplugin.CreateObject('CAdESCOM.About'); + } catch (error) { + reject('Настройки ЭП на данной машине не верны'); + } + + resolve(); + }); + } + + /** + * Получить сертификат в формате cades по хэшу + * */ + function getCadesCert(hash) { + return new Promise(function (resolve, reject) { + var oStore = cadesplugin.CreateObject('CAdESCOM.Store'), + certs, + certCnt, + cert; + + if (!oStore) { + reject('Не удалось получить доступ к хранилищу сертификатов'); + return; + } + + // Открываем хранилище + try { + oStore.Open( + cadesplugin.CAPICOM_CURRENT_USER_STORE, + cadesplugin.CAPICOM_MY_STORE, + cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED + ); + } catch (err) { + reject('Ошибка при открытии хранилища: ' + err.message); + return; + } + + // Получаем доступ к сертификатам + try { + certs = oStore.Certificates; + certCnt = certs.Count; + } catch (err) { + reject('Ошибка получения списка сертификатов: ' + err.message); + return; + } + + if (!certCnt) { + reject('Нет доступных сертификатов'); + return; + } + + // Получаем сертификат по хэшу + try { + certs = certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH, hash); + + if (certs.Count) { + cert = certs.Item(1); + } else { + throw new Error('Нет доступных сертификатов'); + } + } catch (err) { + reject('Не удалось получить сертификат по хэшу: ' + err.message); + return; + } + + oStore.Close(); + + resolve(cert); + }); + } + + /** + * Разбирает информацию сертификата по тэгам + * */ + function getCertInfo(tags, propName) { + var cert = this._cert; + + return new Promise(function (resolve, reject) { + var propInfo; + + try { + propInfo = cert[propName]; + } catch (err) { + reject('Ошибка при извлечении данных из сертификата: ', err.message); + return; + } + + resolve(cryptoCommon.parseCertInfo(tags, propInfo)); + }); + } + + /** + * Возвращает список сертификатов, доступных в системе + * + * @param {Boolean} [resetCache=false] -- нужно ли сбросить кэш списка сертификатов + * @returns {Promise} -- со списком сертификатов {Array} + * */ + function getCertsList(resetCache) { + return new Promise(function (resolve, reject) { + if (!resetCache && _certListCache) { + resolve(_certListCache); + return; + } + + var oStore = cadesplugin.CreateObject('CAdESCOM.Store'), + result = [], + certs, + count, + item; + + // Открываем хранилище + try { + oStore.Open( + cadesplugin.CAPICOM_CURRENT_USER_STORE, + cadesplugin.CAPICOM_MY_STORE, + cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED + ); + } catch (err) { + reject('Ошибка при открытии хранилища: ' + err.message); + return; + } + + // Получаем доступ к сертификатам + try { + certs = oStore.Certificates; + + if (certs) { + certs = certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID); + /** + * Не рассматриваются сертификаты, в которых отсутствует закрытый ключ + * или не действительны на данный момент + * */ + certs = certs.Find( + cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY, + cryptoConstants.PropId.CAPICOM_PROPID_KEY_PROV_INFO + ); + + count = certs.Count; + } + } catch (err) { + reject('Ошибка получения списка сертификатов: ' + err.message); + return; + } + + if (!count) { + reject('Нет доступных сертификатов'); + return; + } + + try { + while (count) { + item = certs.Item(count); + + result.push(Object.assign(Object.create(_certProto), { + _cert: item, + thumbprint: item.Thumbprint, + subjectName: item.SubjectName, + issuerName: item.IssuerName, + validFrom: item.ValidFromDate, + validTo: item.ValidToDate + })); + + count--; + } + } catch (err) { + reject('Ошибка обработки сертификатов: ' + err.message); + return; + } + + oStore.Close(); + + _certListCache = cryptoCommon.prepareCertsInfo(result); + + resolve(_certListCache); + }); + } + + /** + * Получить сертификат по хэшу + * */ + function getCert(hash) { + return new Promise(function (resolve, reject) { + if (!hash) { + reject('Хэш не указан'); + return; + } + + getCertsList().then(function (list) { + var foundCert; + + list.some(function (cert) { + if (hash === cert.thumbprint) { + foundCert = cert; + return true; + } + }); + + if (foundCert) { + resolve(foundCert); + } else { + reject('Сертификат с хэшем: "' + hash + '" не найден'); + } + }, reject); + }); + } + + /** + * Создает подпись base64 строки по hash'у сертификата + * + * @param {String} hash -- fingerprint (thumbprint) сертификата + * @param {String} dataBase64 -- строковые данные в формате base64 + * @param {String} signType -- тип подписи открепленная (true) / присоединенная (false) (default: false) + * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String} + * */ + function signData(hash, dataBase64, signType) { + return new Promise(function (resolve, reject) { + getCadesCert(hash).then(function (cert) { + var clientTime = new Date(), + oAttrs = cadesplugin.CreateObject('CADESCOM.CPAttribute'), + oSignedData = cadesplugin.CreateObject('CAdESCOM.CadesSignedData'), + oSigner = cadesplugin.CreateObject('CAdESCOM.CPSigner'), + attrs, + signature; + + clientTime = cryptoCommon.getDateObj(clientTime); + + try { + oAttrs.Name = cryptoConstants.Time.AUTHENTICATED_ATTRIBUTE_SIGNING_TIME; + oAttrs.Value = clientTime; + } catch (err) { + reject('Ошибка при установке данных подписи: ' + err.message); + return; + } + + // Задаем настройки для подписи + try { + oSigner.Certificate = cert; + attrs = oSigner.AuthenticatedAttributes2; + attrs.Add(oAttrs); + oSignedData.ContentEncoding = cadesplugin.CADESCOM_BASE64_TO_BINARY; + oSignedData.Content = dataBase64; + oSigner.Options = cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY; + } catch (err) { + reject('Не удалось установить настройки для подписи: ' + err.message); + return; + } + + try { + signature = oSignedData.SignCades( + oSigner, + cadesplugin.CADESCOM_CADES_BES, + Boolean(signType) + ); + } catch (err) { + reject('Не удалось создать подпись: ' + err.message); + return; + } + + resolve(signature); + }); + }); + } + + /** + * Создает подпись XML строки по hash'у сертификата + * + * @param {String} hash -- fingerprint (thumbprint) сертификата + * @param {String} dataXML -- данные в формате XML + * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String} + * */ + function signDataXML(hash, dataXML) { + return new Promise(function (resolve, reject) { + getCadesCert(hash).then(function (cert) { + var oSigner = cadesplugin.CreateObject('CAdESCOM.CPSigner'), + signerXML = cadesplugin.CreateObject('CAdESCOM.SignedXML'), + cnts = cryptoConstants, + signature; + + // Задаем настройки для подписи + try { + oSigner.Certificate = cert; + // Добавляем данные для подписи + signerXML.Content = dataXML; + // Устанавливаем тип подписи + signerXML.SignatureType = cnts.SignatureType.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED; + // Устанавливаем алгоритм подписи + signerXML.SignatureMethod = cnts.GostXmlDSigUrls.XmlDsigGost3410Url; + // Устанавливаем алгоритм хэширования + signerXML.DigestMethod = cnts.GostXmlDSigUrls.XmlDsigGost3411Url; + } catch (err) { + reject('Не удалось установить настройки для подписи: ' + err.message); + return; + } + + try { + signature = signerXML.Sign(oSigner); + } catch (err) { + reject('Не удалось создать подпись: ' + err.message); + return; + } + + resolve(signature); + }); + }); + } + + /** + * Возвращает информацию о версии CSP и плагина + * */ + function getSystemInfo() { + var sysInfo = cryptoCommon.getEnvInfo(); + + return new Promise(function (resolve, reject) { + var e; + + try { + e = cadesplugin.CreateObject('CAdESCOM.About'); + + sysInfo.cadesVersion = e.PluginVersion; + // Возможен вызов в ранних версиях в виде sysInfo.cspVersion = e.CSPVersion('', 75); + sysInfo.cspVersion = e.CSPVersion(); + + if (!sysInfo.cadesVersion) { + sysInfo.cadesVersion = e.Version; + } + + sysInfo.cadesVersion = sysInfo.cadesVersion.toString(); + sysInfo.cspVersion = sysInfo.cspVersion.toString(); + + resolve(sysInfo); + } catch (err) { + reject('Ошибка при получении информации о системе: ', err.message); + } + }); + } + + /** + * Promise обертка для синхронного вызова проверки версии CSP + * */ + function isValidCSPVersion(version) { + return new Promise(function (resolve) { + resolve(cryptoCommon.isValidCSPVersion(version)); + }); + } + + /** + * Promise обертка для синхронного вызова проверки версии плагина + * */ + function isValidCadesVersion(version) { + return new Promise(function (resolve) { + resolve(cryptoCommon.isValidCadesVersion(version)); + }); + } + + module.exports = { + isValidEDSSettings: isValidEDSSettings, + getCertsList: getCertsList, + getCert: getCert, + signData: signData, + signDataXML: signDataXML, + getSystemInfo: getSystemInfo, + isValidCSPVersion: isValidCSPVersion, + isValidCadesVersion: isValidCadesVersion + }; + +/***/ } +]); +//# sourceMappingURL=2.crypto-pro.js.map \ No newline at end of file diff --git a/dist/2.crypto-pro.js.map b/dist/2.crypto-pro.js.map new file mode 100644 index 0000000..f80e539 --- /dev/null +++ b/dist/2.crypto-pro.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///./common.js?fc46","webpack:///../~/bowser/bowser.js?0fbd","webpack:///../~/webpack/buildin/amd-define.js?8f18","webpack:///./oids.js?7c42","webpack:///./constants.js?532c","webpack:///./apiSync.js"],"names":[],"mappings":";;;;;;;AAAA;AACA;;AAEA;AACA,UAAS,4EAA4E;AACrF,UAAS,+CAA+C;AACxD,UAAS,8CAA8C;AACvD,UAAS,kDAAkD;AAC3D,UAAS,4CAA4C;AACrD,UAAS,4CAA4C;AACrD,UAAS,gDAAgD;AACzD,UAAS,8CAA8C;AACvD,UAAS,0DAA0D;AACnE,UAAS,+CAA+C;AACxD,UAAS,qDAAqD;AAC9D,UAAS,2DAA2D;AACpE,UAAS,wDAAwD;AACjE,UAAS,kDAAkD;AAC3D,UAAS,2CAA2C;AACpD,UAAS;AACT;;AAEA;AACA,UAAS,4EAA4E;AACrF,UAAS,2DAA2D;AACpE,UAAS,4CAA4C;AACrD,UAAS,4CAA4C;AACrD,UAAS,gDAAgD;AACzD,UAAS,8CAA8C;AACvD,UAAS,0CAA0C;AACnD,UAAS,+CAA+C;AACxD,UAAS,qDAAqD;AAC9D,UAAS,2DAA2D;AACpE,UAAS,wDAAwD;AACjE,UAAS,kDAAkD;AAC3D,UAAS,2CAA2C;AACpD,UAAS;AACT;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sCAAqC,EAAE;;AAEvC;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,kBAAiB;AACjB,cAAa;;AAEb;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kBAAiB;AACjB;AACA;;AAEA;AACA,cAAa;AACb,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA,YAAW,aAAa;AACxB,cAAa,QAAQ,gCAAgC;AACrD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,sBAAqB;AACrB,kBAAiB;AACjB,cAAa;AACb;AACA;AACA,kBAAiB;AACjB;;AAEA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA,UAAS;AACT;AACA;;AAEA;AACA,MAAK,IAAI;;AAET;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;ACrRA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;;AAEA;AACA,oBAAmB,wBAAwB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc,OAAO;AACrB,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAc,MAAM;AACpB,eAAc,SAAS;AACvB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,gBAAe,gBAAgB;AAC/B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,sDAAqD;AACrD,mDAAkD;AAClD,mDAAkD;AAClD;AACA,eAAc,cAAc;AAC5B,eAAc,OAAO;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,QAAO;AACP,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;AACR;AACA,eAAc,OAAO;AACrB,eAAc,QAAQ;AACtB,eAAc,OAAO;AACrB,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,uBAAsB;AACtB;;AAEA;AACA;AACA;AACA,eAAc,OAAO;AACrB,eAAc,QAAQ;AACtB,eAAc,OAAO;AACrB,eAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,EAAC;;;;;;;ACnkBD,8BAA6B,mDAAmD;;;;;;;ACAhF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,G;;;;;;AC1IA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA,cAAa;AACb,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA,cAAa;AACb,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA,cAAa;AACb,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA,gCAA+B;AAC/B;;AAEA;AACA;AACA;;AAEA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA,cAAa;AACb,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;;AAEA;AACA,cAAa;AACb,UAAS;;AAET;;AAEA;AACA,MAAK;;AAEL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,cAAa,QAAQ,6BAA6B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;;AAEjB;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa;;AAEb;AACA;AACA,cAAa;AACb;AACA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa,QAAQ,wDAAwD;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa,QAAQ,wDAAwD;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,UAAS;AACT;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,G","file":"2.crypto-pro.js","sourcesContent":["var bowser = require('bowser/bowser');\nvar oids = require('./oids');\n\nvar subjectNameTagsTranslations = [\n {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'},\n {possibleNames: ['CN'], translation: 'Владелец'},\n {possibleNames: ['SN'], translation: 'Фамилия'},\n {possibleNames: ['G'], translation: 'Имя Отчество'},\n {possibleNames: ['C'], translation: 'Страна'},\n {possibleNames: ['S'], translation: 'Регион'},\n {possibleNames: ['STREET'], translation: 'Адрес'},\n {possibleNames: ['O'], translation: 'Компания'},\n {possibleNames: ['OU'], translation: 'Отдел/подразделение'},\n {possibleNames: ['T'], translation: 'Должность'},\n {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'},\n {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'},\n {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'},\n {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'},\n {possibleNames: ['E'], translation: 'Email'},\n {possibleNames: ['L'], translation: 'Город'}\n ],\n\n issuerNameTagsTranslations = [\n {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'},\n {possibleNames: ['CN'], translation: 'Удостоверяющий центр'},\n {possibleNames: ['S'], translation: 'Регион'},\n {possibleNames: ['C'], translation: 'Страна'},\n {possibleNames: ['STREET'], translation: 'Адрес'},\n {possibleNames: ['O'], translation: 'Компания'},\n {possibleNames: ['OU'], translation: 'Тип'},\n {possibleNames: ['T'], translation: 'Должность'},\n {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'},\n {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'},\n {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'},\n {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'},\n {possibleNames: ['E'], translation: 'Email'},\n {possibleNames: ['L'], translation: 'Город'}\n ];\n\n/**\n * Парсит информацию из строки с информацией о сертификате\n * */\nfunction parseCertInfo(tags, infoString) {\n /**\n * Пример входной строки:\n *\n\n T=Генеральный директор, UnstructuredName=\"INN=7811514257/KPP=781101001/OGRN=1127847087884\",\n STREET=\"Крыленко, д.3, лит.Б\", CN=Король Анатолий Евгеньевич, G=Анатолий Евгеньевич, SN=Король,\n OU=Администрация, O=\"ООО \"\"Аксиома\"\"\", L=Санкт-Петербург, S=78 г. Санкт-Петербург, C=RU, E=korol@sferasro.ru,\n INN=007811514257, OGRN=1127847087884, SNILS=11617693460\n\n * */\n var result = infoString.match(/([а-яА-Яa-zA-Z0-9\\.]+)=(?:(\"[^\"]+?\")|(.+?))(?:,|$)/g);\n\n if (result) {\n result = result.map(function (group) {\n /**\n * Пример входной строки:\n *\n\n UnstructuredName=\"INN=7811514257/KPP=781101001/OGRN=1127847087884\",\n\n * */\n var parts = group.match(/^([а-яА-Яa-zA-Z0-9\\.]+)=(.+?),?$/),\n title = parts && parts[1],\n descr = parts && parts[2],\n translated = false,\n oidTitle;\n\n // Если тайтл содержит ОИД, пытаемся расшифровать\n if (/^OID./.test(title)) {\n oidTitle = title.match(/^OID\\.(.*)/);\n\n if (oidTitle && oidTitle[1]) {\n oidTitle = oids[oidTitle[1]];\n\n if (oidTitle) {\n title = oidTitle;\n }\n }\n }\n\n // Вырезаем лишние кавычки\n descr = descr.replace(/^\"(.*)\"/, '$1');\n descr = descr.replace(/\"{2}/g, '\"');\n\n tags.some(function (tag) {\n return tag.possibleNames.some(function (possible) {\n var match = possible === title;\n\n if (match) {\n title = tag.translation;\n translated = true;\n }\n\n return match;\n });\n });\n\n return {\n title: title,\n descr: descr,\n translated: translated\n };\n });\n }\n\n return result;\n}\n\n/**\n * Возвращает дату в формате (dd.mm.yyyy hh:mm:ss) из строки, формата, используемого плагином cryptoPro\n * */\nfunction getReadableDate(date) {\n date = new Date(date);\n\n return ([\n date.getDate(),\n date.getMonth() + 1,\n date.getFullYear()\n ].join('.') + ' ' + [\n date.getHours(),\n date.getMinutes(),\n date.getSeconds()\n ].join(':')).replace(/\\b(\\d)\\b/g, '0$1');\n}\n\n/**\n * Преобразует дату для IE\n * */\nfunction getDateObj(dateObj) {\n return bowser.msie ? dateObj.getVarDate() : dateObj;\n}\n\n/**\n * Подготавливает информацию о сертификатах\n * */\nfunction prepareCertsInfo(items) {\n return items.map(function (c) {\n c.name = c.subjectName.match(/CN=(.+?),/);\n\n // Удалось ли вытащить Common Name\n if (c.name && c.name[1]) {\n c.name = c.name[1];\n }\n\n c.validFrom = getReadableDate(c.validFrom);\n c.validTo = getReadableDate(c.validTo);\n\n c.label = c.name + ' (до ' + c.validTo + ')';\n\n return c;\n });\n}\n\n/**\n * Возвращает расшифрованные ОИД'ы\n * */\nfunction getDecodedExtendedKeyUsage() {\n var that = this;\n\n return new Promise(function (resolve) {\n that.getExtendedKeyUsage().then(function (certOids) {\n resolve(certOids.reduce(function (oidsLst, oid) {\n oid = {\n id: oid,\n descr: oids[oid] || null\n };\n\n if (oid.descr) {\n oidsLst.unshift(oid);\n } else {\n oidsLst.push(oid);\n }\n\n return oidsLst;\n }, []));\n });\n });\n}\n\n/**\n * Проверка наличия ОИД'а(ОИД'ов) у сертификата\n *\n * @param {String|Array} oids - ОИД'ы для проверки\n * @returns {Promise} с отложенным результатом типа {Boolean}\n * */\nfunction hasExtendedKeyUsage(oids) {\n var that = this;\n\n return new Promise(function (resolve) {\n that.getExtendedKeyUsage().then(function (certOids) {\n var result;\n\n if (Array.isArray(oids)) {\n result = oids.every(function (oidToCheck) {\n return certOids.some(function (certOid) {\n return certOid === oidToCheck;\n });\n });\n } else {\n result = certOids.some(function (certOid) {\n return certOid === oids;\n });\n }\n\n resolve(result);\n });\n });\n}\n\n/**\n * Выводит информацию о системе пользователя\n * */\nfunction getEnvInfo() {\n var parsed = bowser._detect(navigator.userAgent),\n info = {\n browserName: parsed.name,\n browserVersion: parsed.version\n };\n\n if (parsed.mac) {\n info.os = 'Mac';\n } else if (parsed.windows) {\n info.os = 'Windows';\n } else if (parsed.linux) {\n info.os = 'Linux';\n }\n\n return info;\n}\n\n/**\n * Подходящая ли версия CSP\n * */\nfunction isValidCSPVersion(version) {\n version = version.match(/\\d+?\\b(?:\\.\\d+)?/);\n\n return version >= 3.6;\n}\n\n/**\n * Подходящая ли версия cades плагина\n * */\nfunction isValidCadesVersion(version) {\n version = version.split('.').reduce(function (verInfo, number, i) {\n if (i === 0) {\n verInfo.major = number;\n } else if (i === 1) {\n verInfo.minor = number;\n } else if (i === 2) {\n verInfo.patch = number;\n }\n\n return verInfo;\n }, {});\n\n if (version.major < 2) {\n return false;\n }\n\n return version.patch >= 12438;\n}\n\nmodule.exports = {\n subjectNameTagsTranslations: subjectNameTagsTranslations,\n issuerNameTagsTranslations: issuerNameTagsTranslations,\n parseCertInfo: parseCertInfo,\n getReadableDate: getReadableDate,\n getDateObj: getDateObj,\n prepareCertsInfo: prepareCertsInfo,\n getDecodedExtendedKeyUsage: getDecodedExtendedKeyUsage,\n hasExtendedKeyUsage: hasExtendedKeyUsage,\n getEnvInfo: getEnvInfo,\n isValidCSPVersion: isValidCSPVersion,\n isValidCadesVersion: isValidCadesVersion\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./common.js\n ** module id = 3\n ** module chunks = 1 2\n **/","/*!\n * Bowser - a browser detector\n * https://github.com/ded/bowser\n * MIT License | (c) Dustin Diaz 2015\n */\n\n!function (root, name, definition) {\n if (typeof module != 'undefined' && module.exports) module.exports = definition()\n else if (typeof define == 'function' && define.amd) define(name, definition)\n else root[name] = definition()\n}(this, 'bowser', function () {\n /**\n * See useragents.js for examples of navigator.userAgent\n */\n\n var t = true\n\n function detect(ua) {\n\n function getFirstMatch(regex) {\n var match = ua.match(regex);\n return (match && match.length > 1 && match[1]) || '';\n }\n\n function getSecondMatch(regex) {\n var match = ua.match(regex);\n return (match && match.length > 1 && match[2]) || '';\n }\n\n var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()\n , likeAndroid = /like android/i.test(ua)\n , android = !likeAndroid && /android/i.test(ua)\n , nexusMobile = /nexus\\s*[0-6]\\s*/i.test(ua)\n , nexusTablet = !nexusMobile && /nexus\\s*[0-9]+/i.test(ua)\n , chromeos = /CrOS/.test(ua)\n , silk = /silk/i.test(ua)\n , sailfish = /sailfish/i.test(ua)\n , tizen = /tizen/i.test(ua)\n , webos = /(web|hpw)os/i.test(ua)\n , windowsphone = /windows phone/i.test(ua)\n , samsungBrowser = /SamsungBrowser/i.test(ua)\n , windows = !windowsphone && /windows/i.test(ua)\n , mac = !iosdevice && !silk && /macintosh/i.test(ua)\n , linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua)\n , edgeVersion = getFirstMatch(/edge\\/(\\d+(\\.\\d+)?)/i)\n , versionIdentifier = getFirstMatch(/version\\/(\\d+(\\.\\d+)?)/i)\n , tablet = /tablet/i.test(ua)\n , mobile = !tablet && /[^-]mobi/i.test(ua)\n , xbox = /xbox/i.test(ua)\n , result\n\n if (/opera/i.test(ua)) {\n // an old Opera\n result = {\n name: 'Opera'\n , opera: t\n , version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n } else if (/opr|opios/i.test(ua)) {\n // a new Opera\n result = {\n name: 'Opera'\n , opera: t\n , version: getFirstMatch(/(?:opr|opios)[\\s\\/](\\d+(\\.\\d+)?)/i) || versionIdentifier\n }\n }\n else if (/SamsungBrowser/i.test(ua)) {\n result = {\n name: 'Samsung Internet for Android'\n , samsungBrowser: t\n , version: versionIdentifier || getFirstMatch(/(?:SamsungBrowser)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/coast/i.test(ua)) {\n result = {\n name: 'Opera Coast'\n , coast: t\n , version: versionIdentifier || getFirstMatch(/(?:coast)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/yabrowser/i.test(ua)) {\n result = {\n name: 'Yandex Browser'\n , yandexbrowser: t\n , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/ucbrowser/i.test(ua)) {\n result = {\n name: 'UC Browser'\n , ucbrowser: t\n , version: getFirstMatch(/(?:ucbrowser)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/mxios/i.test(ua)) {\n result = {\n name: 'Maxthon'\n , maxthon: t\n , version: getFirstMatch(/(?:mxios)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/epiphany/i.test(ua)) {\n result = {\n name: 'Epiphany'\n , epiphany: t\n , version: getFirstMatch(/(?:epiphany)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/puffin/i.test(ua)) {\n result = {\n name: 'Puffin'\n , puffin: t\n , version: getFirstMatch(/(?:puffin)[\\s\\/](\\d+(?:\\.\\d+)?)/i)\n }\n }\n else if (/sleipnir/i.test(ua)) {\n result = {\n name: 'Sleipnir'\n , sleipnir: t\n , version: getFirstMatch(/(?:sleipnir)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (/k-meleon/i.test(ua)) {\n result = {\n name: 'K-Meleon'\n , kMeleon: t\n , version: getFirstMatch(/(?:k-meleon)[\\s\\/](\\d+(?:\\.\\d+)+)/i)\n }\n }\n else if (windowsphone) {\n result = {\n name: 'Windows Phone'\n , windowsphone: t\n }\n if (edgeVersion) {\n result.msedge = t\n result.version = edgeVersion\n }\n else {\n result.msie = t\n result.version = getFirstMatch(/iemobile\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/msie|trident/i.test(ua)) {\n result = {\n name: 'Internet Explorer'\n , msie: t\n , version: getFirstMatch(/(?:msie |rv:)(\\d+(\\.\\d+)?)/i)\n }\n } else if (chromeos) {\n result = {\n name: 'Chrome'\n , chromeos: t\n , chromeBook: t\n , chrome: t\n , version: getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.\\d+)?)/i)\n }\n } else if (/chrome.+? edge/i.test(ua)) {\n result = {\n name: 'Microsoft Edge'\n , msedge: t\n , version: edgeVersion\n }\n }\n else if (/vivaldi/i.test(ua)) {\n result = {\n name: 'Vivaldi'\n , vivaldi: t\n , version: getFirstMatch(/vivaldi\\/(\\d+(\\.\\d+)?)/i) || versionIdentifier\n }\n }\n else if (sailfish) {\n result = {\n name: 'Sailfish'\n , sailfish: t\n , version: getFirstMatch(/sailfish\\s?browser\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/seamonkey\\//i.test(ua)) {\n result = {\n name: 'SeaMonkey'\n , seamonkey: t\n , version: getFirstMatch(/seamonkey\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/firefox|iceweasel|fxios/i.test(ua)) {\n result = {\n name: 'Firefox'\n , firefox: t\n , version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \\/](\\d+(\\.\\d+)?)/i)\n }\n if (/\\((mobile|tablet);[^\\)]*rv:[\\d\\.]+\\)/i.test(ua)) {\n result.firefoxos = t\n }\n }\n else if (silk) {\n result = {\n name: 'Amazon Silk'\n , silk: t\n , version : getFirstMatch(/silk\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/phantom/i.test(ua)) {\n result = {\n name: 'PhantomJS'\n , phantom: t\n , version: getFirstMatch(/phantomjs\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/slimerjs/i.test(ua)) {\n result = {\n name: 'SlimerJS'\n , slimer: t\n , version: getFirstMatch(/slimerjs\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/blackberry|\\bbb\\d+/i.test(ua) || /rim\\stablet/i.test(ua)) {\n result = {\n name: 'BlackBerry'\n , blackberry: t\n , version: versionIdentifier || getFirstMatch(/blackberry[\\d]+\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (webos) {\n result = {\n name: 'WebOS'\n , webos: t\n , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\\/(\\d+(\\.\\d+)?)/i)\n };\n /touchpad\\//i.test(ua) && (result.touchpad = t)\n }\n else if (/bada/i.test(ua)) {\n result = {\n name: 'Bada'\n , bada: t\n , version: getFirstMatch(/dolfin\\/(\\d+(\\.\\d+)?)/i)\n };\n }\n else if (tizen) {\n result = {\n name: 'Tizen'\n , tizen: t\n , version: getFirstMatch(/(?:tizen\\s?)?browser\\/(\\d+(\\.\\d+)?)/i) || versionIdentifier\n };\n }\n else if (/qupzilla/i.test(ua)) {\n result = {\n name: 'QupZilla'\n , qupzilla: t\n , version: getFirstMatch(/(?:qupzilla)[\\s\\/](\\d+(?:\\.\\d+)+)/i) || versionIdentifier\n }\n }\n else if (/chromium/i.test(ua)) {\n result = {\n name: 'Chromium'\n , chromium: t\n , version: getFirstMatch(/(?:chromium)[\\s\\/](\\d+(?:\\.\\d+)?)/i) || versionIdentifier\n }\n }\n else if (/chrome|crios|crmo/i.test(ua)) {\n result = {\n name: 'Chrome'\n , chrome: t\n , version: getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (android) {\n result = {\n name: 'Android'\n , version: versionIdentifier\n }\n }\n else if (/safari|applewebkit/i.test(ua)) {\n result = {\n name: 'Safari'\n , safari: t\n }\n if (versionIdentifier) {\n result.version = versionIdentifier\n }\n }\n else if (iosdevice) {\n result = {\n name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod'\n }\n // WTF: version is not part of user agent in web apps\n if (versionIdentifier) {\n result.version = versionIdentifier\n }\n }\n else if(/googlebot/i.test(ua)) {\n result = {\n name: 'Googlebot'\n , googlebot: t\n , version: getFirstMatch(/googlebot\\/(\\d+(\\.\\d+))/i) || versionIdentifier\n }\n }\n else {\n result = {\n name: getFirstMatch(/^(.*)\\/(.*) /),\n version: getSecondMatch(/^(.*)\\/(.*) /)\n };\n }\n\n // set webkit or gecko flag for browsers based on these engines\n if (!result.msedge && /(apple)?webkit/i.test(ua)) {\n if (/(apple)?webkit\\/537\\.36/i.test(ua)) {\n result.name = result.name || \"Blink\"\n result.blink = t\n } else {\n result.name = result.name || \"Webkit\"\n result.webkit = t\n }\n if (!result.version && versionIdentifier) {\n result.version = versionIdentifier\n }\n } else if (!result.opera && /gecko\\//i.test(ua)) {\n result.name = result.name || \"Gecko\"\n result.gecko = t\n result.version = result.version || getFirstMatch(/gecko\\/(\\d+(\\.\\d+)?)/i)\n }\n\n // set OS flags for platforms that have multiple browsers\n if (!result.windowsphone && !result.msedge && (android || result.silk)) {\n result.android = t\n } else if (!result.windowsphone && !result.msedge && iosdevice) {\n result[iosdevice] = t\n result.ios = t\n } else if (mac) {\n result.mac = t\n } else if (xbox) {\n result.xbox = t\n } else if (windows) {\n result.windows = t\n } else if (linux) {\n result.linux = t\n }\n\n // OS version extraction\n var osVersion = '';\n if (result.windowsphone) {\n osVersion = getFirstMatch(/windows phone (?:os)?\\s?(\\d+(\\.\\d+)*)/i);\n } else if (iosdevice) {\n osVersion = getFirstMatch(/os (\\d+([_\\s]\\d+)*) like mac os x/i);\n osVersion = osVersion.replace(/[_\\s]/g, '.');\n } else if (android) {\n osVersion = getFirstMatch(/android[ \\/-](\\d+(\\.\\d+)*)/i);\n } else if (result.webos) {\n osVersion = getFirstMatch(/(?:web|hpw)os\\/(\\d+(\\.\\d+)*)/i);\n } else if (result.blackberry) {\n osVersion = getFirstMatch(/rim\\stablet\\sos\\s(\\d+(\\.\\d+)*)/i);\n } else if (result.bada) {\n osVersion = getFirstMatch(/bada\\/(\\d+(\\.\\d+)*)/i);\n } else if (result.tizen) {\n osVersion = getFirstMatch(/tizen[\\/\\s](\\d+(\\.\\d+)*)/i);\n }\n if (osVersion) {\n result.osversion = osVersion;\n }\n\n // device type extraction\n var osMajorVersion = osVersion.split('.')[0];\n if (\n tablet\n || nexusTablet\n || iosdevice == 'ipad'\n || (android && (osMajorVersion == 3 || (osMajorVersion >= 4 && !mobile)))\n || result.silk\n ) {\n result.tablet = t\n } else if (\n mobile\n || iosdevice == 'iphone'\n || iosdevice == 'ipod'\n || android\n || nexusMobile\n || result.blackberry\n || result.webos\n || result.bada\n ) {\n result.mobile = t\n }\n\n // Graded Browser Support\n // http://developer.yahoo.com/yui/articles/gbs\n if (result.msedge ||\n (result.msie && result.version >= 10) ||\n (result.yandexbrowser && result.version >= 15) ||\n\t\t (result.vivaldi && result.version >= 1.0) ||\n (result.chrome && result.version >= 20) ||\n (result.samsungBrowser && result.version >= 4) ||\n (result.firefox && result.version >= 20.0) ||\n (result.safari && result.version >= 6) ||\n (result.opera && result.version >= 10.0) ||\n (result.ios && result.osversion && result.osversion.split(\".\")[0] >= 6) ||\n (result.blackberry && result.version >= 10.1)\n || (result.chromium && result.version >= 20)\n ) {\n result.a = t;\n }\n else if ((result.msie && result.version < 10) ||\n (result.chrome && result.version < 20) ||\n (result.firefox && result.version < 20.0) ||\n (result.safari && result.version < 6) ||\n (result.opera && result.version < 10.0) ||\n (result.ios && result.osversion && result.osversion.split(\".\")[0] < 6)\n || (result.chromium && result.version < 20)\n ) {\n result.c = t\n } else result.x = t\n\n return result\n }\n\n var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent || '' : '')\n\n bowser.test = function (browserList) {\n for (var i = 0; i < browserList.length; ++i) {\n var browserItem = browserList[i];\n if (typeof browserItem=== 'string') {\n if (browserItem in bowser) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Get version precisions count\n *\n * @example\n * getVersionPrecision(\"1.10.3\") // 3\n *\n * @param {string} version\n * @return {number}\n */\n function getVersionPrecision(version) {\n return version.split(\".\").length;\n }\n\n /**\n * Array::map polyfill\n *\n * @param {Array} arr\n * @param {Function} iterator\n * @return {Array}\n */\n function map(arr, iterator) {\n var result = [], i;\n if (Array.prototype.map) {\n return Array.prototype.map.call(arr, iterator);\n }\n for (i = 0; i < arr.length; i++) {\n result.push(iterator(arr[i]));\n }\n return result;\n }\n\n /**\n * Calculate browser version weight\n *\n * @example\n * compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1\n * compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1\n * compareVersions(['1.10.2.1', '1.10.2.1']); // 0\n * compareVersions(['1.10.2.1', '1.0800.2']); // -1\n *\n * @param {Array} versions versions to compare\n * @return {Number} comparison result\n */\n function compareVersions(versions) {\n // 1) get common precision for both versions, for example for \"10.0\" and \"9\" it should be 2\n var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1]));\n var chunks = map(versions, function (version) {\n var delta = precision - getVersionPrecision(version);\n\n // 2) \"9\" -> \"9.0\" (for precision = 2)\n version = version + new Array(delta + 1).join(\".0\");\n\n // 3) \"9.0\" -> [\"000000000\"\", \"000000009\"]\n return map(version.split(\".\"), function (chunk) {\n return new Array(20 - chunk.length).join(\"0\") + chunk;\n }).reverse();\n });\n\n // iterate in reverse order by reversed chunks array\n while (--precision >= 0) {\n // 4) compare: \"000000009\" > \"000000010\" = false (but \"9\" > \"10\" = true)\n if (chunks[0][precision] > chunks[1][precision]) {\n return 1;\n }\n else if (chunks[0][precision] === chunks[1][precision]) {\n if (precision === 0) {\n // all version chunks are same\n return 0;\n }\n }\n else {\n return -1;\n }\n }\n }\n\n /**\n * Check if browser is unsupported\n *\n * @example\n * bowser.isUnsupportedBrowser({\n * msie: \"10\",\n * firefox: \"23\",\n * chrome: \"29\",\n * safari: \"5.1\",\n * opera: \"16\",\n * phantom: \"534\"\n * });\n *\n * @param {Object} minVersions map of minimal version to browser\n * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map\n * @param {String} [ua] user agent string\n * @return {Boolean}\n */\n function isUnsupportedBrowser(minVersions, strictMode, ua) {\n var _bowser = bowser;\n\n // make strictMode param optional with ua param usage\n if (typeof strictMode === 'string') {\n ua = strictMode;\n strictMode = void(0);\n }\n\n if (strictMode === void(0)) {\n strictMode = false;\n }\n if (ua) {\n _bowser = detect(ua);\n }\n\n var version = \"\" + _bowser.version;\n for (var browser in minVersions) {\n if (minVersions.hasOwnProperty(browser)) {\n if (_bowser[browser]) {\n if (typeof minVersions[browser] !== 'string') {\n throw new Error('Browser version in the minVersion map should be a string: ' + browser + ': ' + String(minVersions));\n }\n\n // browser version and min supported version.\n return compareVersions([version, minVersions[browser]]) < 0;\n }\n }\n }\n\n return strictMode; // not found\n }\n\n /**\n * Check if browser is supported\n *\n * @param {Object} minVersions map of minimal version to browser\n * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map\n * @param {String} [ua] user agent string\n * @return {Boolean}\n */\n function check(minVersions, strictMode, ua) {\n return !isUnsupportedBrowser(minVersions, strictMode, ua);\n }\n\n bowser.isUnsupportedBrowser = isUnsupportedBrowser;\n bowser.compareVersions = compareVersions;\n bowser.check = check;\n\n /*\n * Set our detect method to the main bowser object so we can\n * reuse it to test other user agents.\n * This is needed to implement future tests.\n */\n bowser._detect = detect;\n\n return bowser\n});\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ../~/bowser/bowser.js\n ** module id = 4\n ** module chunks = 1 2\n **/","module.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ../~/webpack/buildin/amd-define.js\n ** module id = 5\n ** module chunks = 1 2\n **/","module.exports = {\n '1.2.840.113549.1.9.2': 'Неструктурированное имя',\n '1.2.643.3.141.1.1': 'РНС ФСС',\n '1.2.643.3.141.1.2': 'КП ФСС',\n '1.2.643.3.131.1.1': 'ИНН',\n '1.3.6.1.5.5.7.3.2': 'Проверка подлинности клиента',\n '1.3.6.1.5.5.7.3.4': 'Защищенная электронная почта',\n '1.2.643.3.8.100.1': 'Сертификат типа \"ekey-ГОСТ\"',\n '1.2.643.3.8.100.1.1': 'Общее использование в системах ИОК без права заверения финансовых документов',\n '1.2.643.3.8.100.1.2': 'Передача отчетности по ТКС',\n '1.2.643.3.8.100.1.3': 'Оформление взаимных обязательств, соглашений, договоров, актов и т.п.',\n '1.2.643.3.8.100.1.4': 'Внутрикорпоративный документооборот',\n '1.2.643.3.8.100.1.5': 'Использование в системах электронной торговли',\n '1.2.643.3.8.100.1.6': 'Использование в торгово-закупочной системе \"ЭЛЕКТРА\"',\n '1.2.643.6.2.1.7.2': 'Использование физическим лицом в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских прав и обязанностей в отношении инвестиционных паев паевых инвестиционных фондов, в том числе отношения, связанные с учетом и/или фиксацией прав на инвестиционные паи паевых инвестиционных фондов',\n '1.2.643.6.2.1.7.1': 'Использование единоличным исполнительным органом юридического лица или уполномоченными представителями юридического лица в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских и иных прав и обязанностей в сфере негосударственного пенсионного обеспечения, негосударственного пенсионного страхования, в сфере деятельности паевых инвестиционных фондов, акционерных инвестиционных фондов, профессиональных участников рынка ценных бумаг, а также связанной с обслуживанием указанной деятельности услуг кредитных и иных организаций',\n '1.3.6.1.4.1.29919.21': 'Использование в системе Портал государственных закупок Ростовской области \"Рефери\".',\n '1.2.643.3.2.100.65.13.11': 'Использование в системе АИС \"Госзакупки\" Сахалинской области.',\n '1.2.643.3.8.100.1.7': 'Использование в системе Портал государственных закупок Ставропольского края.',\n '1.2.643.3.8.100.1.8': 'Использование в Единой системе электронной торговли B2B-Center и B2G.',\n '1.2.643.3.8.100.1.9': 'Для участия в электронных торгах и подписания государственного контракта в электронной площадке ОАО «ЕЭТП» уполномоченными лицами участников размещения государственного или муниципального заказа',\n '1.2.643.3.8.100.1.10': 'Для участия в электронных торгах и подписания государственного контракта в информационных системах Тендерного комитета города Москвы уполномоченными лицами участников размещения государственного заказа города Москвы',\n '1.2.643.3.8.100.1.11': 'Подписание электронных документов в автоматизированной информационной системе размещения государственного и муниципального заказа Саратовской области',\n '1.2.643.3.8.100.1.12': 'Использование в системе государственного заказа Иркутской области',\n '1.2.643.3.8.100.1.13': 'Использование в электронной торговой площадке агентства государственного заказа Красноярского края',\n '1.3.6.1.4.1.24138.1.1.8.1': 'Обеспечение юридической значимости в Системе \"Электронная Торговая Площадка\"',\n '1.2.643.3.8.100.1.14': 'Использование в электронной торговой площадке \"Тендер\"',\n '1.2.643.6.3': 'Использование в электронных торговых системах и в программном обеспечении, связанным с обменом электронных сообщений',\n '1.2.643.2.2.34.6': 'Пользователь Центра Регистрации',\n '1.2.643.2.39.1.1': 'Использование в программных продуктах системы \"1С:Предприятие 8\"',\n '1.2.643.5.1.24.2.1.3': 'Формирование документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя',\n '1.2.643.5.1.24.2.1.3.1': 'Формирование кадастровым инженером документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя',\n '1.2.643.5.1.24.2.2.2': 'Формирование документов как результата оказания услуги со стороны органов регистрации прав',\n '1.2.643.5.1.24.2.2.3': 'Формирование документов для получения государственных услуг в сфере государственной регистрации прав на недвижимое имущество и сделок с ним со стороны заявителя',\n '1.2.643.6.3.1.1': 'Использование на электронных площадок отобранных для проведения аукционах в электронной форме',\n '1.2.643.6.3.1.2.1': 'Тип участника - Юридическое лицо',\n '1.2.643.6.3.1.2.2': 'Тип участника - Физическое лицо',\n '1.2.643.6.3.1.2.3': 'Тип участника - Индивидуальный предприниматель',\n '1.2.643.6.3.1.3.1': 'Участник размещения заказа',\n '1.2.643.6.3.1.4.1': 'Администратор организации',\n '1.2.643.6.3.1.4.2': 'Уполномоченный специалист',\n '1.2.643.6.3.1.4.3': 'Специалист с правом подписи контракта',\n '1.3.643.3.8.100.15': 'Использование в ЭТП \"uTender\"'\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./oids.js\n ** module id = 6\n ** module chunks = 1 2\n **/","module.exports = {\n // CAPICOM_STORE_LOCATION enumeration\n StoreLocation: {\n CAPICOM_MEMORY_STORE: 0,\n CAPICOM_LOCAL_MACHINE_STORE: 1,\n CAPICOM_CURRENT_USER_STORE: 2,\n CAPICOM_ACTIVE_DIRECTORY_USER_STORE: 3,\n CAPICOM_SMART_CARD_USER_STORE: 4\n },\n // CAPICOM_STORE_OPEN_MODE enumeration\n StoreOpenMode: {\n CAPICOM_STORE_OPEN_READ_ONLY: 0,\n CAPICOM_STORE_OPEN_READ_WRITE: 1,\n CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED: 2,\n CAPICOM_STORE_OPEN_EXISTING_ONLY: 128,\n CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED: 256\n },\n // CAPICOM_CERTIFICATE_FIND_TYPE enumeration\n CertFindType: {\n CAPICOM_CERTIFICATE_FIND_SHA1_HASH: 0,\n CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME: 1,\n CAPICOM_CERTIFICATE_FIND_ISSUER_NAME: 2,\n CAPICOM_CERTIFICATE_FIND_ROOT_NAME: 3,\n CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME: 4,\n CAPICOM_CERTIFICATE_FIND_EXTENSION: 5,\n CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY: 6,\n CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY: 7,\n CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY: 8,\n CAPICOM_CERTIFICATE_FIND_TIME_VALID: 9,\n CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID: 10,\n CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED: 11,\n CAPICOM_CERTIFICATE_FIND_KEY_USAGE: 12\n },\n Time: {\n AUTHENTICATED_ATTRIBUTE_SIGNING_TIME: 0\n },\n Check: {\n CHECK_NONE: 0,\n CHECK_TRUSTED_ROOT: 1,\n CHECK_TIME_VALIDITY: 2,\n CHECK_SIGNATURE_VALIDITY: 4,\n CHECK_ONLINE_REVOCATION_STATUS: 8,\n CHECK_OFFLINE_REVOCATION_STATUS: 16,\n TRUST_IS_NOT_TIME_VALID: 1,\n TRUST_IS_NOT_TIME_NESTED: 2,\n TRUST_IS_REVOKED: 4,\n TRUST_IS_NOT_SIGNATURE_VALID: 8,\n TRUST_IS_NOT_VALID_FOR_USAGE: 16,\n TRUST_IS_UNTRUSTED_ROOT: 32,\n TRUST_REVOCATION_STATUS_UNKNOWN: 64,\n TRUST_IS_CYCLIC: 128,\n TRUST_IS_PARTIAL_CHAIN: 65536,\n TRUST_CTL_IS_NOT_TIME_VALID: 131072,\n TRUST_CTL_IS_NOT_SIGNATURE_VALID: 262144,\n TRUST_CTL_IS_NOT_VALID_FOR_USAGE: 524288,\n },\n // CAPICOM_PROPID enumeration\n PropId: {\n CAPICOM_PROPID_UNKNOWN: 0,\n CAPICOM_PROPID_KEY_PROV_HANDLE: 1,\n CAPICOM_PROPID_KEY_PROV_INFO: 2,\n CAPICOM_PROPID_SHA1_HASH: 3,\n CAPICOM_PROPID_HASH_PROP: 3,\n CAPICOM_PROPID_MD5_HASH: 4,\n CAPICOM_PROPID_KEY_CONTEXT: 5,\n CAPICOM_PROPID_KEY_SPEC: 6,\n CAPICOM_PROPID_IE30_RESERVED: 7,\n CAPICOM_PROPID_PUBKEY_HASH_RESERVED: 8,\n CAPICOM_PROPID_ENHKEY_USAGE: 9,\n CAPICOM_PROPID_CTL_USAGE: 9,\n CAPICOM_PROPID_NEXT_UPDATE_LOCATION: 10,\n CAPICOM_PROPID_FRIENDLY_NAME: 11,\n CAPICOM_PROPID_PVK_FILE: 12,\n CAPICOM_PROPID_DESCRIPTION: 13,\n CAPICOM_PROPID_ACCESS_STATE: 14,\n CAPICOM_PROPID_SIGNATURE_HASH: 15,\n CAPICOM_PROPID_SMART_CARD_DATA: 16,\n CAPICOM_PROPID_EFS: 17,\n CAPICOM_PROPID_FORTEZZA_DATA: 18,\n CAPICOM_PROPID_ARCHIVED: 19,\n CAPICOM_PROPID_KEY_IDENTIFIER: 20,\n CAPICOM_PROPID_AUTO_ENROLL: 21,\n CAPICOM_PROPID_PUBKEY_ALG_PARA: 22,\n CAPICOM_PROPID_CROSS_CERT_DIST_POINTS: 23,\n CAPICOM_PROPID_ISSUER_PUBLIC_KEY_MD5_HASH: 24,\n CAPICOM_PROPID_SUBJECT_PUBLIC_KEY_MD5_HASH: 25,\n CAPICOM_PROPID_ENROLLMENT: 26,\n CAPICOM_PROPID_DATE_STAMP: 27,\n CAPICOM_PROPID_ISSUER_SERIAL_NUMBER_MD5_HASH: 28,\n CAPICOM_PROPID_SUBJECT_NAME_MD5_HASH: 29,\n CAPICOM_PROPID_EXTENDED_ERROR_INFO: 30,\n CAPICOM_PROPID_RENEWAL: 64,\n CAPICOM_PROPID_ARCHIVED_KEY_HASH: 65,\n CAPICOM_PROPID_FIRST_RESERVED: 66,\n CAPICOM_PROPID_LAST_RESERVED: 0x00007FFF,\n CAPICOM_PROPID_FIRST_USER: 0x00008000,\n CAPICOM_PROPID_LAST_USER: 0x0000FFFF\n },\n // CADESCOM_XML_SIGNATURE_TYPE enumeration\n SignatureType: {\n CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED: 0,\n CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING: 1,\n CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE: 2\n },\n // CADESCOM_HASH_ALGORITHM enumeration\n HashAlgorithm: {\n CADESCOM_HASH_ALGORITHM_CP_GOST_3411: 100,\n CADESCOM_HASH_ALGORITHM_MD2: 1,\n CADESCOM_HASH_ALGORITHM_MD4: 2,\n CADESCOM_HASH_ALGORITHM_MD5: 3,\n CADESCOM_HASH_ALGORITHM_SHA_256: 4,\n CADESCOM_HASH_ALGORITHM_SHA_384: 5,\n CADESCOM_HASH_ALGORITHM_SHA_512: 6,\n CADESCOM_HASH_ALGORITHM_SHA1: 0\n },\n CadesType: {\n CADESCOM_CADES_DEFAULT: 0,\n CADESCOM_CADES_BES: 1,\n CADESCOM_CADES_X_LONG_TYPE_1: 0x5d\n },\n ContentEncoding: {\n CADESCOM_BASE64_TO_BINARY: 0x01,\n CADESCOM_STRING_TO_UCS2LE: 0x00\n },\n StoreNames: {\n CAPICOM_MY_STORE: 'My'\n },\n Chain: {\n CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT: 0,\n CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN: 1,\n CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY: 2\n },\n GostXmlDSigUrls: {\n XmlDsigGost3410Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411',\n XmlDsigGost3411Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411',\n XmlDsigGost3410UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411',\n XmlDsigGost3411UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr3411'\n }\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./constants.js\n ** module id = 7\n ** module chunks = 1 2\n **/","var cryptoCommon = require('./common'),\n cryptoConstants = require('./constants'),\n\n _certProto = {\n /**\n * Проверяет, валиден ли сертификат\n * */\n isValid: function isValid() {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n var result;\n\n try {\n result = cert.IsValid();\n result = result.Result;\n } catch (err) {\n reject('Ошибка при проверке сертификата: ', err.message);\n return;\n }\n\n resolve(result);\n });\n },\n\n /**\n * Достает указанное свойство у сертификата\n * */\n getProp: function (propName) {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n var result;\n\n try {\n result = cert[propName];\n } catch (err) {\n reject('Ошибка при обращении к свойству сертификата: ', err.message);\n return;\n }\n\n resolve(result);\n });\n },\n\n /**\n * Экспорт base64 представления сертификата пользователя\n * */\n exportBase64: function exportBase64() {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n var base64;\n\n try {\n base64 = cert.Export(0);\n } catch (err) {\n reject('Ошибка при экспорте сертификата: ', err.message);\n return;\n }\n\n resolve(base64);\n });\n },\n\n /**\n * Возвращает информацию об алгоритме\n * */\n getAlgorithm: function getAlgorithm() {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n var result = {},\n algorithm;\n\n try {\n algorithm = cert.PublicKey();\n algorithm = algorithm.Algorithm;\n\n result.algorithm = algorithm.FriendlyName;\n result.oid = algorithm.Value;\n } catch (err) {\n reject('Ошибка при получении алгоритма: ', err.message);\n return;\n }\n\n resolve(result);\n });\n },\n\n /**\n * Разбирает SubjectName сертификата по тэгам\n * */\n getOwnerInfo: function getOwnerInfo() {\n return getCertInfo.call(this, cryptoCommon.subjectNameTagsTranslations, 'SubjectName');\n },\n\n /**\n * Разбирает IssuerName сертификата по тэгам\n * */\n getIssuerInfo: function getIssuerInfo() {\n return getCertInfo.call(this, cryptoCommon.issuerNameTagsTranslations, 'IssuerName');\n },\n\n /**\n * Получение OID сертификата\n * Возвращает массив OID (улучшенного ключа)\n * */\n getExtendedKeyUsage: function getExtendedKeyUsage() {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n var OIDS = [],\n count,\n item;\n\n try {\n count = cert.ExtendedKeyUsage();\n count = count.EKUs;\n count = count.Count;\n\n if (count > 0) {\n while (count > 0) {\n item = cert.ExtendedKeyUsage();\n item = item.EKUs;\n item = item.Item(count);\n item = item.OID;\n\n OIDS.push(item);\n\n count--;\n }\n }\n } catch (err) {\n reject('Ошибка при получении ОИД\\'ов: ', err.message);\n return;\n }\n\n resolve(OIDS);\n });\n },\n\n getDecodedExtendedKeyUsage: cryptoCommon.getDecodedExtendedKeyUsage,\n\n hasExtendedKeyUsage: cryptoCommon.hasExtendedKeyUsage\n },\n\n _certListCache;\n\n/**\n * Проверяет корректность настроек ЭП на машине\n * */\nfunction isValidEDSSettings() {\n return new Promise(function (resolve, reject) {\n var result;\n\n try {\n result = cadesplugin.CreateObject('CAdESCOM.About');\n } catch (error) {\n reject('Настройки ЭП на данной машине не верны');\n }\n\n resolve();\n });\n}\n\n/**\n * Получить сертификат в формате cades по хэшу\n * */\nfunction getCadesCert(hash) {\n return new Promise(function (resolve, reject) {\n var oStore = cadesplugin.CreateObject('CAdESCOM.Store'),\n certs,\n certCnt,\n cert;\n\n if (!oStore) {\n reject('Не удалось получить доступ к хранилищу сертификатов');\n return;\n }\n\n // Открываем хранилище\n try {\n oStore.Open(\n cadesplugin.CAPICOM_CURRENT_USER_STORE,\n cadesplugin.CAPICOM_MY_STORE,\n cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED\n );\n } catch (err) {\n reject('Ошибка при открытии хранилища: ' + err.message);\n return;\n }\n\n // Получаем доступ к сертификатам\n try {\n certs = oStore.Certificates;\n certCnt = certs.Count;\n } catch (err) {\n reject('Ошибка получения списка сертификатов: ' + err.message);\n return;\n }\n\n if (!certCnt) {\n reject('Нет доступных сертификатов');\n return;\n }\n\n // Получаем сертификат по хэшу\n try {\n certs = certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH, hash);\n\n if (certs.Count) {\n cert = certs.Item(1);\n } else {\n throw new Error('Нет доступных сертификатов');\n }\n } catch (err) {\n reject('Не удалось получить сертификат по хэшу: ' + err.message);\n return;\n }\n\n oStore.Close();\n\n resolve(cert);\n });\n}\n\n/**\n * Разбирает информацию сертификата по тэгам\n * */\nfunction getCertInfo(tags, propName) {\n var cert = this._cert;\n\n return new Promise(function (resolve, reject) {\n var propInfo;\n\n try {\n propInfo = cert[propName];\n } catch (err) {\n reject('Ошибка при извлечении данных из сертификата: ', err.message);\n return;\n }\n\n resolve(cryptoCommon.parseCertInfo(tags, propInfo));\n });\n}\n\n/**\n * Возвращает список сертификатов, доступных в системе\n *\n * @param {Boolean} [resetCache=false] -- нужно ли сбросить кэш списка сертификатов\n * @returns {Promise} -- со списком сертификатов {Array}\n * */\nfunction getCertsList(resetCache) {\n return new Promise(function (resolve, reject) {\n if (!resetCache && _certListCache) {\n resolve(_certListCache);\n return;\n }\n\n var oStore = cadesplugin.CreateObject('CAdESCOM.Store'),\n result = [],\n certs,\n count,\n item;\n\n // Открываем хранилище\n try {\n oStore.Open(\n cadesplugin.CAPICOM_CURRENT_USER_STORE,\n cadesplugin.CAPICOM_MY_STORE,\n cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED\n );\n } catch (err) {\n reject('Ошибка при открытии хранилища: ' + err.message);\n return;\n }\n\n // Получаем доступ к сертификатам\n try {\n certs = oStore.Certificates;\n\n if (certs) {\n certs = certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID);\n /**\n * Не рассматриваются сертификаты, в которых отсутствует закрытый ключ\n * или не действительны на данный момент\n * */\n certs = certs.Find(\n cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY,\n cryptoConstants.PropId.CAPICOM_PROPID_KEY_PROV_INFO\n );\n\n count = certs.Count;\n }\n } catch (err) {\n reject('Ошибка получения списка сертификатов: ' + err.message);\n return;\n }\n\n if (!count) {\n reject('Нет доступных сертификатов');\n return;\n }\n\n try {\n while (count) {\n item = certs.Item(count);\n\n result.push(Object.assign(Object.create(_certProto), {\n _cert: item,\n thumbprint: item.Thumbprint,\n subjectName: item.SubjectName,\n issuerName: item.IssuerName,\n validFrom: item.ValidFromDate,\n validTo: item.ValidToDate\n }));\n\n count--;\n }\n } catch (err) {\n reject('Ошибка обработки сертификатов: ' + err.message);\n return;\n }\n\n oStore.Close();\n\n _certListCache = cryptoCommon.prepareCertsInfo(result);\n\n resolve(_certListCache);\n });\n}\n\n/**\n * Получить сертификат по хэшу\n * */\nfunction getCert(hash) {\n return new Promise(function (resolve, reject) {\n if (!hash) {\n reject('Хэш не указан');\n return;\n }\n\n getCertsList().then(function (list) {\n var foundCert;\n\n list.some(function (cert) {\n if (hash === cert.thumbprint) {\n foundCert = cert;\n return true;\n }\n });\n\n if (foundCert) {\n resolve(foundCert);\n } else {\n reject('Сертификат с хэшем: \"' + hash + '\" не найден');\n }\n }, reject);\n });\n}\n\n/**\n * Создает подпись base64 строки по hash'у сертификата\n *\n * @param {String} hash -- fingerprint (thumbprint) сертификата\n * @param {String} dataBase64 -- строковые данные в формате base64\n * @param {String} signType -- тип подписи открепленная (true) / присоединенная (false) (default: false)\n * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String}\n * */\nfunction signData(hash, dataBase64, signType) {\n return new Promise(function (resolve, reject) {\n getCadesCert(hash).then(function (cert) {\n var clientTime = new Date(),\n oAttrs = cadesplugin.CreateObject('CADESCOM.CPAttribute'),\n oSignedData = cadesplugin.CreateObject('CAdESCOM.CadesSignedData'),\n oSigner = cadesplugin.CreateObject('CAdESCOM.CPSigner'),\n attrs,\n signature;\n\n clientTime = cryptoCommon.getDateObj(clientTime);\n\n try {\n oAttrs.Name = cryptoConstants.Time.AUTHENTICATED_ATTRIBUTE_SIGNING_TIME;\n oAttrs.Value = clientTime;\n } catch (err) {\n reject('Ошибка при установке данных подписи: ' + err.message);\n return;\n }\n\n // Задаем настройки для подписи\n try {\n oSigner.Certificate = cert;\n attrs = oSigner.AuthenticatedAttributes2;\n attrs.Add(oAttrs);\n oSignedData.ContentEncoding = cadesplugin.CADESCOM_BASE64_TO_BINARY;\n oSignedData.Content = dataBase64;\n oSigner.Options = cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY;\n } catch (err) {\n reject('Не удалось установить настройки для подписи: ' + err.message);\n return;\n }\n\n try {\n signature = oSignedData.SignCades(\n oSigner,\n cadesplugin.CADESCOM_CADES_BES,\n Boolean(signType)\n );\n } catch (err) {\n reject('Не удалось создать подпись: ' + err.message);\n return;\n }\n\n resolve(signature);\n });\n });\n}\n\n/**\n * Создает подпись XML строки по hash'у сертификата\n *\n * @param {String} hash -- fingerprint (thumbprint) сертификата\n * @param {String} dataXML -- данные в формате XML\n * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String}\n * */\nfunction signDataXML(hash, dataXML) {\n return new Promise(function (resolve, reject) {\n getCadesCert(hash).then(function (cert) {\n var oSigner = cadesplugin.CreateObject('CAdESCOM.CPSigner'),\n signerXML = cadesplugin.CreateObject('CAdESCOM.SignedXML'),\n cnts = cryptoConstants,\n signature;\n\n // Задаем настройки для подписи\n try {\n oSigner.Certificate = cert;\n // Добавляем данные для подписи\n signerXML.Content = dataXML;\n // Устанавливаем тип подписи\n signerXML.SignatureType = cnts.SignatureType.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED;\n // Устанавливаем алгоритм подписи\n signerXML.SignatureMethod = cnts.GostXmlDSigUrls.XmlDsigGost3410Url;\n // Устанавливаем алгоритм хэширования\n signerXML.DigestMethod = cnts.GostXmlDSigUrls.XmlDsigGost3411Url;\n } catch (err) {\n reject('Не удалось установить настройки для подписи: ' + err.message);\n return;\n }\n\n try {\n signature = signerXML.Sign(oSigner);\n } catch (err) {\n reject('Не удалось создать подпись: ' + err.message);\n return;\n }\n\n resolve(signature);\n });\n });\n}\n\n/**\n * Возвращает информацию о версии CSP и плагина\n * */\nfunction getSystemInfo() {\n var sysInfo = cryptoCommon.getEnvInfo();\n\n return new Promise(function (resolve, reject) {\n var e;\n\n try {\n e = cadesplugin.CreateObject('CAdESCOM.About');\n\n sysInfo.cadesVersion = e.PluginVersion;\n // Возможен вызов в ранних версиях в виде sysInfo.cspVersion = e.CSPVersion('', 75);\n sysInfo.cspVersion = e.CSPVersion();\n\n if (!sysInfo.cadesVersion) {\n sysInfo.cadesVersion = e.Version;\n }\n\n sysInfo.cadesVersion = sysInfo.cadesVersion.toString();\n sysInfo.cspVersion = sysInfo.cspVersion.toString();\n\n resolve(sysInfo);\n } catch (err) {\n reject('Ошибка при получении информации о системе: ', err.message);\n }\n });\n}\n\n/**\n * Promise обертка для синхронного вызова проверки версии CSP\n * */\nfunction isValidCSPVersion(version) {\n return new Promise(function (resolve) {\n resolve(cryptoCommon.isValidCSPVersion(version));\n });\n}\n\n/**\n * Promise обертка для синхронного вызова проверки версии плагина\n * */\nfunction isValidCadesVersion(version) {\n return new Promise(function (resolve) {\n resolve(cryptoCommon.isValidCadesVersion(version));\n });\n}\n\nmodule.exports = {\n isValidEDSSettings: isValidEDSSettings,\n getCertsList: getCertsList,\n getCert: getCert,\n signData: signData,\n signDataXML: signDataXML,\n getSystemInfo: getSystemInfo,\n isValidCSPVersion: isValidCSPVersion,\n isValidCadesVersion: isValidCadesVersion\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./apiSync.js\n ** module id = 8\n ** module chunks = 2\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/crypto-pro.js b/dist/crypto-pro.js new file mode 100644 index 0000000..f45b761 --- /dev/null +++ b/dist/crypto-pro.js @@ -0,0 +1,845 @@ +var CryptoPro = +/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ var parentJsonpFunction = window["webpackJsonpCryptoPro"]; +/******/ window["webpackJsonpCryptoPro"] = function webpackJsonpCallback(chunkIds, moreModules) { +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, callbacks = []; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(installedChunks[chunkId]) +/******/ callbacks.push.apply(callbacks, installedChunks[chunkId]); +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules); +/******/ while(callbacks.length) +/******/ callbacks.shift().call(null, __webpack_require__); +/******/ +/******/ }; +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // object to store loaded and loading chunks +/******/ // "0" means "already loaded" +/******/ // Array means "loading", array contains callbacks +/******/ var installedChunks = { +/******/ 0:0 +/******/ }; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = function requireEnsure(chunkId, callback) { +/******/ // "0" is the signal for "already loaded" +/******/ if(installedChunks[chunkId] === 0) +/******/ return callback.call(null, __webpack_require__); +/******/ +/******/ // an array means "currently loading". +/******/ if(installedChunks[chunkId] !== undefined) { +/******/ installedChunks[chunkId].push(callback); +/******/ } else { +/******/ // start chunk loading +/******/ installedChunks[chunkId] = [callback]; +/******/ var head = document.getElementsByTagName('head')[0]; +/******/ var script = document.createElement('script'); +/******/ script.type = 'text/javascript'; +/******/ script.charset = 'utf-8'; +/******/ script.async = true; +/******/ +/******/ script.src = __webpack_require__.p + "" + chunkId + ".crypto-pro.js"; +/******/ head.appendChild(script); +/******/ } +/******/ }; +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + __webpack_require__(1); + + var global = Function('return this')(), + canPromise = Boolean(global.Promise), + cadesplugin = global.cadesplugin, + canAsync = Boolean(cadesplugin.CreateObjectAsync), + CryptoProConfig = global.CryptoProConfig, + cryptoService, + _errorMsg = '', + _isLoaded = false, + _onLoadCbQueue = []; + + function execOnloadQueue() { + _onLoadCbQueue.forEach(function (callback) { + callback(); + }); + } + + function passToWaitOnLoad(callback) { + if (Object.prototype.toString.call(callback) === '[object Function]') { + _onLoadCbQueue.push(callback); + } + } + + function callOnLoad(method) { + _isLoaded ? method() : passToWaitOnLoad(method); + } + + function finishLoading() { + _isLoaded = true; + + execOnloadQueue(); + } + + function call() { + var args = Array.prototype.slice.call(arguments), + methodName = args.shift(); + + return new Promise(function (resolve, reject) { + callOnLoad(function () { + var method; + + if (_errorMsg) { + reject(_errorMsg); + return; + } + + method = cryptoService[methodName]; + + if (!method) { + reject('Метод "' + methodName + '" не доступен'); + return; + } + + method.apply(null, args).then(resolve, reject); + }); + }); + } + + if (cadesplugin) { + canAsync = Boolean(cadesplugin.CreateObjectAsync); + + // Уровень отладки (LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_ERROR) + cadesplugin.set_log_level(cadesplugin.LOG_LEVEL_ERROR); + + // Получаем указанные конфиги + if (CryptoProConfig && CryptoProConfig.publicPath) { + __webpack_require__.p = CryptoProConfig.publicPath; + } else { + throw new Error('Не указан путь к компонентам CryptoPro'); + } + + if (canPromise) { + cadesplugin.then( + function () { + if (canAsync) { + __webpack_require__.e/* nsure */(1, function () { + cryptoService = __webpack_require__(2); + finishLoading(); + }); + } else { + __webpack_require__.e/* nsure */(2, function () { + cryptoService = __webpack_require__(8); + finishLoading(); + }); + } + }, + + function () { + _errorMsg = 'КриптоПРО ЭЦП Browser Plug-In не доступен'; + finishLoading(); + } + ); + } else { + throw new Error('Не поддерживаются промисы. Необходим полифилл.'); + } + } else { + throw new Error('Не подключен модуль для работы с cades plugin'); + } + + module.exports = { + call: call + }; + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + ;(function () { + /** + * Это переделанная версия cadesplugin_api.js с сайта Крипто ПРО, + * в которую добавлена поддержка IE-8. + * + * Обсуждение: + * https://www.cryptopro.ru/forum2/default.aspx?g=posts&t=9271 + * + * Оригинальный файл: + * https://www.cryptopro.ru/sites/default/files/products/cades/cadesplugin_api.js + * */ + var pluginObject, + plugin_resolved = 0, + plugin_reject, + plugin_resolve, + isOpera = 0, + isYaBrowser = 0, + failed_extensions = 0, + canPromise = Boolean(window.Promise), + cadesplugin; + + if (window.cadesplugin) { + return; + } + + if (canPromise) { + cadesplugin = new Promise(function (resolve, reject) { + plugin_resolve = resolve; + plugin_reject = reject; + }); + } else { + cadesplugin = {}; + } + + function cpcsp_console_log(level, msg) { + if (level <= cadesplugin.current_log_level) { + if (level == cadesplugin.LOG_LEVEL_DEBUG) { + console.log('DEBUG: %s', msg); + } + + if (level == cadesplugin.LOG_LEVEL_INFO) { + console.info('INFO: %s', msg); + } + + if (level == cadesplugin.LOG_LEVEL_ERROR) { + console.error('ERROR: %s', msg); + } + } + } + + function set_log_level(level) { + var isSetLoglevel = (level == cadesplugin.LOG_LEVEL_DEBUG) + || (level == cadesplugin.LOG_LEVEL_INFO) + || (level == cadesplugin.LOG_LEVEL_ERROR); + + if (!isSetLoglevel) { + cpcsp_console_log(cadesplugin.LOG_LEVEL_ERROR, 'cadesplugin_api.js: Incorrect log_level: ' + level); + + return; + } + + cadesplugin.current_log_level = level; + + if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_DEBUG) { + cpcsp_console_log(cadesplugin.LOG_LEVEL_INFO, 'cadesplugin_api.js: log_level = DEBUG'); + } + + if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_INFO) { + cpcsp_console_log(cadesplugin.LOG_LEVEL_INFO, 'cadesplugin_api.js: log_level = INFO'); + } + + if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_ERROR) { + cpcsp_console_log(cadesplugin.LOG_LEVEL_INFO, 'cadesplugin_api.js: log_level = ERROR'); + } + + if (isChromiumBased()) { + if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_DEBUG) { + window.postMessage('set_log_level=debug', '*'); + } + + if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_INFO) { + window.postMessage('set_log_level=info', '*'); + } + + if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_ERROR) { + window.postMessage('set_log_level=error', '*'); + } + } + } + + function set_constantValues() { + cadesplugin.CAPICOM_LOCAL_MACHINE_STORE = 1; + cadesplugin.CAPICOM_CURRENT_USER_STORE = 2; + cadesplugin.CAPICOM_MY_STORE = 'My'; + cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2; + cadesplugin.CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1; + cadesplugin.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED = 0; + cadesplugin.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING = 1; + cadesplugin.CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE = 2; + cadesplugin.XmlDsigGost3410UrlObsolete = 'http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411'; + cadesplugin.XmlDsigGost3411UrlObsolete = 'http://www.w3.org/2001/04/xmldsig-more#gostr3411'; + cadesplugin.XmlDsigGost3410Url = 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411'; + cadesplugin.XmlDsigGost3411Url = 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411'; + cadesplugin.CADESCOM_CADES_DEFAULT = 0; + cadesplugin.CADESCOM_CADES_BES = 1; + cadesplugin.CADESCOM_CADES_T = 0x5; + cadesplugin.CADESCOM_CADES_X_LONG_TYPE_1 = 0x5d; + cadesplugin.CADESCOM_ENCODE_BASE64 = 0; + cadesplugin.CADESCOM_ENCODE_BINARY = 1; + cadesplugin.CADESCOM_ENCODE_ANY = -1; + cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT = 0; + cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN = 1; + cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY = 2; + cadesplugin.CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME = 0; + cadesplugin.CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME = 1; + cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH = 0; + cadesplugin.CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1; + cadesplugin.CAPICOM_CERTIFICATE_FIND_ISSUER_NAME = 2; + cadesplugin.CAPICOM_CERTIFICATE_FIND_ROOT_NAME = 3; + cadesplugin.CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME = 4; + cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENSION = 5; + cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY = 6; + cadesplugin.CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY = 7; + cadesplugin.CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY = 8; + cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID = 9; + cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID = 10; + cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED = 11; + cadesplugin.CAPICOM_CERTIFICATE_FIND_KEY_USAGE = 12; + cadesplugin.CAPICOM_DIGITAL_SIGNATURE_KEY_USAGE = 128; + cadesplugin.CAPICOM_PROPID_ENHKEY_USAGE = 9; + cadesplugin.CAPICOM_OID_OTHER = 0; + cadesplugin.CAPICOM_OID_KEY_USAGE_EXTENSION = 10; + cadesplugin.CAPICOM_EKU_CLIENT_AUTH = 2; + cadesplugin.CAPICOM_EKU_SMARTCARD_LOGON = 5; + cadesplugin.CAPICOM_EKU_OTHER = 0; + cadesplugin.CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0; + cadesplugin.CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME = 1; + cadesplugin.CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION = 2; + cadesplugin.CADESCOM_ATTRIBUTE_OTHER = -1; + cadesplugin.CADESCOM_STRING_TO_UCS2LE = 0; + cadesplugin.CADESCOM_BASE64_TO_BINARY = 1; + cadesplugin.CADESCOM_DISPLAY_DATA_NONE = 0; + cadesplugin.CADESCOM_DISPLAY_DATA_CONTENT = 1; + cadesplugin.CADESCOM_DISPLAY_DATA_ATTRIBUTE = 2; + cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_RC2 = 0; + cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_RC4 = 1; + cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_DES = 2; + cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_3DES = 3; + cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_AES = 4; + cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_GOST_28147_89 = 25; + cadesplugin.CADESCOM_HASH_ALGORITHM_SHA1 = 0; + cadesplugin.CADESCOM_HASH_ALGORITHM_MD2 = 1; + cadesplugin.CADESCOM_HASH_ALGORITHM_MD4 = 2; + cadesplugin.CADESCOM_HASH_ALGORITHM_MD5 = 3; + cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_256 = 4; + cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_384 = 5; + cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_512 = 6; + cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411 = 100; + cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256 = 101; + cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_512 = 102; + cadesplugin.LOG_LEVEL_DEBUG = 4; + cadesplugin.LOG_LEVEL_INFO = 2; + cadesplugin.LOG_LEVEL_ERROR = 1; + } + + function async_spawn(generatorFunc) { + var generator = generatorFunc(Array.prototype.slice.call(arguments, 1)), + onFulfilled = continuer.bind(continuer, 'next'), + onRejected = continuer.bind(continuer, 'throw'); + + function continuer(verb, arg) { + var result; + + try { + result = generator[verb](arg); + } catch (err) { + return Promise.reject(err); + } + + if (result.done) { + return result.value; + } else { + return Promise.resolve(result.value).then(onFulfilled, onRejected); + } + } + + return onFulfilled(); + } + + function isIE() { + return navigator.appName === 'Microsoft Internet Explorer' // IE < 11 + || navigator.userAgent.match(/Trident\/./i); // IE 11 + } + + function isIOS() { + return navigator.userAgent.match(/ipod/i) + || navigator.userAgent.match(/ipad/i) + || navigator.userAgent.match(/iphone/i); + } + + function isChromiumBased() { + var retVal_chrome = navigator.userAgent.match(/chrome/i), + + // некоторых версиях IE8 с подключенным плагином chromeframe он определяется как + // Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; chromeframe/29.0.1547.67; + // и может попадать в ветку Chrome + retVal_chromeframe = navigator.userAgent.match(/chromeframe/i); + + isOpera = navigator.userAgent.match(/opr/i); + isYaBrowser = navigator.userAgent.match(/YaBrowser/i); + + if (retVal_chrome == null) { + // В Firefox и IE работаем через NPAPI + return false; + } else { + // В Chrome и Opera работаем через асинхронную версию + if (retVal_chrome.length > 0 || isOpera != null) { + return true; + } + } + + return false; + } + + // Функция активации объектов КриптоПро ЭЦП Browser plug-in + function CreateObject(name) { + if (isIOS()) { + // На iOS для создания объектов используется функция + // call_ru_cryptopro_npcades_10_native_bridge, определенная в IOS_npcades_supp.js + return call_ru_cryptopro_npcades_10_native_bridge('CreateObject', [name]); + } + + if (isIE()) { + // В Internet Explorer создаются COM-объекты + if (name.match(/X509Enrollment/i)) { + try { + // Объекты CertEnroll создаются через CX509EnrollmentWebClassFactory + var objCertEnrollClassFactory = document.getElementById('certEnrollClassFactory'); + return objCertEnrollClassFactory.CreateObject(name); + } catch (e) { + throw( + 'Для создания обьектов X509Enrollment следует настроить ' + + 'веб-узел на использование проверки подлинности по протоколу HTTPS' + ); + } + } + + // Объекты CAPICOM и CAdESCOM создаются через CAdESCOM.WebClassFactory + try { + var objWebClassFactory = document.getElementById('webClassFactory'); + + return objWebClassFactory.CreateObject(name); + } catch (e) { + try { + // Для версий плагина ниже 2.0.12538 + return new ActiveXObject(name); + } catch (e) { + var mimetype = navigator.mimeTypes['application/x-cades']; + + if (mimetype) { + if (mimetype.enabledPlugin) { + console.log( + 'EDS:', + 'Плагин КриптоПРО ЭЦП browser plug-in загружен,', + 'но не создаются обьекты' + ); + } else { + console.log('EDS:', 'Ошибка при загрузке плагина КриптоПРО ЭЦП browser plug-in'); + } + } else { + console.log('EDS:', 'Плагин КриптоПРО ЭЦП browser plug-in недоступен'); + } + } + } + } + + // В Firefox, Safari создаются объекты NPAPI + return pluginObject.CreateObject(name); + } + + // Функция активации асинхронных объектов КриптоПро ЭЦП Browser plug-in + function CreateObjectAsync(name) { + return pluginObject.CreateObjectAsync(name); + } + + // Функции для IOS + var ru_cryptopro_npcades_10_native_bridge = { + callbacksCount: 1, + callbacks: {}, + + // Automatically called by native layer when a result is available + resultForCallback: function resultForCallback(callbackId, resultArray) { + var callback = ru_cryptopro_npcades_10_native_bridge.callbacks[callbackId]; + + if (!callback) { + return; + } + + callback.apply(null, resultArray); + }, + + // Use this in javascript to request native objective-c code + // functionName : string (I think the name is explicit :p) + // args : array of arguments + // callback : function with n-arguments that is going to be called when the native code returned + call: function call(functionName, args, callback) { + var hasCallback = callback && typeof callback == 'function', + callbackId = hasCallback ? ru_cryptopro_npcades_10_native_bridge.callbacksCount++ : 0, + iframe, + arrObjs; + + if (hasCallback) { + ru_cryptopro_npcades_10_native_bridge.callbacks[callbackId] = callback; + } + + iframe = document.createElement('IFRAME'); + + arrObjs = new Array('_CPNP_handle'); + + try { + iframe.setAttribute( + 'src', + 'cpnp-js-call:' + + functionName + ':' + callbackId + ':' + encodeURIComponent(JSON.stringify(args, arrObjs)) + ); + } catch (e) { + alert(e); + } + + document.documentElement.appendChild(iframe); + + iframe.parentNode.removeChild(iframe); + iframe = null; + } + }; + + function call_ru_cryptopro_npcades_10_native_bridge(functionName, array) { + var tmpobj, + ex; + + ru_cryptopro_npcades_10_native_bridge.call(functionName, array, function (e, response) { + ex = e; + var str = 'tmpobj=' + response; + + eval(str); + + if (typeof (tmpobj) == 'string') { + tmpobj = tmpobj.replace(/\\\n/gm, '\n'); + tmpobj = tmpobj.replace(/\\\r/gm, '\r'); + } + }); + + if (ex) { + throw ex; + } + + return tmpobj; + } + + // Выводим окно поверх других с предложением установить расширение для Opera. + // Если установленна переменная cadesplugin_skip_extension_install - не предлагаем установить расширение + function install_opera_extension() { + if (!window.cadesplugin_skip_extension_install) { + document.addEventListener('DOMContentLoaded', function () { + var ovr = document.createElement('div'); + + ovr.id = 'cadesplugin_ovr'; + ovr.style = [ + 'visibility: hidden; position: fixed; left: 0px; top: 0px;', + 'width:100%; height:100%; background-color: rgba(0,0,0,0.7)' + ].join(' '); + + ovr.innerHTML = '\ +
\ + \ +

\ + Для работы КриптоПро ЭЦП Browser plugin на данном сайте необходимо установить\ + расширение из каталога дополнений Opera.\ +

\ +

\ +
\ + '; + + document.getElementsByTagName('Body')[0].appendChild(ovr); + + var btn_install = document.getElementById('cadesplugin_install'); + + btn_install.addEventListener('click', function (event) { + opr.addons.installExtension('epebfcehmdedogndhlcacafjaacknbcm', + function () { + document.getElementById('cadesplugin_ovr').style.visibility = 'hidden'; + location.reload(); + }, + function () {} + ); + }); + + document.getElementById('cadesplugin_close_install').addEventListener('click', function () { + plugin_loaded_error('Плагин недоступен'); + document.getElementById('cadesplugin_ovr').style.visibility = 'hidden'; + }); + + ovr.addEventListener('click', function () { + plugin_loaded_error('Плагин недоступен'); + document.getElementById('cadesplugin_ovr').style.visibility = 'hidden'; + }); + + ovr.style.visibility = 'visible'; + + document.getElementById('cadesplugin_ovr_item').addEventListener('click', function (e) { + e.stopPropagation(); + }); + }); + } else { + plugin_loaded_error('Плагин недоступен'); + } + } + + function extension_onload() { + window.postMessage('cadesplugin_echo_request', '*'); + + window.addEventListener('message', function (event) { + if (event.data != 'cadesplugin_loaded') { + return; + } + + cpcsp_chrome_nmcades.check_chrome_plugin(plugin_loaded, plugin_loaded_error); + }, false); + } + + // Загружаем расширения для Chrome, Opera, YaBrowser + function load_extension() { + var fileref = document.createElement('script'); + + fileref.setAttribute('type', 'text/javascript'); + fileref.setAttribute('src', 'chrome-extension://iifchhfnnmpdbibifmljnfjhpififfog/nmcades_plugin_api.js'); + fileref.onerror = plugin_loaded_error; + fileref.onload = extension_onload; + + document.getElementsByTagName('head')[0].appendChild(fileref); + + fileref = document.createElement('script'); + fileref.setAttribute('type', 'text/javascript'); + fileref.setAttribute('src', 'chrome-extension://epebfcehmdedogndhlcacafjaacknbcm/nmcades_plugin_api.js'); + fileref.onerror = plugin_loaded_error; + fileref.onload = extension_onload; + document.getElementsByTagName('head')[0].appendChild(fileref); + } + + // Загружаем плагин для NPAPI + function load_npapi_plugin() { + var elem = document.createElement('object'); + + elem.setAttribute('id', 'cadesplugin_object'); + elem.setAttribute('type', 'application/x-cades'); + elem.setAttribute('style', 'visibility=hidden'); + document.getElementsByTagName('body')[0].appendChild(elem); + + pluginObject = document.getElementById('cadesplugin_object'); + + if (isIE()) { + var elem1 = document.createElement('object'); + + elem1.setAttribute('id', 'certEnrollClassFactory'); + elem1.setAttribute('classid', 'clsid:884e2049-217d-11da-b2a4-000e7bbb2b09'); + elem1.setAttribute('style', 'visibility=hidden'); + document.getElementsByTagName('body')[0].appendChild(elem1); + + var elem2 = document.createElement('object'); + elem2.setAttribute('id', 'webClassFactory'); + elem2.setAttribute('classid', 'clsid:B04C8637-10BD-484E-B0DA-B8A039F60024'); + elem2.setAttribute('style', 'visibility=hidden'); + + document.getElementsByTagName('body')[0].appendChild(elem2); + } + } + + // Отправляем событие что все ок. + function plugin_loaded() { + plugin_resolved = 1; + if (canPromise) { + plugin_resolve(); + } else { + window.postMessage('cadesplugin_loaded', '*'); + } + } + + // Отправляем событие что сломались. + function plugin_loaded_error(msg) { + if (isChromiumBased()) { + // в асинхронном варианте подключаем оба расширения, если сломались оба пробуем установить для Opera + failed_extensions++; + + if (failed_extensions < 2) { + return; + } + + if (isOpera && (typeof(msg) == 'undefined' || typeof(msg) == 'object')) { + install_opera_extension(); + return; + } + } + + if (typeof(msg) == 'undefined' || typeof(msg) == 'object') { + msg = 'Плагин недоступен'; + } + + plugin_resolved = 1; + + if (canPromise) { + plugin_reject(msg); + } else { + window.postMessage('cadesplugin_load_error', '*'); + } + } + + // проверяем что у нас хоть какое то событие ушло, и если не уходило кидаем еще раз ошибку + function check_load_timeout() { + if (plugin_resolved == 1) { + return; + } + + plugin_resolved = 1; + + if (canPromise) { + plugin_reject('Истекло время ожидания загрузки плагина'); + } else { + window.postMessage('cadesplugin_load_error', '*'); + } + + } + + // Вспомогательная функция для NPAPI + function createPromise(arg) { + return new Promise(arg); + } + + function check_npapi_plugin() { + try { + var oAbout = CreateObject('CAdESCOM.About'); + + plugin_loaded(); + } catch (err) { + document.getElementById('cadesplugin_object').style.display = 'none'; + // Объект создать не удалось, проверим, установлен ли + // вообще плагин. Такая возможность есть не во всех браузерах + var mimetype = navigator.mimeTypes['application/x-cades']; + if (mimetype) { + var plugin = mimetype.enabledPlugin; + if (plugin) { + plugin_loaded_error('Плагин загружен, но не создаются обьекты'); + } else { + plugin_loaded_error('Ошибка при загрузке плагина'); + } + } else { + plugin_loaded_error('Плагин недоступен'); + } + } + } + + // Проверяем работает ли плагин + function check_plugin_working() { + if (isChromiumBased()) { + load_extension(); + } else if (!canPromise) { + window.addEventListener('message', function (event) { + if (event.data != 'cadesplugin_echo_request') { + return; + } + + load_npapi_plugin(); + check_npapi_plugin(); + }, false); + } else { + if (window.addEventListener) { + window.addEventListener('load', function (event) { + load_npapi_plugin(); + check_npapi_plugin(); + }, false); + } else { + load_npapi_plugin(); + check_npapi_plugin(); + } + } + } + + function set_pluginObject(obj) { + pluginObject = obj; + } + + // Export + cadesplugin.JSModuleVersion = '2.0.2'; + cadesplugin.async_spawn = async_spawn; + cadesplugin.set = set_pluginObject; + cadesplugin.set_log_level = set_log_level; + + if (isChromiumBased()) { + cadesplugin.CreateObjectAsync = CreateObjectAsync; + } + + if (!isChromiumBased()) { + cadesplugin.CreateObject = CreateObject; + } + + if (window.cadesplugin_load_timeout) { + setTimeout(check_load_timeout, window.cadesplugin_load_timeout); + } else { + /** + * Даже при слабом интернете плагин успевает загрузиться + * менее чем за секунду, тк отдается из кэша + * */ + setTimeout(check_load_timeout, 20000); + } + + set_constantValues(); + + cadesplugin.current_log_level = cadesplugin.LOG_LEVEL_ERROR; + + window.cadesplugin = cadesplugin; + + check_plugin_working(); + }()); + +/***/ } +/******/ ]); +//# sourceMappingURL=crypto-pro.js.map \ No newline at end of file diff --git a/dist/crypto-pro.js.map b/dist/crypto-pro.js.map new file mode 100644 index 0000000..7691447 --- /dev/null +++ b/dist/crypto-pro.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap 3b36c26c34a4b266bc29","webpack:///./index.js","webpack:///./cades.js"],"names":[],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACzFA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,UAAS;AACT,MAAK;AACL;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB,kBAAiB;AACjB;AACA;AACA;AACA,sBAAqB;AACrB;AACA,cAAa;;AAEb;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,EAAC;AACD;AACA;;AAEA;AACA;AACA,G;;;;;;ACtGA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;;AAEA;AACA;AACA,cAAa;AACb;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,yDAAwD;AACxD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,wCAAuC,UAAU,gBAAgB,aAAa;AAC9E;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,cAAa;AACb;AACA;AACA;AACA,kBAAiB;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA,sBAAqB;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,sBAAqB;;AAErB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,yCAAwC,iBAAiB,WAAW,UAAU;AAC9E,iCAAgC,aAAa;AAC7C;;AAEA;AACA;AACA,2CAA0C;AAC1C,qCAAoC;AACpC,2CAA0C;AAC1C,+CAA8C;AAC9C,+CAA8C;AAC9C,sCAAqC;AACrC,2CAA0C;AAC1C,oCAAmC;AACnC;AACA;AACA;AACA,6CAA4C,iBAAiB,yBAAyB,WAAW;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,0BAAyB;AACzB;AACA;AACA,kBAAiB;;AAEjB;AACA;AACA;AACA,kBAAiB;;AAEjB;AACA;AACA;AACA,kBAAiB;;AAEjB;;AAEA;AACA;AACA,kBAAiB;AACjB,cAAa;AACb,UAAS;AACT;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,UAAS;AACT;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,UAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,UAAS;AACT;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA,cAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA,kBAAiB;AACjB,cAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA,EAAC,I","file":"crypto-pro.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonpCryptoPro\"];\n \twindow[\"webpackJsonpCryptoPro\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n \t\twhile(callbacks.length)\n \t\t\tcallbacks.shift().call(null, __webpack_require__);\n\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// \"0\" means \"already loaded\"\n \t// Array means \"loading\", array contains callbacks\n \tvar installedChunks = {\n \t\t0:0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n \t\t// \"0\" is the signal for \"already loaded\"\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn callback.call(null, __webpack_require__);\n\n \t\t// an array means \"currently loading\".\n \t\tif(installedChunks[chunkId] !== undefined) {\n \t\t\tinstalledChunks[chunkId].push(callback);\n \t\t} else {\n \t\t\t// start chunk loading\n \t\t\tinstalledChunks[chunkId] = [callback];\n \t\t\tvar head = document.getElementsByTagName('head')[0];\n \t\t\tvar script = document.createElement('script');\n \t\t\tscript.type = 'text/javascript';\n \t\t\tscript.charset = 'utf-8';\n \t\t\tscript.async = true;\n\n \t\t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".crypto-pro.js\";\n \t\t\thead.appendChild(script);\n \t\t}\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 3b36c26c34a4b266bc29\n **/","require('./cades');\n\nvar global = Function('return this')(),\n canPromise = Boolean(global.Promise),\n cadesplugin = global.cadesplugin,\n canAsync = Boolean(cadesplugin.CreateObjectAsync),\n CryptoProConfig = global.CryptoProConfig,\n cryptoService,\n _errorMsg = '',\n _isLoaded = false,\n _onLoadCbQueue = [];\n\nfunction execOnloadQueue() {\n _onLoadCbQueue.forEach(function (callback) {\n callback();\n });\n}\n\nfunction passToWaitOnLoad(callback) {\n if (Object.prototype.toString.call(callback) === '[object Function]') {\n _onLoadCbQueue.push(callback);\n }\n}\n\nfunction callOnLoad(method) {\n _isLoaded ? method() : passToWaitOnLoad(method);\n}\n\nfunction finishLoading() {\n _isLoaded = true;\n\n execOnloadQueue();\n}\n\nfunction call() {\n var args = Array.prototype.slice.call(arguments),\n methodName = args.shift();\n\n return new Promise(function (resolve, reject) {\n callOnLoad(function () {\n var method;\n\n if (_errorMsg) {\n reject(_errorMsg);\n return;\n }\n\n method = cryptoService[methodName];\n\n if (!method) {\n reject('Метод \"' + methodName + '\" не доступен');\n return;\n }\n\n method.apply(null, args).then(resolve, reject);\n });\n });\n}\n\nif (cadesplugin) {\n canAsync = Boolean(cadesplugin.CreateObjectAsync);\n\n // Уровень отладки (LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_ERROR)\n cadesplugin.set_log_level(cadesplugin.LOG_LEVEL_ERROR);\n\n // Получаем указанные конфиги\n if (CryptoProConfig && CryptoProConfig.publicPath) {\n __webpack_public_path__ = CryptoProConfig.publicPath;\n } else {\n throw new Error('Не указан путь к компонентам CryptoPro');\n }\n\n if (canPromise) {\n cadesplugin.then(\n function () {\n if (canAsync) {\n require.ensure([], function () {\n cryptoService = require('./apiAsync');\n finishLoading();\n });\n } else {\n require.ensure([], function () {\n cryptoService = require('./apiSync');\n finishLoading();\n });\n }\n },\n\n function () {\n _errorMsg = 'КриптоПРО ЭЦП Browser Plug-In не доступен';\n finishLoading();\n }\n );\n } else {\n throw new Error('Не поддерживаются промисы. Необходим полифилл.');\n }\n} else {\n throw new Error('Не подключен модуль для работы с cades plugin');\n}\n\nmodule.exports = {\n call: call\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./index.js\n ** module id = 0\n ** module chunks = 0\n **/",";(function () {\n /**\n * Это переделанная версия cadesplugin_api.js с сайта Крипто ПРО,\n * в которую добавлена поддержка IE-8.\n *\n * Обсуждение:\n * https://www.cryptopro.ru/forum2/default.aspx?g=posts&t=9271\n *\n * Оригинальный файл:\n * https://www.cryptopro.ru/sites/default/files/products/cades/cadesplugin_api.js\n * */\n var pluginObject,\n plugin_resolved = 0,\n plugin_reject,\n plugin_resolve,\n isOpera = 0,\n isYaBrowser = 0,\n failed_extensions = 0,\n canPromise = Boolean(window.Promise),\n cadesplugin;\n\n if (window.cadesplugin) {\n return;\n }\n\n if (canPromise) {\n cadesplugin = new Promise(function (resolve, reject) {\n plugin_resolve = resolve;\n plugin_reject = reject;\n });\n } else {\n cadesplugin = {};\n }\n\n function cpcsp_console_log(level, msg) {\n if (level <= cadesplugin.current_log_level) {\n if (level == cadesplugin.LOG_LEVEL_DEBUG) {\n console.log('DEBUG: %s', msg);\n }\n\n if (level == cadesplugin.LOG_LEVEL_INFO) {\n console.info('INFO: %s', msg);\n }\n\n if (level == cadesplugin.LOG_LEVEL_ERROR) {\n console.error('ERROR: %s', msg);\n }\n }\n }\n\n function set_log_level(level) {\n var isSetLoglevel = (level == cadesplugin.LOG_LEVEL_DEBUG)\n || (level == cadesplugin.LOG_LEVEL_INFO)\n || (level == cadesplugin.LOG_LEVEL_ERROR);\n\n if (!isSetLoglevel) {\n cpcsp_console_log(cadesplugin.LOG_LEVEL_ERROR, 'cadesplugin_api.js: Incorrect log_level: ' + level);\n\n return;\n }\n\n cadesplugin.current_log_level = level;\n\n if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_DEBUG) {\n cpcsp_console_log(cadesplugin.LOG_LEVEL_INFO, 'cadesplugin_api.js: log_level = DEBUG');\n }\n\n if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_INFO) {\n cpcsp_console_log(cadesplugin.LOG_LEVEL_INFO, 'cadesplugin_api.js: log_level = INFO');\n }\n\n if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_ERROR) {\n cpcsp_console_log(cadesplugin.LOG_LEVEL_INFO, 'cadesplugin_api.js: log_level = ERROR');\n }\n\n if (isChromiumBased()) {\n if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_DEBUG) {\n window.postMessage('set_log_level=debug', '*');\n }\n\n if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_INFO) {\n window.postMessage('set_log_level=info', '*');\n }\n\n if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_ERROR) {\n window.postMessage('set_log_level=error', '*');\n }\n }\n }\n\n function set_constantValues() {\n cadesplugin.CAPICOM_LOCAL_MACHINE_STORE = 1;\n cadesplugin.CAPICOM_CURRENT_USER_STORE = 2;\n cadesplugin.CAPICOM_MY_STORE = 'My';\n cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1;\n cadesplugin.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED = 0;\n cadesplugin.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING = 1;\n cadesplugin.CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE = 2;\n cadesplugin.XmlDsigGost3410UrlObsolete = 'http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411';\n cadesplugin.XmlDsigGost3411UrlObsolete = 'http://www.w3.org/2001/04/xmldsig-more#gostr3411';\n cadesplugin.XmlDsigGost3410Url = 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411';\n cadesplugin.XmlDsigGost3411Url = 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411';\n cadesplugin.CADESCOM_CADES_DEFAULT = 0;\n cadesplugin.CADESCOM_CADES_BES = 1;\n cadesplugin.CADESCOM_CADES_T = 0x5;\n cadesplugin.CADESCOM_CADES_X_LONG_TYPE_1 = 0x5d;\n cadesplugin.CADESCOM_ENCODE_BASE64 = 0;\n cadesplugin.CADESCOM_ENCODE_BINARY = 1;\n cadesplugin.CADESCOM_ENCODE_ANY = -1;\n cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT = 0;\n cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN = 1;\n cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY = 2;\n cadesplugin.CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME = 0;\n cadesplugin.CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME = 1;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH = 0;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_ISSUER_NAME = 2;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_ROOT_NAME = 3;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME = 4;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENSION = 5;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY = 6;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY = 7;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY = 8;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID = 9;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID = 10;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED = 11;\n cadesplugin.CAPICOM_CERTIFICATE_FIND_KEY_USAGE = 12;\n cadesplugin.CAPICOM_DIGITAL_SIGNATURE_KEY_USAGE = 128;\n cadesplugin.CAPICOM_PROPID_ENHKEY_USAGE = 9;\n cadesplugin.CAPICOM_OID_OTHER = 0;\n cadesplugin.CAPICOM_OID_KEY_USAGE_EXTENSION = 10;\n cadesplugin.CAPICOM_EKU_CLIENT_AUTH = 2;\n cadesplugin.CAPICOM_EKU_SMARTCARD_LOGON = 5;\n cadesplugin.CAPICOM_EKU_OTHER = 0;\n cadesplugin.CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0;\n cadesplugin.CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME = 1;\n cadesplugin.CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION = 2;\n cadesplugin.CADESCOM_ATTRIBUTE_OTHER = -1;\n cadesplugin.CADESCOM_STRING_TO_UCS2LE = 0;\n cadesplugin.CADESCOM_BASE64_TO_BINARY = 1;\n cadesplugin.CADESCOM_DISPLAY_DATA_NONE = 0;\n cadesplugin.CADESCOM_DISPLAY_DATA_CONTENT = 1;\n cadesplugin.CADESCOM_DISPLAY_DATA_ATTRIBUTE = 2;\n cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_RC2 = 0;\n cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_RC4 = 1;\n cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_DES = 2;\n cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_3DES = 3;\n cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_AES = 4;\n cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_GOST_28147_89 = 25;\n cadesplugin.CADESCOM_HASH_ALGORITHM_SHA1 = 0;\n cadesplugin.CADESCOM_HASH_ALGORITHM_MD2 = 1;\n cadesplugin.CADESCOM_HASH_ALGORITHM_MD4 = 2;\n cadesplugin.CADESCOM_HASH_ALGORITHM_MD5 = 3;\n cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_256 = 4;\n cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_384 = 5;\n cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_512 = 6;\n cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411 = 100;\n cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256 = 101;\n cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_512 = 102;\n cadesplugin.LOG_LEVEL_DEBUG = 4;\n cadesplugin.LOG_LEVEL_INFO = 2;\n cadesplugin.LOG_LEVEL_ERROR = 1;\n }\n\n function async_spawn(generatorFunc) {\n var generator = generatorFunc(Array.prototype.slice.call(arguments, 1)),\n onFulfilled = continuer.bind(continuer, 'next'),\n onRejected = continuer.bind(continuer, 'throw');\n\n function continuer(verb, arg) {\n var result;\n\n try {\n result = generator[verb](arg);\n } catch (err) {\n return Promise.reject(err);\n }\n\n if (result.done) {\n return result.value;\n } else {\n return Promise.resolve(result.value).then(onFulfilled, onRejected);\n }\n }\n\n return onFulfilled();\n }\n\n function isIE() {\n return navigator.appName === 'Microsoft Internet Explorer' // IE < 11\n || navigator.userAgent.match(/Trident\\/./i); // IE 11\n }\n\n function isIOS() {\n return navigator.userAgent.match(/ipod/i)\n || navigator.userAgent.match(/ipad/i)\n || navigator.userAgent.match(/iphone/i);\n }\n\n function isChromiumBased() {\n var retVal_chrome = navigator.userAgent.match(/chrome/i),\n\n // некоторых версиях IE8 с подключенным плагином chromeframe он определяется как\n // Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; chromeframe/29.0.1547.67;\n // и может попадать в ветку Chrome\n retVal_chromeframe = navigator.userAgent.match(/chromeframe/i);\n\n isOpera = navigator.userAgent.match(/opr/i);\n isYaBrowser = navigator.userAgent.match(/YaBrowser/i);\n\n if (retVal_chrome == null) {\n // В Firefox и IE работаем через NPAPI\n return false;\n } else {\n // В Chrome и Opera работаем через асинхронную версию\n if (retVal_chrome.length > 0 || isOpera != null) {\n return true;\n }\n }\n\n return false;\n }\n\n // Функция активации объектов КриптоПро ЭЦП Browser plug-in\n function CreateObject(name) {\n if (isIOS()) {\n // На iOS для создания объектов используется функция\n // call_ru_cryptopro_npcades_10_native_bridge, определенная в IOS_npcades_supp.js\n return call_ru_cryptopro_npcades_10_native_bridge('CreateObject', [name]);\n }\n\n if (isIE()) {\n // В Internet Explorer создаются COM-объекты\n if (name.match(/X509Enrollment/i)) {\n try {\n // Объекты CertEnroll создаются через CX509EnrollmentWebClassFactory\n var objCertEnrollClassFactory = document.getElementById('certEnrollClassFactory');\n return objCertEnrollClassFactory.CreateObject(name);\n } catch (e) {\n throw(\n 'Для создания обьектов X509Enrollment следует настроить ' +\n 'веб-узел на использование проверки подлинности по протоколу HTTPS'\n );\n }\n }\n\n // Объекты CAPICOM и CAdESCOM создаются через CAdESCOM.WebClassFactory\n try {\n var objWebClassFactory = document.getElementById('webClassFactory');\n\n return objWebClassFactory.CreateObject(name);\n } catch (e) {\n try {\n // Для версий плагина ниже 2.0.12538\n return new ActiveXObject(name);\n } catch (e) {\n var mimetype = navigator.mimeTypes['application/x-cades'];\n\n if (mimetype) {\n if (mimetype.enabledPlugin) {\n console.log(\n 'EDS:',\n 'Плагин КриптоПРО ЭЦП browser plug-in загружен,',\n 'но не создаются обьекты'\n );\n } else {\n console.log('EDS:', 'Ошибка при загрузке плагина КриптоПРО ЭЦП browser plug-in');\n }\n } else {\n console.log('EDS:', 'Плагин КриптоПРО ЭЦП browser plug-in недоступен');\n }\n }\n }\n }\n\n // В Firefox, Safari создаются объекты NPAPI\n return pluginObject.CreateObject(name);\n }\n\n // Функция активации асинхронных объектов КриптоПро ЭЦП Browser plug-in\n function CreateObjectAsync(name) {\n return pluginObject.CreateObjectAsync(name);\n }\n\n // Функции для IOS\n var ru_cryptopro_npcades_10_native_bridge = {\n callbacksCount: 1,\n callbacks: {},\n\n // Automatically called by native layer when a result is available\n resultForCallback: function resultForCallback(callbackId, resultArray) {\n var callback = ru_cryptopro_npcades_10_native_bridge.callbacks[callbackId];\n\n if (!callback) {\n return;\n }\n\n callback.apply(null, resultArray);\n },\n\n // Use this in javascript to request native objective-c code\n // functionName : string (I think the name is explicit :p)\n // args : array of arguments\n // callback : function with n-arguments that is going to be called when the native code returned\n call: function call(functionName, args, callback) {\n var hasCallback = callback && typeof callback == 'function',\n callbackId = hasCallback ? ru_cryptopro_npcades_10_native_bridge.callbacksCount++ : 0,\n iframe,\n arrObjs;\n\n if (hasCallback) {\n ru_cryptopro_npcades_10_native_bridge.callbacks[callbackId] = callback;\n }\n\n iframe = document.createElement('IFRAME');\n\n arrObjs = new Array('_CPNP_handle');\n\n try {\n iframe.setAttribute(\n 'src',\n 'cpnp-js-call:' +\n functionName + ':' + callbackId + ':' + encodeURIComponent(JSON.stringify(args, arrObjs))\n );\n } catch (e) {\n alert(e);\n }\n\n document.documentElement.appendChild(iframe);\n\n iframe.parentNode.removeChild(iframe);\n iframe = null;\n }\n };\n\n function call_ru_cryptopro_npcades_10_native_bridge(functionName, array) {\n var tmpobj,\n ex;\n\n ru_cryptopro_npcades_10_native_bridge.call(functionName, array, function (e, response) {\n ex = e;\n var str = 'tmpobj=' + response;\n\n eval(str);\n\n if (typeof (tmpobj) == 'string') {\n tmpobj = tmpobj.replace(/\\\\\\n/gm, '\\n');\n tmpobj = tmpobj.replace(/\\\\\\r/gm, '\\r');\n }\n });\n\n if (ex) {\n throw ex;\n }\n\n return tmpobj;\n }\n\n // Выводим окно поверх других с предложением установить расширение для Opera.\n // Если установленна переменная cadesplugin_skip_extension_install - не предлагаем установить расширение\n function install_opera_extension() {\n if (!window.cadesplugin_skip_extension_install) {\n document.addEventListener('DOMContentLoaded', function () {\n var ovr = document.createElement('div');\n\n ovr.id = 'cadesplugin_ovr';\n ovr.style = [\n 'visibility: hidden; position: fixed; left: 0px; top: 0px;',\n 'width:100%; height:100%; background-color: rgba(0,0,0,0.7)'\n ].join(' ');\n\n ovr.innerHTML = '\\\n
\\\n \\\n

\\\n Для работы КриптоПро ЭЦП Browser plugin на данном сайте необходимо установить\\\n расширение из каталога дополнений Opera.\\\n

\\\n

\\\n
\\\n ';\n\n document.getElementsByTagName('Body')[0].appendChild(ovr);\n\n var btn_install = document.getElementById('cadesplugin_install');\n\n btn_install.addEventListener('click', function (event) {\n opr.addons.installExtension('epebfcehmdedogndhlcacafjaacknbcm',\n function () {\n document.getElementById('cadesplugin_ovr').style.visibility = 'hidden';\n location.reload();\n },\n function () {}\n );\n });\n\n document.getElementById('cadesplugin_close_install').addEventListener('click', function () {\n plugin_loaded_error('Плагин недоступен');\n document.getElementById('cadesplugin_ovr').style.visibility = 'hidden';\n });\n\n ovr.addEventListener('click', function () {\n plugin_loaded_error('Плагин недоступен');\n document.getElementById('cadesplugin_ovr').style.visibility = 'hidden';\n });\n\n ovr.style.visibility = 'visible';\n\n document.getElementById('cadesplugin_ovr_item').addEventListener('click', function (e) {\n e.stopPropagation();\n });\n });\n } else {\n plugin_loaded_error('Плагин недоступен');\n }\n }\n\n function extension_onload() {\n window.postMessage('cadesplugin_echo_request', '*');\n\n window.addEventListener('message', function (event) {\n if (event.data != 'cadesplugin_loaded') {\n return;\n }\n\n cpcsp_chrome_nmcades.check_chrome_plugin(plugin_loaded, plugin_loaded_error);\n }, false);\n }\n\n // Загружаем расширения для Chrome, Opera, YaBrowser\n function load_extension() {\n var fileref = document.createElement('script');\n\n fileref.setAttribute('type', 'text/javascript');\n fileref.setAttribute('src', 'chrome-extension://iifchhfnnmpdbibifmljnfjhpififfog/nmcades_plugin_api.js');\n fileref.onerror = plugin_loaded_error;\n fileref.onload = extension_onload;\n\n document.getElementsByTagName('head')[0].appendChild(fileref);\n\n fileref = document.createElement('script');\n fileref.setAttribute('type', 'text/javascript');\n fileref.setAttribute('src', 'chrome-extension://epebfcehmdedogndhlcacafjaacknbcm/nmcades_plugin_api.js');\n fileref.onerror = plugin_loaded_error;\n fileref.onload = extension_onload;\n document.getElementsByTagName('head')[0].appendChild(fileref);\n }\n\n // Загружаем плагин для NPAPI\n function load_npapi_plugin() {\n var elem = document.createElement('object');\n\n elem.setAttribute('id', 'cadesplugin_object');\n elem.setAttribute('type', 'application/x-cades');\n elem.setAttribute('style', 'visibility=hidden');\n document.getElementsByTagName('body')[0].appendChild(elem);\n\n pluginObject = document.getElementById('cadesplugin_object');\n\n if (isIE()) {\n var elem1 = document.createElement('object');\n\n elem1.setAttribute('id', 'certEnrollClassFactory');\n elem1.setAttribute('classid', 'clsid:884e2049-217d-11da-b2a4-000e7bbb2b09');\n elem1.setAttribute('style', 'visibility=hidden');\n document.getElementsByTagName('body')[0].appendChild(elem1);\n\n var elem2 = document.createElement('object');\n elem2.setAttribute('id', 'webClassFactory');\n elem2.setAttribute('classid', 'clsid:B04C8637-10BD-484E-B0DA-B8A039F60024');\n elem2.setAttribute('style', 'visibility=hidden');\n\n document.getElementsByTagName('body')[0].appendChild(elem2);\n }\n }\n\n // Отправляем событие что все ок.\n function plugin_loaded() {\n plugin_resolved = 1;\n if (canPromise) {\n plugin_resolve();\n } else {\n window.postMessage('cadesplugin_loaded', '*');\n }\n }\n\n // Отправляем событие что сломались.\n function plugin_loaded_error(msg) {\n if (isChromiumBased()) {\n // в асинхронном варианте подключаем оба расширения, если сломались оба пробуем установить для Opera\n failed_extensions++;\n\n if (failed_extensions < 2) {\n return;\n }\n\n if (isOpera && (typeof(msg) == 'undefined' || typeof(msg) == 'object')) {\n install_opera_extension();\n return;\n }\n }\n\n if (typeof(msg) == 'undefined' || typeof(msg) == 'object') {\n msg = 'Плагин недоступен';\n }\n\n plugin_resolved = 1;\n\n if (canPromise) {\n plugin_reject(msg);\n } else {\n window.postMessage('cadesplugin_load_error', '*');\n }\n }\n\n // проверяем что у нас хоть какое то событие ушло, и если не уходило кидаем еще раз ошибку\n function check_load_timeout() {\n if (plugin_resolved == 1) {\n return;\n }\n\n plugin_resolved = 1;\n\n if (canPromise) {\n plugin_reject('Истекло время ожидания загрузки плагина');\n } else {\n window.postMessage('cadesplugin_load_error', '*');\n }\n\n }\n\n // Вспомогательная функция для NPAPI\n function createPromise(arg) {\n return new Promise(arg);\n }\n\n function check_npapi_plugin() {\n try {\n var oAbout = CreateObject('CAdESCOM.About');\n\n plugin_loaded();\n } catch (err) {\n document.getElementById('cadesplugin_object').style.display = 'none';\n // Объект создать не удалось, проверим, установлен ли\n // вообще плагин. Такая возможность есть не во всех браузерах\n var mimetype = navigator.mimeTypes['application/x-cades'];\n if (mimetype) {\n var plugin = mimetype.enabledPlugin;\n if (plugin) {\n plugin_loaded_error('Плагин загружен, но не создаются обьекты');\n } else {\n plugin_loaded_error('Ошибка при загрузке плагина');\n }\n } else {\n plugin_loaded_error('Плагин недоступен');\n }\n }\n }\n\n // Проверяем работает ли плагин\n function check_plugin_working() {\n if (isChromiumBased()) {\n load_extension();\n } else if (!canPromise) {\n window.addEventListener('message', function (event) {\n if (event.data != 'cadesplugin_echo_request') {\n return;\n }\n\n load_npapi_plugin();\n check_npapi_plugin();\n }, false);\n } else {\n if (window.addEventListener) {\n window.addEventListener('load', function (event) {\n load_npapi_plugin();\n check_npapi_plugin();\n }, false);\n } else {\n load_npapi_plugin();\n check_npapi_plugin();\n }\n }\n }\n\n function set_pluginObject(obj) {\n pluginObject = obj;\n }\n\n // Export\n cadesplugin.JSModuleVersion = '2.0.2';\n cadesplugin.async_spawn = async_spawn;\n cadesplugin.set = set_pluginObject;\n cadesplugin.set_log_level = set_log_level;\n\n if (isChromiumBased()) {\n cadesplugin.CreateObjectAsync = CreateObjectAsync;\n }\n\n if (!isChromiumBased()) {\n cadesplugin.CreateObject = CreateObject;\n }\n\n if (window.cadesplugin_load_timeout) {\n setTimeout(check_load_timeout, window.cadesplugin_load_timeout);\n } else {\n /**\n * Даже при слабом интернете плагин успевает загрузиться\n * менее чем за секунду, тк отдается из кэша\n * */\n setTimeout(check_load_timeout, 20000);\n }\n\n set_constantValues();\n\n cadesplugin.current_log_level = cadesplugin.LOG_LEVEL_ERROR;\n\n window.cadesplugin = cadesplugin;\n\n check_plugin_working();\n}());\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./cades.js\n ** module id = 1\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/example/index.html b/example/index.html new file mode 100755 index 0000000..3552b91 --- /dev/null +++ b/example/index.html @@ -0,0 +1,27 @@ + + + + + Пример использования CryptoPro + + + + + +

+
+    
+
+    
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..6dc98d2
--- /dev/null
+++ b/package.json
@@ -0,0 +1,29 @@
+{
+  "name": "@vgoma/crypto-pro",
+  "version": "1.0.0",
+  "description": "API для взаимодействия с КриптоПро",
+  "main": "index.js",
+  "scripts": {
+    "start": "node_modules/.bin/webpack --config webpack.config.js",
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "/home/vgoma/Dropbox/dev/crypto-pro.git"
+  },
+  "author": "vgoma",
+  "keywords": [
+    "crypto",
+    "cryptopro",
+    "crypto-pro",
+    "cades",
+    "КриптоПро"
+  ],
+  "license": "ISC",
+  "dependencies": {
+    "bowser": "^1.5.0"
+  },
+  "devDependencies": {
+    "webpack": "1.13.2"
+  }
+}
diff --git a/src/apiAsync.js b/src/apiAsync.js
new file mode 100755
index 0000000..da1f9f8
--- /dev/null
+++ b/src/apiAsync.js
@@ -0,0 +1,545 @@
+var cryptoCommon = require('./common'),
+    cryptoConstants = require('./constants'),
+
+    _certProto = {
+        /**
+         * Проверяет, валиден ли сертификат
+         * */
+        isValid: function isValid() {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                cadesplugin.async_spawn(function* () {
+                    var result;
+
+                    try {
+                        result = yield cert.IsValid();
+                        result = yield result.Result;
+                    } catch (err) {
+                        reject('Ошибка при проверке сертификата: ', err.message);
+                        return;
+                    }
+
+                    resolve(result);
+                });
+            });
+        },
+
+        /**
+         * Достает указанное свойство у сертификата
+         * */
+        getProp: function (propName) {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                cadesplugin.async_spawn(function* () {
+                    var result;
+
+                    try {
+                        result = yield cert[propName];
+                    } catch (err) {
+                        reject('Ошибка при обращении к свойству сертификата: ', err.message);
+                        return;
+                    }
+
+                    resolve(result);
+                });
+            });
+        },
+
+        /**
+         * Экспорт base64 представления сертификата пользователя
+         * */
+        exportBase64: function exportBase64() {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                cadesplugin.async_spawn(function* () {
+                    var base64;
+
+                    try {
+                        base64 = yield cert.Export(0);
+                    } catch (err) {
+                        reject('Ошибка при экспорте сертификата: ', err.message);
+                        return;
+                    }
+
+                    resolve(base64);
+                });
+            });
+        },
+
+        /**
+         * Возвращает информацию об алгоритме
+         * */
+        getAlgorithm: function getAlgorithm() {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                cadesplugin.async_spawn(function* () {
+                    var result = {},
+                        algorithm;
+
+                    try {
+                        algorithm = yield cert.PublicKey();
+                        algorithm = yield algorithm.Algorithm;
+
+                        result.algorithm = yield algorithm.FriendlyName;
+                        result.oid = yield algorithm.Value;
+                    } catch (err) {
+                        reject('Ошибка при получении алгоритма: ', err.message);
+                        return;
+                    }
+
+                    resolve(result);
+                });
+            });
+        },
+
+        /**
+         * Разбирает SubjectName сертификата по тэгам
+         * */
+        getOwnerInfo: function getOwnerInfo() {
+            return getCertInfo.call(this, cryptoCommon.subjectNameTagsTranslations, 'SubjectName');
+        },
+
+        /**
+         * Разбирает IssuerName сертификата по тэгам
+         * */
+        getIssuerInfo: function getIssuerInfo() {
+            return getCertInfo.call(this, cryptoCommon.issuerNameTagsTranslations, 'IssuerName');
+        },
+
+        /**
+         * Получение OID сертификата
+         *
+         * @returns {Array} Возвращает массив OID (улучшенного ключа)
+         * */
+        getExtendedKeyUsage: function getExtendedKeyUsage() {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                cadesplugin.async_spawn(function* () {
+                    var OIDS = [],
+                        count,
+                        item;
+
+                    try {
+                        count = yield cert.ExtendedKeyUsage();
+                        count = yield count.EKUs;
+                        count = yield count.Count;
+
+                        if (count > 0) {
+                            while (count > 0) {
+                                item = yield cert.ExtendedKeyUsage();
+                                item = yield item.EKUs;
+                                item = yield item.Item(count);
+                                item = yield item.OID;
+
+                                OIDS.push(item);
+
+                                count--;
+                            }
+                        }
+                    } catch (err) {
+                        reject('Ошибка при получении ОИД\'ов: ', err.message);
+                        return;
+                    }
+
+                    resolve(OIDS);
+                });
+            });
+        },
+
+        getDecodedExtendedKeyUsage: cryptoCommon.getDecodedExtendedKeyUsage,
+
+        hasExtendedKeyUsage: cryptoCommon.hasExtendedKeyUsage
+    },
+
+    _certListCache;
+
+/**
+ * Проверяет корректность настроек ЭП на машине
+ * */
+function isValidEDSSettings() {
+    return new Promise(function (resolve, reject) {
+        cadesplugin.async_spawn(function* () {
+            var result;
+
+            try {
+                result = yield cadesplugin.CreateObjectAsync('CAdESCOM.About');
+            } catch (error) {
+                reject('Настройки ЭП на данной машине не верны');
+            }
+
+            resolve();
+        });
+    });
+}
+
+/**
+ * Получить сертификат в формате cades по хэшу
+ * */
+function getCadesCert(hash) {
+    return new Promise(function (resolve, reject) {
+        cadesplugin.async_spawn(function* () {
+            var oStore = yield cadesplugin.CreateObjectAsync('CAdESCOM.Store'),
+                certs,
+                certCnt,
+                cert;
+
+            if (!oStore) {
+                reject('Не удалось получить доступ к хранилищу сертификатов');
+                return;
+            }
+
+            // Открываем хранилище
+            try {
+                yield oStore.Open(
+                    cadesplugin.CAPICOM_CURRENT_USER_STORE,
+                    cadesplugin.CAPICOM_MY_STORE,
+                    cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED
+                );
+            } catch (err) {
+                reject('Ошибка при открытии хранилища: ' + err.message);
+                return;
+            }
+
+            // Получаем доступ к сертификатам
+            try {
+                certs = yield oStore.Certificates;
+                certCnt = yield certs.Count;
+            } catch (err) {
+                reject('Ошибка получения списка сертификатов: ' + err.message);
+                return;
+            }
+
+            if (!certCnt) {
+                reject('Нет доступных сертификатов');
+                return;
+            }
+
+            // Получаем сертификат по хэшу
+            try {
+                certs = yield certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH, hash);
+
+                if (certs.Count) {
+                    cert = yield certs.Item(1);
+                } else {
+                    throw new Error('Нет доступных сертификатов');
+                }
+            } catch (err) {
+                reject('Не удалось получить сертификат по хэшу: ' + err.message);
+                return;
+            }
+
+            oStore.Close();
+
+            resolve(cert);
+        });
+    });
+}
+
+/**
+ * Разбирает информацию сертификата по тэгам
+ * */
+function getCertInfo(tags, propName) {
+    var cert = this._cert;
+
+    return new Promise(function (resolve, reject) {
+        cadesplugin.async_spawn(function* () {
+            var propInfo;
+
+            try {
+                propInfo = yield cert[propName];
+            } catch (err) {
+                reject('Ошибка при извлечении данных из сертификата: ', err.message);
+                return;
+            }
+
+            resolve(cryptoCommon.parseCertInfo(tags, propInfo));
+        });
+    });
+}
+
+/**
+ * Возвращает список сертификатов, доступных в системе
+ *
+ * @param {Boolean} [resetCache=false] -- нужно ли сбросить кэш списка сертификатов
+ * @returns {Promise} -- со списком сертификатов {Array}
+ * */
+function getCertsList(resetCache) {
+    return new Promise(function (resolve, reject) {
+        if (!resetCache && _certListCache) {
+            resolve(_certListCache);
+            return;
+        }
+
+        cadesplugin.async_spawn(function* () {
+            var oStore = yield cadesplugin.CreateObjectAsync('CAdESCOM.Store'),
+                result = [],
+                certs,
+                count,
+                item;
+
+            // Открываем хранилище
+            try {
+                yield oStore.Open(
+                    cadesplugin.CAPICOM_CURRENT_USER_STORE,
+                    cadesplugin.CAPICOM_MY_STORE,
+                    cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED
+                );
+            } catch (err) {
+                reject('Ошибка при открытии хранилища: ' + err.message);
+                return;
+            }
+
+            // Получаем доступ к сертификатам
+            try {
+                certs = yield oStore.Certificates;
+
+                if (certs) {
+                    certs = yield certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID);
+                    /**
+                     * Не рассматриваются сертификаты, в которых отсутствует закрытый ключ
+                     * или не действительны на данный момент
+                     * */
+                    certs = yield certs.Find(
+                        cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY,
+                        cryptoConstants.PropId.CAPICOM_PROPID_KEY_PROV_INFO
+                    );
+
+                    count = yield certs.Count;
+                }
+            } catch (err) {
+                reject('Ошибка получения списка сертификатов: ' + err.message);
+                return;
+            }
+
+            if (!count) {
+                reject('Нет доступных сертификатов');
+                return;
+            }
+
+            try {
+                while (count) {
+                    item = yield certs.Item(count);
+
+                    result.push(Object.assign(Object.create(_certProto), {
+                        _cert: yield item,
+                        thumbprint: yield item.Thumbprint,
+                        subjectName: yield item.SubjectName,
+                        issuerName: yield item.IssuerName,
+                        validFrom: yield item.ValidFromDate,
+                        validTo: yield item.ValidToDate
+                    }));
+
+                    count--;
+                }
+            } catch (err) {
+                reject('Ошибка обработки сертификатов: ' + err.message);
+                return;
+            }
+
+            oStore.Close();
+
+            _certListCache = cryptoCommon.prepareCertsInfo(result);
+
+            resolve(_certListCache);
+        });
+    });
+}
+
+/**
+ * Получить сертификат по хэшу
+ * */
+function getCert(hash) {
+    return new Promise(function (resolve, reject) {
+        if (!hash) {
+            reject('Хэш не указан');
+            return;
+        }
+
+        getCertsList().then(function (list) {
+            var foundCert;
+
+            list.some(function (cert) {
+                if (hash === cert.thumbprint) {
+                    foundCert = cert;
+                    return true;
+                }
+            });
+
+            if (foundCert) {
+                resolve(foundCert);
+            } else {
+                reject('Сертификат с хэшем: "' + hash + '" не найден');
+            }
+        }, reject);
+    });
+}
+
+/**
+ * Создает подпись base64 строки по hash'у сертификата
+ *
+ * @param {String} hash -- fingerprint (thumbprint) сертификата
+ * @param {String} dataBase64 -- строковые данные в формате base64
+ * @param {String} signType -- тип подписи открепленная (true) / присоединенная (false) (default: false)
+ * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String}
+ * */
+function signData(hash, dataBase64, signType) {
+    return new Promise(function (resolve, reject) {
+        getCadesCert(hash).then(function (cert) {
+            cadesplugin.async_spawn(function* () {
+                var clientTime = new Date(),
+                    oAttrs = yield cadesplugin.CreateObjectAsync('CADESCOM.CPAttribute'),
+                    oSignedData = yield cadesplugin.CreateObjectAsync('CAdESCOM.CadesSignedData'),
+                    oSigner = yield cadesplugin.CreateObjectAsync('CAdESCOM.CPSigner'),
+                    attrs,
+                    signature;
+
+                clientTime = cryptoCommon.getDateObj(clientTime);
+
+                try {
+                    yield oAttrs.propset_Name(cryptoConstants.Time.AUTHENTICATED_ATTRIBUTE_SIGNING_TIME);
+                    yield oAttrs.propset_Value(clientTime);
+                } catch (err) {
+                    reject('Ошибка при установке данных подписи: ' + err.message);
+                    return;
+                }
+
+                // Задаем настройки для подписи
+                try {
+                    yield oSigner.propset_Certificate(cert);
+                    attrs = yield oSigner.AuthenticatedAttributes2;
+                    yield attrs.Add(oAttrs);
+                    yield oSignedData.propset_ContentEncoding(cadesplugin.CADESCOM_BASE64_TO_BINARY);
+                    yield oSignedData.propset_Content(dataBase64);
+                    yield oSigner.propset_Options(cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY);
+                } catch (err) {
+                    reject('Не удалось установить настройки для подписи: ' + err.message);
+                    return;
+                }
+
+                try {
+                    signature = yield oSignedData.SignCades(
+                        oSigner,
+                        cadesplugin.CADESCOM_CADES_BES,
+                        Boolean(signType)
+                    );
+                } catch (err) {
+                    reject('Не удалось создать подпись: ' + err.message);
+                    return;
+                }
+
+                resolve(signature);
+            });
+        });
+    });
+}
+
+/**
+ * Создает подпись XML строки по hash'у сертификата
+ *
+ * @param {String} hash -- fingerprint (thumbprint) сертификата
+ * @param {String} dataXML -- данные в формате XML
+ * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String}
+ * */
+function signDataXML(hash, dataXML) {
+    return new Promise(function (resolve, reject) {
+        getCadesCert(hash).then(function (cert) {
+            cadesplugin.async_spawn(function* () {
+                var oSigner = yield cadesplugin.CreateObjectAsync('CAdESCOM.CPSigner'),
+                    signerXML = yield cadesplugin.CreateObjectAsync('CAdESCOM.SignedXML'),
+                    cnts = cryptoConstants,
+                    signature;
+
+                // Задаем настройки для подписи
+                try {
+                    yield oSigner.propset_Certificate(cert);
+                    // Добавляем данные для подписи
+                    yield signerXML.propset_Content(dataXML);
+                    // Устанавливаем тип подписи
+                    yield signerXML.propset_SignatureType(cnts.SignatureType.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED);
+                    // Устанавливаем алгоритм подписи
+                    yield signerXML.propset_SignatureMethod(cnts.GostXmlDSigUrls.XmlDsigGost3410Url);
+                    // Устанавливаем алгоритм хэширования
+                    yield signerXML.propset_DigestMethod(cnts.GostXmlDSigUrls.XmlDsigGost3411Url);
+                } catch (err) {
+                    reject('Не удалось установить настройки для подписи: ' + err.message);
+                    return;
+                }
+
+                try {
+                    signature = yield signerXML.Sign(oSigner);
+                } catch (err) {
+                    reject('Не удалось создать подпись: ' + err.message);
+                    return;
+                }
+
+                resolve(signature);
+            });
+        });
+    });
+}
+
+/**
+ * Возвращает информацию о версии CSP и плагина
+ * */
+function getSystemInfo() {
+    var sysInfo = cryptoCommon.getEnvInfo();
+
+    return new Promise(function (resolve, reject) {
+        cadesplugin.async_spawn(function* () {
+            var e;
+
+            try {
+                e = yield cadesplugin.CreateObjectAsync('CAdESCOM.About');
+
+                sysInfo.cadesVersion = yield e.PluginVersion;
+                // Возможен вызов в ранних версиях в виде sysInfo.cspVersion = yield e.CSPVersion('', 75);
+                sysInfo.cspVersion = yield e.CSPVersion();
+
+                if (!sysInfo.cadesVersion) {
+                    sysInfo.cadesVersion = yield e.Version;
+                }
+
+                sysInfo.cadesVersion = yield sysInfo.cadesVersion.toString();
+                sysInfo.cspVersion = yield sysInfo.cspVersion.toString();
+
+                resolve(sysInfo);
+            } catch (err) {
+                reject('Ошибка при получении информации о системе: ', err.message);
+            }
+        });
+    });
+}
+
+/**
+ * Promise обертка для синхронного вызова проверки версии CSP
+ * */
+function isValidCSPVersion(version) {
+    return new Promise(function (resolve) {
+        resolve(cryptoCommon.isValidCSPVersion(version));
+    });
+}
+
+/**
+ * Promise обертка для синхронного вызова проверки версии плагина
+ * */
+function isValidCadesVersion(version) {
+    return new Promise(function (resolve) {
+        resolve(cryptoCommon.isValidCadesVersion(version));
+    });
+}
+
+module.exports = {
+    isValidEDSSettings: isValidEDSSettings,
+    getCertsList: getCertsList,
+    getCert: getCert,
+    signData: signData,
+    signDataXML: signDataXML,
+    getSystemInfo: getSystemInfo,
+    isValidCSPVersion: isValidCSPVersion,
+    isValidCadesVersion: isValidCadesVersion
+};
\ No newline at end of file
diff --git a/src/apiSync.js b/src/apiSync.js
new file mode 100755
index 0000000..deaf101
--- /dev/null
+++ b/src/apiSync.js
@@ -0,0 +1,520 @@
+var cryptoCommon = require('./common'),
+    cryptoConstants = require('./constants'),
+
+    _certProto = {
+        /**
+         * Проверяет, валиден ли сертификат
+         * */
+        isValid: function isValid() {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                var result;
+
+                try {
+                    result = cert.IsValid();
+                    result = result.Result;
+                } catch (err) {
+                    reject('Ошибка при проверке сертификата: ', err.message);
+                    return;
+                }
+
+                resolve(result);
+            });
+        },
+
+        /**
+         * Достает указанное свойство у сертификата
+         * */
+        getProp: function (propName) {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                var result;
+
+                try {
+                    result = cert[propName];
+                } catch (err) {
+                    reject('Ошибка при обращении к свойству сертификата: ', err.message);
+                    return;
+                }
+
+                resolve(result);
+            });
+        },
+
+        /**
+         * Экспорт base64 представления сертификата пользователя
+         * */
+        exportBase64: function exportBase64() {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                var base64;
+
+                try {
+                    base64 = cert.Export(0);
+                } catch (err) {
+                    reject('Ошибка при экспорте сертификата: ', err.message);
+                    return;
+                }
+
+                resolve(base64);
+            });
+        },
+
+        /**
+         * Возвращает информацию об алгоритме
+         * */
+        getAlgorithm: function getAlgorithm() {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                var result = {},
+                    algorithm;
+
+                try {
+                    algorithm = cert.PublicKey();
+                    algorithm = algorithm.Algorithm;
+
+                    result.algorithm = algorithm.FriendlyName;
+                    result.oid = algorithm.Value;
+                } catch (err) {
+                    reject('Ошибка при получении алгоритма: ', err.message);
+                    return;
+                }
+
+                resolve(result);
+            });
+        },
+
+        /**
+         * Разбирает SubjectName сертификата по тэгам
+         * */
+        getOwnerInfo: function getOwnerInfo() {
+            return getCertInfo.call(this, cryptoCommon.subjectNameTagsTranslations, 'SubjectName');
+        },
+
+        /**
+         * Разбирает IssuerName сертификата по тэгам
+         * */
+        getIssuerInfo: function getIssuerInfo() {
+            return getCertInfo.call(this, cryptoCommon.issuerNameTagsTranslations, 'IssuerName');
+        },
+
+        /**
+         * Получение OID сертификата
+         * Возвращает массив OID (улучшенного ключа)
+         * */
+        getExtendedKeyUsage: function getExtendedKeyUsage() {
+            var cert = this._cert;
+
+            return new Promise(function (resolve, reject) {
+                var OIDS = [],
+                    count,
+                    item;
+
+                try {
+                    count = cert.ExtendedKeyUsage();
+                    count = count.EKUs;
+                    count = count.Count;
+
+                    if (count > 0) {
+                        while (count > 0) {
+                            item = cert.ExtendedKeyUsage();
+                            item = item.EKUs;
+                            item = item.Item(count);
+                            item = item.OID;
+
+                            OIDS.push(item);
+
+                            count--;
+                        }
+                    }
+                } catch (err) {
+                    reject('Ошибка при получении ОИД\'ов: ', err.message);
+                    return;
+                }
+
+                resolve(OIDS);
+            });
+        },
+
+        getDecodedExtendedKeyUsage: cryptoCommon.getDecodedExtendedKeyUsage,
+
+        hasExtendedKeyUsage: cryptoCommon.hasExtendedKeyUsage
+    },
+
+    _certListCache;
+
+/**
+ * Проверяет корректность настроек ЭП на машине
+ * */
+function isValidEDSSettings() {
+    return new Promise(function (resolve, reject) {
+        var result;
+
+        try {
+            result = cadesplugin.CreateObject('CAdESCOM.About');
+        } catch (error) {
+            reject('Настройки ЭП на данной машине не верны');
+        }
+
+        resolve();
+    });
+}
+
+/**
+ * Получить сертификат в формате cades по хэшу
+ * */
+function getCadesCert(hash) {
+    return new Promise(function (resolve, reject) {
+        var oStore = cadesplugin.CreateObject('CAdESCOM.Store'),
+            certs,
+            certCnt,
+            cert;
+
+        if (!oStore) {
+            reject('Не удалось получить доступ к хранилищу сертификатов');
+            return;
+        }
+
+        // Открываем хранилище
+        try {
+            oStore.Open(
+                cadesplugin.CAPICOM_CURRENT_USER_STORE,
+                cadesplugin.CAPICOM_MY_STORE,
+                cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED
+            );
+        } catch (err) {
+            reject('Ошибка при открытии хранилища: ' + err.message);
+            return;
+        }
+
+        // Получаем доступ к сертификатам
+        try {
+            certs = oStore.Certificates;
+            certCnt = certs.Count;
+        } catch (err) {
+            reject('Ошибка получения списка сертификатов: ' + err.message);
+            return;
+        }
+
+        if (!certCnt) {
+            reject('Нет доступных сертификатов');
+            return;
+        }
+
+        // Получаем сертификат по хэшу
+        try {
+            certs = certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH, hash);
+
+            if (certs.Count) {
+                cert = certs.Item(1);
+            } else {
+                throw new Error('Нет доступных сертификатов');
+            }
+        } catch (err) {
+            reject('Не удалось получить сертификат по хэшу: ' + err.message);
+            return;
+        }
+
+        oStore.Close();
+
+        resolve(cert);
+    });
+}
+
+/**
+ * Разбирает информацию сертификата по тэгам
+ * */
+function getCertInfo(tags, propName) {
+    var cert = this._cert;
+
+    return new Promise(function (resolve, reject) {
+        var propInfo;
+
+        try {
+            propInfo = cert[propName];
+        } catch (err) {
+            reject('Ошибка при извлечении данных из сертификата: ', err.message);
+            return;
+        }
+
+        resolve(cryptoCommon.parseCertInfo(tags, propInfo));
+    });
+}
+
+/**
+ * Возвращает список сертификатов, доступных в системе
+ *
+ * @param {Boolean} [resetCache=false] -- нужно ли сбросить кэш списка сертификатов
+ * @returns {Promise} -- со списком сертификатов {Array}
+ * */
+function getCertsList(resetCache) {
+    return new Promise(function (resolve, reject) {
+        if (!resetCache && _certListCache) {
+            resolve(_certListCache);
+            return;
+        }
+
+        var oStore = cadesplugin.CreateObject('CAdESCOM.Store'),
+            result = [],
+            certs,
+            count,
+            item;
+
+        // Открываем хранилище
+        try {
+            oStore.Open(
+                cadesplugin.CAPICOM_CURRENT_USER_STORE,
+                cadesplugin.CAPICOM_MY_STORE,
+                cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED
+            );
+        } catch (err) {
+            reject('Ошибка при открытии хранилища: ' + err.message);
+            return;
+        }
+
+        // Получаем доступ к сертификатам
+        try {
+            certs = oStore.Certificates;
+
+            if (certs) {
+                certs = certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID);
+                /**
+                 * Не рассматриваются сертификаты, в которых отсутствует закрытый ключ
+                 * или не действительны на данный момент
+                 * */
+                certs = certs.Find(
+                    cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY,
+                    cryptoConstants.PropId.CAPICOM_PROPID_KEY_PROV_INFO
+                );
+
+                count = certs.Count;
+            }
+        } catch (err) {
+            reject('Ошибка получения списка сертификатов: ' + err.message);
+            return;
+        }
+
+        if (!count) {
+            reject('Нет доступных сертификатов');
+            return;
+        }
+
+        try {
+            while (count) {
+                item = certs.Item(count);
+
+                result.push(Object.assign(Object.create(_certProto), {
+                    _cert: item,
+                    thumbprint: item.Thumbprint,
+                    subjectName: item.SubjectName,
+                    issuerName: item.IssuerName,
+                    validFrom: item.ValidFromDate,
+                    validTo: item.ValidToDate
+                }));
+
+                count--;
+            }
+        } catch (err) {
+            reject('Ошибка обработки сертификатов: ' + err.message);
+            return;
+        }
+
+        oStore.Close();
+
+        _certListCache = cryptoCommon.prepareCertsInfo(result);
+
+        resolve(_certListCache);
+    });
+}
+
+/**
+ * Получить сертификат по хэшу
+ * */
+function getCert(hash) {
+    return new Promise(function (resolve, reject) {
+        if (!hash) {
+            reject('Хэш не указан');
+            return;
+        }
+
+        getCertsList().then(function (list) {
+            var foundCert;
+
+            list.some(function (cert) {
+                if (hash === cert.thumbprint) {
+                    foundCert = cert;
+                    return true;
+                }
+            });
+
+            if (foundCert) {
+                resolve(foundCert);
+            } else {
+                reject('Сертификат с хэшем: "' + hash + '" не найден');
+            }
+        }, reject);
+    });
+}
+
+/**
+ * Создает подпись base64 строки по hash'у сертификата
+ *
+ * @param {String} hash -- fingerprint (thumbprint) сертификата
+ * @param {String} dataBase64 -- строковые данные в формате base64
+ * @param {String} signType -- тип подписи открепленная (true) / присоединенная (false) (default: false)
+ * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String}
+ * */
+function signData(hash, dataBase64, signType) {
+    return new Promise(function (resolve, reject) {
+        getCadesCert(hash).then(function (cert) {
+            var clientTime = new Date(),
+                oAttrs = cadesplugin.CreateObject('CADESCOM.CPAttribute'),
+                oSignedData = cadesplugin.CreateObject('CAdESCOM.CadesSignedData'),
+                oSigner = cadesplugin.CreateObject('CAdESCOM.CPSigner'),
+                attrs,
+                signature;
+
+            clientTime = cryptoCommon.getDateObj(clientTime);
+
+            try {
+                oAttrs.Name = cryptoConstants.Time.AUTHENTICATED_ATTRIBUTE_SIGNING_TIME;
+                oAttrs.Value = clientTime;
+            } catch (err) {
+                reject('Ошибка при установке данных подписи: ' + err.message);
+                return;
+            }
+
+            // Задаем настройки для подписи
+            try {
+                oSigner.Certificate = cert;
+                attrs = oSigner.AuthenticatedAttributes2;
+                attrs.Add(oAttrs);
+                oSignedData.ContentEncoding = cadesplugin.CADESCOM_BASE64_TO_BINARY;
+                oSignedData.Content = dataBase64;
+                oSigner.Options = cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY;
+            } catch (err) {
+                reject('Не удалось установить настройки для подписи: ' + err.message);
+                return;
+            }
+
+            try {
+                signature = oSignedData.SignCades(
+                    oSigner,
+                    cadesplugin.CADESCOM_CADES_BES,
+                    Boolean(signType)
+                );
+            } catch (err) {
+                reject('Не удалось создать подпись: ' + err.message);
+                return;
+            }
+
+            resolve(signature);
+        });
+    });
+}
+
+/**
+ * Создает подпись XML строки по hash'у сертификата
+ *
+ * @param {String} hash -- fingerprint (thumbprint) сертификата
+ * @param {String} dataXML -- данные в формате XML
+ * @returns {Promise} -- обещание, которое зарезолвится с данными о подписи {String}
+ * */
+function signDataXML(hash, dataXML) {
+    return new Promise(function (resolve, reject) {
+        getCadesCert(hash).then(function (cert) {
+            var oSigner = cadesplugin.CreateObject('CAdESCOM.CPSigner'),
+                signerXML = cadesplugin.CreateObject('CAdESCOM.SignedXML'),
+                cnts = cryptoConstants,
+                signature;
+
+            // Задаем настройки для подписи
+            try {
+                oSigner.Certificate = cert;
+                // Добавляем данные для подписи
+                signerXML.Content = dataXML;
+                // Устанавливаем тип подписи
+                signerXML.SignatureType = cnts.SignatureType.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED;
+                // Устанавливаем алгоритм подписи
+                signerXML.SignatureMethod = cnts.GostXmlDSigUrls.XmlDsigGost3410Url;
+                // Устанавливаем алгоритм хэширования
+                signerXML.DigestMethod = cnts.GostXmlDSigUrls.XmlDsigGost3411Url;
+            } catch (err) {
+                reject('Не удалось установить настройки для подписи: ' + err.message);
+                return;
+            }
+
+            try {
+                signature = signerXML.Sign(oSigner);
+            } catch (err) {
+                reject('Не удалось создать подпись: ' + err.message);
+                return;
+            }
+
+            resolve(signature);
+        });
+    });
+}
+
+/**
+ * Возвращает информацию о версии CSP и плагина
+ * */
+function getSystemInfo() {
+    var sysInfo = cryptoCommon.getEnvInfo();
+
+    return new Promise(function (resolve, reject) {
+        var e;
+
+        try {
+            e = cadesplugin.CreateObject('CAdESCOM.About');
+
+            sysInfo.cadesVersion = e.PluginVersion;
+            // Возможен вызов в ранних версиях в виде sysInfo.cspVersion = e.CSPVersion('', 75);
+            sysInfo.cspVersion = e.CSPVersion();
+
+            if (!sysInfo.cadesVersion) {
+                sysInfo.cadesVersion = e.Version;
+            }
+
+            sysInfo.cadesVersion = sysInfo.cadesVersion.toString();
+            sysInfo.cspVersion = sysInfo.cspVersion.toString();
+
+            resolve(sysInfo);
+        } catch (err) {
+            reject('Ошибка при получении информации о системе: ', err.message);
+        }
+    });
+}
+
+/**
+ * Promise обертка для синхронного вызова проверки версии CSP
+ * */
+function isValidCSPVersion(version) {
+    return new Promise(function (resolve) {
+        resolve(cryptoCommon.isValidCSPVersion(version));
+    });
+}
+
+/**
+ * Promise обертка для синхронного вызова проверки версии плагина
+ * */
+function isValidCadesVersion(version) {
+    return new Promise(function (resolve) {
+        resolve(cryptoCommon.isValidCadesVersion(version));
+    });
+}
+
+module.exports = {
+    isValidEDSSettings: isValidEDSSettings,
+    getCertsList: getCertsList,
+    getCert: getCert,
+    signData: signData,
+    signDataXML: signDataXML,
+    getSystemInfo: getSystemInfo,
+    isValidCSPVersion: isValidCSPVersion,
+    isValidCadesVersion: isValidCadesVersion
+};
\ No newline at end of file
diff --git a/src/cades.js b/src/cades.js
new file mode 100755
index 0000000..2d43462
--- /dev/null
+++ b/src/cades.js
@@ -0,0 +1,635 @@
+;(function () {
+    /**
+     * Это переделанная версия cadesplugin_api.js с сайта Крипто ПРО,
+     * в которую добавлена поддержка IE-8.
+     *
+     * Обсуждение:
+     * https://www.cryptopro.ru/forum2/default.aspx?g=posts&t=9271
+     *
+     * Оригинальный файл:
+     * https://www.cryptopro.ru/sites/default/files/products/cades/cadesplugin_api.js
+     * */
+    var pluginObject,
+        plugin_resolved = 0,
+        plugin_reject,
+        plugin_resolve,
+        isOpera = 0,
+        isYaBrowser = 0,
+        failed_extensions = 0,
+        canPromise = Boolean(window.Promise),
+        cadesplugin;
+
+    if (window.cadesplugin) {
+        return;
+    }
+
+    if (canPromise) {
+        cadesplugin = new Promise(function (resolve, reject) {
+            plugin_resolve = resolve;
+            plugin_reject = reject;
+        });
+    } else {
+        cadesplugin = {};
+    }
+
+    function cpcsp_console_log(level, msg) {
+        if (level <= cadesplugin.current_log_level) {
+            if (level == cadesplugin.LOG_LEVEL_DEBUG) {
+                console.log('DEBUG: %s', msg);
+            }
+
+            if (level == cadesplugin.LOG_LEVEL_INFO) {
+                console.info('INFO: %s', msg);
+            }
+
+            if (level == cadesplugin.LOG_LEVEL_ERROR) {
+                console.error('ERROR: %s', msg);
+            }
+        }
+    }
+
+    function set_log_level(level) {
+        var isSetLoglevel = (level == cadesplugin.LOG_LEVEL_DEBUG)
+            || (level == cadesplugin.LOG_LEVEL_INFO)
+            || (level == cadesplugin.LOG_LEVEL_ERROR);
+
+        if (!isSetLoglevel) {
+            cpcsp_console_log(cadesplugin.LOG_LEVEL_ERROR, 'cadesplugin_api.js: Incorrect log_level: ' + level);
+
+            return;
+        }
+
+        cadesplugin.current_log_level = level;
+
+        if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_DEBUG) {
+            cpcsp_console_log(cadesplugin.LOG_LEVEL_INFO, 'cadesplugin_api.js: log_level = DEBUG');
+        }
+
+        if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_INFO) {
+            cpcsp_console_log(cadesplugin.LOG_LEVEL_INFO, 'cadesplugin_api.js: log_level = INFO');
+        }
+
+        if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_ERROR) {
+            cpcsp_console_log(cadesplugin.LOG_LEVEL_INFO, 'cadesplugin_api.js: log_level = ERROR');
+        }
+
+        if (isChromiumBased()) {
+            if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_DEBUG) {
+                window.postMessage('set_log_level=debug', '*');
+            }
+
+            if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_INFO) {
+                window.postMessage('set_log_level=info', '*');
+            }
+
+            if (cadesplugin.current_log_level == cadesplugin.LOG_LEVEL_ERROR) {
+                window.postMessage('set_log_level=error', '*');
+            }
+        }
+    }
+
+    function set_constantValues() {
+        cadesplugin.CAPICOM_LOCAL_MACHINE_STORE = 1;
+        cadesplugin.CAPICOM_CURRENT_USER_STORE = 2;
+        cadesplugin.CAPICOM_MY_STORE = 'My';
+        cadesplugin.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1;
+        cadesplugin.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED = 0;
+        cadesplugin.CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING = 1;
+        cadesplugin.CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE = 2;
+        cadesplugin.XmlDsigGost3410UrlObsolete = 'http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411';
+        cadesplugin.XmlDsigGost3411UrlObsolete = 'http://www.w3.org/2001/04/xmldsig-more#gostr3411';
+        cadesplugin.XmlDsigGost3410Url = 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411';
+        cadesplugin.XmlDsigGost3411Url = 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411';
+        cadesplugin.CADESCOM_CADES_DEFAULT = 0;
+        cadesplugin.CADESCOM_CADES_BES = 1;
+        cadesplugin.CADESCOM_CADES_T = 0x5;
+        cadesplugin.CADESCOM_CADES_X_LONG_TYPE_1 = 0x5d;
+        cadesplugin.CADESCOM_ENCODE_BASE64 = 0;
+        cadesplugin.CADESCOM_ENCODE_BINARY = 1;
+        cadesplugin.CADESCOM_ENCODE_ANY = -1;
+        cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT = 0;
+        cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN = 1;
+        cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY = 2;
+        cadesplugin.CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME = 0;
+        cadesplugin.CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME = 1;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH = 0;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_ISSUER_NAME = 2;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_ROOT_NAME = 3;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME = 4;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENSION = 5;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY = 6;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY = 7;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY = 8;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_VALID = 9;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID = 10;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED = 11;
+        cadesplugin.CAPICOM_CERTIFICATE_FIND_KEY_USAGE = 12;
+        cadesplugin.CAPICOM_DIGITAL_SIGNATURE_KEY_USAGE = 128;
+        cadesplugin.CAPICOM_PROPID_ENHKEY_USAGE = 9;
+        cadesplugin.CAPICOM_OID_OTHER = 0;
+        cadesplugin.CAPICOM_OID_KEY_USAGE_EXTENSION = 10;
+        cadesplugin.CAPICOM_EKU_CLIENT_AUTH = 2;
+        cadesplugin.CAPICOM_EKU_SMARTCARD_LOGON = 5;
+        cadesplugin.CAPICOM_EKU_OTHER = 0;
+        cadesplugin.CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0;
+        cadesplugin.CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME = 1;
+        cadesplugin.CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION = 2;
+        cadesplugin.CADESCOM_ATTRIBUTE_OTHER = -1;
+        cadesplugin.CADESCOM_STRING_TO_UCS2LE = 0;
+        cadesplugin.CADESCOM_BASE64_TO_BINARY = 1;
+        cadesplugin.CADESCOM_DISPLAY_DATA_NONE = 0;
+        cadesplugin.CADESCOM_DISPLAY_DATA_CONTENT = 1;
+        cadesplugin.CADESCOM_DISPLAY_DATA_ATTRIBUTE = 2;
+        cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_RC2 = 0;
+        cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_RC4 = 1;
+        cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_DES = 2;
+        cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_3DES = 3;
+        cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_AES = 4;
+        cadesplugin.CADESCOM_ENCRYPTION_ALGORITHM_GOST_28147_89 = 25;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_SHA1 = 0;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_MD2 = 1;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_MD4 = 2;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_MD5 = 3;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_256 = 4;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_384 = 5;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_SHA_512 = 6;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411 = 100;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256 = 101;
+        cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_512 = 102;
+        cadesplugin.LOG_LEVEL_DEBUG = 4;
+        cadesplugin.LOG_LEVEL_INFO = 2;
+        cadesplugin.LOG_LEVEL_ERROR = 1;
+    }
+
+    function async_spawn(generatorFunc) {
+        var generator = generatorFunc(Array.prototype.slice.call(arguments, 1)),
+            onFulfilled = continuer.bind(continuer, 'next'),
+            onRejected = continuer.bind(continuer, 'throw');
+
+        function continuer(verb, arg) {
+            var result;
+
+            try {
+                result = generator[verb](arg);
+            } catch (err) {
+                return Promise.reject(err);
+            }
+
+            if (result.done) {
+                return result.value;
+            } else {
+                return Promise.resolve(result.value).then(onFulfilled, onRejected);
+            }
+        }
+
+        return onFulfilled();
+    }
+
+    function isIE() {
+        return navigator.appName === 'Microsoft Internet Explorer' // IE < 11
+            || navigator.userAgent.match(/Trident\/./i); // IE 11
+    }
+
+    function isIOS() {
+        return navigator.userAgent.match(/ipod/i)
+            || navigator.userAgent.match(/ipad/i)
+            || navigator.userAgent.match(/iphone/i);
+    }
+
+    function isChromiumBased() {
+        var retVal_chrome = navigator.userAgent.match(/chrome/i),
+
+            // некоторых версиях IE8 с подключенным плагином chromeframe он определяется как
+            // Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; chromeframe/29.0.1547.67;
+            // и может попадать в ветку Chrome
+            retVal_chromeframe = navigator.userAgent.match(/chromeframe/i);
+
+        isOpera = navigator.userAgent.match(/opr/i);
+        isYaBrowser = navigator.userAgent.match(/YaBrowser/i);
+
+        if (retVal_chrome == null) {
+            // В Firefox и IE работаем через NPAPI
+            return false;
+        } else {
+            // В Chrome и Opera работаем через асинхронную версию
+            if (retVal_chrome.length > 0 || isOpera != null) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    // Функция активации объектов КриптоПро ЭЦП Browser plug-in
+    function CreateObject(name) {
+        if (isIOS()) {
+            // На iOS для создания объектов используется функция
+            // call_ru_cryptopro_npcades_10_native_bridge, определенная в IOS_npcades_supp.js
+            return call_ru_cryptopro_npcades_10_native_bridge('CreateObject', [name]);
+        }
+
+        if (isIE()) {
+            // В Internet Explorer создаются COM-объекты
+            if (name.match(/X509Enrollment/i)) {
+                try {
+                    // Объекты CertEnroll создаются через CX509EnrollmentWebClassFactory
+                    var objCertEnrollClassFactory = document.getElementById('certEnrollClassFactory');
+                    return objCertEnrollClassFactory.CreateObject(name);
+                } catch (e) {
+                    throw(
+                        'Для создания обьектов X509Enrollment следует настроить ' +
+                        'веб-узел на использование проверки подлинности по протоколу HTTPS'
+                    );
+                }
+            }
+
+            // Объекты CAPICOM и CAdESCOM создаются через CAdESCOM.WebClassFactory
+            try {
+                var objWebClassFactory = document.getElementById('webClassFactory');
+
+                return objWebClassFactory.CreateObject(name);
+            } catch (e) {
+                try {
+                    // Для версий плагина ниже 2.0.12538
+                    return new ActiveXObject(name);
+                } catch (e) {
+                    var mimetype = navigator.mimeTypes['application/x-cades'];
+
+                    if (mimetype) {
+                        if (mimetype.enabledPlugin) {
+                            console.log(
+                                'EDS:',
+                                'Плагин КриптоПРО ЭЦП browser plug-in загружен,',
+                                'но не создаются обьекты'
+                            );
+                        } else {
+                            console.log('EDS:', 'Ошибка при загрузке плагина КриптоПРО ЭЦП browser plug-in');
+                        }
+                    } else {
+                        console.log('EDS:', 'Плагин КриптоПРО ЭЦП browser plug-in недоступен');
+                    }
+                }
+            }
+        }
+
+        // В Firefox, Safari создаются объекты NPAPI
+        return pluginObject.CreateObject(name);
+    }
+
+    // Функция активации асинхронных объектов КриптоПро ЭЦП Browser plug-in
+    function CreateObjectAsync(name) {
+        return pluginObject.CreateObjectAsync(name);
+    }
+
+    // Функции для IOS
+    var ru_cryptopro_npcades_10_native_bridge = {
+        callbacksCount: 1,
+        callbacks: {},
+
+        // Automatically called by native layer when a result is available
+        resultForCallback: function resultForCallback(callbackId, resultArray) {
+            var callback = ru_cryptopro_npcades_10_native_bridge.callbacks[callbackId];
+
+            if (!callback) {
+                return;
+            }
+
+            callback.apply(null, resultArray);
+        },
+
+        // Use this in javascript to request native objective-c code
+        // functionName : string (I think the name is explicit :p)
+        // args : array of arguments
+        // callback : function with n-arguments that is going to be called when the native code returned
+        call: function call(functionName, args, callback) {
+            var hasCallback = callback && typeof callback == 'function',
+                callbackId = hasCallback ? ru_cryptopro_npcades_10_native_bridge.callbacksCount++ : 0,
+                iframe,
+                arrObjs;
+
+            if (hasCallback) {
+                ru_cryptopro_npcades_10_native_bridge.callbacks[callbackId] = callback;
+            }
+
+            iframe = document.createElement('IFRAME');
+
+            arrObjs = new Array('_CPNP_handle');
+
+            try {
+                iframe.setAttribute(
+                    'src',
+                    'cpnp-js-call:' +
+                    functionName + ':' + callbackId + ':' + encodeURIComponent(JSON.stringify(args, arrObjs))
+                );
+            } catch (e) {
+                alert(e);
+            }
+
+            document.documentElement.appendChild(iframe);
+
+            iframe.parentNode.removeChild(iframe);
+            iframe = null;
+        }
+    };
+
+    function call_ru_cryptopro_npcades_10_native_bridge(functionName, array) {
+        var tmpobj,
+            ex;
+
+        ru_cryptopro_npcades_10_native_bridge.call(functionName, array, function (e, response) {
+            ex = e;
+            var str = 'tmpobj=' + response;
+
+            eval(str);
+
+            if (typeof (tmpobj) == 'string') {
+                tmpobj = tmpobj.replace(/\\\n/gm, '\n');
+                tmpobj = tmpobj.replace(/\\\r/gm, '\r');
+            }
+        });
+
+        if (ex) {
+            throw ex;
+        }
+
+        return tmpobj;
+    }
+
+    // Выводим окно поверх других с предложением установить расширение для Opera.
+    // Если установленна переменная cadesplugin_skip_extension_install - не предлагаем установить расширение
+    function install_opera_extension() {
+        if (!window.cadesplugin_skip_extension_install) {
+            document.addEventListener('DOMContentLoaded', function () {
+                var ovr = document.createElement('div');
+
+                ovr.id = 'cadesplugin_ovr';
+                ovr.style = [
+                    'visibility: hidden; position: fixed; left: 0px; top: 0px;',
+                    'width:100%; height:100%; background-color: rgba(0,0,0,0.7)'
+                ].join(' ');
+
+                ovr.innerHTML = '\
+                    
\ + \ +

\ + Для работы КриптоПро ЭЦП Browser plugin на данном сайте необходимо установить\ + расширение из каталога дополнений Opera.\ +

\ +

\ +
\ + '; + + document.getElementsByTagName('Body')[0].appendChild(ovr); + + var btn_install = document.getElementById('cadesplugin_install'); + + btn_install.addEventListener('click', function (event) { + opr.addons.installExtension('epebfcehmdedogndhlcacafjaacknbcm', + function () { + document.getElementById('cadesplugin_ovr').style.visibility = 'hidden'; + location.reload(); + }, + function () {} + ); + }); + + document.getElementById('cadesplugin_close_install').addEventListener('click', function () { + plugin_loaded_error('Плагин недоступен'); + document.getElementById('cadesplugin_ovr').style.visibility = 'hidden'; + }); + + ovr.addEventListener('click', function () { + plugin_loaded_error('Плагин недоступен'); + document.getElementById('cadesplugin_ovr').style.visibility = 'hidden'; + }); + + ovr.style.visibility = 'visible'; + + document.getElementById('cadesplugin_ovr_item').addEventListener('click', function (e) { + e.stopPropagation(); + }); + }); + } else { + plugin_loaded_error('Плагин недоступен'); + } + } + + function extension_onload() { + window.postMessage('cadesplugin_echo_request', '*'); + + window.addEventListener('message', function (event) { + if (event.data != 'cadesplugin_loaded') { + return; + } + + cpcsp_chrome_nmcades.check_chrome_plugin(plugin_loaded, plugin_loaded_error); + }, false); + } + + // Загружаем расширения для Chrome, Opera, YaBrowser + function load_extension() { + var fileref = document.createElement('script'); + + fileref.setAttribute('type', 'text/javascript'); + fileref.setAttribute('src', 'chrome-extension://iifchhfnnmpdbibifmljnfjhpififfog/nmcades_plugin_api.js'); + fileref.onerror = plugin_loaded_error; + fileref.onload = extension_onload; + + document.getElementsByTagName('head')[0].appendChild(fileref); + + fileref = document.createElement('script'); + fileref.setAttribute('type', 'text/javascript'); + fileref.setAttribute('src', 'chrome-extension://epebfcehmdedogndhlcacafjaacknbcm/nmcades_plugin_api.js'); + fileref.onerror = plugin_loaded_error; + fileref.onload = extension_onload; + document.getElementsByTagName('head')[0].appendChild(fileref); + } + + // Загружаем плагин для NPAPI + function load_npapi_plugin() { + var elem = document.createElement('object'); + + elem.setAttribute('id', 'cadesplugin_object'); + elem.setAttribute('type', 'application/x-cades'); + elem.setAttribute('style', 'visibility=hidden'); + document.getElementsByTagName('body')[0].appendChild(elem); + + pluginObject = document.getElementById('cadesplugin_object'); + + if (isIE()) { + var elem1 = document.createElement('object'); + + elem1.setAttribute('id', 'certEnrollClassFactory'); + elem1.setAttribute('classid', 'clsid:884e2049-217d-11da-b2a4-000e7bbb2b09'); + elem1.setAttribute('style', 'visibility=hidden'); + document.getElementsByTagName('body')[0].appendChild(elem1); + + var elem2 = document.createElement('object'); + elem2.setAttribute('id', 'webClassFactory'); + elem2.setAttribute('classid', 'clsid:B04C8637-10BD-484E-B0DA-B8A039F60024'); + elem2.setAttribute('style', 'visibility=hidden'); + + document.getElementsByTagName('body')[0].appendChild(elem2); + } + } + + // Отправляем событие что все ок. + function plugin_loaded() { + plugin_resolved = 1; + if (canPromise) { + plugin_resolve(); + } else { + window.postMessage('cadesplugin_loaded', '*'); + } + } + + // Отправляем событие что сломались. + function plugin_loaded_error(msg) { + if (isChromiumBased()) { + // в асинхронном варианте подключаем оба расширения, если сломались оба пробуем установить для Opera + failed_extensions++; + + if (failed_extensions < 2) { + return; + } + + if (isOpera && (typeof(msg) == 'undefined' || typeof(msg) == 'object')) { + install_opera_extension(); + return; + } + } + + if (typeof(msg) == 'undefined' || typeof(msg) == 'object') { + msg = 'Плагин недоступен'; + } + + plugin_resolved = 1; + + if (canPromise) { + plugin_reject(msg); + } else { + window.postMessage('cadesplugin_load_error', '*'); + } + } + + // проверяем что у нас хоть какое то событие ушло, и если не уходило кидаем еще раз ошибку + function check_load_timeout() { + if (plugin_resolved == 1) { + return; + } + + plugin_resolved = 1; + + if (canPromise) { + plugin_reject('Истекло время ожидания загрузки плагина'); + } else { + window.postMessage('cadesplugin_load_error', '*'); + } + + } + + // Вспомогательная функция для NPAPI + function createPromise(arg) { + return new Promise(arg); + } + + function check_npapi_plugin() { + try { + var oAbout = CreateObject('CAdESCOM.About'); + + plugin_loaded(); + } catch (err) { + document.getElementById('cadesplugin_object').style.display = 'none'; + // Объект создать не удалось, проверим, установлен ли + // вообще плагин. Такая возможность есть не во всех браузерах + var mimetype = navigator.mimeTypes['application/x-cades']; + if (mimetype) { + var plugin = mimetype.enabledPlugin; + if (plugin) { + plugin_loaded_error('Плагин загружен, но не создаются обьекты'); + } else { + plugin_loaded_error('Ошибка при загрузке плагина'); + } + } else { + plugin_loaded_error('Плагин недоступен'); + } + } + } + + // Проверяем работает ли плагин + function check_plugin_working() { + if (isChromiumBased()) { + load_extension(); + } else if (!canPromise) { + window.addEventListener('message', function (event) { + if (event.data != 'cadesplugin_echo_request') { + return; + } + + load_npapi_plugin(); + check_npapi_plugin(); + }, false); + } else { + if (window.addEventListener) { + window.addEventListener('load', function (event) { + load_npapi_plugin(); + check_npapi_plugin(); + }, false); + } else { + load_npapi_plugin(); + check_npapi_plugin(); + } + } + } + + function set_pluginObject(obj) { + pluginObject = obj; + } + + // Export + cadesplugin.JSModuleVersion = '2.0.2'; + cadesplugin.async_spawn = async_spawn; + cadesplugin.set = set_pluginObject; + cadesplugin.set_log_level = set_log_level; + + if (isChromiumBased()) { + cadesplugin.CreateObjectAsync = CreateObjectAsync; + } + + if (!isChromiumBased()) { + cadesplugin.CreateObject = CreateObject; + } + + if (window.cadesplugin_load_timeout) { + setTimeout(check_load_timeout, window.cadesplugin_load_timeout); + } else { + /** + * Даже при слабом интернете плагин успевает загрузиться + * менее чем за секунду, тк отдается из кэша + * */ + setTimeout(check_load_timeout, 20000); + } + + set_constantValues(); + + cadesplugin.current_log_level = cadesplugin.LOG_LEVEL_ERROR; + + window.cadesplugin = cadesplugin; + + check_plugin_working(); +}()); \ No newline at end of file diff --git a/src/common.js b/src/common.js new file mode 100755 index 0000000..d440614 --- /dev/null +++ b/src/common.js @@ -0,0 +1,278 @@ +var bowser = require('bowser/bowser'); +var oids = require('./oids'); + +var subjectNameTagsTranslations = [ + {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'}, + {possibleNames: ['CN'], translation: 'Владелец'}, + {possibleNames: ['SN'], translation: 'Фамилия'}, + {possibleNames: ['G'], translation: 'Имя Отчество'}, + {possibleNames: ['C'], translation: 'Страна'}, + {possibleNames: ['S'], translation: 'Регион'}, + {possibleNames: ['STREET'], translation: 'Адрес'}, + {possibleNames: ['O'], translation: 'Компания'}, + {possibleNames: ['OU'], translation: 'Отдел/подразделение'}, + {possibleNames: ['T'], translation: 'Должность'}, + {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'}, + {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'}, + {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'}, + {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'}, + {possibleNames: ['E'], translation: 'Email'}, + {possibleNames: ['L'], translation: 'Город'} + ], + + issuerNameTagsTranslations = [ + {possibleNames: ['UnstructuredName'], translation: 'Неструктурированное имя'}, + {possibleNames: ['CN'], translation: 'Удостоверяющий центр'}, + {possibleNames: ['S'], translation: 'Регион'}, + {possibleNames: ['C'], translation: 'Страна'}, + {possibleNames: ['STREET'], translation: 'Адрес'}, + {possibleNames: ['O'], translation: 'Компания'}, + {possibleNames: ['OU'], translation: 'Тип'}, + {possibleNames: ['T'], translation: 'Должность'}, + {possibleNames: ['ОГРН', 'OGRN'], translation: 'ОГРН'}, + {possibleNames: ['ОГРНИП', 'OGRNIP'], translation: 'ОГРНИП'}, + {possibleNames: ['СНИЛС', 'SNILS'], translation: 'СНИЛС'}, + {possibleNames: ['ИНН', 'INN'], translation: 'ИНН'}, + {possibleNames: ['E'], translation: 'Email'}, + {possibleNames: ['L'], translation: 'Город'} + ]; + +/** + * Парсит информацию из строки с информацией о сертификате + * */ +function parseCertInfo(tags, infoString) { + /** + * Пример входной строки: + * + + T=Генеральный директор, UnstructuredName="INN=7811514257/KPP=781101001/OGRN=1127847087884", + STREET="Крыленко, д.3, лит.Б", CN=Король Анатолий Евгеньевич, G=Анатолий Евгеньевич, SN=Король, + OU=Администрация, O="ООО ""Аксиома""", L=Санкт-Петербург, S=78 г. Санкт-Петербург, C=RU, E=korol@sferasro.ru, + INN=007811514257, OGRN=1127847087884, SNILS=11617693460 + + * */ + var result = infoString.match(/([а-яА-Яa-zA-Z0-9\.]+)=(?:("[^"]+?")|(.+?))(?:,|$)/g); + + if (result) { + result = result.map(function (group) { + /** + * Пример входной строки: + * + + UnstructuredName="INN=7811514257/KPP=781101001/OGRN=1127847087884", + + * */ + var parts = group.match(/^([а-яА-Яa-zA-Z0-9\.]+)=(.+?),?$/), + title = parts && parts[1], + descr = parts && parts[2], + translated = false, + oidTitle; + + // Если тайтл содержит ОИД, пытаемся расшифровать + if (/^OID./.test(title)) { + oidTitle = title.match(/^OID\.(.*)/); + + if (oidTitle && oidTitle[1]) { + oidTitle = oids[oidTitle[1]]; + + if (oidTitle) { + title = oidTitle; + } + } + } + + // Вырезаем лишние кавычки + descr = descr.replace(/^"(.*)"/, '$1'); + descr = descr.replace(/"{2}/g, '"'); + + tags.some(function (tag) { + return tag.possibleNames.some(function (possible) { + var match = possible === title; + + if (match) { + title = tag.translation; + translated = true; + } + + return match; + }); + }); + + return { + title: title, + descr: descr, + translated: translated + }; + }); + } + + return result; +} + +/** + * Возвращает дату в формате (dd.mm.yyyy hh:mm:ss) из строки, формата, используемого плагином cryptoPro + * */ +function getReadableDate(date) { + date = new Date(date); + + return ([ + date.getDate(), + date.getMonth() + 1, + date.getFullYear() + ].join('.') + ' ' + [ + date.getHours(), + date.getMinutes(), + date.getSeconds() + ].join(':')).replace(/\b(\d)\b/g, '0$1'); +} + +/** + * Преобразует дату для IE + * */ +function getDateObj(dateObj) { + return bowser.msie ? dateObj.getVarDate() : dateObj; +} + +/** + * Подготавливает информацию о сертификатах + * */ +function prepareCertsInfo(items) { + return items.map(function (c) { + c.name = c.subjectName.match(/CN=(.+?),/); + + // Удалось ли вытащить Common Name + if (c.name && c.name[1]) { + c.name = c.name[1]; + } + + c.validFrom = getReadableDate(c.validFrom); + c.validTo = getReadableDate(c.validTo); + + c.label = c.name + ' (до ' + c.validTo + ')'; + + return c; + }); +} + +/** + * Возвращает расшифрованные ОИД'ы + * */ +function getDecodedExtendedKeyUsage() { + var that = this; + + return new Promise(function (resolve) { + that.getExtendedKeyUsage().then(function (certOids) { + resolve(certOids.reduce(function (oidsLst, oid) { + oid = { + id: oid, + descr: oids[oid] || null + }; + + if (oid.descr) { + oidsLst.unshift(oid); + } else { + oidsLst.push(oid); + } + + return oidsLst; + }, [])); + }); + }); +} + +/** + * Проверка наличия ОИД'а(ОИД'ов) у сертификата + * + * @param {String|Array} oids - ОИД'ы для проверки + * @returns {Promise} с отложенным результатом типа {Boolean} + * */ +function hasExtendedKeyUsage(oids) { + var that = this; + + return new Promise(function (resolve) { + that.getExtendedKeyUsage().then(function (certOids) { + var result; + + if (Array.isArray(oids)) { + result = oids.every(function (oidToCheck) { + return certOids.some(function (certOid) { + return certOid === oidToCheck; + }); + }); + } else { + result = certOids.some(function (certOid) { + return certOid === oids; + }); + } + + resolve(result); + }); + }); +} + +/** + * Выводит информацию о системе пользователя + * */ +function getEnvInfo() { + var parsed = bowser._detect(navigator.userAgent), + info = { + browserName: parsed.name, + browserVersion: parsed.version + }; + + if (parsed.mac) { + info.os = 'Mac'; + } else if (parsed.windows) { + info.os = 'Windows'; + } else if (parsed.linux) { + info.os = 'Linux'; + } + + return info; +} + +/** + * Подходящая ли версия CSP + * */ +function isValidCSPVersion(version) { + version = version.match(/\d+?\b(?:\.\d+)?/); + + return version >= 3.6; +} + +/** + * Подходящая ли версия cades плагина + * */ +function isValidCadesVersion(version) { + version = version.split('.').reduce(function (verInfo, number, i) { + if (i === 0) { + verInfo.major = number; + } else if (i === 1) { + verInfo.minor = number; + } else if (i === 2) { + verInfo.patch = number; + } + + return verInfo; + }, {}); + + if (version.major < 2) { + return false; + } + + return version.patch >= 12438; +} + +module.exports = { + subjectNameTagsTranslations: subjectNameTagsTranslations, + issuerNameTagsTranslations: issuerNameTagsTranslations, + parseCertInfo: parseCertInfo, + getReadableDate: getReadableDate, + getDateObj: getDateObj, + prepareCertsInfo: prepareCertsInfo, + getDecodedExtendedKeyUsage: getDecodedExtendedKeyUsage, + hasExtendedKeyUsage: hasExtendedKeyUsage, + getEnvInfo: getEnvInfo, + isValidCSPVersion: isValidCSPVersion, + isValidCadesVersion: isValidCadesVersion +}; \ No newline at end of file diff --git a/src/constants.js b/src/constants.js new file mode 100755 index 0000000..89822bb --- /dev/null +++ b/src/constants.js @@ -0,0 +1,139 @@ +module.exports = { + // CAPICOM_STORE_LOCATION enumeration + StoreLocation: { + CAPICOM_MEMORY_STORE: 0, + CAPICOM_LOCAL_MACHINE_STORE: 1, + CAPICOM_CURRENT_USER_STORE: 2, + CAPICOM_ACTIVE_DIRECTORY_USER_STORE: 3, + CAPICOM_SMART_CARD_USER_STORE: 4 + }, + // CAPICOM_STORE_OPEN_MODE enumeration + StoreOpenMode: { + CAPICOM_STORE_OPEN_READ_ONLY: 0, + CAPICOM_STORE_OPEN_READ_WRITE: 1, + CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED: 2, + CAPICOM_STORE_OPEN_EXISTING_ONLY: 128, + CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED: 256 + }, + // CAPICOM_CERTIFICATE_FIND_TYPE enumeration + CertFindType: { + CAPICOM_CERTIFICATE_FIND_SHA1_HASH: 0, + CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME: 1, + CAPICOM_CERTIFICATE_FIND_ISSUER_NAME: 2, + CAPICOM_CERTIFICATE_FIND_ROOT_NAME: 3, + CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME: 4, + CAPICOM_CERTIFICATE_FIND_EXTENSION: 5, + CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY: 6, + CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY: 7, + CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY: 8, + CAPICOM_CERTIFICATE_FIND_TIME_VALID: 9, + CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID: 10, + CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED: 11, + CAPICOM_CERTIFICATE_FIND_KEY_USAGE: 12 + }, + Time: { + AUTHENTICATED_ATTRIBUTE_SIGNING_TIME: 0 + }, + Check: { + CHECK_NONE: 0, + CHECK_TRUSTED_ROOT: 1, + CHECK_TIME_VALIDITY: 2, + CHECK_SIGNATURE_VALIDITY: 4, + CHECK_ONLINE_REVOCATION_STATUS: 8, + CHECK_OFFLINE_REVOCATION_STATUS: 16, + TRUST_IS_NOT_TIME_VALID: 1, + TRUST_IS_NOT_TIME_NESTED: 2, + TRUST_IS_REVOKED: 4, + TRUST_IS_NOT_SIGNATURE_VALID: 8, + TRUST_IS_NOT_VALID_FOR_USAGE: 16, + TRUST_IS_UNTRUSTED_ROOT: 32, + TRUST_REVOCATION_STATUS_UNKNOWN: 64, + TRUST_IS_CYCLIC: 128, + TRUST_IS_PARTIAL_CHAIN: 65536, + TRUST_CTL_IS_NOT_TIME_VALID: 131072, + TRUST_CTL_IS_NOT_SIGNATURE_VALID: 262144, + TRUST_CTL_IS_NOT_VALID_FOR_USAGE: 524288, + }, + // CAPICOM_PROPID enumeration + PropId: { + CAPICOM_PROPID_UNKNOWN: 0, + CAPICOM_PROPID_KEY_PROV_HANDLE: 1, + CAPICOM_PROPID_KEY_PROV_INFO: 2, + CAPICOM_PROPID_SHA1_HASH: 3, + CAPICOM_PROPID_HASH_PROP: 3, + CAPICOM_PROPID_MD5_HASH: 4, + CAPICOM_PROPID_KEY_CONTEXT: 5, + CAPICOM_PROPID_KEY_SPEC: 6, + CAPICOM_PROPID_IE30_RESERVED: 7, + CAPICOM_PROPID_PUBKEY_HASH_RESERVED: 8, + CAPICOM_PROPID_ENHKEY_USAGE: 9, + CAPICOM_PROPID_CTL_USAGE: 9, + CAPICOM_PROPID_NEXT_UPDATE_LOCATION: 10, + CAPICOM_PROPID_FRIENDLY_NAME: 11, + CAPICOM_PROPID_PVK_FILE: 12, + CAPICOM_PROPID_DESCRIPTION: 13, + CAPICOM_PROPID_ACCESS_STATE: 14, + CAPICOM_PROPID_SIGNATURE_HASH: 15, + CAPICOM_PROPID_SMART_CARD_DATA: 16, + CAPICOM_PROPID_EFS: 17, + CAPICOM_PROPID_FORTEZZA_DATA: 18, + CAPICOM_PROPID_ARCHIVED: 19, + CAPICOM_PROPID_KEY_IDENTIFIER: 20, + CAPICOM_PROPID_AUTO_ENROLL: 21, + CAPICOM_PROPID_PUBKEY_ALG_PARA: 22, + CAPICOM_PROPID_CROSS_CERT_DIST_POINTS: 23, + CAPICOM_PROPID_ISSUER_PUBLIC_KEY_MD5_HASH: 24, + CAPICOM_PROPID_SUBJECT_PUBLIC_KEY_MD5_HASH: 25, + CAPICOM_PROPID_ENROLLMENT: 26, + CAPICOM_PROPID_DATE_STAMP: 27, + CAPICOM_PROPID_ISSUER_SERIAL_NUMBER_MD5_HASH: 28, + CAPICOM_PROPID_SUBJECT_NAME_MD5_HASH: 29, + CAPICOM_PROPID_EXTENDED_ERROR_INFO: 30, + CAPICOM_PROPID_RENEWAL: 64, + CAPICOM_PROPID_ARCHIVED_KEY_HASH: 65, + CAPICOM_PROPID_FIRST_RESERVED: 66, + CAPICOM_PROPID_LAST_RESERVED: 0x00007FFF, + CAPICOM_PROPID_FIRST_USER: 0x00008000, + CAPICOM_PROPID_LAST_USER: 0x0000FFFF + }, + // CADESCOM_XML_SIGNATURE_TYPE enumeration + SignatureType: { + CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED: 0, + CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING: 1, + CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE: 2 + }, + // CADESCOM_HASH_ALGORITHM enumeration + HashAlgorithm: { + CADESCOM_HASH_ALGORITHM_CP_GOST_3411: 100, + CADESCOM_HASH_ALGORITHM_MD2: 1, + CADESCOM_HASH_ALGORITHM_MD4: 2, + CADESCOM_HASH_ALGORITHM_MD5: 3, + CADESCOM_HASH_ALGORITHM_SHA_256: 4, + CADESCOM_HASH_ALGORITHM_SHA_384: 5, + CADESCOM_HASH_ALGORITHM_SHA_512: 6, + CADESCOM_HASH_ALGORITHM_SHA1: 0 + }, + CadesType: { + CADESCOM_CADES_DEFAULT: 0, + CADESCOM_CADES_BES: 1, + CADESCOM_CADES_X_LONG_TYPE_1: 0x5d + }, + ContentEncoding: { + CADESCOM_BASE64_TO_BINARY: 0x01, + CADESCOM_STRING_TO_UCS2LE: 0x00 + }, + StoreNames: { + CAPICOM_MY_STORE: 'My' + }, + Chain: { + CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT: 0, + CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN: 1, + CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY: 2 + }, + GostXmlDSigUrls: { + XmlDsigGost3410Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411', + XmlDsigGost3411Url: 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411', + XmlDsigGost3410UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411', + XmlDsigGost3411UrlObsolete: 'http://www.w3.org/2001/04/xmldsig-more#gostr3411' + } +}; \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100755 index 0000000..5bebe4b --- /dev/null +++ b/src/index.js @@ -0,0 +1,103 @@ +require('./cades'); + +var global = Function('return this')(), + canPromise = Boolean(global.Promise), + cadesplugin = global.cadesplugin, + canAsync = Boolean(cadesplugin.CreateObjectAsync), + CryptoProConfig = global.CryptoProConfig, + cryptoService, + _errorMsg = '', + _isLoaded = false, + _onLoadCbQueue = []; + +function execOnloadQueue() { + _onLoadCbQueue.forEach(function (callback) { + callback(); + }); +} + +function passToWaitOnLoad(callback) { + if (Object.prototype.toString.call(callback) === '[object Function]') { + _onLoadCbQueue.push(callback); + } +} + +function callOnLoad(method) { + _isLoaded ? method() : passToWaitOnLoad(method); +} + +function finishLoading() { + _isLoaded = true; + + execOnloadQueue(); +} + +function call() { + var args = Array.prototype.slice.call(arguments), + methodName = args.shift(); + + return new Promise(function (resolve, reject) { + callOnLoad(function () { + var method; + + if (_errorMsg) { + reject(_errorMsg); + return; + } + + method = cryptoService[methodName]; + + if (!method) { + reject('Метод "' + methodName + '" не доступен'); + return; + } + + method.apply(null, args).then(resolve, reject); + }); + }); +} + +if (cadesplugin) { + canAsync = Boolean(cadesplugin.CreateObjectAsync); + + // Уровень отладки (LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_ERROR) + cadesplugin.set_log_level(cadesplugin.LOG_LEVEL_ERROR); + + // Получаем указанные конфиги + if (CryptoProConfig && CryptoProConfig.publicPath) { + __webpack_public_path__ = CryptoProConfig.publicPath; + } else { + throw new Error('Не указан путь к компонентам CryptoPro'); + } + + if (canPromise) { + cadesplugin.then( + function () { + if (canAsync) { + require.ensure([], function () { + cryptoService = require('./apiAsync'); + finishLoading(); + }); + } else { + require.ensure([], function () { + cryptoService = require('./apiSync'); + finishLoading(); + }); + } + }, + + function () { + _errorMsg = 'КриптоПРО ЭЦП Browser Plug-In не доступен'; + finishLoading(); + } + ); + } else { + throw new Error('Не поддерживаются промисы. Необходим полифилл.'); + } +} else { + throw new Error('Не подключен модуль для работы с cades plugin'); +} + +module.exports = { + call: call +}; \ No newline at end of file diff --git a/src/oids.js b/src/oids.js new file mode 100755 index 0000000..2cee4e0 --- /dev/null +++ b/src/oids.js @@ -0,0 +1,44 @@ +module.exports = { + '1.2.840.113549.1.9.2': 'Неструктурированное имя', + '1.2.643.3.141.1.1': 'РНС ФСС', + '1.2.643.3.141.1.2': 'КП ФСС', + '1.2.643.3.131.1.1': 'ИНН', + '1.3.6.1.5.5.7.3.2': 'Проверка подлинности клиента', + '1.3.6.1.5.5.7.3.4': 'Защищенная электронная почта', + '1.2.643.3.8.100.1': 'Сертификат типа "ekey-ГОСТ"', + '1.2.643.3.8.100.1.1': 'Общее использование в системах ИОК без права заверения финансовых документов', + '1.2.643.3.8.100.1.2': 'Передача отчетности по ТКС', + '1.2.643.3.8.100.1.3': 'Оформление взаимных обязательств, соглашений, договоров, актов и т.п.', + '1.2.643.3.8.100.1.4': 'Внутрикорпоративный документооборот', + '1.2.643.3.8.100.1.5': 'Использование в системах электронной торговли', + '1.2.643.3.8.100.1.6': 'Использование в торгово-закупочной системе "ЭЛЕКТРА"', + '1.2.643.6.2.1.7.2': 'Использование физическим лицом в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских прав и обязанностей в отношении инвестиционных паев паевых инвестиционных фондов, в том числе отношения, связанные с учетом и/или фиксацией прав на инвестиционные паи паевых инвестиционных фондов', + '1.2.643.6.2.1.7.1': 'Использование единоличным исполнительным органом юридического лица или уполномоченными представителями юридического лица в отношениях, связанных с возникновением, исполнением (осуществлением) и прекращением гражданских и иных прав и обязанностей в сфере негосударственного пенсионного обеспечения, негосударственного пенсионного страхования, в сфере деятельности паевых инвестиционных фондов, акционерных инвестиционных фондов, профессиональных участников рынка ценных бумаг, а также связанной с обслуживанием указанной деятельности услуг кредитных и иных организаций', + '1.3.6.1.4.1.29919.21': 'Использование в системе Портал государственных закупок Ростовской области "Рефери".', + '1.2.643.3.2.100.65.13.11': 'Использование в системе АИС "Госзакупки" Сахалинской области.', + '1.2.643.3.8.100.1.7': 'Использование в системе Портал государственных закупок Ставропольского края.', + '1.2.643.3.8.100.1.8': 'Использование в Единой системе электронной торговли B2B-Center и B2G.', + '1.2.643.3.8.100.1.9': 'Для участия в электронных торгах и подписания государственного контракта в электронной площадке ОАО «ЕЭТП» уполномоченными лицами участников размещения государственного или муниципального заказа', + '1.2.643.3.8.100.1.10': 'Для участия в электронных торгах и подписания государственного контракта в информационных системах Тендерного комитета города Москвы уполномоченными лицами участников размещения государственного заказа города Москвы', + '1.2.643.3.8.100.1.11': 'Подписание электронных документов в автоматизированной информационной системе размещения государственного и муниципального заказа Саратовской области', + '1.2.643.3.8.100.1.12': 'Использование в системе государственного заказа Иркутской области', + '1.2.643.3.8.100.1.13': 'Использование в электронной торговой площадке агентства государственного заказа Красноярского края', + '1.3.6.1.4.1.24138.1.1.8.1': 'Обеспечение юридической значимости в Системе "Электронная Торговая Площадка"', + '1.2.643.3.8.100.1.14': 'Использование в электронной торговой площадке "Тендер"', + '1.2.643.6.3': 'Использование в электронных торговых системах и в программном обеспечении, связанным с обменом электронных сообщений', + '1.2.643.2.2.34.6': 'Пользователь Центра Регистрации', + '1.2.643.2.39.1.1': 'Использование в программных продуктах системы "1С:Предприятие 8"', + '1.2.643.5.1.24.2.1.3': 'Формирование документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя', + '1.2.643.5.1.24.2.1.3.1': 'Формирование кадастровым инженером документов для получения государственных услуг в сфере ведения государственного кадастра недвижимости со стороны заявителя', + '1.2.643.5.1.24.2.2.2': 'Формирование документов как результата оказания услуги со стороны органов регистрации прав', + '1.2.643.5.1.24.2.2.3': 'Формирование документов для получения государственных услуг в сфере государственной регистрации прав на недвижимое имущество и сделок с ним со стороны заявителя', + '1.2.643.6.3.1.1': 'Использование на электронных площадок отобранных для проведения аукционах в электронной форме', + '1.2.643.6.3.1.2.1': 'Тип участника - Юридическое лицо', + '1.2.643.6.3.1.2.2': 'Тип участника - Физическое лицо', + '1.2.643.6.3.1.2.3': 'Тип участника - Индивидуальный предприниматель', + '1.2.643.6.3.1.3.1': 'Участник размещения заказа', + '1.2.643.6.3.1.4.1': 'Администратор организации', + '1.2.643.6.3.1.4.2': 'Уполномоченный специалист', + '1.2.643.6.3.1.4.3': 'Специалист с правом подписи контракта', + '1.3.643.3.8.100.15': 'Использование в ЭТП "uTender"' +}; \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js new file mode 100755 index 0000000..4f2d4b6 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,11 @@ +module.exports = { + context: __dirname + '/src', + entry: './index.js', + output: { + path: 'dist', + filename: 'crypto-pro.js', + library: 'CryptoPro' + }, + devtool: 'source-map', + watch: true +}; \ No newline at end of file