Check if a configuration profile is installed on iOS

时间:2021-09-20 12:04:05

Configuration profiles can be downloaded to an iOS device through Safari to configure the device in a certain way. You can do things like force the user to set a passcode or set restrictions like not allowing them to install apps or not allowing access to Safari. They’re created using iPhone Configuration Utility. There’s no API to check if a profile is installed but you can check indirectly. You basically embed a certificate authority in the configuration profile. When the profile is installed it also installs the certificate authority. You create a certificate signed by the certificate authority and embed it in the app. Then in the app you check if the embedded certificate is trusted which indirectly tells you whether the profile is installed. I got most of the information from this blog post but it took me a little while to work out what certificates to create so this version is a bit more comprehensive.

In Keychain Access goto Keychain Access > Certificate Assistant > Create a Certificate Authority…

Check if a configuration profile is installed on iOS

Check “Let me override defaults” and keep the defaults in the subsequent steps apart from the one’s shown below:

Check if a configuration profile is installed on iOS

Uncheck “Sign your invitation”.

Check if a configuration profile is installed on iOS

You might need to change the email address.

Check if a configuration profile is installed on iOS

You can set capabilities to “Any”, though I’m not sure if it makes much difference.

When you’re finished creating the certificate authority it should show up in the login certificates. From there export the certificate authority as a .cer file. Don’t set any password on the exported certificate. If you want to delete the certificate authority and create it again deleting it in Kechain Access doesn’t remove it properly. You will need to go to ~/Library/Application Support/Certificate Authority and delete the relevant folder there.

Next open iPhone Configuration Utility. Select “Configuration Profiles” on the left and create a new configuration profile. Scroll down to Credentials and press the “Configure” button on the right and select the certificate you just exported.

Check if a configuration profile is installed on iOS

Check if a configuration profile is installed on iOS

Now export your configuration profile. You will probably need to sign it before you upload it to a web server so it shows up as “Verified” on the device. The mime type of the .mobileconfig files needs to be set to application/x-apple-aspen-config on your web server.

You will now need to create a certificate signed by the certificate authority. Go back to Keychain Access and goto Keychain Access > Certificate Assistant > Create a Certificate…

Check if a configuration profile is installed on iOS

Set the identity type to “Leaf” and check “Let me override defaults”. Keep the defaults in the subsequent steps apart from the screens shown below:

Check if a configuration profile is installed on iOS

You might want to change the email address.

Check if a configuration profile is installed on iOS

You can set capabilities to “Any”, though I’m not sure if it makes much difference.

Again this certificate will be added to login keychains. Export the certificate as a .cer file and add it to XCode and make sure it’s part of your app’s package.

Use the following code to check if the profile is installed:

NSString* certPath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"];

02.if (certPath==nil)
03.return TernaryIndefinite;
04.NSData* certData = [NSData dataWithContentsOfFile:certPath];
05.SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData);
06.SecPolicyRef policy = SecPolicyCreateBasicX509();
07.SecTrustRef trust;
08.OSStatus err = SecTrustCreateWithCertificates((__bridge CFArrayRef) [NSArray arrayWithObject:(__bridge id)cert], policy, &trust);
09.SecTrustResultType trustResult = -1;
10.err = SecTrustEvaluate(trust, &trustResult);
11.CFRelease(trust);
12.CFRelease(policy);
13.CFRelease(cert);
14. 
15.if(trustResult == kSecTrustResultUnspecified)
16.// Profile is installed
17.else
18.// Profile not installed