Hi all,

First of all, I hope everyone is still doing well!

I realised that this lockdown period made me slack a bit on keeping the momentum of this blog going. But fear not, I have a few new topics lined up already!

Let’s start with this one: how to sign packages and profiles with the built-in Jamf Pro CA? Although not so new as topic as such, I came across a few discussions with people who did not know this was possible.

Before we dive into the how-to part of things, why would we actually need this?

Well, the first and probably the most important reason, is the need for signed packages to install during the Automated MDM enrolment (e.g. Jamf Pro prestage packages). Since Jamf Pro 10.9 we can add an installer package to the prestage (Jamf Pro 10.19 and later allows multiple packages to be added), which will install in the background during the Setup Assistant. This allows users to have the most important software or tools installed right from the beginning after initial deployment.

A great example of this would be the installation of Jamf Connect Login, allowing the end user to provision the mac with a user account through Jamf Connect immediately after the Setup Assistant. This in contrast to waiting for Jamf Connect to be installed post-enrolment.

Note: a must when doing enrolment customisation passing user info from Single Sign On to Jamf Connect.

In order to allow the Setup Assistant to install the packages, there are 2 important requirements: the package need to be hosted in a cloud distribution point, and the package needs to be signed by a trusted signing certificate. More about this below.

If we look at configuration profiles, we know that an MDM solution like Jamf Pro would sign them automatically prior to pushing them out, so why would we need to sign them manually? Well, there are scenarios where you’d need to tweak an existing config profile, or build a custom one yourself to circumvent a product issue, work around a missing feature (for instance enabling FileVault at login instead of logout via a config profile in Jamf Pro), etc… When you would make a custom profile and upload it to your MDM solution, chances are that the MDM server would try to tweak the profile and add or remove keys which you added/removed prior to pushing it out to your macs. The result would be that the content of the custom profile you created changes, defeating the idea of creating a custom profile after all. To avoid this you need to sign the profile prior to uploading it to your MDM server.

In both of the above use cases, signing packages and profiles, there is however one important consideration to make. In order for the signature to work, or let’s say to be accepted by the mac/iOS device which is going to install it, it needs to be trusted. This either by using a publicly trusted signing cert (purchased), an Apple Developer certificate which each Apple device automatically trusts,… or any signing certificate which has been signed by a Certificate Authority which the device already trusts…

And this brings us to ‘using the built-in Jamf Pro CA as Certificate Authority for our signing certificate‘, because in both of the above scenarios (packages installing during the Setup Assistant and profiles pushed out by MDM) the MDM profile and the Jamf Pro root CA certificates are already installed on the enrolled device. This means that the signature on our package or profile, signed by a signing certificate which in turn was signed by the built-in Jamf Pro CA, is automatically trusted as well.

I hope all the above makes sense, so let’s have a look at how to achieve this!

Step 1: CREATE A SIGNING CERT, signed by the built-in Jamf Pro CA

So the first thing we need is our signing certificate, signed by the built-in Jamf Pro CA. To do this, we need to create a Certificate Signing Request (or CSR) first. Either by using the Keychain Certificate Assistant, or Terminal. Let’s have a look a the Keychain Certificate Assistant first:

On a mac launch Keychain Access and select Certificate Assistant -> Request a Certificate From a Certificate Authority from the Certificate Assistant menu:

In the Certificate Assistant window enter the User Email Address and Common Name for your signing certificate and set the request to ‘Saved to Disk‘. As we’ll need to upload the certificate to Jamf Pro, we can’t send it by email to the CA. Select the Continue button, save the CSR file to your Desktop and hit done.

Next we need the content of the CSR, so open it with your preferred text editor and copy the entire text content (Yes, including the “—–BEGIN CERTIFICATE REQUEST—–” and “—–END CERTIFICATE REQUEST—–“)

Now that we copied the content of our CSR we’ll ask the built-in Jamf Pro CA to sign it. To do so, we go to Jamf Pro -> Settings -> Global Management -> PKI Certificates, and select the the Management Certificate Template tab.

Click the Create Certificate from CSR button…

… and paste the copied content of the CSR into the CSR field. Make sure to set the Certificate Type to Web Server Certificate:

Hit create to save the certificate to your mac. The result will be a .pem type certificate, signed by the built-in CA of your Jamf Pro instance. A certificate which will be trusted by ANY Mac or iOS device which is correctly enrolled in this Jamf Pro server.

Double click on the newly generated certificate to add it to your keychain, we’ll need that for our next step. Because we created the CSR within the Keychain Certificate Assistant, you’ll notice that the private key of this certificate will already be there, and it will be linked to the certificate after importing the corresponding signing certificate we created:

On the screenshot above you might have noticed that this certificate is not trusted, but why? Well, nothing more than the fact that my mac is not enrolled in the test Jamf Pro instance which I used to sign the certificate. By lack of having the root CA of this Jamf Pro test instance in my keychain, I don’t have a complete chain of trust, hence the certificate is not trusted. Let me quickly go back to my test Jamf Pro server, download the CA and double click on it to install it in my keychain…

