Post

Install CA and Subordinates on MacOS

Script to install a corporate CA and subordinate CA on MacOS

Install CA and Subordinates on MacOS

This is a quick fix I wrote for developers to install internal root and subordinate CAs. It pulls the root certificate from a web server, verifies the fingerprint, parses and downloads subordinates, and installs them in the MacOS keychain. It was intended to be run interactively at the command line, but also works well as a machine setup script.

The thumbprint verification is required to prevent malicious endpoints. Since the CA server is, in this case, is a windows CA server and signed by the same root, an insecure curl -k is used leaving the user open to a xITM attack. The thumbprint is a hash of the certificate with a very low probability of collision.

#!/bin/bash
# Ensure the script is run as root
((EUID != 0)) && exec sudo -- "$0" "$@"
cd /tmp/ &>/dev/null
clear
# Define the certificate URL and fingerprint
crturl="https://scriptops.corp/CertEnroll/"
rootfingerprint="00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF"
rootcrtfile="Corporate Root CA.crt"
# Define the list of intermediate certificates
declare -a crtfilelist
crtfilelist=("Corporate Intermediate CA 2.crt" "Corporate Intermediate CA 1.crt")
# Download the root certificate
curl -# --url "$crturl${rootcrtfile// /%20}" -k -o "$rootcrtfile"
# Compare the expected and downloaded certificate fingerprints
diff -as --label "Expected CA Fingerprint" \
<(echo "SHA256 Fingerprint=$rootfingerprint") \
--label "Downloaded CA Fingerprint" \
<(openssl x509 -noout -in "./$rootcrtfile" -fingerprint -sha256)
# Check if the fingerprints match
if [ $? -ne 0 ]; then
echo "Downloaded certificate fingerprint mismatch!"
cd - &>/dev/null
sudo -k
rm "$rootcrtfile"
exit 1
fi
# Add the root certificate to the system keychain
security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "$rootcrtfile"
# Download and add each intermediate certificate to the system keychain
for crtfile in "${crtfilelist[@]}"; do
curl -# --url "$crturl${crtfile// /%20}" -k -o "$crtfile"
security add-trusted-cert -d -r trustAsRoot -k /Library/Keychains/System.keychain "$crtfile"
done
#
cd - &>/dev/null
sudo -k
exit 0

Tips

  • if your https endpoint is signed by a pre-installed MacOS CA, please remove -k from the curl command.

References

This post is licensed under CC BY 4.0 by the author.