Signing .mobileconfig Profiles With Keychain Certificates

Generating .mobileconfig profiles should be a straightforward process for the Mac admin. There are many tools to do so – Profile Manager, Apple Configurator (although it lacks the OS-X specific keys), just about every MDM, mcxToProfile, etc.

In most cases, the profiles generated this way are unsigned – meaning that there’s no verification that the profile that gets installed on a client node was the one you wrote. Generally speaking, this isn’t really an issue if you trust your deployment system. I’ve yet to see a case where anyone tried to “exploit” a profile maliciously, but if nothing else, it could be irritating to have someone hijack a profile. It’s a good security practice to ensure that your clients only get installed what you expect, and signing a profile prevents tampering.

Signing a profile is surprisingly easy, thanks to Greg Neagle who pointed me in the right direction.

First, you need to decide what certificate you want to sign your profiles with. This can be any certificate, really, but the value of signing your profile is to use a certificate that your clients automatically trust. You can either use your own institution’s trusted CA (if you have one), or you can use a certificate trusted by a root CA already in the system – such as anything by RapidSSL, StartSSL, VeriSign, etc. It must be a certificate for which you have the private key.

You can also use Apple Developer certificates, if you subscribe to the Apple developer programs (and you should, as a Mac or iOS admin – $99 goes a really, really long way).

In this example, I’m going to use my Apple Developer cert. Sign into the dev center first, and then click on “Certificates”:

Screenshot 2015-04-21 15.32.46

If you don’t already have a certificate, you can add one:
Screenshot 2015-04-21 15.32.59

Once you’ve got the certificate added and downloaded, make sure you import it and the private key into your Keychain. In this example, I’m going to use my organization’s “Developer ID Installer” certificate to sign my certificates.

How do I know which certificates I can use?

Not every certificate in your Keychain will be valid for signing. You can only sign with valid identities. To figure out which of your identities will work for signing things, you can use the security command:

/usr/bin/security find-identity -p codesigning -v

The -p codesigning argument tells it to only display identities that match the codesigning policy.

The -v argument tells security to only display valid identities. (Without this option, you could see revoked or expired identities).

Take note of the name of the certificates that this command outputs – you’ll use one of them in the next section.

Signing an individual profile:

Use the security command to sign the profile using your identity:

/usr/bin/security cms -S -N "Mac Developer Application" -i /path/to/your.mobileconfig -o /path/to/your/signed/output.mobileconfig

As the manpage suggests, the -S argument tells security cms to sign something.

The -N argument, in this case “Mac Developer Application”, tells it to sign something using a certificate that matches the name. Note: it will fail if it can’t figure out which certificate you mean. If there’s any ambiguity (i.e. more than one possible certificate that matches the string you provided), it will fail and complain. Try and be as explicit as possible, and make sure you only use a valid identity found from the previous section.

The -i argument provides an input .mobileconfig file to be signed.

The -o argument provides an output signed .mobileconfig file to be created.

NOTE: When you run this command, you’ll get a security prompt. The security command will request that access to use the keychain, each time it runs (unless you click “Always Allow”). You can control this in the Keychain Access.app by going to “Get Info” on the private key of the certificate and choosing “Access control,” and making changes there.

Signing multiple profiles:

You can use a simple bash script:


#!/bin/bash
for profile in Profiles/*.mobileconfig
do
s=${profile##*/}
outName=${s%.*}
outName+="Signed.mobileconfig"
/usr/bin/security cms -S -N "Mac Developer Application" -i $profile -o "$outName"
done

view raw

SignProfiles.sh

hosted with ❤ by GitHub

In a directory called “Profiles” that is, unsurprisingly, full of .mobileconfig files, go through each one, run the security cms command on it, and create a file with “Signed” in the name.

The s and outName variables are just fun, unreadable ways of using Bash string manipulations to insert “Signed” into the filename.

The end result is that you’ll now have a folder full of ProfileNameSigned.mobileconfig files, signed with the certificate you specified using -N.

NOTE: When you run this script, you’ll get a security prompt. The security command will request that access to use the keychain, each time it runs (unless you click “Always Allow”). You can control this in the Keychain Access.app by going to “Get Info” on the private key of the certificate and choosing “Access control,” and making changes there.

Testing the profile out:

Before deploying, try testing this profile out on a VM. When I install one of these signed VMs, this is what I see in the Profiles pane:
2

If you click on the “Verified” in green, you’ll see the certificate:
Screen Shot 2015-04-22 at 7.27.12 AM

When your profile is signed and trusted, you can rest easy knowing that nobody can mess with it anywhere in transit without breaking the code signing.

10 thoughts on “Signing .mobileconfig Profiles With Keychain Certificates

  1. You mention, “If there’s any ambiguity (i.e. more than one possible certificate that matches the string you provided), it will fail and complain.” This might be a good reason to use -Z rather than -N. Using -Z, you provide the hash, rather than a name, to prevent any ambiguity. You can find the hash with either security find-identity or by looking in Keychain Access.

    Like

  2. I have try this blog information for verfied .mobileconfig file. but When I am trying to install this .mobileconfig in device alert appear with message Invalid profie.

    Like

    • Sounds like you might have an XML issue. Try doing plutil -lint on your .mobileconfig file to make sure that the profile isn’t malformed.

      Like

  3. Just a bit of info that may help other JAMF admins using this technique —

    If you are in a dilemma such as “I need a cert to sign my profiles with. It will need to be trusted by my clients. But I don’t have access to Apple Developer certs, and my organization will kill me if I use some other public CA”

    Your answer – the JSS CA. Just create a CSR and submit to Management Settings – Global Management – PKI – Create Certificate from CSR. (Use web server certificate)

    You will end up with a cert / key pair that you can use for signing profiles that will be trusted by your clients b/c they are enrolled in the JSS and trust the JSS’s CA already. (Assuming you are using the JSS built in CA)

    Like

  4. It’s a good article but NotAfter is always only 3 months later. I don’t want to keep re-doing it every 3 months so how to work around that?!

    Like

Leave a comment