#!/bin/bash
TMPFILE=/tmp/EVRootsTmp
cat > "$TMPFILE" << EOF
1.3.6.1.4.1.6449.1.2.1.5.1 \
"COMODOCertificationAuthority.crt" "AddTrust External CA Root.crt"
1.3.6.1.4.1.6334.1.100.1 "BTCTRT.cer" "GTEGB18.cer"
2.16.840.1.114412.2.1 \
"DigiCertHighAssuranceEVRootCA.crt" "EntrustRootCA1024.crt"
2.16.840.1.114412.1.3.0.2 \
"DigiCertHighAssuranceEVRootCA.crt" "EntrustRootCA1024.crt"
2.16.528.1.1001.1.1.1.12.6.1.1.1 "DigiNotarRootCA2007.crt"
2.16.840.1.114028.10.1.2 "EntrustRootCA1024.crt" "EntrustEVRoot.crt"
1.3.6.1.4.1.14370.1.6 \
"geotrust-primary-ca.crt" "Equifax_Secure_Certificate_Auth"
1.3.6.1.4.1.4146.1.1 "GlobalSignRootCA-R2.cer" "globalSignRoot.cer"
2.16.840.1.114413.1.7.23.3 "GD-Class2-root.crt" "ValiCertClass2PVA.cer"
2.16.840.1.114414.1.7.23.3 "SF-Class2-root.crt" "ValiCertClass2PVA.cer"
1.3.6.1.4.1.782.1.2.1.8.1 \
"NetworkSolutionsEVRoot.crt" "AddTrust External CA Root.crt"
1.3.6.1.4.1.8024.0.2.100.1.2 "qvrca.crt" "qvrca2.crt"
1.2.392.200091.100.721.1 \
"SCRoot1ca.cer"
2.16.840.1.114404.1.1.2.4.1 \
"Trustwave-STCA.der" "Trustwave-SGCA.der" "XGCA.crt" "EntrustRootCA1024.crt"
2.16.840.1.113733.1.7.48.1 "thawte-primary-root-ca.crt" "serverpremium.crt"
2.16.840.1.113733.1.7.23.6 \
"VeriSignC3PublicPrimaryCA-G5.cer" "PCA3ss_v4.509"
EOF
CWD=`/bin/pwd`
ROOT_CERT_DIR="$CWD"/roots
ALT_ROOT_CERT_DIR="$CWD"/roots_incoming
KC_DIR="$CWD"/BuiltKeychains
USE_PUBKEY=0
if [ "$USE_PUBKEY" -ne 0 ]; then
CERTLIST="$CWD"/../../tests/certlist
if [ ! -e "$CERTLIST" ]; then
printf "### BUILD FAILED: $CERTLIST is missing\n"
exit 1
fi
fi
SECURITY=/usr/bin/security
OPENSSL=/usr/bin/openssl
PLB=/usr/libexec/PlistBuddy
SaveKeychainList() {
SAVED_KC_LIST=`"$SECURITY" list -d user`
}
RestoreKeychainList() {
/bin/echo -n "$SAVED_KC_LIST" | xargs "$SECURITY" list -d user -s
}
if [ ! -e "$ROOT_CERT_DIR" ] || [ ! -e "$KC_DIR" ]; then
printf "You do not seem to be in a current security_certificates directory. Aborting.\n"
exit 1
fi
EVROOTS_KC=EVRoots.keychain
EVROOTS_KC_PATH="/tmp/$EVROOTS_KC"
EVROOTS_PLIST=EVRoots.plist
EVROOTS_PLIST_PATH="$KC_DIR/$EVROOTS_PLIST"
SaveKeychainList
printf "Creating empty %s...\n" "$EVROOTS_KC"
/bin/rm -f "$EVROOTS_KC_PATH" || exit 1
"$SECURITY" create-keychain -p "$EVROOTS_KC" "$EVROOTS_KC_PATH" || exit 1
TMPIFS=$IFS
IFS=$'\x0A'$'\x0D'
for OID in `cat "$TMPFILE"`; do
OID=`echo "$OID" | sed -e 's/^ if [ "$OID" = "" ]; then continue; fi
OIDKEY=`echo "$OID" | awk '{print $1}'`
CERTFILES=`echo "$OID" | sed -e 's/^[0-9A-Z\.]* //' -e 's/\"\ */\:/g'`
IFS=$'\x3A'
for CERTFILE in $CERTFILES; do
if [ "$CERTFILE" = "" ]; then continue; fi
printf "Adding cert from file: %s\n" "$CERTFILE"
CERT_TO_ADD="$ROOT_CERT_DIR/$CERTFILE"
if [ ! -e "$CERT_TO_ADD" ]; then
CERT_TO_ADD="$ALT_ROOT_CERT_DIR/$CERTFILE"
fi
# should prune duplicates first; for now, just ignore errors
"$SECURITY" \
-q add-certificates \
-k "$EVROOTS_KC_PATH" \
"$CERT_TO_ADD"
done
IFS=$'\x0A'$'\x0D'
done
printf "Removing %s...\n" "$EVROOTS_PLIST"
/bin/rm -f "$EVROOTS_PLIST_PATH"
# second pass: get hashes and build the EVRoots plist
for OID in `cat "$TMPFILE"`; do
# ignore comments and blank lines
OID=`echo "$OID" | sed -e 's/^#.*//'`
if [ "$OID" = "" ]; then continue; fi
# grab OID key
OIDKEY=`echo "$OID" | awk '{print $1}'`
# add an array for this OID key
"$PLB" -c "add :$OIDKEY array" "$EVROOTS_PLIST_PATH"
# convert rest of line into comma-delimited filename list
CERTFILES=`echo "$OID" | sed -e 's/^[0-9A-Z\.]* //' -e 's/\"\ */\:/g'`
IFS=$'\x3A'
# process each certificate file
IDX=0
for CERTFILE in $CERTFILES; do
if [ "$CERTFILE" = "" ]; then continue; fi
CERT_TO_HASH="$ROOT_CERT_DIR/$CERTFILE"
if [ ! -e "$CERT_TO_HASH" ]; then
CERT_TO_HASH="$ALT_ROOT_CERT_DIR/$CERTFILE"
fi
if [ "$USE_PUBKEY" -ne 0 ]; then
# get hash values for the certificate's public key
PK_SHA1=`"$OPENSSL" x509 -inform DER -in "$CERT_TO_HASH" -ocspid | grep "Public key" | awk '{print $5}'`
PK_MD5=`"$CERTLIST" -k "$EVROOTS_KC_PATH" -p --md5 --sha1 | grep "$PK_SHA1" | sed -e 's/^.\{37\}//' | awk '{print $1}'`
printf "Public key hashes for \"%s\":\n" "$CERTFILE"
printf " MD5: %s SHA1: %s\n" "$PK_MD5" "$PK_SHA1"
printf "%s" "$PK_MD5" | xxd -r -p > /tmp/md5hashtmp
printf "%s" "$PK_SHA1" | xxd -r -p > /tmp/sha1hashtmp
IDX_NEXT=`expr $IDX + 1`
"$PLB" -c "add :$OIDKEY:$IDX data" \
-c "import :$OIDKEY:$IDX /tmp/md5hashtmp" \
-c "add :$OIDKEY:$IDX_NEXT data" \
-c "import :$OIDKEY:$IDX_NEXT /tmp/sha1hashtmp" \
"$EVROOTS_PLIST_PATH"
VERIFY_ERROR=0
DATA=`"$PLB" -c "print :$OIDKEY:$IDX data" \
"$EVROOTS_PLIST_PATH" | \
xxd -u -p | sed -e 's/0A$//'`
if [ "$DATA" != "$PK_MD5" ]; then VERIFY_ERROR=1; fi
DATA=`"$PLB" -c "print :$OIDKEY:$IDX_NEXT data" \
"$EVROOTS_PLIST_PATH" | \
xxd -u -p | sed -e 's/0A$//'`
if [ "$DATA" != "$PK_SHA1" ]; then VERIFY_ERROR=1; fi
if [ ! "$VERIFY_ERROR" -eq 0 ]; then
printf "### BUILD FAILED: data verification error!\n"
printf "You likely need to install a newer version of $PLB; see <rdar://6208924> for details\n"
RestoreKeychainList
/bin/rm -f "$EVROOTS_PLIST_PATH"
exit 1
fi
else
CERT_SHA1=`"$OPENSSL" x509 -inform DER -in "$CERT_TO_HASH" -fingerprint -sha1 -noout | sed -e 's/SHA1 Fingerprint=//' -e 's/://g'`
printf "Certificate fingerprint for \"%s\":\n" "$CERTFILE"
printf " SHA1: %s\n" "$CERT_SHA1"
printf "%s" "$CERT_SHA1" | xxd -r -p > /tmp/certsha1hashtmp
IDX_NEXT=`expr $IDX + 1`
"$PLB" -c "add :$OIDKEY:$IDX data" \
-c "import :$OIDKEY:$IDX /tmp/certsha1hashtmp" \
"$EVROOTS_PLIST_PATH"
VERIFY_ERROR=0
DATA=`"$PLB" -c "print :$OIDKEY:$IDX data" \
"$EVROOTS_PLIST_PATH" | \
xxd -u -p | sed -e 's/0A$//'`
if [ "$DATA" != "$CERT_SHA1" ]; then VERIFY_ERROR=1; fi
if [ ! "$VERIFY_ERROR" -eq 0 ]; then
printf "### BUILD FAILED: data verification error!\n"
printf "You likely need to install a newer version of $PLB; see <rdar://6208924> for details\n"
RestoreKeychainList
/bin/rm -f "$EVROOTS_PLIST_PATH"
exit 1
fi
fi
IDX="$IDX_NEXT"
done
IFS=$'\x0A'$'\x0D'
done
IFS="$TMPIFS"
RestoreKeychainList
/bin/chmod 0644 "$EVROOTS_PLIST_PATH"
printf "Built $EVROOTS_PLIST_PATH successfully\n"
exit 0