mirror of
https://github.com/marcogll/passkit-generator.git
synced 2026-03-15 18:25:24 +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);
|
Object.assign(this[propsSymbol], overridesValidation);
|
||||||
|
|
||||||
|
this.certificates = certificates;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -491,8 +493,8 @@ export default class PKPass extends Bundle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private [createManifestSymbol]() {
|
private [createManifestSymbol](): Buffer {
|
||||||
return Object.entries(this[filesSymbol]).reduce<{
|
const manifest = Object.entries(this[filesSymbol]).reduce<{
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}>((acc, [fileName, buffer]) => {
|
}>((acc, [fileName, buffer]) => {
|
||||||
const hashFlow = forge.md.sha1.create();
|
const hashFlow = forge.md.sha1.create();
|
||||||
@@ -504,6 +506,8 @@ export default class PKPass extends Bundle {
|
|||||||
[fileName]: hashFlow.digest().toHex(),
|
[fileName]: hashFlow.digest().toHex(),
|
||||||
};
|
};
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
|
return Buffer.from(JSON.stringify(manifest));
|
||||||
}
|
}
|
||||||
|
|
||||||
private [closePassSymbol]() {
|
private [closePassSymbol]() {
|
||||||
@@ -576,10 +580,13 @@ export default class PKPass extends Bundle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const manifest = this[createManifestSymbol]();
|
const manifestBuffer = this[createManifestSymbol]();
|
||||||
super.addBuffer("manifest.json", Buffer.from(JSON.stringify(manifest)));
|
super.addBuffer("manifest.json", manifestBuffer);
|
||||||
|
|
||||||
const signatureBuffer = Signature.create(manifest, this.certificates);
|
const signatureBuffer = Signature.create(
|
||||||
|
manifestBuffer,
|
||||||
|
this.certificates,
|
||||||
|
);
|
||||||
super.addBuffer("signature", signatureBuffer);
|
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 "./SemanticTags";
|
||||||
export * from "./PassFields";
|
export * from "./PassFields";
|
||||||
export * from "./Personalize";
|
export * from "./Personalize";
|
||||||
|
export * from "./Certificates";
|
||||||
|
|
||||||
import Joi from "joi";
|
import Joi from "joi";
|
||||||
import debug from "debug";
|
import debug from "debug";
|
||||||
@@ -18,6 +19,7 @@ import { Field } from "./PassFieldContent";
|
|||||||
import { PassFields, TransitType } from "./PassFields";
|
import { PassFields, TransitType } from "./PassFields";
|
||||||
import { Personalization } from "./Personalize";
|
import { Personalization } from "./Personalize";
|
||||||
import { Semantics } from "./SemanticTags";
|
import { Semantics } from "./SemanticTags";
|
||||||
|
import { CertificatesSchema } from "./Certificates";
|
||||||
|
|
||||||
const schemaDebug = debug("Schema");
|
const schemaDebug = debug("Schema");
|
||||||
|
|
||||||
@@ -25,33 +27,6 @@ export interface FileBuffers {
|
|||||||
[key: string]: Buffer;
|
[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 {
|
export interface PassProps {
|
||||||
serialNumber?: string;
|
serialNumber?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
@@ -206,12 +181,6 @@ type AvailableSchemas =
|
|||||||
| typeof CertificatesSchema
|
| typeof CertificatesSchema
|
||||||
| typeof OverridablePassProps;
|
| 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
|
* Checks if the passed options are compliant with the indicated schema
|
||||||
* @param {any} opts - options to be checks
|
* @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.
|
* Generates the PKCS #7 cryptografic signature for the manifest file.
|
||||||
*
|
*
|
||||||
* @method create
|
* @method create
|
||||||
* @params manifest - Manifest content.
|
* @params manifest
|
||||||
|
* @params certificates
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function create(
|
export function create(
|
||||||
manifest: { [key: string]: string },
|
manifestBuffer: Buffer,
|
||||||
certificates: Schemas.CertificatesSchema,
|
certificates: Schemas.CertificatesSchema,
|
||||||
): Buffer {
|
): Buffer {
|
||||||
const signature = forge.pkcs7.createSignedData();
|
const signature = forge.pkcs7.createSignedData();
|
||||||
|
|
||||||
signature.content = forge.util.createBuffer(
|
signature.content = forge.util.createBuffer(manifestBuffer.buffer, "utf8");
|
||||||
JSON.stringify(manifest),
|
|
||||||
"utf8",
|
const { wwdr, signerCert, signerKey } = parseCertificates(
|
||||||
|
getStringCertificates(certificates),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { wwdr, signerCert, signerKey, signerKeyPassphrase } = certificates;
|
signature.addCertificate(wwdr);
|
||||||
|
signature.addCertificate(signerCert);
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* authenticatedAttributes belong to PKCS#9 standard.
|
* authenticatedAttributes belong to PKCS#9 standard.
|
||||||
@@ -43,8 +35,8 @@ export function create(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
signature.addSigner({
|
signature.addSigner({
|
||||||
key: signerKeyString,
|
key: signerKey,
|
||||||
certificate: signerCertString,
|
certificate: signerCert,
|
||||||
digestAlgorithm: forge.pki.oids.sha1,
|
digestAlgorithm: forge.pki.oids.sha1,
|
||||||
authenticatedAttributes: [
|
authenticatedAttributes: [
|
||||||
{
|
{
|
||||||
@@ -86,3 +78,35 @@ export function create(
|
|||||||
"binary",
|
"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