Updates

Trusting Certificates in System Keychain without Prompting

Note: This no longer works due to SIP protection on macOS after Big Sur

A common activity when deploying Macs in Enterprise and Education environments is trusted a certificate in the System keychain. Before macOS 11 Big Sur, this was done using the security command.

However, macOS 11 Big Sur changed this:

macOS Big Sur 11 beta improves system security by requiring an administrator password when a certificate trust settings change is made in the admin trust domain. Running as the root user alone is no longer sufficient to modify certificate trust. User trust domain settings continue to require confirmation by entering the password for the user’s account. This change may affect you if one of the following is true:
You have written scripts which call /usr/bin/security add-trusted-cert -d ... as root.
Your process runs as root and calls the SecTrustSettingsSetTrustSettings function to trust a certificate.

In Big Sur, when you use the security command to add / trust a certificate, you get prompted:

sudo security add-trusted-cert  -r trustRoot /tmp/web.twocanoes.com.cer
sudo security trust-settings-import -d  /tmp/settings

Adding a certificate to the System keychain doesn’t prompt:

sudo  security add-certificates -k /Library/Keychains/System.keychain /tmp/web.twocanoes.com.cer

However, that last command doesn’t trust the certificate. It just imports it.

The trust information on both the user and system keychain is stored in /Library/Security/Trust Settings. The System keychain trust setting are in a file named “Admin.plist” and looks like this:

<?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>trustList</key>
	<dict>
		<key>1F9575A7FDCE56AB5461E89C0738841C94F02C81</key>
		<dict>
			<key>issuerName</key>
			<data>
			MEAxEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJkiaJk/IsZAEZ
			Fgl0d29jYW5vZXMxDjAMBgNVBAMTBVRDU0NB
			</data>
			<key>modDate</key>
			<date>2021-08-20T14:15:32Z</date>
			<key>serialNumber</key>
			<data>
			EwAAAF+zxdRuiaLqIAAAAAAAXw==
			</data>
			<key>trustSettings</key>
			<array>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAED
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>sslServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147408896</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAED
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>sslServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEI
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>SMIME</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147408872</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEI
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>SMIME</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEJ
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>eapServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEL
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>ipsecServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEQ
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>CodeSigning</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEU
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>AppleTimeStamping</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEC
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>basicX509</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
			</array>
		</dict>
		<key>A93342811590725BF3EDB290545EBF3BD40814B0</key>
		<dict>
			<key>issuerName</key>
			<data>
			MEAxEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJkiaJk/IsZAEZ
			Fgl0d29jYW5vZXMxDjAMBgNVBAMTBVRDU0NB
			</data>
			<key>modDate</key>
			<date>2021-08-20T01:29:18Z</date>
			<key>serialNumber</key>
			<data>
			WPQVDB1u0KFKnBg34gSxkw==
			</data>
			<key>trustSettings</key>
			<array>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAED
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>sslServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147408896</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAED
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>sslServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEI
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>SMIME</string>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147408872</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEI
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>SMIME</string>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEJ
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>eapServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEL
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>ipsecServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEQ
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>CodeSigning</string>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEU
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>AppleTimeStamping</string>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEC
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>basicX509</string>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsResult</key>
					<integer>1</integer>
				</dict>
			</array>
		</dict>
	</dict>
	<key>trustVersion</key>
	<integer>1</integer>
</dict>
</plist>

Each trusted certificate has a entry in the trustList. For example, there is the trust for the certificate web.twocanoes.com:

<key>1F9575A7FDCE56AB5461E89C0738841C94F02C81</key>
		<dict>
			<key>issuerName</key>
			<data>
			MEAxEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJkiaJk/IsZAEZ
			Fgl0d29jYW5vZXMxDjAMBgNVBAMTBVRDU0NB
			</data>
			<key>modDate</key>
			<date>2021-08-20T14:15:32Z</date>
			<key>serialNumber</key>
			<data>
			EwAAAF+zxdRuiaLqIAAAAAAAXw==
			</data>
			<key>trustSettings</key>
			<array>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAED
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>sslServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147408896</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAED
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>sslServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEI
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>SMIME</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147408872</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEI
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>SMIME</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEJ
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>eapServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEL
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>ipsecServer</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEQ
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>CodeSigning</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEU
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>AppleTimeStamping</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
				<dict>
					<key>kSecTrustSettingsAllowedError</key>
					<integer>-2147409654</integer>
					<key>kSecTrustSettingsPolicy</key>
					<data>
					KoZIhvdjZAEC
					</data>
					<key>kSecTrustSettingsPolicyName</key>
					<string>basicX509</string>
					<key>kSecTrustSettingsResult</key>
					<integer>2</integer>
				</dict>
			</array>
		</dict>


The key of 1F9575A7FDCE56AB5461E89C0738841C94F02C81 is the sha1 has of the certificate.

The issuername is base64 of the asn1 of the issue from the cert:

echo MEAxEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJkiaJk/IsZAEZFgl0d29jYW5vZXMxDjAMBgNVBAMTBVRDU0NB  | base64 -D|openssl asn1parse -inform der
    0:d=0  hl=2 l=  64 cons: SEQUENCE          
    2:d=1  hl=2 l=  19 cons: SET               
    4:d=2  hl=2 l=  17 cons: SEQUENCE          
    6:d=3  hl=2 l=  10 prim: OBJECT            :domainComponent
   18:d=3  hl=2 l=   3 prim: IA5STRING         :com
   23:d=1  hl=2 l=  25 cons: SET               
   25:d=2  hl=2 l=  23 cons: SEQUENCE          
   27:d=3  hl=2 l=  10 prim: OBJECT            :domainComponent
   39:d=3  hl=2 l=   9 prim: IA5STRING         :twocanoes
   50:d=1  hl=2 l=  14 cons: SET               
   52:d=2  hl=2 l=  12 cons: SEQUENCE          
   54:d=3  hl=2 l=   3 prim: OBJECT            :commonName
   59:d=3  hl=2 l=   5 prim: PRINTABLESTRING   :TCSCA

The serial number is the base64 of the cert serial:

echo EwAAAF+zxdRuiaLqIAAAAAAAXw==  | base64 -D  |xxd -p

The trustSettings do not seem to change for different certificates and see to be constants. For instance:

AllowedError

kSecTrustSettingsPolicy

Adding and Trusting without Prompting

Knowing this information makes it easy to add in trusted certificate. If you are deploying a bunch of Macs that need a set up root certificates trusted, do this:

  1. Add the certificate the System Keychain in Keychain Utility, and mark it as trusted.
  2. Copy the /Library/Security/Trust Settings/Admin.plist and the certificate file to the target macs. Note that this will overwrite the current trust setting so be aware you may need to merge if you want to keep the old settings.
  3. Import the certificate by running:
    sudo security add-certificates -k /Library/Keychains/System.keychain /tmp/web.twocanoes.com.cer
  4. Move Admin.plist to /Library/Security/Trust Settings and set the permissions to read and write only by root:wheel.
  5. Reboot