PureBasic
PureBasic
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 PureBasic Downloads
IncludeFile "CkJsonObject.pb"
IncludeFile "CkXmlCertVault.pb"
IncludeFile "CkCrypt2.pb"
IncludeFile "CkZip.pb"
IncludeFile "CkStringBuilder.pb"
IncludeFile "CkCert.pb"
Procedure ChilkatExample()
success.i = 0
; 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.i = CkJsonObject::ckCreate()
If manifest.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
crypt.i = CkCrypt2::ckCreate()
If crypt.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
zip.i = CkZip::ckCreate()
If zip.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkZip::ckNewZip(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::setCkAppendFromDir(zip, "qa_data/p7s/pass-wallet/")
CkCrypt2::setCkHashAlgorithm(crypt, "sha1")
; Return hashes as lowercase hex.
CkCrypt2::setCkEncodingMode(crypt, "hexlower")
fileHash.s
filePath.s
filePath = "qa_data/p7s/pass-wallet/icon.png"
fileHash = CkCrypt2::ckHashFileENC(crypt,filePath)
CkZip::ckAddFile(zip,"icon.png",0)
CkJsonObject::ckUpdateString(manifest,Chr(34) + "icon.png" + Chr(34),fileHash)
filePath = "qa_data/p7s/pass-wallet/icon@2x.png"
fileHash = CkCrypt2::ckHashFileENC(crypt,filePath)
CkZip::ckAddFile(zip,"icon@2x.png",0)
CkJsonObject::ckUpdateString(manifest,Chr(34) + "icon@2x.png" + Chr(34),fileHash)
filePath = "qa_data/p7s/pass-wallet/logo.png"
fileHash = CkCrypt2::ckHashFileENC(crypt,filePath)
CkZip::ckAddFile(zip,"logo.png",0)
CkJsonObject::ckUpdateString(manifest,Chr(34) + "logo.png" + Chr(34),fileHash)
filePath = "qa_data/p7s/pass-wallet/logo@2x.png"
fileHash = CkCrypt2::ckHashFileENC(crypt,filePath)
CkZip::ckAddFile(zip,"logo@2x.png",0)
CkJsonObject::ckUpdateString(manifest,Chr(34) + "logo@2x.png" + Chr(34),fileHash)
filePath = "qa_data/p7s/pass-wallet/pass.json"
fileHash = CkCrypt2::ckHashFileENC(crypt,filePath)
CkZip::ckAddFile(zip,"pass.json",0)
CkJsonObject::ckUpdateString(manifest,Chr(34) + "pass.json" + Chr(34),fileHash)
sbJson.i = CkStringBuilder::ckCreate()
If sbJson.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkJsonObject::ckEmitSb(manifest,sbJson)
manifestPath.s = "qa_data/p7s/pass-wallet/manifest.json"
CkStringBuilder::ckWriteFile(sbJson,manifestPath,"utf-8",0)
CkZip::ckAddFile(zip,"manifest.json",0)
; Make sure we have the Apple WWDR intermediate certificate available for
; the cert chain in the signature.
certVault.i = CkXmlCertVault::ckCreate()
If certVault.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
appleWwdrCert.i = CkCert::ckCreate()
If appleWwdrCert.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkCert::ckLoadByCommonName(appleWwdrCert,"Apple Worldwide Developer Relations Certification Authority")
If success <> 1
Debug "The Apple WWDR intermediate certificate is not installed."
Debug "It is available at https://developer.apple.com/certificationauthority/AppleWWDRCA.cer"
Debug "You may alternatively load the .cer like this..."
success = CkCert::ckLoadFromFile(appleWwdrCert,"qa_data/certs/AppleWWDRCA.cer")
If success = 0
Debug CkCert::ckLastErrorText(appleWwdrCert)
CkJsonObject::ckDispose(manifest)
CkCrypt2::ckDispose(crypt)
CkZip::ckDispose(zip)
CkStringBuilder::ckDispose(sbJson)
CkXmlCertVault::ckDispose(certVault)
CkCert::ckDispose(appleWwdrCert)
ProcedureReturn
EndIf
EndIf
CkXmlCertVault::ckAddCert(certVault,appleWwdrCert)
CkCrypt2::ckUseCertVault(crypt,certVault)
; Use a digital certificate and private key from a PFX file (.pfx or .p12).
pfxPath.s = "qa_data/pfx/cert_test123.pfx"
pfxPassword.s = "test123"
cert.i = CkCert::ckCreate()
If cert.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkCert::ckLoadPfxFile(cert,pfxPath,pfxPassword)
If success = 0
Debug CkCert::ckLastErrorText(cert)
CkJsonObject::ckDispose(manifest)
CkCrypt2::ckDispose(crypt)
CkZip::ckDispose(zip)
CkStringBuilder::ckDispose(sbJson)
CkXmlCertVault::ckDispose(certVault)
CkCert::ckDispose(appleWwdrCert)
CkCert::ckDispose(cert)
ProcedureReturn
EndIf
; Provide the signing cert (with associated private key).
success = CkCrypt2::ckSetSigningCert(crypt,cert)
If success = 0
Debug CkCrypt2::ckLastErrorText(crypt)
CkJsonObject::ckDispose(manifest)
CkCrypt2::ckDispose(crypt)
CkZip::ckDispose(zip)
CkStringBuilder::ckDispose(sbJson)
CkXmlCertVault::ckDispose(certVault)
CkCert::ckDispose(appleWwdrCert)
CkCert::ckDispose(cert)
ProcedureReturn
EndIf
; 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.i = CkJsonObject::ckCreate()
If jsonSignedAttrs.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkJsonObject::ckUpdateInt(jsonSignedAttrs,"contentType",1)
CkJsonObject::ckUpdateInt(jsonSignedAttrs,"signingTime",1)
CkCrypt2::setCkSigningAttributes(crypt, CkJsonObject::ckEmit(jsonSignedAttrs))
; Sign the manifest JSON file to produce a file named "signature".
sigPath.s = "qa_data/p7s/pass-wallet/signature"
; Create the "signature" file.
success = CkCrypt2::ckCreateP7S(crypt,manifestPath,sigPath)
If success = 0
Debug CkCrypt2::ckLastErrorText(crypt)
CkJsonObject::ckDispose(manifest)
CkCrypt2::ckDispose(crypt)
CkZip::ckDispose(zip)
CkStringBuilder::ckDispose(sbJson)
CkXmlCertVault::ckDispose(certVault)
CkCert::ckDispose(appleWwdrCert)
CkCert::ckDispose(cert)
CkJsonObject::ckDispose(jsonSignedAttrs)
ProcedureReturn
EndIf
CkZip::ckAddFile(zip,"signature",0)
; ---------------------------------------------------------------------------------------------
; 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::ckWriteZipAndClose(zip)
If success = 0
Debug CkZip::ckLastErrorText(zip)
CkJsonObject::ckDispose(manifest)
CkCrypt2::ckDispose(crypt)
CkZip::ckDispose(zip)
CkStringBuilder::ckDispose(sbJson)
CkXmlCertVault::ckDispose(certVault)
CkCert::ckDispose(appleWwdrCert)
CkCert::ckDispose(cert)
CkJsonObject::ckDispose(jsonSignedAttrs)
ProcedureReturn
EndIf
Debug "Success."
CkJsonObject::ckDispose(manifest)
CkCrypt2::ckDispose(crypt)
CkZip::ckDispose(zip)
CkStringBuilder::ckDispose(sbJson)
CkXmlCertVault::ckDispose(certVault)
CkCert::ckDispose(appleWwdrCert)
CkCert::ckDispose(cert)
CkJsonObject::ckDispose(jsonSignedAttrs)
ProcedureReturn
EndProcedure