UNPKG

passkit-generator

Version:

The easiest way to generate custom Apple Wallet passes in Node.js

101 lines 6.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createHash = createHash; exports.create = create; const tslib_1 = require("tslib"); const node_forge_1 = tslib_1.__importDefault(require("node-forge")); const node_buffer_1 = require("node:buffer"); /** * Creates an hash for a buffer. Used by manifest * * @param buffer * @returns */ function createHash(buffer) { const hashFlow = node_forge_1.default.md.sha1.create(); hashFlow.update(buffer.toString("binary")); return hashFlow.digest().toHex(); } /** * Generates the PKCS #7 cryptografic signature for the manifest file. * * @method create * @params manifest * @params certificates * @returns */ function create(manifestBuffer, certificates) { const signature = node_forge_1.default.pkcs7.createSignedData(); signature.content = new node_forge_1.default.util.ByteStringBuffer(manifestBuffer); const { wwdr, signerCert, signerKey } = parseCertificates(getStringCertificates(certificates)); signature.addCertificate(wwdr); signature.addCertificate(signerCert); /** * authenticatedAttributes belong to PKCS#9 standard. * It requires at least 2 values: * • content-type (which is a PKCS#7 oid) and * • message-digest oid. * * Wallet requires a signingTime. */ signature.addSigner({ key: signerKey, certificate: signerCert, digestAlgorithm: node_forge_1.default.pki.oids.sha1, authenticatedAttributes: [ { type: node_forge_1.default.pki.oids.contentType, value: node_forge_1.default.pki.oids.data, }, { type: node_forge_1.default.pki.oids.messageDigest, }, { type: node_forge_1.default.pki.oids.signingTime, }, ], }); /** * We are creating a detached signature because we don't need the signed content. * Detached signature is a property of PKCS#7 cryptography standard. */ signature.sign({ detached: true }); /** * Signature here is an ASN.1 valid structure (DER-compliant). * Generating a non-detached signature, would have pushed inside signature.contentInfo * (which has type 16, or "SEQUENCE", and is an array) a Context-Specific element, with the * signed content as value. * * In fact the previous approach was to generating a detached signature and the pull away the generated * content. * * That's what happens when you copy a fu****g line without understanding what it does. * Well, nevermind, it was funny to study BER, DER, CER, ASN.1 and PKCS#7. You can learn a lot * of beautiful things. ¯\_(ツ)_/¯ */ return node_buffer_1.Buffer.from(node_forge_1.default.asn1.toDer(signature.toAsn1()).getBytes(), "binary"); } /** * Parses the PEM-formatted passed text (certificates) * * @param element - Text content of .pem files * @param passphrase - passphrase for the key * @returns The parsed certificate or key in node forge format */ function parseCertificates(certificates) { const { signerCert, signerKey, wwdr, signerKeyPassphrase } = certificates; return { signerCert: node_forge_1.default.pki.certificateFromPem(signerCert.toString("utf-8")), wwdr: node_forge_1.default.pki.certificateFromPem(wwdr.toString("utf-8")), signerKey: node_forge_1.default.pki.decryptRsaPrivateKey(signerKey.toString("utf-8"), signerKeyPassphrase), }; } function getStringCertificates(certificates) { return { signerKeyPassphrase: certificates.signerKeyPassphrase, wwdr: node_buffer_1.Buffer.from(certificates.wwdr).toString("utf-8"), signerCert: node_buffer_1.Buffer.from(certificates.signerCert).toString("utf-8"), signerKey: node_buffer_1.Buffer.from(certificates.signerKey).toString("utf-8"), }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2lnbmF0dXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL1NpZ25hdHVyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVdBLGdDQUtDO0FBV0Qsd0JBbUVDOztBQTlGRCxvRUFBK0I7QUFFL0IsNkNBQXFDO0FBRXJDOzs7OztHQUtHO0FBRUgsU0FBZ0IsVUFBVSxDQUFDLE1BQWM7SUFDeEMsTUFBTSxRQUFRLEdBQUcsb0JBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3hDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBRTNDLE9BQU8sUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ2xDLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBRUgsU0FBZ0IsTUFBTSxDQUNyQixjQUFzQixFQUN0QixZQUF3QztJQUV4QyxNQUFNLFNBQVMsR0FBRyxvQkFBSyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBRWpELFNBQVMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxvQkFBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUVwRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsR0FBRyxpQkFBaUIsQ0FDeEQscUJBQXFCLENBQUMsWUFBWSxDQUFDLENBQ25DLENBQUM7SUFFRixTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9CLFNBQVMsQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFckM7Ozs7Ozs7T0FPRztJQUVILFNBQVMsQ0FBQyxTQUFTLENBQUM7UUFDbkIsR0FBRyxFQUFFLFNBQVM7UUFDZCxXQUFXLEVBQUUsVUFBVTtRQUN2QixlQUFlLEVBQUUsb0JBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUk7UUFDcEMsdUJBQXVCLEVBQUU7WUFDeEI7Z0JBQ0MsSUFBSSxFQUFFLG9CQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXO2dCQUNoQyxLQUFLLEVBQUUsb0JBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUk7YUFDMUI7WUFDRDtnQkFDQyxJQUFJLEVBQUUsb0JBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWE7YUFDbEM7WUFDRDtnQkFDQyxJQUFJLEVBQUUsb0JBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVc7YUFDaEM7U0FDRDtLQUNELENBQUMsQ0FBQztJQUVIOzs7T0FHRztJQUVILFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUVuQzs7Ozs7Ozs7Ozs7O09BWUc7SUFFSCxPQUFPLG9CQUFNLENBQUMsSUFBSSxDQUNqQixvQkFBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQy9DLFFBQVEsQ0FDUixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUVILFNBQVMsaUJBQWlCLENBQUMsWUFBd0M7SUFDbEUsTUFBTSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixFQUFFLEdBQUcsWUFBWSxDQUFDO0lBRTFFLE9BQU87UUFDTixVQUFVLEVBQUUsb0JBQUssQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN0RSxJQUFJLEVBQUUsb0JBQUssQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxRCxTQUFTLEVBQUUsb0JBQUssQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQ3hDLFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQzNCLG1CQUFtQixDQUNuQjtLQUNELENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxxQkFBcUIsQ0FDN0IsWUFBd0M7SUFLeEMsT0FBTztRQUNOLG1CQUFtQixFQUFFLFlBQVksQ0FBQyxtQkFBbUI7UUFDckQsSUFBSSxFQUFFLG9CQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO1FBQ3RELFVBQVUsRUFBRSxvQkFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztRQUNsRSxTQUFTLEVBQUUsb0JBQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7S0FDaEUsQ0FBQztBQUNILENBQUMifQ==