crypto-pro-cadesplugin
Version:
Библиотека предоставляет API для работы c cadesplugin и Крипто Про
250 lines (214 loc) • 9.78 kB
JavaScript
'use strict';
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE Imports
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const CertificateAdjuster = require('./certificateAdjuster');
const cadescomMethods = require('./cadescomMethods');
const { doXmlSitnatureAlgorithm, doXmlSitnatureType } = require('./xmlSitnatureMethods');
const {
CAPICOM: {
CAPICOM_CURRENT_USER_STORE,
CAPICOM_MY_STORE,
CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED,
CAPICOM_CERTIFICATE_FIND_SHA1_HASH,
CAPICOM_CERTIFICATE_FIND_TIME_VALID,
CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY,
CAPICOM_PROPID_KEY_PROV_INFO,
CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME,
CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY
},
CADESCOM: {
CADESCOM_BASE64_TO_BINARY,
CADESCOM_CADES_BES,
CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED
}
} = require('./constants');
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE Object create
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @description объект предоставляет методы для получения данных о сертификатах, а так же для их подписания
*/
const CertificatesApi = Object.create(null);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE Methods
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @async
* @method about
* @description выводит информацию
*/
CertificatesApi.about = async function about() {
try {
return await cadescomMethods.oAbout();
} catch (error) {
throw new Error(error.message);
}
};
/**
* @async
* @method getCertsList
* @throws {Error}
* @description получает массив валидных сертификатов
*/
CertificatesApi.getCertsList = async function getCertsList() {
try {
const oStore = await cadescomMethods.oStore();
await oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
const certificates = await oStore.Certificates;
if (!certificates) {
throw new Error('Нет доступных сертификатов');
}
const findCertificate = await certificates.Find(CAPICOM_CERTIFICATE_FIND_TIME_VALID);
const findCertsWithPrivateKey = await findCertificate.Find(CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY, CAPICOM_PROPID_KEY_PROV_INFO);
const count = await findCertsWithPrivateKey.Count;
if (!count) {
throw new Error('Нет сертификатов с приватным ключём');
}
const createCertList = [];
for (let index = 0; index < count; index++) {
const certApi = await findCertsWithPrivateKey.Item(index + 1);
const certificateAdjuster = Object.create(CertificateAdjuster);
certificateAdjuster.init({
certApi,
issuerInfo: await certApi.IssuerName,
privateKey: await certApi.PrivateKey,
serialNumber: await certApi.SerialNumber,
subjectInfo: await certApi.SubjectName,
thumbprint: await certApi.Thumbprint,
validPeriod: {
from: await certApi.ValidFromDate,
to: await certApi.ValidToDate
}
});
createCertList.push(certificateAdjuster);
}
oStore.Close();
return createCertList;
} catch (error) {
throw new Error(error.message);
}
};
/**
* @async
* @method currentCadesCert
* @param {String} thumbprint значение сертификата
* @throws {Error}
* @description получает сертификат по thumbprint значению сертификата
*/
CertificatesApi.currentCadesCert = async function currentCadesCert(thumbprint) {
try {
if (!thumbprint) {
throw new Error('Не указано thumbprint значение сертификата');
} else if (typeof thumbprint !== 'string') {
throw new Error('Не валидное значение thumbprint сертификата');
}
const oStore = await cadescomMethods.oStore();
await oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
const certificates = await oStore.Certificates;
const count = await certificates.Count;
const findCertificate = await certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, thumbprint);
if (count) {
const certificateItem = await findCertificate.Item(1);
oStore.Close();
return certificateItem;
} else {
throw new Error(`Произошла ошибка при получении сертификата по thumbprint значению: ${thumbprint}`);
}
} catch (error) {
throw new Error(error.message);
}
};
/**
* @async
* @method getCert
* @param {String} thumbprint значение сертификата
* @throws {Error}
* @description
* Получает сертификат по thumbprint значению сертификата.
* В отличие от currentCadesCert использует для поиска коллбек функцию getCertsList
* С помощью этой функции в сертификате доступны методы из certificateAdjuster
*/
CertificatesApi.getCert = async function getCert(thumbprint) {
try {
if (!thumbprint) {
throw new Error('Не указано thumbprint значение сертификата');
} else if (typeof thumbprint !== 'string') {
throw new Error('Не валидное значение thumbprint сертификата');
}
const certList = await this.getCertsList();
for (let index = 0; index < certList.length; index++) {
if (thumbprint === certList[index].thumbprint) {
return await certList[index];
}
}
throw new Error(`Не найдено сертификата по thumbprint значению: ${thumbprint}`);
} catch (error) {
throw new Error(error.message);
}
};
/**
* @async
* @method signBase64
* @param {String} thumbprint значение сертификата
* @param {String} base64 строка в формате base64
* @param {Boolean} type тип подписи true=откреплённая false=прикреплённая
* @throws {Error}
* @description подпись строки в формате base64
*/
CertificatesApi.signBase64 = async function signBase64(thumbprint, base64, type = true) {
try {
if (!thumbprint) {
throw new Error('Не указано thumbprint значение сертификата');
} else if (typeof thumbprint !== 'string') {
throw new Error('Не валидное значение thumbprint сертификата');
}
const oAttrs = await cadescomMethods.oAtts();
const oSignedData = await cadescomMethods.oSignedData();
const oSigner = await cadescomMethods.oSigner();
const currentCert = await this.currentCadesCert(thumbprint);
const authenticatedAttributes2 = await oSigner.AuthenticatedAttributes2;
await oAttrs.propset_Name(CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME);
await oAttrs.propset_Value(new Date());
await authenticatedAttributes2.Add(oAttrs);
await oSignedData.propset_ContentEncoding(CADESCOM_BASE64_TO_BINARY);
await oSignedData.propset_Content(base64);
await oSigner.propset_Certificate(currentCert);
await oSigner.propset_Options(CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY);
return await oSignedData.SignCades(oSigner, CADESCOM_CADES_BES, type);
} catch (error) {
throw new Error(error.message);
}
};
/**
* @async
* @method signXml
* @param {String} thumbprint значение сертификата
* @param {String} xml строка в формате XML
* @param {Number} CADESCOM_XML_SIGNATURE_TYPE тип подписи 0=Вложенная 1=Оборачивающая 2=по шаблону @default 0
* @description подписание XML документа
*/
CertificatesApi.signXml = async function signXml(thumbprint, xml, cadescomXmlSignatureType = CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED) {
try {
const currentCert = await this.currentCadesCert(thumbprint);
const publicKey = await currentCert.PublicKey();
const algorithm = await publicKey.Algorithm;
const value = await algorithm.Value;
const oSigner = await cadescomMethods.oSigner();
const oSignerXML = await cadescomMethods.oSignedXml();
const { signAlgorithm, hashAlgorithm } = doXmlSitnatureAlgorithm(value);
const xmlSitnatureType = doXmlSitnatureType(cadescomXmlSignatureType);
await oSigner.propset_Certificate(currentCert);
await oSignerXML.propset_Content(xml);
await oSignerXML.propset_SignatureType(xmlSitnatureType);
await oSignerXML.propset_SignatureMethod(signAlgorithm);
await oSignerXML.propset_DigestMethod(hashAlgorithm);
return await oSignerXML.Sign(oSigner);
} catch (error) {
throw new Error(error.message);
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE Exports
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module.exports = CertificatesApi;