Failed profile install removes certificate from keychain

Originator:calum.h
Number:rdar://25102086 Date Originated:11-Mar-2016 02:08 PM
Status:Resolved Resolved:
Product:OS X Product Version:10.11.3
Classification:Crash/Hang/Data Loss Reproducible:Always
 
Summary:
When installing a profile that contains a certificate that already exists in the system keychain, if this profile installation fails. The certificate in the keychain is removed.

Example:
A self signed root certificate is installed into the system keychain manually.
A configuration profile is generated to obtain a client certificate from ADCS via RPC/DCE
The profile also attempts to connect to the 802.11x wifi via EAP-TLS
As part of this profile we add the self signed root certificate and intermediate certificates to this profile.
If this profile fails to install it removes the self signed root certificate that was included in the profile from the keychain as part of its clean up.


Steps to Reproduce:
1. Install 10.11.3
2. Configure basic user accounts
3. Install self signed root certificate into system keychain with keychain access
4. Bind machine to AD
5. Create configuration profile with profile manager 
	- Obtain AD Certificate (Acquire via DCE/RPC)
	- Certificates
		- Include the self signed root certificate
		- Include the self signed intermediate certificate
	-Network
		- WPA2
		- TLS
		- Identity Certificate, AD Certificate: Acquire Cert via DCE/RPC
		- Trust:
			- Self Signed Root Certificate
			- Self Signed Intermediate certificate

6. Install configuration profile.

7. Ensure the profile installation will fail by preventing access to ADCS or any other method to induce a failure.

8. Note that the profile failed to install as described by the popup dialog box.

9. Check keychain access and note that the self signed certificates have been removed.

Expected Results:
Failed profile installation should not remove a certificate from the system keychain if it was already installed.

Actual Results:
A failed profile installation removes a certificate from the system keychain, even though it was already installed by another method

Notes:
I can understand why this occurs, the profile installs the certificates into the keychain as normal, the profile install fails, it then cleans up after itself and removes any items it installed. However, perhaps some logic can be added to determine if a certificate needs to be installed first before over writing an existing certificate in the keychain.
This would hopefully help the clean up functions when a profile fails to install
For example if the profile attempts to install a certificate in the system keychain but an existing item already exists and is exactly the same, then the profile should not install it. Because it is not being installed by the profile, should the install of the profile fail, there would be no reason to clean up and remove that certificate.

Comments

Calum Hunter26-Sep-2016 11:08 AM

Hi,

I have just tested again using 10.11.6 and 10.12.0 and you are correct! Importing a certificate by using a profile does indeed set the trust setting to "Always trust" I am certain that in the past this was not the case - I can't be sure how far back I started using the security command instead, probably around 10.8 or 10.9. Some searching on jamfnation also revealed other users who experienced certificates imported via profiles getting the system defaults so there was definitely a release somewhere along the line that had this issue, however this seems to be fixed in the current OS releases so good news!

Installing the certificates via profiles instead of via the security command solves my issue of failed profile installs removing the cert from the keychain so I can close this bug report now :)

Thank you again for you help it has been very much appreciated!

Regards, Apple Developer Relations24-Sep-2016 02:18 AM

Importing a root certificate via a config profile should always mark is as "Always Trust" by default. No options necessary. It has been that way from the beginning. Please do file a separate bug report for that case and include your profile with cert. Maybe our code isn't considering it a root certificate for some reason?

Please provide your response or results by updating your bug report. If uploading files, please compress first. Calum Hunter23-Sep-2016 11:02 AM

Hi,

When importing a cert via a profile it imports it with "Use System Defaults" we need to then change it to "Always Trust" using keychain access manually, or import the cert using the security command. [ security add-trusted-cert -d -r trustRoot -k ]

When we import an intermediate certificate that we also wish to set as "Always Trust" we also need to import it with the security command because again using a profile results in the certificate being imported with the "Use System Defaults" setting. But the command to import an intermediate cert is slightly different: [ security add-trusted-cert -d -r trustAsRoot -k ]

Perhaps, if you think that a cert installed via profile should get "Always Trust" then I should log a bug report for that?

I must admit I have not checked macOS 10.12 Profile Manager (I am still using 10.11.6) to see if there are any additional options in the Certificates pane that allow me to set the trust settings on an imported certificate when generating a profile. Perhaps there is a key/value that could be added to a profile xml to set this trust setting that I am not aware of?

Ok cool I'll see what I can do with using SecCertificateSetPreferred, my coding skills are pretty average but I should be able to smash together something in python to get the job done

Thanks again for your input much appreciated Apple Developer Relations23-Sep-2016 04:08 AM

