mirror of
https://github.com/marcogll/passkit-generator.git
synced 2026-03-15 13:25:19 +00:00
Added certificates saving in constructor and parsing them when signature is being created; changed Manifest to be exported as a Buffer
This commit is contained in:
@@ -167,6 +167,8 @@ export default class PKPass extends Bundle {
|
||||
);
|
||||
|
||||
Object.assign(this[propsSymbol], overridesValidation);
|
||||
|
||||
this.certificates = certificates;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -491,8 +493,8 @@ export default class PKPass extends Bundle {
|
||||
}
|
||||
}
|
||||
|
||||
private [createManifestSymbol]() {
|
||||
return Object.entries(this[filesSymbol]).reduce<{
|
||||
private [createManifestSymbol](): Buffer {
|
||||
const manifest = Object.entries(this[filesSymbol]).reduce<{
|
||||
[key: string]: string;
|
||||
}>((acc, [fileName, buffer]) => {
|
||||
const hashFlow = forge.md.sha1.create();
|
||||
@@ -504,6 +506,8 @@ export default class PKPass extends Bundle {
|
||||
[fileName]: hashFlow.digest().toHex(),
|
||||
};
|
||||
}, {});
|
||||
|
||||
return Buffer.from(JSON.stringify(manifest));
|
||||
}
|
||||
|
||||
private [closePassSymbol]() {
|
||||
@@ -576,10 +580,13 @@ export default class PKPass extends Bundle {
|
||||
}
|
||||
}
|
||||
|
||||
const manifest = this[createManifestSymbol]();
|
||||
super.addBuffer("manifest.json", Buffer.from(JSON.stringify(manifest)));
|
||||
const manifestBuffer = this[createManifestSymbol]();
|
||||
super.addBuffer("manifest.json", manifestBuffer);
|
||||
|
||||
const signatureBuffer = Signature.create(manifest, this.certificates);
|
||||
const signatureBuffer = Signature.create(
|
||||
manifestBuffer,
|
||||
this.certificates,
|
||||
);
|
||||
super.addBuffer("signature", signatureBuffer);
|
||||
}
|
||||
|
||||
|
||||
18
src/schemas/Certificates.ts
Normal file
18
src/schemas/Certificates.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import type forge from "node-forge";
|
||||
import Joi from "joi";
|
||||
|
||||
export interface CertificatesSchema {
|
||||
wwdr: string | Buffer;
|
||||
signerCert: string | Buffer;
|
||||
signerKey: string | Buffer;
|
||||
signerKeyPassphrase?: string;
|
||||
}
|
||||
|
||||
export const CertificatesSchema = Joi.object<CertificatesSchema>()
|
||||
.keys({
|
||||
wwdr: Joi.alternatives(Joi.binary(), Joi.string()).required(),
|
||||
signerCert: Joi.alternatives(Joi.binary(), Joi.string()).required(),
|
||||
signerKey: Joi.alternatives(Joi.binary(), Joi.string()).required(),
|
||||
signerKeyPassphrase: Joi.string(),
|
||||
})
|
||||
.required();
|
||||
@@ -6,6 +6,7 @@ export * from "./NFC";
|
||||
export * from "./SemanticTags";
|
||||
export * from "./PassFields";
|
||||
export * from "./Personalize";
|
||||
export * from "./Certificates";
|
||||
|
||||
import Joi from "joi";
|
||||
import debug from "debug";
|
||||
@@ -18,6 +19,7 @@ import { Field } from "./PassFieldContent";
|
||||
import { PassFields, TransitType } from "./PassFields";
|
||||
import { Personalization } from "./Personalize";
|
||||
import { Semantics } from "./SemanticTags";
|
||||
import { CertificatesSchema } from "./Certificates";
|
||||
|
||||
const schemaDebug = debug("Schema");
|
||||
|
||||
@@ -25,33 +27,6 @@ export interface FileBuffers {
|
||||
[key: string]: Buffer;
|
||||
}
|
||||
|
||||
/* export interface Certificates {
|
||||
wwdr?: string;
|
||||
signerCert?: string;
|
||||
signerKey?:
|
||||
| {
|
||||
keyFile: string;
|
||||
passphrase?: string;
|
||||
}
|
||||
| string;
|
||||
}*/
|
||||
|
||||
export interface CertificatesSchema {
|
||||
wwdr: string | Buffer;
|
||||
signerCert: string | Buffer;
|
||||
signerKey: string | Buffer;
|
||||
signerKeyPassphrase?: string;
|
||||
}
|
||||
|
||||
export const CertificatesSchema = Joi.object<CertificatesSchema>()
|
||||
.keys({
|
||||
wwdr: Joi.alternatives(Joi.binary(), Joi.string()).required(),
|
||||
signerCert: Joi.alternatives(Joi.binary(), Joi.string()).required(),
|
||||
signerKey: Joi.alternatives(Joi.binary(), Joi.string()).required(),
|
||||
signerKeyPassphrase: Joi.string(),
|
||||
})
|
||||
.required();
|
||||
|
||||
export interface PassProps {
|
||||
serialNumber?: string;
|
||||
description?: string;
|
||||
@@ -206,12 +181,6 @@ type AvailableSchemas =
|
||||
| typeof CertificatesSchema
|
||||
| typeof OverridablePassProps;
|
||||
|
||||
export type ArrayPassSchema = Beacon | Location | Barcode;
|
||||
|
||||
/* function resolveSchemaName(name: Schema) {
|
||||
return schemas[name] || undefined;
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* Checks if the passed options are compliant with the indicated schema
|
||||
* @param {any} opts - options to be checks
|
||||
|
||||
@@ -5,33 +5,25 @@ import type * as Schemas from "./schemas";
|
||||
* Generates the PKCS #7 cryptografic signature for the manifest file.
|
||||
*
|
||||
* @method create
|
||||
* @params manifest - Manifest content.
|
||||
* @params manifest
|
||||
* @params certificates
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export function create(
|
||||
manifest: { [key: string]: string },
|
||||
manifestBuffer: Buffer,
|
||||
certificates: Schemas.CertificatesSchema,
|
||||
): Buffer {
|
||||
const signature = forge.pkcs7.createSignedData();
|
||||
|
||||
signature.content = forge.util.createBuffer(
|
||||
JSON.stringify(manifest),
|
||||
"utf8",
|
||||
signature.content = forge.util.createBuffer(manifestBuffer.buffer, "utf8");
|
||||
|
||||
const { wwdr, signerCert, signerKey } = parseCertificates(
|
||||
getStringCertificates(certificates),
|
||||
);
|
||||
|
||||
const { wwdr, signerCert, signerKey, signerKeyPassphrase } = certificates;
|
||||
|
||||
const wwdrString = wwdr instanceof Buffer ? wwdr.toString("utf-8") : wwdr;
|
||||
const signerCertString =
|
||||
signerCert instanceof Buffer
|
||||
? signerCert.toString("utf-8")
|
||||
: signerCert;
|
||||
const signerKeyString =
|
||||
signerKey instanceof Buffer ? signerKey.toString("utf-8") : signerKey;
|
||||
|
||||
signature.addCertificate(wwdrString);
|
||||
signature.addCertificate(signerCertString);
|
||||
signature.addCertificate(wwdr);
|
||||
signature.addCertificate(signerCert);
|
||||
|
||||
/**
|
||||
* authenticatedAttributes belong to PKCS#9 standard.
|
||||
@@ -43,8 +35,8 @@ export function create(
|
||||
*/
|
||||
|
||||
signature.addSigner({
|
||||
key: signerKeyString,
|
||||
certificate: signerCertString,
|
||||
key: signerKey,
|
||||
certificate: signerCert,
|
||||
digestAlgorithm: forge.pki.oids.sha1,
|
||||
authenticatedAttributes: [
|
||||
{
|
||||
@@ -86,3 +78,35 @@ export function create(
|
||||
"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: Schemas.CertificatesSchema) {
|
||||
const { signerCert, signerKey, wwdr, signerKeyPassphrase } = certificates;
|
||||
|
||||
return {
|
||||
signerCert: forge.pki.certificateFromPem(signerCert.toString("utf-8")),
|
||||
wwdr: forge.pki.certificateFromPem(wwdr.toString("utf-8")),
|
||||
signerKey: forge.pki.decryptRsaPrivateKey(
|
||||
signerKey.toString("utf-8"),
|
||||
signerKeyPassphrase,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function getStringCertificates(
|
||||
certificates: Schemas.CertificatesSchema,
|
||||
): Record<keyof Schemas.CertificatesSchema, string> {
|
||||
return {
|
||||
signerKeyPassphrase: certificates.signerKeyPassphrase,
|
||||
wwdr: Buffer.from(certificates.wwdr).toString("utf-8"),
|
||||
signerCert: Buffer.from(certificates.wwdr).toString("utf-8"),
|
||||
signerKey: Buffer.from(certificates.wwdr).toString("utf-8"),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user