Sample code for 30+ languages & platforms
Lua Requires Chilkat v11.0.0+

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 Lua Downloads

Lua
local chilkat = require("chilkat")

-- 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

local manifest = chilkat.JsonObject.new()
local crypt = chilkat.Crypt2.new()

local zip = chilkat.Zip.new()
zip:new_zip("notUsedAndNeverCreated.zip")

crypt.hash_algorithm = "sha1"
-- Return hashes as lowercase hex.
crypt.encoding_mode = "hexlower"

local pngData = chilkat.BinData.new()
-- Assume we load the pngData with bytes for "icon.png" from somewhere, such as a byte array in memory.
zip:add_bd("icon.png", pngData)
local digestStr = crypt:hash_bd_enc(pngData)
manifest:update_string("\"icon.png\"", digestStr)

pngData:clear()
-- Assume we load the pngData with bytes for "icon@2x.png" from somewhere...
zip:add_bd("icon@2x.png", pngData)
digestStr = crypt:hash_bd_enc(pngData)
manifest:update_string("\"icon@2x.png\"", digestStr)

pngData:clear()
-- Assume we load the pngData with bytes for "logo.png" from somewhere...
zip:add_bd("logo.png", pngData)
digestStr = crypt:hash_bd_enc(pngData)
manifest:update_string("\"logo.png\"", digestStr)

pngData:clear()
-- Assume we load the pngData with bytes for "logo@2x.png" from somewhere...
zip:add_bd("logo@2x.png", pngData)
digestStr = crypt:hash_bd_enc(pngData)
manifest:update_string("\"logo@2x.png\"", digestStr)

local passJson = "{ .... }"   -- Contains the contents of pass.json
zip:add_string("pass.json", passJson, "utf-8")
digestStr = crypt:hash_string_enc(passJson)
manifest:update_string("\"pass.json\"", digestStr)

zip:add_string("manifest.json", manifest:emit(), "utf-8")

-- Make sure we have the Apple WWDR intermediate certificate available for
-- the cert chain in the signature.
local certVault = chilkat.XmlCertVault.new()
local appleWwdrCert = chilkat.Cert.new()
local success = appleWwdrCert:load_by_common_name("Apple Worldwide Developer Relations Certification Authority")
if not success then
    print("The Apple WWDR intermediate certificate is not installed.")
    print("It is available at https://developer.apple.com/certificationauthority/AppleWWDRCA.cer")
    print("You may alternatively load the .cer like this...")
    success = appleWwdrCert:load_from_file("qa_data/certs/AppleWWDRCA.cer")
    if not success then
        print(appleWwdrCert.last_error_text)
        return
    end
end

certVault:add_cert(appleWwdrCert)
crypt:use_cert_vault(certVault)

-- Use a digital certificate and private key from a PFX
local bdPfx = chilkat.BinData.new()
-- Assume we loaded a PFX into bdPfx....
local pfxPassword = "test123"

local cert = chilkat.Cert.new()
success = cert:load_pfx_bd(bdPfx, pfxPassword)
if not success then
    print(cert.last_error_text)
    return
end

-- Provide the signing cert (with associated private key).
success = crypt:set_signing_cert(cert)
if not success then
    print(crypt.last_error_text)
    return
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.)
local jsonSignedAttrs = chilkat.JsonObject.new()
jsonSignedAttrs:update_int("contentType", 1)
jsonSignedAttrs:update_int("signingTime", 1)
crypt.signing_attributes = jsonSignedAttrs:emit()

-- Sign the manifest JSON to produce a signature
crypt.encoding_mode = "base64"
local sig = crypt:sign_string_enc(manifest:emit())
local bdSig = chilkat.BinData.new()
bdSig:append_encoded(sig, "base64")
zip:add_bd("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
local bdZip = chilkat.BinData.new()
success = zip:write_bd(bdZip)
if not success then
    print(zip.last_error_text)
    return
end

print("Success.")