There’s three aspects to this:
-
How do you sign a configuration profile?
-
Digital identity provisioning
-
Whether this is a good idea at all
With regarding signing a configuration profile, signed profiles are actually CMS signed data values. To see this in action, take an example signed profile (I used the CFNetwork for iOS profile from our Profiles and Logs page) and dump it like so:
% xxd CFNetworkDiagnostics.mobileconfig
00000000: 3082 1665 0609 2a86 4886 f70d 0107 02a0 0..e..*.H.......
00000010: 8216 5630 8216 5202 0103 310d 300b 0609 ..V0..R...1.0...
00000020: 6086 4801 6503 0402 0130 820b 8206 092a `.H.e....0.....*
00000030: 8648 86f7 0d01 0701 a082 0b73 0482 0b6f .H.........s...o
00000040: 3c3f 786d 6c20 7665 7273 696f 6e3d 2231 <?xml version="1
00000050: 2e30 2220 656e 636f 6469 6e67 3d22 5554 .0" encoding="UT
00000060: 462d 3822 3f3e 0a3c 2144 4f43 5459 5045 F-8"?>.<!DOCTYPE
00000070: 2070 6c69 7374 2050 5542 4c49 4320 222d plist PUBLIC "-
00000080: 2f2f 4170 706c 652f 2f44 5444 2050 4c49 //Apple//DTD PLI
00000090: 5354 2031 2e30 2f2f 454e 2220 2268 7474 ST 1.0//EN" "htt
000000a0: 703a 2f2f 7777 772e 6170 706c 652e 636f p://www.apple.co
000000b0: 6d2f 4454 4473 2f50 726f 7065 7274 794c m/DTDs/PropertyL
000000c0: 6973 742d 312e 302e 6474 6422 3e0a 3c70 ist-1.0.dtd">.<p
000000d0: 6c69 7374 2076 6572 7369 6f6e 3d22 312e list version="1.
000000e0: 3022 3e0a 3c64 6963 743e 0a09 3c6b 6579 0">.<dict>..<key
000000f0: 3e43 6f6e 7365 6e74 5465 7874 3c2f 6b65 >ConsentText</ke
…
As you can see, it contains a property list that’s embedded in some wrapper. This is the CMS wrapper and you can extract it like so:
% security cms -D -i CFNetworkDiagnostics.mobileconfig
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ConsentText</key>
…
iOS does not have APIs for encoding or decoding CMS values [1]. You’ll need to write, or acquire, your own code for this.
To sign a profile you need a digital identity. Your goal is to create a profile that is trusted by the device by default. This is going to be challenging:
-
It’s hard to get a digital identity that can sign profiles so that they’re trusted by the device (more on this below).
-
Even if you can, you can’t sign on-device because that requires your app to have a copy of the digital identity, and if your app has a copy then there’s a chance that someone could extract it from the app and use it to sign their own profiles. The only reasonable way to do hold the digital identity on a server and use that to sign profiles.
The reason why the above is such a problem relates to my last point: Should you be doing this at all?
Configuration profiles are intended to be used in a managed environment. In such environments it’s typical for the initial management setup to include a custom root certificate. With that root certificate installed, any certificate issued by that root is trusted by the device. So the management system can issue a signing certificate for the profile system, and any profiles it signs are trusted.
Doing this outside of a managed environment is tricky because the built-in root certificates come from CAs that are reluctant to issue you general-purpose signing certificates.
So, are you planning to deploy this app in a managed environment?
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] We do have an API for this on macOS, namely CMSEncoder, but it’s not available on iOS.