C
C
Sign Manifest File to Generate a Passbook .pkpass file
See more Digital Signatures Examples
Demonstrates how to create a Passbook .pkpass archive by creating a signature of a manifest file and then zipping to a .pkpass archive.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
Chilkat C Downloads
#include <C_CkJsonObject.h>
#include <C_CkCrypt2.h>
#include <C_CkZip.h>
#include <C_CkStringBuilder.h>
#include <C_CkXmlCertVault.h>
#include <C_CkCert.h>
void ChilkatSample(void)
{
BOOL success;
HCkJsonObject manifest;
HCkCrypt2 crypt;
HCkZip zip;
const char *fileHash;
const char *filePath;
HCkStringBuilder sbJson;
const char *manifestPath;
HCkXmlCertVault certVault;
HCkCert appleWwdrCert;
const char *pfxPath;
const char *pfxPassword;
HCkCert cert;
HCkJsonObject jsonSignedAttrs;
const char *sigPath;
success = FALSE;
// This requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
// ---------------------------------------------------------------------------------------------
// Note: Chilkat also has the capability to do everything in-memory (no files would be involved).
// See this example: Sign Manifest File to Generate a Passbook .pkpass in Memory
// ---------------------------------------------------------------------------------------------
// First create the manifest.json
manifest = CkJsonObject_Create();
crypt = CkCrypt2_Create();
zip = CkZip_Create();
CkZip_NewZip(zip,"qa_data/p7s/pass-wallet/example.pkpass");
// Set the AppendFromDir property to prevent that relative paths from being stored in the .pkpass archive.
CkZip_putAppendFromDir(zip,"qa_data/p7s/pass-wallet/");
CkCrypt2_putHashAlgorithm(crypt,"sha1");
// Return hashes as lowercase hex.
CkCrypt2_putEncodingMode(crypt,"hexlower");
filePath = "qa_data/p7s/pass-wallet/icon.png";
fileHash = CkCrypt2_hashFileENC(crypt,filePath);
CkZip_AddFile(zip,"icon.png",FALSE);
CkJsonObject_UpdateString(manifest,"\"icon.png\"",fileHash);
filePath = "qa_data/p7s/pass-wallet/icon@2x.png";
fileHash = CkCrypt2_hashFileENC(crypt,filePath);
CkZip_AddFile(zip,"icon@2x.png",FALSE);
CkJsonObject_UpdateString(manifest,"\"icon@2x.png\"",fileHash);
filePath = "qa_data/p7s/pass-wallet/logo.png";
fileHash = CkCrypt2_hashFileENC(crypt,filePath);
CkZip_AddFile(zip,"logo.png",FALSE);
CkJsonObject_UpdateString(manifest,"\"logo.png\"",fileHash);
filePath = "qa_data/p7s/pass-wallet/logo@2x.png";
fileHash = CkCrypt2_hashFileENC(crypt,filePath);
CkZip_AddFile(zip,"logo@2x.png",FALSE);
CkJsonObject_UpdateString(manifest,"\"logo@2x.png\"",fileHash);
filePath = "qa_data/p7s/pass-wallet/pass.json";
fileHash = CkCrypt2_hashFileENC(crypt,filePath);
CkZip_AddFile(zip,"pass.json",FALSE);
CkJsonObject_UpdateString(manifest,"\"pass.json\"",fileHash);
sbJson = CkStringBuilder_Create();
CkJsonObject_EmitSb(manifest,sbJson);
manifestPath = "qa_data/p7s/pass-wallet/manifest.json";
CkStringBuilder_WriteFile(sbJson,manifestPath,"utf-8",FALSE);
CkZip_AddFile(zip,"manifest.json",FALSE);
// 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) {
printf("The Apple WWDR intermediate certificate is not installed.\n");
printf("It is available at https://developer.apple.com/certificationauthority/AppleWWDRCA.cer\n");
printf("You may alternatively load the .cer like this...\n");
success = CkCert_LoadFromFile(appleWwdrCert,"qa_data/certs/AppleWWDRCA.cer");
if (success == FALSE) {
printf("%s\n",CkCert_lastErrorText(appleWwdrCert));
CkJsonObject_Dispose(manifest);
CkCrypt2_Dispose(crypt);
CkZip_Dispose(zip);
CkStringBuilder_Dispose(sbJson);
CkXmlCertVault_Dispose(certVault);
CkCert_Dispose(appleWwdrCert);
return;
}
}
CkXmlCertVault_AddCert(certVault,appleWwdrCert);
CkCrypt2_UseCertVault(crypt,certVault);
// Use a digital certificate and private key from a PFX file (.pfx or .p12).
pfxPath = "qa_data/pfx/cert_test123.pfx";
pfxPassword = "test123";
cert = CkCert_Create();
success = CkCert_LoadPfxFile(cert,pfxPath,pfxPassword);
if (success == FALSE) {
printf("%s\n",CkCert_lastErrorText(cert));
CkJsonObject_Dispose(manifest);
CkCrypt2_Dispose(crypt);
CkZip_Dispose(zip);
CkStringBuilder_Dispose(sbJson);
CkXmlCertVault_Dispose(certVault);
CkCert_Dispose(appleWwdrCert);
CkCert_Dispose(cert);
return;
}
// Provide the signing cert (with associated private key).
success = CkCrypt2_SetSigningCert(crypt,cert);
if (success == FALSE) {
printf("%s\n",CkCrypt2_lastErrorText(crypt));
CkJsonObject_Dispose(manifest);
CkCrypt2_Dispose(crypt);
CkZip_Dispose(zip);
CkStringBuilder_Dispose(sbJson);
CkXmlCertVault_Dispose(certVault);
CkCert_Dispose(appleWwdrCert);
CkCert_Dispose(cert);
return;
}
// 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 file to produce a file named "signature".
sigPath = "qa_data/p7s/pass-wallet/signature";
// Create the "signature" file.
success = CkCrypt2_CreateP7S(crypt,manifestPath,sigPath);
if (success == FALSE) {
printf("%s\n",CkCrypt2_lastErrorText(crypt));
CkJsonObject_Dispose(manifest);
CkCrypt2_Dispose(crypt);
CkZip_Dispose(zip);
CkStringBuilder_Dispose(sbJson);
CkXmlCertVault_Dispose(certVault);
CkCert_Dispose(appleWwdrCert);
CkCert_Dispose(cert);
CkJsonObject_Dispose(jsonSignedAttrs);
return;
}
CkZip_AddFile(zip,"signature",FALSE);
// ---------------------------------------------------------------------------------------------
// 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).
success = CkZip_WriteZipAndClose(zip);
if (success == FALSE) {
printf("%s\n",CkZip_lastErrorText(zip));
CkJsonObject_Dispose(manifest);
CkCrypt2_Dispose(crypt);
CkZip_Dispose(zip);
CkStringBuilder_Dispose(sbJson);
CkXmlCertVault_Dispose(certVault);
CkCert_Dispose(appleWwdrCert);
CkCert_Dispose(cert);
CkJsonObject_Dispose(jsonSignedAttrs);
return;
}
printf("Success.\n");
CkJsonObject_Dispose(manifest);
CkCrypt2_Dispose(crypt);
CkZip_Dispose(zip);
CkStringBuilder_Dispose(sbJson);
CkXmlCertVault_Dispose(certVault);
CkCert_Dispose(appleWwdrCert);
CkCert_Dispose(cert);
CkJsonObject_Dispose(jsonSignedAttrs);
}