Sample code for 30+ languages & platforms
Delphi DLL

Sign Manifest File to Generate a Passbook .pkpass in Memory

Demonstrates how to create a Passbook .pkpass archive by creating a signature of a manifest file and then zipping to a .pkpass archive in memory

Chilkat Delphi DLL Downloads

Delphi DLL
uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Zip, XmlCertVault, JsonObject, Cert, Crypt2, BinData;

...

procedure TForm1.Button1Click(Sender: TObject);
var
success: Boolean;
manifest: HCkJsonObject;
crypt: HCkCrypt2;
zip: HCkZip;
digestStr: PWideChar;
pngData: HCkBinData;
passJson: PWideChar;
certVault: HCkXmlCertVault;
appleWwdrCert: HCkCert;
bdPfx: HCkBinData;
pfxPassword: PWideChar;
cert: HCkCert;
jsonSignedAttrs: HCkJsonObject;
sig: PWideChar;
bdSig: HCkBinData;
bdZip: HCkBinData;

begin
success := False;

// This requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.

// ---------------------------------------------------------------------------------------------
// This example is the same as Sign Manifest File to Generate a Passbook .pkpass file
// except everything happens in memory (no input files, no output files)
// ---------------------------------------------------------------------------------------------

// First create the manifest.json

manifest := CkJsonObject_Create();
crypt := CkCrypt2_Create();

zip := CkZip_Create();
CkZip_NewZip(zip,'notUsedAndNeverCreated.zip');

CkCrypt2_putHashAlgorithm(crypt,'sha1');
// Return hashes as lowercase hex.
CkCrypt2_putEncodingMode(crypt,'hexlower');

pngData := CkBinData_Create();
// Assume we load the pngData with bytes for "icon.png" from somewhere, such as a byte array in memory.
CkZip_AddBd(zip,'icon.png',pngData);
digestStr := CkCrypt2__hashBdENC(crypt,pngData);
CkJsonObject_UpdateString(manifest,'"icon.png"',digestStr);

CkBinData_Clear(pngData);
// Assume we load the pngData with bytes for "icon@2x.png" from somewhere...
CkZip_AddBd(zip,'icon@2x.png',pngData);
digestStr := CkCrypt2__hashBdENC(crypt,pngData);
CkJsonObject_UpdateString(manifest,'"icon@2x.png"',digestStr);

CkBinData_Clear(pngData);
// Assume we load the pngData with bytes for "logo.png" from somewhere...
CkZip_AddBd(zip,'logo.png',pngData);
digestStr := CkCrypt2__hashBdENC(crypt,pngData);
CkJsonObject_UpdateString(manifest,'"logo.png"',digestStr);

CkBinData_Clear(pngData);
// Assume we load the pngData with bytes for "logo@2x.png" from somewhere...
CkZip_AddBd(zip,'logo@2x.png',pngData);
digestStr := CkCrypt2__hashBdENC(crypt,pngData);
CkJsonObject_UpdateString(manifest,'"logo@2x.png"',digestStr);

passJson := '{ .... }';//  Contains the contents of pass.json
CkZip_AddString(zip,'pass.json',passJson,'utf-8');
digestStr := CkCrypt2__hashStringENC(crypt,passJson);
CkJsonObject_UpdateString(manifest,'"pass.json"',digestStr);

CkZip_AddString(zip,'manifest.json',CkJsonObject__emit(manifest),'utf-8');

// Make sure we have the Apple WWDR intermediate certificate available for 
// the cert chain in the signature.
certVault := CkXmlCertVault_Create();
appleWwdrCert := CkCert_Create();
success := CkCert_LoadByCommonName(appleWwdrCert,'Apple Worldwide Developer Relations Certification Authority');
if (success <> True) then
  begin
    Memo1.Lines.Add('The Apple WWDR intermediate certificate is not installed.');
    Memo1.Lines.Add('It is available at https://developer.apple.com/certificationauthority/AppleWWDRCA.cer');
    Memo1.Lines.Add('You may alternatively load the .cer like this...');
    success := CkCert_LoadFromFile(appleWwdrCert,'qa_data/certs/AppleWWDRCA.cer');
    if (success = False) then
      begin
        Memo1.Lines.Add(CkCert__lastErrorText(appleWwdrCert));
        Exit;
      end;

  end;
CkXmlCertVault_AddCert(certVault,appleWwdrCert);
CkCrypt2_UseCertVault(crypt,certVault);

// Use a digital certificate and private key from a PFX
bdPfx := CkBinData_Create();
// Assume we loaded a PFX into bdPfx....
pfxPassword := 'test123';

cert := CkCert_Create();
success := CkCert_LoadPfxBd(cert,bdPfx,pfxPassword);
if (success = False) then
  begin
    Memo1.Lines.Add(CkCert__lastErrorText(cert));
    Exit;
  end;

// Provide the signing cert (with associated private key).
success := CkCrypt2_SetSigningCert(crypt,cert);
if (success = False) then
  begin
    Memo1.Lines.Add(CkCrypt2__lastErrorText(crypt));
    Exit;
  end;

// Specify the signed attributes to be included.
// (These attributes appear to not be necessary, but we're including
// them just in case they become necessary in the future.)
jsonSignedAttrs := CkJsonObject_Create();
CkJsonObject_UpdateInt(jsonSignedAttrs,'contentType',1);
CkJsonObject_UpdateInt(jsonSignedAttrs,'signingTime',1);
CkCrypt2_putSigningAttributes(crypt,CkJsonObject__emit(jsonSignedAttrs));

// Sign the manifest JSON to produce a signature
CkCrypt2_putEncodingMode(crypt,'base64');
sig := CkCrypt2__signStringENC(crypt,CkJsonObject__emit(manifest));
bdSig := CkBinData_Create();
CkBinData_AppendEncoded(bdSig,sig,'base64');
CkZip_AddBd(zip,'signature',bdSig);

// ---------------------------------------------------------------------------------------------
// Note: Chilkat also has the capability to do everything in-memory (no files would be involved).  
// If this is of interest, please send email to support@chilkatsoft.com
// ---------------------------------------------------------------------------------------------

// Create the .pkipass archive (which is a .zip archive containing the required files).
// the .zip is written to bdZip
bdZip := CkBinData_Create();
success := CkZip_WriteBd(zip,bdZip);
if (success = False) then
  begin
    Memo1.Lines.Add(CkZip__lastErrorText(zip));
    Exit;
  end;

Memo1.Lines.Add('Success.');

CkJsonObject_Dispose(manifest);
CkCrypt2_Dispose(crypt);
CkZip_Dispose(zip);
CkBinData_Dispose(pngData);
CkXmlCertVault_Dispose(certVault);
CkCert_Dispose(appleWwdrCert);
CkBinData_Dispose(bdPfx);
CkCert_Dispose(cert);
CkJsonObject_Dispose(jsonSignedAttrs);
CkBinData_Dispose(bdSig);
CkBinData_Dispose(bdZip);

end;