views:

75

answers:

3

Is there a way to determine programmatically if the currently running app was built and signed for development only or whether it was built for distribution? And can one determine if was build for app store or ad hoc distribution?

Is it e.g. possibly to access the code signature and get the information from there? Or are there certain files present in one of variants that don't exist in the other ones? Is part of the bundle info? Or can it be derived from the executable file?

Any hints are appreciated.

A: 

The obvious way to check is to look at embedded.mobileprovision ([[NSBundle mainBundle] pathForResource:@"embedded.mobileprovision" ofType:nil] or so). It's a bit of a pain to parse, but it contains all the information you'll need (App Store contains no UDIDs, Development has <key>get-task-allow</key><true/>, and Ad Hoc contains UDIDs but has get-task-allow=false). Apart from that and the certificate it's signed with, there's no difference between Development/Ad Hoc/App Store apps.

It would help if you mentioned why you want to do this. If you want to enable different features for different things, the easiest way is to set compiler macros in your build configurations.

EDIT: The provisioning profile is signed in the code signature, so you can probably assume that it isn't removed (presumably you can set it as "ignored" in ResourceRules.plist). It's also integral to the code-signing.

An easy hack is is to check something like:

NSString * profilePath = [[NSBundle mainBundle] pathForResource:@"embedded.mobileprovision" ofType:nil];
NSString * profileAsString = [NSString stringWithContentsOfFile:profilePath encoding:NSISOLatin1StringEncoding error:NULL]
bool isDevelopmentOrAdHoc = [profileAsString rangeOfString:[[UIDevice currentDevice] uniqueIdentifier] options: NSCaseInsensitiveSearch].length;

Note that there are some false-negatives (e.g. the provisioning profile doesn't need to contain the device UDID as long as a "matching" profile installed on the device does), but in general it should work.

tc.
Thanks a lot for your useful input.The reason for determining the distribution type is that I'd like to sell a library that can be used for free during development and testing but requires a license for App Store distribution.The embedded.mobileprovision files that I found in the build directory of Xcode are binary files with some XML embedded. Is this the same once the app is installed on the device, or is the XML part installed only?
Codo
A: 

It seems that the embedded.mobileprovision file is in ASN.1 format.

Codo
Well, from my research, "A provisioning profile is DER-encoded "pkcs7-signedData", consisting of an XML blob (the data), a certificate chain (Apple Root Certificate Authority → Apple iPhone Certification Authority → Apple iPhone OS Provisioning Profile Signing), and the signature" but that's not exactly useful to anyone, is it?
tc.
A: 

I've extracted an embedded.mobileprovision file and pasted into an online ASN.1 viewer (e.g. http://www.geocities.co.jp/SiliconValley-SanJose/3377/asn1JS.html), and that's what a got:

SEQUENCE {
   OBJECTIDENTIFIER 1.2.840.113549.1.7.2 (signedData)
   [0] {
      SEQUENCE {
         INTEGER 1
         SET {
            SEQUENCE {
               OBJECTIDENTIFIER 1.3.14.3.2.26
               NULL 
            }
         }
         SEQUENCE {
            OBJECTIDENTIFIER 1.2.840.113549.1.7.1 (data)
            [0] {
               OCTETSTRING 3c3f786d6c20766 ... 6c6973743e0a
            }
         }
         [0] {
            SEQUENCE {
               SEQUENCE {
                  [0] {
                     INTEGER 2
                  }
 ... [much more]

With this and some ASN.1 knowledge, your explanation makes perfect sense.

The interesting part is the octet string starting 3c3f786d6c. That's the XML part in Apple's property list format that contains all the answers about the distribution type (developer, ad-hoc, App Store).

Codo