#!/bin/bash # # Build EVRoots.plist in ./BuiltKeychains/, given the embedded list of # OIDs in this script and their associated root certificate(s) which can # be found by the specified filename in ./roots. # TMPFILE=/tmp/EVRootsTmp cat > "$TMPFILE" << EOF # ------------------------------------------------------------------------------ # Extended Validation CA Policy OIDs # Last updated: 20 Oct 2008 # # Each uncommented non-empty line contains a mapping from a CA-defined EV OID # to the certificate file(s) in ./roots which are authoritative for that OID. # These lines are processed by the buildEVRoots script to generate the plist. # # Buypass (Norway) # source: <sonr://Request/66633590> # confirmed by https://cert.webtrust.org/ViewSeal?id=848 # confirmed by http://www.buypass.no/Bedrift/Produkter+og+tjenester/SSL/SSL%20dokumentasjon # # (2.16.578.1.26.1.3.3) = # # root: Buypass Class 3 CA 1 # 2.16.578.1.26.1.3.3 "BuypassClass3CA1.cer" # Comodo # source: <http://www.mozilla.org/projects/security/certs/included/> # confirmed by <http://www.comodo.com/repository/EV_CPS_120806.pdf> # # (1.3.6.1.4.1.6449.1.2.1.5.1) = 060C2B06010401B2310102010501 # # root: COMODO Certification Authority # subordinate CA of: Add Trust External CA Root # 1.3.6.1.4.1.6449.1.2.1.5.1 \ "COMODOCertificationAuthority.crt" "AddTrust External CA Root.crt" # Cybertrust (aka Verizon Business) # source: <http://en.wikipedia.org/wiki/Extended_Validation_Certificate> # confirmed by <http://cybertrust.omniroot.com/repository.cfm> # # (1.3.6.1.4.1.6334.1.100.1) = 060A2B06010401B13E016401 # # root: GTE Cybertrust Global Root # root: Baltimore Cybertrust Root # 1.3.6.1.4.1.6334.1.100.1 "BTCTRT.cer" "GTEGB18.cer" # DigiCert # source: <http://www.mozilla.org/projects/security/certs/included/> # confirmed by <https://www.digicert.com/> # confirmed by <http://www.digicert.com/CPS_V3-0-3_3-15-2007.pdf> # # (2.16.840.1.114412.2.1) = 06096086480186FD6C0201 // EV CA-1 # (2.16.840.1.114412.1.3.0.2) = 060B6086480186FD6C01030002 // EV CA-2 # # root: DigiCert High Assurance EV Root CA # subordinate CA of: Entrust.net Secure Server Certification Authority # 2.16.840.1.114412.2.1 \ "DigiCertHighAssuranceEVRootCA.crt" "EntrustRootCA1024.crt" 2.16.840.1.114412.1.3.0.2 \ "DigiCertHighAssuranceEVRootCA.crt" "EntrustRootCA1024.crt" # DigiNotar # source: <http://www.mozilla.org/projects/security/certs/included/> # confirmed by <https://www.diginotar.com/> # # (2.16.528.1.1001.1.1.1.12.6.1.1.1) = 060E6084100187690101010C06010101 # # root: DigiNotar Root CA # 2.16.528.1.1001.1.1.1.12.6.1.1.1 "DigiNotarRootCA2007.crt" # Entrust # source: <http://www.mozilla.org/projects/security/certs/included/> # confirmed by <http://www.entrust.net/CPS/pdf/webcps051404.pdf> # # (2.16.840.1.114028.10.1.2) = 060A6086480186FA6C0A0102 # # root: Entrust.net Secure Server Certification Authority # root: Entrust Root Certification Authority # 2.16.840.1.114028.10.1.2 "EntrustRootCA1024.crt" "EntrustEVRoot.crt" # GeoTrust # source: <http://www.mozilla.org/projects/security/certs/included/> # confirmed by <http://www.geotrust.com/resources/cps/pdfs/GeoTrustCPS-Version1.pdf> # # (1.3.6.1.4.1.14370.1.6) = 06092B06010401F0220106 # # root: GeoTrust Primary Certification Authority # subordinate CA of: Equifax Secure Certificate Authority # 1.3.6.1.4.1.14370.1.6 \ "geotrust-primary-ca.crt" "Equifax_Secure_Certificate_Auth" # GlobalSign # source: <http://www.mozilla.org/projects/security/certs/included/> # confirmed by <https://www.globalsign.com/> # # (1.3.6.1.4.1.4146.1.1) = 06092B06010401A0320101 # # root: GlobalSign Root CA - R2 # root: GlobalSign Root CA # 1.3.6.1.4.1.4146.1.1 "GlobalSignRootCA-R2.cer" "globalSignRoot.cer" # Go Daddy (aka Starfield Technologies) # source: <http://www.mozilla.org/projects/security/certs/included/> # confirmed by <https://certs.starfieldtech.com/repository/StarfieldCP-CPS.pdf> # # (2.16.840.1.114413.1.7.23.3) = 060B6086480186FD6D01071703 # (2.16.840.1.114414.1.7.23.3) = 060B6086480186FD6E01071703 # # root: Go Daddy Class 2 Certification Authority (for 114413) # root: Starfield Class 2 Certificate Authority (for 114414) # subordinate CA of: Valicert Class 2 Policy Validation Authority (both) # 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" # Izenpe # source: <sonr://Request/74637008> # confirmed by <https://servicios.izenpe.com/jsp/descarga_ca/s27descarga_ca_c.jsp> # # (1.3.6.1.4.1.14777.6.1.1) = # # root: Izenpe.com # root: Izenpe.com/emailAddress=Info@izenpe.com # 1.3.6.1.4.1.14777.6.1.1 "Izenpe-RAIZ2007.crt" "Izenpe-ca_raiz2003.crt" # KEYNECTIS (aka Certplus) # source: <sonr://request/76327342> # confirmed by <https://www.keynectis.com/fr/accueil.html> # # (1.3.6.1.4.1.22234.2.5.2.3.1) = # # root: Class 2 Primary CA # 1.3.6.1.4.1.22234.2.5.2.3.1 "certplus_class2.der" # Network Solutions # source: <http://www.mozilla.org/projects/security/certs/included/> # confirmed by <https://www.networksolutions.com/legal/SSL-legal-repository-ev-cps.jsp> # # (1.3.6.1.4.1.782.1.2.1.8.1) = 060C2B06010401860E0102010801 # # root: Network Solutions Certificate Authority # subordinate CA of: AddTrust External CA Root # 1.3.6.1.4.1.782.1.2.1.8.1 \ "NetworkSolutionsEVRoot.crt" "AddTrust External CA Root.crt" # QuoVadis # source: <http://www.mozilla.org/projects/security/certs/included/> # confirmed by <http://www.quovadisglobal.bm/Repository.aspx> # # (1.3.6.1.4.1.8024.0.2.100.1.2) = 060C2B06010401BE580002640102 # # root: QuoVadis Root Certification Authority # root: QuoVadis Root CA 2 # 1.3.6.1.4.1.8024.0.2.100.1.2 "qvrca.crt" "qvrca2.crt" # Secom (aka SECOM Trust Systems Co., Ltd.) # source: <https://repository.secomtrust.net/SC-Root1/> # # (1.2.392.200091.100.721.1) = ... # # root: Security Communication RootCA1 # 1.2.392.200091.100.721.1 "SCRoot1ca.cer" "SECOM-EVRoot1ca.cer" # StartCom # source: <http://www.mozilla.org/projects/security/certs/included/#StartCom> # confirmed by <https://www.startssl.com/certs/> # # (1.3.6.1.4.1.23223.2) = # # root: StartCom Certification Authority # 1.3.6.1.4.1.23223.2 "startcom-sfsca.der" # SwissSign # source: <https://swisssign.com/english/download-document/20-swisssign-gold-ca-g2.html> # repository: https://swisssign.com/english/gold/view-category.html # # (2.16.756.1.89.1.2.1.1) = ... # # root: SwissSign Gold CA - G2 # 2.16.756.1.89.1.2.1.1 \ "SwissSign-Gold_G2.der" # Trustwave (aka SecureTrust, formerly XRamp) # source: <http://www.mozilla.org/projects/security/certs/included/> # # (2.16.840.1.114404.1.1.2.4.1) = 060C6086480186FD640101020401 # # root: SecureTrust CA # root: Secure Global CA # root: XRamp Global CA # subordinate CA of: Entrust.net Secure Server Certification Authority # 2.16.840.1.114404.1.1.2.4.1 \ "Trustwave-STCA.der" "Trustwave-SGCA.der" "XGCA.crt" "EntrustRootCA1024.crt" # Thawte # source: <http://www.mozilla.org/projects/security/certs/included/> # # (2.16.840.1.113733.1.7.48.1) = 060B6086480186F84501073001 # # root: thawte Primary Root CA # subordinate CA of: Thawte Premium Server CA # 2.16.840.1.113733.1.7.48.1 "thawte-primary-root-ca.crt" "serverpremium.crt" # VeriSign # source: <http://www.mozilla.org/projects/security/certs/included/> # # (2.16.840.1.113733.1.7.23.6) = 060B6086480186F84501071706 # # root: VeriSign Class 3 Public Primary Certification Authority - G5 # subordinate CA of: Class 3 Public Primary Certification Authority # 2.16.840.1.113733.1.7.23.6 \ "VeriSignC3PublicPrimaryCA-G5.cer" "PCA3ss_v4.509" # Wells Fargo # source: <sonr://request/72493272> # confirmed by <https://www.wellsfargo.com/com/cp> # # (2.16.840.1.114171.500.9) = # # root: WellsSecure Public Root Certificate Authority # 2.16.840.1.114171.500.9 "WellsSecurePRCA.der" # ------------------------------------------------------------------------------ EOF CWD=`/bin/pwd` ROOT_CERT_DIR="$CWD"/roots ALT_ROOT_CERT_DIR="$CWD"/roots_incoming KC_DIR="$CWD"/BuiltKeychains # Set USE_PUBKEY to a non-zero value to generate public key hashes; # default behavior is to generate a hash of the certificate itself USE_PUBKEY=0 if [ "$USE_PUBKEY" -ne 0 ]; then ### NOTE: the certlist tool is used here to generate the MD5 hash of a ### certificate's public key. This functionality needs to be added to the ### security command at some point; there doesn't seem to be a way to get ### it from openssl. 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 #PLB="$CWD"/../../tests/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" # save keychain list so we don't add EVRoots.keychain to it 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' # first pass: build the EVRoots keychain 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}'` # convert rest of line into comma-delimited filename list 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 # add hash values to the array 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 the hash values were added correctly 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 # get SHA-1 hash value for the certificate CERT_SHA1=`"$OPENSSL" x509 -inform DER -in "$CERT_TO_HASH" -fingerprint -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 # add hash value to the array IDX_NEXT=`expr $IDX + 1` "$PLB" -c "add :$OIDKEY:$IDX data" \ -c "import :$OIDKEY:$IDX /tmp/certsha1hashtmp" \ "$EVROOTS_PLIST_PATH" # verify the hash value was added correctly 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