With this CA installed in my keychain… all should be good now right? Well not really… If I look at the signing certificate I created/imported earlier again, it still says it’s not trusted, but the reason why actually changed:

As you can see, it now recognises the “Travelling Tech Guy JSS Built-in CA” as the issuer of the certificate, but now it complains that this Certificate Authority is not trusted… Are we running in circles here? No, don’t worry, let’s fix that too!

I know, we are a bit side tracking from the initial objective of this post and walking more into a ‘certificate 101’ session, but I want to make sure that everyone understands why we can use the built-in Jamf Pro as root CA for our signing cert.

As my mac is not enrolled in the test Jamf Pro server which I used to sign the signing cert, it lacked the root CA to trust the signing cert, so I downloaded and installed it manually. But even doing that did not fix our trust issue, why? Well, because the root CA of Jamf Pro is not a publicly trusted CA either! By installing the CA manually we just moved the trust problem of the signing cert one level higher in the chain of trust, to the CA who signed it. As this CA is not trusted either, nothing really changed. Fortunately, I can manually fix this as well by going to the imported root CA and tell the mac to trust this CA from now on:

And now if I check my fancy signing cert… all is finally OK:

But wait a second… we had to tweak some trust settings manually, so how on earth would this work if we want to scale that to all our enrolled devices remotely? Well fortunately, and this is the secret clue to our certificate game here, the built-in CA of Jamf Pro, installed during MDM enrolment, is automatically trusted upon installation! Hence all certificates signed by this CA will also automatically be trusted by all the enrolled macs and iOS devices, including our fancy signing cert!

All good? If not, pause here and review some certificate basics like https://en.wikipedia.org/wiki/Chain_of_trust

Now, before we have a look at how to use this certificate to sign packages and profiles, let’s quickly do the same exercise like a pro, from the command line :-).

For this we’ll use openssl to create a Private Key and Certificate Signing Request

Note: here we need to create a private key, while the Keychain Certificate Assistant automatically did this for us
$ openssl req -nodes -newkey rsa:2048 -keyout ttgSigningCert.key -out ttgSigningCert.csr

You will be asked to answer a few questions about your certificate request, like Country, Province, City,…. but the most important one is the Common Name, just like we did in the Keychain Assistant.

Note: don't set a challenge password. The fields email addressoptional company name and challenge password can be left blank for a webserver certificate.

This will create both the private key as the CSR in the directory where we executed the command from in Terminal:

And just like we did earlier, we can now copy the content of our CSR and paste that into Jamf Pro (use ‘nano’ or ‘vi’ to read the CSR…):

Step 2a: Sign a profile

Now that we have our signing cert, let’s have a look at how to sign configuration profiles!

Here I’ll assume that you went trough step 1 and you do have your signing cert in the keychain of the mac you are using to manage and sign your profiles.

The only thing you need to sign your profile with the signing cert you created earlier is one Terminal command:

$ /usr/bin/security cms -S -N "[Signing Certificate]" -i "[/Desktop/profileTOSign]" -o “[/Desktop/profileSIGNED]"

Let’s break that command up in different pieces:

/usr/bin/security cms -S -N (= the command)
"[Signing Certificate]" (= the signing cert name)
-i "[/Desktop/profileTOSign]" (= the path to the profile to sign)
-o “[/Desktop/profileSIGNED]" (= the path where to save the signed profile)

The most important part in the command above is the “[Signing Certificate]” piece, which is nothing more than the common name of the signing cert you want to use, for instance “TTG’s Signing Cert”.

You can crosscheck this in your keychain or by running security find-identity -v, which will list all certificates you can use. In the example below you’ll see that I also have some Apple Developer certificates on my mac:

$ security find-identity -v

1) 5C3F43XYXYXYXXYXYXYXYF51F651BDC8BE8D4916 "Apple Development: Travelling TechGuy (XYXYXYXYXY)"

2) 73E587XYXYXYXXYXYXYXY9F69F426502152FF8E9 "Developer ID Installer: Travelling TechGuy (XYXYXYXYXY)
3) 7CC23FXYXYXYXXYXYXYXYDF7239E816B3C09B7DE “TTG's Signing Cert"

3 valid identities found

The result is a profile which can be uploaded to Jamf Pro (or installed manually on an enrolled mac or iOS device), without worrying about Jamf Pro changing the content or the device not trusting the profile signature.

Step 2b: Sign a .pkg package

The same idea can be applied to signing packages. Once you have your signing certificate ready, you can use the following command to sign a .pkg with it:

$ productsign --sign "[Signing Certificate]" ~/Desktop/example.pkg ~/Desktop/signed-example.pkg

For instance:

$ productsign --sign "TTG's Signing Cert" /Users/frederick.abeloos/Desktop/TTG.pkg /Users/frederick.abeloos/Desktop/TTGSigned.pkg

Once the package is signed you can even check the signature with:

$ pkgutil —-check-signature /path-to/package.pkg

For instance:

$ pkgutil --check-signature /Users/frederick.abeloos/Desktop/TTGSigned.pkg

Here the result is a signed package which can be used as prestage package during Automated MDM Enrolment!

That’s it! As always, if you liked the post, hit the like button, tell your friends about it and leave a comment down below!