ec-sri-invoice-signer
Version:
Ecuador SRI invoice signer.
105 lines (104 loc) • 5.22 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.signInvoiceXml = void 0;
const c14n_1 = require("../canonicalization/c14n");
const constants_1 = require("../utils/constants");
const cryptography_1 = require("../utils/cryptography");
const Utils = __importStar(require("../utils/utils"));
const keyInfo_1 = require("./templates/keyInfo");
const signature_1 = require("./templates/signature");
const signedInfo_1 = require("./templates/signedInfo");
const signedProperties_1 = require("./templates/signedProperties");
const insertSignatureIntoInvoiceXml = (invoiceXml, signatureXml) => {
return invoiceXml.replace('</factura>', `${signatureXml}</factura>`);
};
/**
*
* @param invoiceXml The invoice XML to be signed.
* @param pkcs12Data The pkcs12 file (.p12/.pfx) data expressed as a node Buffer or base64 string.
* @param options Options are:
* - **pkcs12Password**: The pkcs12 file password. Defaults to no password.
* @returns
*/
const signInvoiceXml = (invoiceXml, pkcs12Data, options) => {
const signingTime = Utils.getDate();
const { privateKey, certificate } = (0, cryptography_1.extractPrivateKeyAndCertificateFromPkcs12)(pkcs12Data, options === null || options === void 0 ? void 0 : options.pkcs12Password);
const { exponent: certificateExponent, modulus: certificateModulus } = (0, cryptography_1.extractPrivateKeyData)(privateKey);
const { issuerName: x509IssuerName, serialNumber: x509SerialNumber, content: certificateContent, contentHash: x509Hash } = (0, cryptography_1.extractX509Data)(certificate);
// IDs
const invoiceTagId = 'comprobante';
const invoiceTagRefId = `InvoiceRef-${Utils.getRandomUuid()}`;
const keyInfoTagId = `Certificate-${Utils.getRandomUuid()}`;
const keyInfoRefTagId = `CertificateRef-${Utils.getRandomUuid()}`;
const signedInfoTagId = `SignedInfo-${Utils.getRandomUuid()}`;
const signedPropertiesRefTagId = `SignedPropertiesRef-${Utils.getRandomUuid()}`;
const signedPropertiesTagId = `SignedProperties-${Utils.getRandomUuid()}`;
const signatureTagId = `Signature-${Utils.getRandomUuid()}`;
const signatureObjectTagId = `SignatureObject-${Utils.getRandomUuid()}`;
const signatureValueTagId = `SignatureValue-${Utils.getRandomUuid()}`;
// XML sections, hashes and signature
const keyInfoTag = (0, keyInfo_1.buildKeyInfoTag)({
certificateContent,
certificateExponent,
certificateModulus,
keyInfoTagId
});
const signedPropertiesTag = (0, signedProperties_1.buildSignedPropertiesTag)({
invoiceTagRefId,
signedPropertiesTagId,
signingTime,
x509Hash,
x509IssuerName,
x509SerialNumber
});
const invoiceHash = (0, cryptography_1.getHash)((0, c14n_1.c14nCanonicalize)(invoiceXml));
const signedPropertiesTagHash = (0, cryptography_1.getHash)((0, c14n_1.c14nCanonicalize)(signedPropertiesTag, { inheritedNamespaces: [{ prefix: 'xades', uri: constants_1.XmlProperties.namespaces.xades }, { prefix: 'ds', uri: constants_1.XmlProperties.namespaces.ds }] }));
const keyInfoTagHash = (0, cryptography_1.getHash)((0, c14n_1.c14nCanonicalize)(keyInfoTag, { inheritedNamespaces: [{ prefix: 'ds', uri: constants_1.XmlProperties.namespaces.ds }] }));
const signedInfoTag = (0, signedInfo_1.buildSignedInfoTag)({
invoiceHash,
invoiceTagId,
invoiceTagRefId,
keyInfoRefTagId,
keyInfoTagHash,
keyInfoTagId,
signedInfoTagId,
signedPropertiesRefTagId,
signedPropertiesTagHash,
signedPropertiesTagId
});
const signedSignedInfoTag = (0, cryptography_1.sign)((0, c14n_1.c14nCanonicalize)(signedInfoTag, { inheritedNamespaces: [{ prefix: 'ds', uri: constants_1.XmlProperties.namespaces.ds }] }), privateKey);
const signatureTag = (0, signature_1.buildSignatureTag)({
keyInfoTag,
signatureTagId,
signatureObjectTagId,
signedInfoTag,
signedSignedInfoTag,
signatureValueTagId,
signedPropertiesTag
});
return insertSignatureIntoInvoiceXml(invoiceXml, signatureTag);
};
exports.signInvoiceXml = signInvoiceXml;