This post is an update (and a translation) of a previous one I published more than a year ago to explain how to remove a Certification Authority (CA) from the Mac OS X Keychain.
It seems quite topical to me after the massive
DigiNotar breach and the quite long time (11 days) it took to Apple to remove the compromises DigiNotar's Root CA certificate from the System with its
Security Update 2011-005.
Moreover it is a common
Operating System Hardening best practice to remove Root certificates of CA you've never heard of...
Certificate Authorities are a major source of trust in the current Internet and the browsers editors (Microsoft, Apple, Mozilla, Google, Opera, ...) have to choose which CA you will trust. The main problem comes from the fact that almost nobody takes some time to look at which CA are trusted by their system and for what purpose (website authentication, code signing, ...). For the record Microsoft decided to drastically reduce the amount of trusted CA in their systems a few years ago, but those days it is still possible to find some editors that didn't even remember where do
some CA certificates come from...
On Mac OS X (10.5 and after) electronic certificats are stored in a
Keychain. The keychains are shared between:
- System keychains, strored in /System/Library/Keychains/
- Users' keychains, stored in /Users/username/Library/Keychains/
Although it is possible to modify users' keychains with the Keychain application, you won't be allowed to modify system keychains and especially the SystemRoot.
As usual, the solution is in the shell ;-) The security command (man 1 security) gives you a mean to interact with the keychains and more widely with the whole OS X security framework.
The security command lets you add or remove certificates from the keychains, modify keychains access control or even specify what TLS (SSL) client certificate to use for each website. It also allows you to modify the trust level of each Root or Sub CA certificate.
The man gives you a good overview of the different possibilities:
jipe$ security help
help Show all commands, or show usage for a command.
list-keychains Display or manipulate the keychain search list.
default-keychain Display or set the default keychain.
login-keychain Display or set the login keychain.
create-keychain Create keychains and add them to the search list.
delete-keychain Delete keychains and remove them from the search list.
lock-keychain Lock the specified keychain.
unlock-keychain Unlock the specified keychain.
set-keychain-settings Set settings for a keychain.
set-keychain-password Set password for a keychain.
show-keychain-info Show the settings for keychain.
dump-keychain Dump the contents of one or more keychains.
create-keypair Create an asymmetric key pair.
add-generic-password Add a generic password item.
add-internet-password Add an internet password item.
add-certificates Add certificates to a keychain.
find-generic-password Find a generic password item.
find-internet-password Find an internet password item.
find-certificate Find a certificate item.
find-identity Find an identity (certificate + private key).
delete-certificate Delete a certificate from a keychain.
set-identity-preference Set the preferred identity to use for a service.
get-identity-preference Get the preferred identity to use for a service.
create-db Create a db using the DL.
export Export items from a keychain.
import Import items into a keychain.
cms Encode or decode CMS messages.
install-mds Install (or re-install) the MDS database.
add-trusted-cert Add trusted certificate(s).
remove-trusted-cert Remove trusted certificate(s).
dump-trust-settings Display contents of trust settings.
user-trust-settings-enable Display or manipulate user-level trust settings.
trust-settings-export Export trust settings.
trust-settings-import Import trust settings.
verify-cert Verify certificate(s).
authorize Perform authorization operations.
authorizationdb Make changes to the authorization policy database.
execute-with-privileges Execute tool with privileges.
leaks Run /usr/bin/leaks on this process.
error Display a descriptive message for the given error code(s).
To come back to our business, we have to focus on the delete-certificate command which will allow you to remove any certificate you want:
jipe$ security delete-certificate -h
Usage: delete-certificate [-c name] [-Z hash] [-t] [keychain...]
-c Specify certificate to delete by its common name
-Z Specify certificate to delete by its SHA-1 hash value
-t Also delete user trust settings for this certificate
The certificate to be deleted must be uniquely specified either by a
string found in its common name, or by its SHA-1 hash.
If no keychains are specified to search, the default search list is used.
Delete a certificate from a keychain.
But first, I recommend you to backup your System Root Certificates before to start any modification:
jipe$ cd /System/Library/Keychains/
jipe$ sudo cp SystemRootCertificates.keychain SystemRootCertificates.keychain.old
It is also possible to export each certificate in the
PEM format with the
Keychain application or the
security command:
jipe$ sudo security export -k /System/Library/Keychains/SystemRootCertificates.keychain -t certs -o BackupCerts.pem
Let's start with a listing of keychaines present on our system, it will give you an overview of applications using keychains:
jipe$ sudo security list-keychains
"/Users/jipe/Library/Keychains/login.keychain"
"/Users/jipe/Library/Keychains/1Password.keychain"
"/Users/jipe/Library/Keychains/Microsoft_Intermediate_Certificates"
"/Users/jipe/Library/Keychains/Microsoft_Entity_Certificates"
"/Users/jipe/Library/Application Support/Adobe/AIR/ELS/TweetDeckFast.[SNIP]/PrivateEncryptedDatak"
"/System/Library/Keychains/SystemRootCertificates.keychain"
"/Library/Keychains/System.keychain"
You may have noticed something is quite odd: there is no reference to the Sub CA keychain /System/Library/Keychains/SystemCACertificates.keychain. It looks like it is not in use (anymore) ?! X509Anchors is deprecated since OS X 10.5 and is still there for compatibility reason only.
jipe$ ls -l /System/Library/Keychains/
total 1464
-rw-r--r-- 1 root wheel 3425 16 oct 11:01 EVRoots.plist
-rw-r--r-- 1 root wheel 158760 18 mai 2009 SystemCACertificates.keychain
-rw-r--r-- 1 root wheel 387552 6 avr 17:04 SystemRootCertificates.keychain
-rw-r--r-- 1 root wheel 73820 16 oct 11:01 SystemTrustSettings.plist
-rw-r--r-- 1 root wheel 282984 10 oct 2008 X509Anchors
jipe$ ls -l /Users/jipe/Library/Keychains/
total 2800
-rw-r--r-- 1 jipe staff 1112220 15 jan 20:39 foobar.keychain
-rw-r--r--@ 1 jipe staff 41976 31 mar 12:33 Microsoft_Entity_Certificates
-rw-r--r-- 1 jipe staff 26036 6 avr 16:01 Microsoft_Intermediate_Certificates
-rw-r--r-- 1 jipe staff 241836 6 avr 18:10 login.keychain
Then the dump-keychain command allow you to list every certificate in a specific keychain:
jipe$ sudo security dump-keychain /System/Library/Keychains/SystemRootCertificates.keychain
And each certificate will be displayed as followed:
keychain: "/System/Library/Keychains/SystemRootCertificates.keychain"
class: 0x80001000
attributes:
"alis"="Entrust.net Certification Authority (2048)"
"cenc"=0x00000003
"ctyp"=0x00000001
"hpky"=0x2A70953A9FF693C5F38AC5A863BB3D942CE6CA07 "*p\225:\237\366\223\305\363\212\305\250c\273=\224,\346\312\007"
"issu"=0x3081B431143012060355040A130B454E54525553542E4E45543140303E060355040B14377777772E656E74727573742E6E65742F4350535F3230343820696E636F72702E206279207265662E20286C696D697473206C6961622E2931253023060355040B131C284329203139393920454E54525553542E4E4554204C494D49544544313330310603550403132A454E54525553542E4E45542043455254494649434154494F4E20415554484F5249545920283230343829 "0\201\2641\0240\022\006\003U\004\012\023\013ENTRUST.NET1@0>\006\003U\004\013\0247www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)1%0#\006\003U\004\013\023\034(C) 1999 ENTRUST.NET LIMITED1301\006\003U\004\003\023*ENTRUST.NET CERTIFICATION AUTHORITY (2048)"
"labl"="Entrust.net Certification Authority (2048)"
"skid"=0x55E481D11180BED889B908A331F9A1240916B970 "U\344\201\321\021\200\276\330\211\271\010\2431\371\241$\011\026\271p"
"snbr"=0x3863B966 "8c\271f"
"subj"=0x3081B431143012060355040A130B454E54525553542E4E45543140303E060355040B14377777772E656E74727573742E6E65742F4350535F3230343820696E636F72702E206279207265662E20286C696D697473206C6961622E2931253023060355040B131C284329203139393920454E54525553542E4E4554204C494D49544544313330310603550403132A454E54525553542E4E45542043455254494649434154494F4E20415554484F5249545920283230343829 "0\201\2641\0240\022\006\003U\004\012\023\013ENTRUST.NET1@0>\006\003U\004\013\0247www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)1%0#\006\003U\004\013\023\034(C) 1999 ENTRUST.NET LIMITED1301\006\003U\004\003\023*ENTRUST.NET CERTIFICATION AUTHORITY (2048)"
Despite the great power of the shell commands I have to say I didn't find an easy/quick way to list all certificates in a good human readable way, thus I recommend you to use the Keychain application to do that.
You will find a lot of Country Root CA: Switzerland, Portugal, Belgium, etc... and it is quite fair as those countries have set up a lot of e-services for their citizens but if you are not living in one of those country it is probably okay to remove them. On the other hand the Root System also contains the chinese Root CA (CNNIC ROOT) and this one will be deleted for sure !
Once you'll have list all the certificates you want to remove, you'll have to list all the corresponding (SHA-1) hashes and to remove them with the delete-certificate command.
For example the chinese CNNIC ROOT certificate could be remove with the following command:
jipe$ sudo security delete-certificate -Z 8BAF4C9B1DF02A92F7DA128EB91BACF498604B6F /System/Library/Keychains/SystemRootCertificates.keychain
It is a long and tedious work and it is quite acceptable to only keep Root certificates from the
Usertrust (UTN*), the most important CA (RSA, Entrust, Thawte, Verisign, Visa, Equifax) and country specific CA you want to trust.
Finally, if you want to restore a certificate you have deleted, you will be able to import it back from the backup you have made:
jipe$ sudo security import backup_certificates_files -k /System/Library/Keychains/SystemRootCertificates.keychain -t cert