mirror of
https://github.com/crypto-pro-web/crypto-pro-js.git
synced 2024-11-24 00:55:00 +03:00
278 lines
8.9 KiB
JavaScript
Executable File
278 lines
8.9 KiB
JavaScript
Executable File
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
|
||
}; |