Skip to main content

We have to remove an old cert from all the Macs. We have the hash, so can identify computers that have the old cert. The cert might exist in /Library/Keychains/System.keychain or /Users/username/Library/Keychains/login.keychain or etc.



In order to list the current logged in user's keychain(s), a script would have to capture the current logged in username, and then run with admin rights, to blast the old cert from either or both keychains.



#!/bin/sh

# Find current logged in username
USER=`/usr/bin/stat -f "%Su" /dev/console`

# Pull list of keychains
/usr/bin/security list-keychains > /private/tmp/"$USER"_keychains.txt

# Prune the list down to just paths
/bin/cat /private/tmp/"$USER"_keychains.txt | tr -d """ | tr -d "  " > /private/tmp/"$USER"_keychains1.txt

# Loop through each keychain and remove Cross Root Cert if it exists and send errors to /dev/null
for keychain in $(/bin/cat /private/tmp/"$USER"_keychains1.txt)
do
/usr/bin/security delete-certificate -Z XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX $keychain 2>/dev/null
done

exit 0


Curious if it would be possible to to rework this script, so we can run the command once for the computer, looping through all users? Not familiar enough with the security command to know if that's possible. If possible, would make more sense than running for each user.



TIA,
Don

@donmontalvo I've not done this for a while, but you might not have to do all the piping to a text file & just try & delete the cert with the hash.



There are a few more security commands like find-certificate that might work to find the cert by name, then you can check the hash & if matches delete.



Again, no need for piping to a text file.


@bentoms Good idea, loop should do it. Looked at the security man page, but it doesn't seem to offer a way to search by the SHA-1 hash.



Unfortunately the old Cross Root Cert we are deleting has the same name as the new Cert, so searching by it's name isn't really an option. I don't think...but as always, I'm happy to admit I'm wrong if someone has a way. :)



Here ya go...



#!/bin/sh
#
##################################################################
# This script will traverse all keychains on this Mac. Including
# /Library/Keychains/System.keychain, all login.keychain keychains
# and any other keychains users might have. This script will only
# loop through users with UID over 500 20160312 DM
##################################################################

# Pull list of users with UDID over 500
over500=`dscl . list /Users UniqueID | awk '$2 > 500 { print $1 }'`

# Remove from System.keychain if it exists.
echo "Remove Cross Root Cert from System.keychain if it exists..."
/usr/bin/security delete-certificate -Z XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /Library/Keychains/System.keychain 2>/dev/null
echo "Removed Cross Root Cert from System.keychain if it existed..."

# Loop through and remove from users keychains if it exists, and pipe errors to /dev/null.
echo "Now loop through all users with UID over 500..."
for u in $over500
do
# Pull list of keychains
KEYCHAIN=`su $u -c 'security list-keychains | tr -d """ | tr -d " " | grep -v "/Library/Keychains/System.keychain"' 2>/dev/null`

for k in $KEYCHAIN
do
echo "Removing Cross Root Cert from keychain $k for user $u if it exists..."
/usr/bin/security delete-certificate -Z XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX $k 2>/dev/null
echo "Removed Cross Root Cert from keychain $k for user $u if it existed..."
done
done

exit 0


Here is output of the script on a computer with users "admin", "test1", and "test2"...



sh-3.2# ./test.sh 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
This script will traverse all keychains on this Mac. Including
/Library/Keychains/System.keychain and all login.keychain keychains
and any other keychains users might have. This script will only
run on users with UID over 500. 20160312 DM
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
First, we will check System.keychain to remove it if it exists...
Removed Cross Root Cert from System.keychain if it existed...
Now loop through all users with UID over 500...
Removing Cross Root Cert from keychain /Users/admin/Library/Keychains/login.keychain for user admin if it exists...
Removed Cross Root Cert from keychain /Users/admin/Library/Keychains/login.keychain for user admin if it existed...
Removing Cross Root Cert from keychain /Users/test1/Library/Keychains/login.keychain for user test1 if it exists...
Removed Cross Root Cert from keychain /Users/test1/Library/Keychains/login.keychain for user test1 if it existed...
Removing Cross Root Cert from keychain /Users/test1/Library/Keychains/test.keychain for user test1 if it exists...
Removed Cross Root Cert from keychain /Users/test1/Library/Keychains/test.keychain for user test1 if it existed...
Removing Cross Root Cert from keychain /Users/test2/Library/Keychains/login.keychain for user test2 if it exists...
Removed Cross Root Cert from keychain /Users/test2/Library/Keychains/login.keychain for user test2 if it existed...
sh-3.2#


Notice we hit System.keychain only once, and we send errors to /dev/null.



@bentoms thanks for the feedback, and the kick in the a**...good practice for CCE. ;)



Thanks,
Don