Wednesday, January 9, 2013

iOS Provisioning Profile demystified

Ever had to create a new provisioning profile for an iOS app? Or had to deal with not working certificates? In this post - a living document - I will try to explain some of the concepts of Apple's code signing workflow which despite the amount of resources and tech-notes has caused me so many headaches.


Why would you need to code-sign? 

In order to provide a relationship of trust between the developer and Apple, it is necessary to know who is who. So the code-signing is used to match a Developer, an Organization and an Application (code).

What is an AppID?

The AppID is an important asset of the code-signing process. It must be unique and identifies a unique Application. You will later use this AppID to create provisioning profiles.

What is a provisioning profile?

A provisioning profile associates an Application and a Developer/Organization. That is it is the association of a Certificate and an AppID.
You need to create a new provisioning profile for each application that needs to be distributed. The provisioning profile has an expiration date after which it is no longer valid. For what I have seen the distribution profile is only worth when submitting to the AppStore. I mean If you submitted an Application and the profile expires, the Application is still selling and nothing will happen. You may delete a used, unused, or expired provisioning profile from the portal with no edge effect. You will need to create a new provisioning profile to submit a new Application or an update to an already submitted Application.

This is where the importance of the AppID really shows. You can create/remove profiles but cannot remove AppIDs. I guess that Apple didn't want to manage orphan Apps and too much user issues so they may have decided to forbid AppIDs removal. Thus, when you create an AppID, take your time to re-read many times your inputs because I can tell you ... you'll be stuck with this AppID for the rest of your Developer/Organization's Account life.

One wise developer has made a safari/chrome extension that will allow you to darken AppIDs in the portal. (You can find it here on github) It's by far the best we can do.

Concerning Certificates

The certificates are the piece of code-bits that identify a developer and/or an organization. You create them by requesting them from an authority. In our case the Authority is Apple. You first create a Certificate Signing Request using the keychain for example. Then you transfer this request file to Apple's servers and get back a certificate if all is well. 

There are two main certificates you will deal with as a iOS developer. The development certificate and the distribution certificate. 

Ye be warned! If you don't backup certificates and for example you reinstall the OS, you will need to recreate them and since each provisioning profile has a reference to a certificate, you will need to recreate each profiles.

But, except for the extra work you will have to do, there is no harm, you CAN safely (as far as I can tell from my own experience...;) recreate them. The Applications already on the AppStore will not get hurt. But you will have to recreate the profiles, delete the old ones etc ... 

There are other certificates you may have to create. For example, the push certificates etc ... The very same remarks apply to them.

Push certificates

You have an Application with certificates and all is well and you'd like to add some feedback functionality through push notifications for your users. Great!
So basically there is no difficulty with this. You go to the Provisioning Portal > AppID > your AppID > update , check the "enable push notification" and with a certificate signing request you create the development and production push certificates. Download each certificate and double click them, Xcode will install them.

There is one pitfall here. Once you updated the AppID, the already existing provisioning profiles are not updated to take into account the enabled push notification. So you need to update a profile or create a new one, re-download it from Apple's and install it on your Mac. Then, remove the old one and select the new profile in the XCode build settings.

To check if an Application has a profile with push notification enabled you run this in a terminal:

$ codesign -dvvvv --entitlements - path/to/<YourAppName>.app

The output should mention an aps-environment. If not, it's a wrong profile.

Pem cert and key

On the server-side, you need to have a pem certificate in order to establish the ssl connection to Apple's push gateway. Here is how I do it:

In Keychain > Certificates > search 'push' (in the upper-right search box)

Select the certificate you want to export in the list (There MUST be a a gray triangle denoting a embedded key, else the certificate is missing it's key which is needed!) > Export "Certificates.p12"

Now, in the terminal:

$ openssl pkcs12 -clcerts -nokeys -out cert.pem -in Certificates.p12

$ openssl pkcs12 -nocerts -out key.pem -in Certificates.p12

This has created the cert.pem and key.pem

To remove the password from the key:

$ openssl rsa -in key.pem -out key.nopass.pem

If you indeed need a combined pem with certificate and key:

$ cat cert.pem key.nopass.pem > identity.pem

To be able to push a notification to Apple I have created a nodejs module named node_apns which is also available on my github profile


You should check this document from Apple


1 comment: