20

The structure of a .mobileprovision file looks something like this:

<!-- small binary data -->

<?xml version="1.0" encoding="UTF-8"?>
<!-- plist data -->
</plist>

<!-- large binary data -->

I have a few questions around this:

  1. What is this binary data?
  2. Is it useful?
  3. How can I extract the plist from a .mobileprovision file without searching for XML boundaries?

Specifically, I will consider this question as answered (and award the +100 bounty alongwith it) when both Q1 and Q3 above are answered.

Jessedc
  • 12,320
  • 3
  • 50
  • 63
Chaitanya Gupta
  • 4,043
  • 2
  • 31
  • 41

5 Answers5

26

I finally got the answer from an answer to another question on SO.

Basically the .mobileprovision file is a CMS encrypted XML file. It can be decoded using security on OS X:

security cms -D -i /path/to/profile.mobileprovision
Community
  • 1
  • 1
Chaitanya Gupta
  • 4,043
  • 2
  • 31
  • 41
  • The information you get from this method can also be gotten by just opening the mobileprovision in a text editor. after the XML, there is a block of extra data which using `security` will not decode. – n_b Nov 26 '13 at 02:33
  • 1
    I know; that is precisely why I asked this question. What I wanted was a programmable/scriptable way of getting just the XML and nothing else. – Chaitanya Gupta Nov 26 '13 at 17:37
7

I don't have an answer to your initial question, but I can explain how to extract the signing certificate from the .mobileprovision file:

  1. The plist part of the .mobileprovision has a key 'DeveloperCertificates', whose value is an array of NSData.
  2. Each NSData is a .cer file - the signing certificate you are looking for.

I have a short shell script for extracting the subject of the signing certificate directly from the .mobileprovision file here: https://gist.github.com/2147247 - the script works with only one certificate in the array mentioned earlier, which should be the common case.

As you can see in the script, I have no answer to your third question, I am just cutting away the first line and everything after the closing tag.

NeoNacho
  • 680
  • 1
  • 5
  • 13
  • Thanks a lot. While, as you said, it does not answer the initial question, it was still very useful -- I finally learned that the certificate in the 'DeveloperCertificates' key is an x509 cert, something I was planning to ask on SO ;-) Thank you. – Chaitanya Gupta Mar 21 '12 at 17:40
2

use

security cms -D -i /path/to/profile.mobileprovision

if you get the error message security: SecPolicySetValue: One or more parameters passed to a function were not valid just pipe the error to /dev/null

security cms -D -i /path/to/profile.mobileprovision 2> /dev/null
schmichri
  • 514
  • 5
  • 13
2

The .mobileprovision file is a DER encoded ASN.1,

The plist is one of the values stored in this ASN.1 message.

Tal Aloni
  • 1,429
  • 14
  • 14
1

The file is basically the public distribution key + Apple public certificate chain + allowed devices that can be installed on to - as long as the IPA file is likewise signed.

Your key is encoded in to the plist entry. and the binary data after the plist are the associated public certficates: the Apple Root public certificate (downloadable from Apple and the Apple iPhone Certification Authority (downloadable via your Apple portal).

[Updated based on comments]

The real goal is to work out the certificate "common name" used my the mobile provision file so that the app can be re-signed.

Inside the mobile provisioning file ApplicationIdentifierPrefix tag contains the certificate UserID. This number could be used to find the certificate in the keychain tool.

So manually, the steps would be:

  1. Extract the ApplicationIdentifierPrefix number from the .mobileprovision file
  2. Open the keychain app. Look through each login/certificate to find the one with matching UserId

To automate the process

  1. run some fancy unix command to extract the ID
  2. run security find-certificate -a >a.out then grep for the ID. Then find the common name from the same record.
peterept
  • 4,407
  • 23
  • 32
  • Basically I want to resign an app with a different provisioning file. I was wondering if, instead of explicitly specifying the certificate name to resign the app with, we could extract the signing certificate info from the new provisioning profile itself. Looking at the contents of a .mobileprovision file led me to this. – Chaitanya Gupta Mar 15 '12 at 10:11
  • How do I extract just the plist info from this file? – Chaitanya Gupta Mar 15 '12 at 10:13
  • AFAIK you can't resign - because you have to sign the binaries as well during compile time in XCode and then the final IPA. Although the later may just be adding the XX.mobileprovisiong file in to the app package as embedded.mobileprovisioning. So your situation is you have a binary IPA/APP but not the source? – peterept Mar 15 '12 at 10:13
  • 1
    This [document](http://www.trailofbits.com/resources/ios4_security_evaluation_paper.pdf) has a good analysis of how the provisioning security is managed. – peterept Mar 15 '12 at 10:16
  • No I am not looking at the plist file in the ipa. Our deployment process is like this -- we embed an app with the ad hoc provisioning profile for beta testing. If beta testing goes fine, we just resign the same app with the app store provisioning profile using the `xcrun` command. Now, the relevant incantation of this command requires me to provide _both_ the provisioning profile and the signing certificate name. Since the provisioning profile does contain signing cert info, I was wondering if we could avoid having to write that. – Chaitanya Gupta Mar 15 '12 at 10:21
  • oh wow, that is a nice idea, I've never actually tried that - I've always rebuilt the project and signed it at that time with either AdHoc or AppStore certificate and the identical certificate name. I just keep that information in a config file, and then have a build script which runs xcodebuild and xcrun. – peterept Mar 15 '12 at 10:39
  • Yeah, using `xcrun`, you don't need to recompile the entire project -- you can just resign the existing .app and get a new ipa. See http://stackoverflow.com/questions/2664885/xcode-build-and-archive-from-command-line for more details. This is cool because you know for sure the binary that you submit to app store is the _same_ binary that your beta testers used. We have tried it, and it works. A side benefit is that you don't need to create a separate dsym file for crash reports. – Chaitanya Gupta Mar 15 '12 at 10:46
  • I will be interested try it. Most of my apps are tested against our distribution certificate and released with a clients app store certificate, so in our case the "Common name" certificate differs (and I pass that name in both xcodebuild and xcrun). So I wonder if re-signing only works if the common name is the same? – peterept Mar 15 '12 at 10:51
  • I did some digging, and can see how the identifier in the .mobileprovision file can lead to the correct common name, which can then be used for signing. I didn't come up with the exact commands to automate it, but I'm sure it wouldn't be hard with a bit of unix cleverness. – peterept Mar 15 '12 at 11:17
  • You pass the signing identity while resigning (using `xcrun` command), so I believe you should be able to sign it with a different cert even if the common name differs. – Chaitanya Gupta Mar 16 '12 at 06:52
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/8955/discussion-between-chaitanya-gupta-and-peterept) – Chaitanya Gupta Mar 16 '12 at 07:00
  • Searching for the value of `ApplicationIdentifierPrefix` doesn't work -- I was unable to find any of my developer or distribution certs this way. Though this does locate our push cert. A better way is to find a way to decode the values in `DeveloperCertificates` key. It contains `NSData` values and if you try to pass that data to the `strings` utility you'll be see that it contains complete info about the signing authority(ies). – Chaitanya Gupta Mar 16 '12 at 07:17