Importing a certificate via a profile should automatically mark that certificate as trusted, assuming it's a root certificate, which sounds like what you are doing? As for creating a certificate preference directly, you'd want to use the SecCertificateSetPreferred() call. You can pass whatever you want for "name" (but keep it simple, I think some characters might not be allowed) and just pass "NULL" for "keyUsage".

Please provide your response or results by updating your bug report. If uploading files, please compress first. Calum Hunter22-Sep-2016 11:11 AM

Hi,

Thanks for the reply. Unfortunately no. Using a profile to install the certificates is not possible as I can not set the trust settings on the certificate, hence the need to use the security tool to do the import of the certificate, and set the trust settings at the same time. I have tried to use a profile to import the certificate and then tried to adjust the trust settings after but have not been successful in this. Perhaps there is something I am missing?

We are probably a very small edge case, but unfortunately we use self signed root CA certificates that must be imported into the system keychain and set to always trust for our users.

Perhaps I could leverage CFPreferences to create a certificate preference for my certificate after it has been imported?

I have tried to locate developer documentation regarding certificate preferences but I haven't found much can you point me in the right direction?

Thanks again for your help Apple Developer Relations22-Sep-2016 04:06 AM

Engineering has requested the following information in order to further investigate this issue:

Unfortunately, it looks like the security tool does not have the ability to create a certificate preference (it does have the ability to set an identity preference). As a completely different workaround, could you install your certificate in a separate profile that only contains the certificate payload? That profile would likely not fail to install. Install this profile before installing any other profile(s) that might depend on the certificate from the first payload.

Other profiles (such as your WiFi profile) can also include the same certificate payload if you want. If those other profiles fail to install, the certificate will not be removed as part of the profile cleanup because the certificate will be seen to be still in use by the profile you installed first. Would that work for you?

Thank you.

Please provide your response or results by updating your bug report and compress any bundled files (e.g. nested folders) prior to uploading. Calum Hunter21-Sep-2016 10:25 AM

Hi,

Sorry for the delay in replying I have been away on leave.

Great the certificate preference sounds like a good work around until a better solution is implemented.

Lets say I import a self signed root ca certificate into the system keychain using the command:

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/ROOT-CA-CERT.cer

Is there anyway to automate the process of adding a certificate preference for this newly imported cert, obviously without using a config profile for the reasons mentioned?

The context behind this is that all of our machines (~25k) require our self signed root CA certificate for various services that we provide so as to not require our end users to accept and install/trust the certs for the servers that are being accessed.

We do this during a boot strap process on deployment of the devices with a simple script as shown above.

Ideally i'd like to be able to set this certificate preference on the imported ca cert so that any future profile installs that include our root cert such as the 802.1x one mentioned below do not interfere with our root ca cert

Thanks for reply Apple Developer Relations14-Sep-2016 06:19 AM

Engineering has requested the following information regarding your bug report:

The scenario you describe only concerns a failure during profile installation. However, a similar issue happens during a "normal" profile removal. For example:

  • Have a certificate already installed in keychain
  • Install profile containing that certificate
  • Remove the profile

This will remove the certificate from the keychain even though it existed prior to the install of the profile. This is because certificates within profiles are assumed to be "owned" by the profile, irrespective of whether the certificate previously existed or not. Is this of a concern to you? Or, is only the "profile removal due to error" case an issue for you?

Both cases can be worked around by creating a "Certificate Preference" (using Keychain Access) that references the previously installed certificate. This will cause the profile code to consider the certificate as "owned" by someone else and the certificate won't be removed when the profile is removed. For example:

  • Manually install certificate "Foo"
  • Use Keychain Access to create a Certificate Preference that references "Foo" (name it anything you want)
  • Install profile containing certificate "Foo"
  • Remove profile ==> The certificate "Foo" remains since some Certificate Preference refers to it.

Note that, for this to work, the Certificate Preference must NOT be created via a configuration profile since that will cause the profile code to think the certificate and certificate preference are fully managed by profiles and allow it to be removed. If the certificate preference is created outside of configuration profiles, then profiles will not remove the certificate realizing something else may still be using the certificate.

Would this mechanism suffice for your needs?

(Creating a "Identity Preference" should likewise prevent an identity from being removed but a recently discovered bug shows that while the identity certificate is prevented from being removed, the identity private key is still removed. We will try to fix this in an upcoming release).

Workaround: If the configuration profile is edited by hand and the certificate data removed. This will still allow a successful install as the certificates have already been installed in the system keychain by a previous method (manual install at machine provisioning/imaging stage)

However, in the event of a failed install. Because the profile does not contain the certificate data, it does not attempt to install these certificates into the system keychain, because of this, when a install fails the certificates do not get removed from the keychain.


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!