Jul 132012
 
photo

After I downloaded  iOS6 on my iPhone last week, the first icon I clicked on was Passbook only to find that Apple had not put any example passes in there. Since Passbook was the primary reason I had downloaded iOS6, I dug into the API and learned how to create a pass myself. It was a great learning experience that I want to share with others. I also provide a shell script to automate the pass generation process and also present to you, iPass.pk, a user-friendly GUI-based service to create passes.

What is a pass? 

A pass is in fact a regular zip archive a .pkpass extension. It contains the following files:

1. logo.png (optional): The file to be used as the logo.

2. background.png (optional): The file to be used as the pass’ background.

3. icon.png (optional): The file to be used as the icon.

4. manifest.json (required):This file contains a JSON object with SHA1 hashes of all files in the pass except the signature file (as its generated using manifest.json) and the manifest.json file itself. The file has the following format:

{
  "pass.json" : "<sha1 pf pass.json file>",
  "logo.png" : "sdfqefqefqef",
  ...
}

For reference, the easiest way to create a SHA1 hash in Linux is to use the command:

openssl SHA1 <filename>

5. signature (required): File created by signing the manifest.json file with the certificate

6. pass.json (required): It contains a JSON object which specifies the type, formatting, and the data to be displayed on the pass. Apple’s reference is available here, however, it is far from complete and is missing several important details. The only real way to understand pass.json is trial-and-error:  try to generate lots of passes with different options and see the outputs on iOS6 itself. So, that what I was doing for the last two weeks.I developed a few tools to helps me iterate through these options really fast. First it a C-shell script to generate passes from the command-line and second is a pass designer at iPass.pk that allows you to change the values/labels of fields in a reasonable GUI.

Let me give you a few examples of what I have learned that was not mentioned any where in Apple’s docs.  First, to privde some context, lets take a look at a sample pass file and its JSON object with a description of each field.

Screenshot of a boarding pass

Boarding Pass

The most interesting fields are: logoText, and primary, secondary, auxiliary, and header fields.  They are all labelled in this annotated screenshot. I have filled each field with <field type abbreviation><field number in the corresponding fields array>. Thus. P1 implies Primary Filed 1, i.e., the first primary field in the primaryFields array. Similarly S* denotes secondary fields, A* auxiliary fields, and H* header fields. Note their positions, font-sized, and styles. To checkout the other fields, try creating some passes using the following procedure or use the GUI at iPass.pk.

 

How to generate passes manually?

In case, you don’t want to use the GUI to iterate through the passes, you can use my C-shell script. The C-shell script in effect performs the following steps.

Step 1: Generate the Apple Developer Certificate

Go to the Apple Developer Portal and request a pass type identifier and your certificate. Export a .p12 file from the Key chain.

Step 2:  Generate key.pem and certificate.pem

openssl pkcs12 -in "My PassKit Cert.p12" -clcerts -nokeys -out certificate.pem
openssl pkcs12 -in "My PassKit Cert.p12" -nocerts -out key.pem

Step 3: Gather files 

Copy pass.json and any logo/icon/background image files in a folder.

Step 4: Generate manifest.json 

The goal is to generate JSON object which contains the SHA1 hashes of all the files your gathered in Step 3. I used the following csh script to generate manifest.json

 set MANIFEST = ../manifest.json
 echo '{' > $MANIFEST
 foreach i (*)
   set sha1 = `openssl sha1 $i | cut -d' ' -f2`
   echo \'$i\' : \'$sha1\', >> $MANIFEST
 end
 echo '}' >> $MANIFEST
 cp $MANIFEST .

Step 5: Generate signature

Execute the following csh commands to get a signature file:

set PASSWORD = xxxx
openssl smime -passin pass:$PASSWORD  -binary -sign -signer $CWD/certificate.pem -inkey $CWD/key.pem -in manifest.json -out signature xs-outform DER

Now email this file to yourself, and open it. Cool?

Step 6: Zip the pass

zip test.pkpass *

 

Now email test.pkpass to yourself and see the magic.

 

Let me know if you if you have any questions/comments about passes, this tutorial, iPass.pk, or the shell script.

 

  10 Responses to “Generating passes for iOS6′s Passbook”

  1. icon.png and icon@2x.png are now required.

  2. Hi, thank you for your tutorial!
    I have followed the steps but the pass I get is not recognised by my iPhone (it’s running iOS6 beta 3, and passes from different sources usually work). The only difference I can see with working tickets is that my generated signature file is seen as a ‘document’ instead of a ‘Unix Executable File’… Would you have an idea of what’s going on?

    • @Georges – Is there any chance you were able to get yours working because I am having the exact same issue. When I mail it to myself, it is not being recognized like the other passes that I have downloaded off of the internet. I press it and an empty box pops up with only a ‘Cancel’ button visible. Any help would be… well… helpful :)

      Thanks! Mike

      • We have the same issue indeed. And unfortunately I could’t make it work yet…

      • Hey, my pass works now!
        And actually I didn’t change anything. I was just trying to upload my pass to a webserver, send it again by email (playing with the MIME type) etc… The last thing I did was to send both my pass and a working pass in the same email and both of them were recognised on my iPhone. Since that, I have no problems anymore – but I have no idea what solved the issue.
        The little difference in my signature file I mentioned seems not to be blocking.

  3. Hi, I was following your steps and when I tried to generate signature it says:

    unable to load certificate
    140735321534940:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:696:Expecting: TRUSTED CERTIFICATE

    is there anything I should do?

    Thanks!

  4. I can’t get your method to work correctly. When I drag the pkpass file into iOS Simulator, the passcard renders correctly, but clicking the ‘Add’ button causes the following error:

    Invalid data error reading card pass.votizen.membership/123456. Manifest signature did not verify successfully

    I am successfully able to package and add the passcard, if I create it using the signpass tool, so I’ve narrowed the culprits to the p12 file or something broken in the packaging tool. I noticed that the signature file created by the signpass tool is much different than the one created by your script, but don’t know if that’s important.

    I created the p12 file from the Pass Type Id certificate in my Keychain Access.

    Do you have any ideas what I could be doing wrong?

    thanks

  5. You are missing -certfile wwdr.pem when singing the manifest

  6. Hi
    Is it possible to download passbook for ipad mini and ios7?
    Thx
    E

  7. I do not know if it’s just me or if perhaps everybody else encountering
    problems with your blog. It seems like some of the written text within your posts
    are running off the screen. Can somebody else please comment and let me know if this is happening to them too?
    This might be a issue with my browser because I’ve had this happen previously.
    Kudos

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>