#!/bin/bash # Begin /usr/sbin/make-ca # # Script to create p11-kit anchors, OpenSSL certs directory, GnuTLS certificate # bundle, NSS shared DB, and Java cacerts from upstream certdata.txt and local # sources # # Authors: DJ Lucas # Bruce Dubbs VERSION="0.9" # Get/set defaults if test -f /etc/make-ca.conf; then . /etc/make-ca.conf else CERTDATA="certdata.txt" PKIDIR="/etc/pki" SSLDIR="/etc/ssl" CERTUTIL="/usr/bin/certutil" KEYTOOL="${JAVA_HOME}/bin/keytool" OPENSSL="/usr/bin/openssl" TRUST="/usr/bin/trust" ANCHORDIR="${PKIDIR}/anchors" CABUNDLE="${SSLDIR}/ca-bundle.crt" SMBUNDLE="${SSLDIR}/email-ca-bundle.crt" CSBUNDLE="${SSLDIR}/objsign-ca-bundle.crt" CERTDIR="${SSLDIR}/certs" KEYSTORE="${SSLDIR}/java/cacerts" NSSDB="${PKIDIR}/nssdb" LOCALDIR="${SSLDIR}/local" DESTDIR="" URL="https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt" fi # Source must be downloaded over https # Valid urls for download are below # Defualt to NSS release brach # https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt # https://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt # https://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt # https://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt # https://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt # Some data in the certs have UTF-8 characters # It doesn't really matter which locale, change if you like export LANG=en_US.utf8 TEMPDIR=$(mktemp -d) WORKDIR="${TEMPDIR}/work" CERTDATAY=0 FORCE=0 GET=0 REBUILD=0 WITH_P12=0 WITH_NSS=0 function get_args(){ while test -n "${1}" ; do case "${1}" in -C | --certdata) if test "${REBUILD}" == "0" -a "${GET}" == "0"; then check_arg $1 $2 CERTDATA="${2}" CERTDATAY="1" shift 2 else echo "Error: ${1} cannot be used with the -r/--rebuild or -g/--get switches." exit 3 fi if test ! -f "${CERTDATA}" -a "${GET}" == "0"; then echo "Error: ${CERTDATA} not found!" exit 3 fi ;; -D | --destdir) check_arg $1 $2 DESTDIR="${2}" shift 2 ;; -P | --pkidir) check_arg $1 $2 PKIDIR="${2}" ANCHORDIR="${PKIDIR}/anchors" NSSDB="${PKIDIR}/nssdb" echo "${@}" | grep -e "-a " -e "--anchordir" \ -e "-n " -e "--nssdb" > /dev/null if test "${?}" == "0"; then echo "Error! ${1} cannot be used with the -a/--anchordir or -n/--nssdb switches." echo "" exit 3 fi shift 2 ;; -S | --ssldir) check_arg $1 $2 SSLDIR="${2}" CABUNDLE="${SSLDIR}/ca-bundle.crt" CERTDIR="${SSLDIR}/certs" KEYSTORE="${SSLDIR}/java/cacerts" LOCALDIR="${SSLDIR}/local" echo "${@}" | grep -e "-c " -e "--cafile" \ -e "-d " -e "--cadir" \ -e "-j " -e "--javacerts" > /dev/null if test "${?}" == "0"; then echo "Error! ${1} cannot be used with the -c/--cafile, -d/--cadir, or" echo "-j/--javacerts switches." echo "" exit 3 fi shift 2 ;; -a | --anchordir) check_arg $1 $2 ANCHORDIR="${2}" echo "${@}" | grep -e "-P " -e "--pkidir" > /dev/null if test "${?}" == "0"; then echo "Error! ${1} cannot be used with the -P/--pkidir switch." echo "" exit 3 fi shift 2 ;; -c | --cafile) check_arg $1 $2 CABUNDLE="${2}" echo "${@}" | grep -e "-S " -e "--ssldir" > /dev/null if test "${?}" == "0"; then echo "Error! ${1} cannot be used with the -S/--ssldir switch." echo "" exit 3 fi shift 2 ;; -d | --cadir) check_arg $1 $2 CADIR="${2}" if test "${?}" == "0"; then echo "Error! ${1} cannot be used with the -S/--ssldir switch." echo "" exit 3 fi shift 2 ;; -g | --get) if test "${REBUILD}" == "0" -a "${CERTDATAY}" == "0"; then GET="1" CERTDATA="${TEMPDIR}/certdatanew.txt" shift 1 else echo "Error: ${1} cannot be used with the -r/--rebuild or -C/--certdata switches." exit 3 fi ;; -j | --javacerts) check_arg $1 $2 KEYSTORE="${2}" if test "${?}" == "0"; then echo "Error! ${1} cannot be used with the -S/--ssldir switch." echo "" exit 3 fi shift 2 ;; -k | --keytool) check_arg $1 $2 KEYTOOL="${2}" shift 2 ;; -l | --localdir) check_arg $1 $2 LOCALDIR="${2}" shift 2 ;; -m | --java-p12) WITH_P12="1" shift 1 ;; -n | --nssdb) echo "${2}" | grep -v "^-" > /dev/null if [ "$?" -ne "0" -o ! -n "$2" ]; then WITH_NSS="1" shift 1 else NSSDB="${2}" WITH_NSS="1" echo "${@}" | grep -e "-P " -e "--pkidir" > /dev/null if test "${?}" == "0"; then echo "Error! ${1} cannot be used with both an argument and the -P/--pkidir switch." echo "" exit 3 fi shift 2 fi ;; -p | --proxy) check_arg $1 $2 PROXY="${2}" shift 2 ;; -r | --rebuild) if test "${CERTDATAY}" == "0" -a "${GET}" == "0"; then REBUILD="1" FORCE="1" shift 1 else echo "Error: ${1} cannot be used with the -C/--certdata or -g/--get switches." exit 3 fi ;; -s | --openssl) check_arg $1 $2 OPENSSL="${2}" shift 2 ;; -t | --certutil) check_arg $1 $2 CERTUTIL="${2}" WITH_NSS="1" shift 2 ;; -u | --trust) check_arg $1 $2 TRUST="${2}" shift 2 ;; -f | --force) FORCE="1" shift 1 ;; -h | --help) showhelp exit 0 ;; -v | --version) echo -e "$(basename ${0}) ${VERSION}\n" exit 0 ;; *) showhelp exit 1 ;; esac done } function check_arg(){ echo "${2}" | grep -v "^-" > /dev/null if [ -z "$?" -o ! -n "$2" ]; then echo "Error: $1 requires a valid argument." exit 1 fi } function showhelp(){ echo "" echo "`basename ${0}` is a utility to deliver and manage a complete PKI configuration" echo "for workstaitons and servers using only standard Unix utilities and OpenSSL. It" echo "will optionally generate keystores for OpenJDK and NSS if already installed," echo "using a Mozilla cacerts.txt or like formatted file. It was originally developed" echo "for use with Linux From Scratch to minimize dependencies for early system" echo "build, but has been written to be generic enough for any Linux distribution." echo "" echo " -C, --certdata [certdata.txt]" echo " The location of the certificates source" echo "" echo " -D, --destdir [/]" echo " Change the output directory and use relative" echo " paths for all other values" echo "" echo " -P, --pkidir [/etc/pki]" echo " The output PKI directory - Cannot be used with" echo " the -a / --anchordir or -n / --nssdb switches" echo "" echo " -S, --ssldir [/etc/ssl]" echo " The output SSL root direcotry - Cannot be used" echo " with the -c / --cafile, -d / --cadir, or" echo " -j / --javacerts switches" echo "" echo " -a, --anchordir [\$PKIDIR/anchors]" echo " The output directory for OpenSSL trusted" echo " CA certificates used as trust anchors" echo "" echo " -c, --cafile [\$SSLDIR/ca-bundle.crt]" echo " The output filename for the PEM formated bundle" echo "" echo " -d, --cadir [\$SSLDIR/certs]" echo " The output directory for the OpenSSL trusted" echo " CA certificates" echo "" echo " -j, --javacerts [\$SSLDIR/java/cacerts]" echo " The output filename for the Java cacerts file" echo "" echo " -l, --localdir [\$SSLDIR/local]" echo " The path to a local set of OpenSSL trusted" echo " certificates, used to both override trust bits" echo " from upstream sources and provide locally" echo " provided certifiates" echo "" echo " -m, --java-p12" echo " Export Java PKCS#12 store - will default to" echo " \$SSLDIR/java/cacerts.p12 unless modified by" echo " the '-j/--javacerts' switch" echo "" echo " -n, --nssdb {\$PKIDIR/nssdb}" echo " The output path for the shared NSS DB" echo "" echo " -p, --proxy [URI:PORT]" echo " Use proxy server for download" echo "" echo " -k, --keytool [\$JAVA_HOME/bin/keytool]" echo " The path of the Java keytool utility" echo "" echo " -s, --openssl [/usr/bin/openssl]" echo " The path of the openssl utility" echo "" echo " -t, --certutil [/usr/bin/certutil]" echo " The path of the NSS certutil utility" echo "" echo " -u, --trust [/usr/bin/trust]" echo " The path of the p11-kit trust utility" echo "" echo " -f, --force Force run, even if source is not newer" echo "" echo " -g, --get Download certdata.txt directly from Mozilla's" echo " Mecurial server" echo "" echo " -h, --help Show this help message and exit" echo "" echo " -r, --rebuild Rebuild the enitre PKI tree using the previous" echo " certdata.txt file" echo "" echo " -v. --version Show version information and exit" echo "" echo "Example: `basename ${0}` -f -C ~/certdata.txt" echo "" } # Convert CKA_TRUST values to trust flags for certutil function convert_trust(){ case $1 in CKT_NSS_TRUSTED_DELEGATOR) echo "C" ;; CKT_NSS_NOT_TRUSTED) echo "p" ;; CKT_NSS_MUST_VERIFY_TRUST) echo "" ;; esac } function convert_trust_arg(){ case $1 in C) case $2 in sa) echo "-addtrust serverAuth" ;; sm) echo "-addtrust emailProtection" ;; cs) echo "-addtrust codeSigning" ;; ca) echo "-addtrust clientAuth" ;; esac ;; p) case $2 in sa) echo "-addreject serverAuth" ;; sm) echo "-addreject emailProtection" ;; cs) echo "-addreject codeSigning" ;; ca) echo "-addreject clientAuth" ;; esac ;; *) echo "" ;; esac } # Define p11-kit ext value constants (see p11-kit API documentation) get-p11-val() { case $1 in p11sasmcs) p11value="0%2a%06%03U%1d%25%01%01%ff%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03" ;; p11sasm) p11value="0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01" ;; p11sacs) p11value="0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03" ;; p11sa) p11value="0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%01" ;; p11smcs) p11value="0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%03" ;; p11sm) p11value="0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%04" ;; p11cs) p11value="0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%03" ;; p11) p11value="0%18%06%03U%1d%25%01%01%ff%04%0e0%0c%06%0a%2b%06%01%04%01%99w%06%0a%10" ;; esac } # Process command line arguments get_args $@ test ! -x "${OPENSSL}" && \ echo "OpenSSL not found at ${OPENSSL}. Exiting..." && exit 1 mkdir -p "${TEMPDIR}"/{certs,pki/anchors,work} if test "${WITH_P12}" -eq "1"; then test ! -x "${KEYTOOL}" && \ echo "Java keytool not found at ${KEYTOOL}. Exiting..." && exit 1 else mkdir -p "${TEMPDIR}/ssl/java" fi if test "${WITH_NSS}" -eq "1"; then test ! -x "${CERTUTIL}" && \ echo "NSS certutil not found at ${CERTUTIL}. Exiting..." && exit 1 # Create a blank NSS DB mkdir -p "${TEMPDIR}/pki/nssdb" "${CERTUTIL}" -N --empty-password -d "sql:${TEMPDIR}/pki/nssdb" fi # Download certdata.txt if selected if test "${GET}" == "1"; then HOST=$(echo "${URL}" | /usr/bin/cut -d / -f 3) _url=$(echo "${URL}" | sed 's@raw-file@log@') SARGS="-ign_eof -connect ${HOST}:443" if test "${PROXY}x" != "x"; then SARGS="${SARGS} -proxy ${PROXY}" fi echo GET ${_url} | \ ${OPENSSL} s_client ${SARGS} 2>/dev/null > "${TEMPDIR}/certdata.txt.log" unset _url # Error out here if we couldn't get the file grep -m1 "" "${TEMPDIR}/certdata.txt.log" 2>&1>/dev/null if test "$?" -gt 0; then echo "Unable to get revision from server! Exiting." exit 1 fi # See if we need to update before downloading the file REVISION=$(grep -m1 "" "${TEMPDIR}/certdata.txt.log" | cut -d "<" -f 1) if test -e "${DESTDIR}${SSLDIR}/certdata.txt"; then OLDVERSION=$(grep "^# Revision:" "${DESTDIR}${SSLDIR}/certdata.txt" | \ cut -d ":" -f 2) if test "${OLDVERSION}x" == "${REVISION}x" -a "${FORCE}" == "0"; then echo "No update required! Use --force to update anyway." exit 0 fi fi # Download the new file echo GET ${URL} | \ ${OPENSSL} s_client ${SARGS} 2>/dev/null >> "${CERTDATA}" _line=$(( $(grep -n "certdata.txt" "${CERTDATA}" | cut -d ":" -f 1) - 1)) sed -e "1,${_line}d" -i "${CERTDATA}" sed "1i # Revision:${REVISION}" -i "${CERTDATA}" fi if test "${REBUILD}" == "1"; then CERTDATA="${DESTDIR}${SSLDIR}/certdata.txt" fi if test ! -r "${CERTDATA}"; then echo "${CERTDATA} was not found. The certdata.txt file must be in the local" echo "directory, speficied with the -C/--certdata switch, or downloaded with" echo "the -g/--get switch." exit 1 fi REVISION=$(grep "^# Revision" "${CERTDATA}" | cut -d ":" -f 2) if test "${REVISION}x" == "x"; then echo "WARNING! ${CERTDATA} has no 'Revision' value." echo "Will run conversion unconditionally." sleep 2 REVISION="$(date -u +%Y%m%d-%H%M)" echo "# Revision:${REVISION}" > "${WORKDIR}/certdata.txt" else if test "${FORCE}" == "1"; then echo "Output forced. Will run conversion unconditionally." sleep 2 elif test "${DESTDIR}x" == "x"; then test -f "${CABUNDLE}" && OLDVERSION=$(grep "^# Revision:" "${CABUNDLE}" | cut -d ":" -f 2) if test "${OLDVERSION}x" == "${REVISION}x"; then echo "No update required! Use --force to update anyway." exit 0 fi fi fi cat "${CERTDATA}" >> "${WORKDIR}/certdata.txt" pushd "${WORKDIR}" > /dev/null # Get a list of starting lines for each cert CERTBEGINLIST=`grep -n "^# Certificate" "${WORKDIR}/certdata.txt" | \ cut -d ":" -f1` # Dump individual certs to temp file for certbegin in ${CERTBEGINLIST}; do awk "NR==$certbegin,/^CKA_TRUST_STEP_UP_APPROVED/" "${WORKDIR}/certdata.txt" \ > "${TEMPDIR}/certs/${certbegin}.tmp" done unset CERTBEGINLIST certbegin for tempfile in ${TEMPDIR}/certs/*.tmp; do # Get a name for the cert certname="$(grep "^# Certificate" "${tempfile}" | cut -d '"' -f 2)" # Determine certificate trust values for SSL/TLS, S/MIME, and Code Signing satrust="$(convert_trust `grep '^CKA_TRUST_SERVER_AUTH' ${tempfile} | \ cut -d " " -f 3`)" smtrust="$(convert_trust `grep '^CKA_TRUST_EMAIL_PROTECTION' ${tempfile} | \ cut -d " " -f 3`)" cstrust="$(convert_trust `grep '^CKA_TRUST_CODE_SIGNING' ${tempfile} | \ cut -d " " -f 3`)" # Not currently included in NSS certdata.txt #catrust="$(convert_trust `grep '^CKA_TRUST_CLIENT_AUTH' ${tempfile} | \ # cut -d " " -f 3`)" # Get args for OpenSSL trust settings saarg="$(convert_trust_arg "${satrust}" sa)" smarg="$(convert_trust_arg "${smtrust}" sm)" csarg="$(convert_trust_arg "${cstrust}" cs)" # Not currently included in NSS certdata.txt #caarg="$(convert_trust_arg "${catrust}" ca)" # Convert to a PEM formated certificate printf $(awk '/^CKA_VALUE/{flag=1;next}/^END/{flag=0}flag{printf $0}' \ "${tempfile}") | "${OPENSSL}" x509 -text -inform DER -fingerprint \ > tempfile.crt # Get individual values for certificates certkey="$(${OPENSSL} x509 -in tempfile.crt -noout -pubkey)" certcer="$(${OPENSSL} x509 -in tempfile.crt)" certtxt="$(${OPENSSL} x509 -in tempfile.crt -noout -text)" # Get p11-kit label, oid, and values p11label="$(grep -m1 "Issuer" ${tempfile} | grep -o CN=.*$ | \ cut -d ',' -f 1 | sed 's@CN=@@')" # if distrusted at all, x-distrusted if test "${satrust}" == "p" -o "${smtrust}" == "p" -o "${cstrust}" == "p" then # if any distrusted, x-distrusted p11trust="x-distrusted: true" p11oid="1.3.6.1.4.1.3319.6.10.1" p11value="0.%06%0a%2b%06%01%04%01%99w%06%0a%01%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03" else p11trust="trusted: true" p11oid="2.5.29.37" trustp11="p11" if test "${satrust}" == "C"; then trustp11="${trustp11}sa" fi if test "${smtrust}" == "C"; then trustp11="${trustp11}sm" fi if test "${cstrust}" == "C"; then trustp11="${trustp11}cs" fi get-p11-val "${trustp11}" fi # Get a hash for the cert keyhash=$("${OPENSSL}" x509 -noout -in tempfile.crt -hash) # Print information about cert echo "Certificate: ${certname}" echo "Keyhash: ${keyhash}" # Place certificate into trust anchors dir anchorfile="${TEMPDIR}/pki/anchors/${keyhash}.pem" echo "[p11-kit-object-v1]" >> "${anchorfile}" echo "label: \"${p11label}\"" >> "${anchorfile}" echo "class: x-certificate-extension" >> "${anchorfile}" echo "object-id: ${p11oid}" >> "${anchorfile}" echo "value: \"${p11value}\"" >> "${anchorfile}" echo "modifiable: false" >> "${anchorfile}" echo "${certkey}" >> "${anchorfile}" echo "" >> "${anchorfile}" echo "[p11-kit-object-v1]" >> "${anchorfile}" echo "label: \"${p11label}\"" >> "${anchorfile}" echo "${p11trust}" >> "${anchorfile}" echo "nss-mozilla-ca-policy: true" >> "${anchorfile}" echo "modifiable: false" >> "${anchorfile}" echo "${certcer}" >> "${anchorfile}" echo "${certtxt}" | sed 's@^@#@' >> "${anchorfile}" echo "Added to p11-kit anchor directory with trust '${satrust},${smtrust},${cstrust}'." # Import all certificates with trust args to the temporary NSS DB if test "${WITH_NSS}" == "1"; then "${CERTUTIL}" -d "sql:${TEMPDIR}/pki/nssdb" -A \ -t "${satrust},${smtrust},${cstrust}" \ -n "${certname}" -i tempfile.crt echo "Added to NSS shared DB with trust '${satrust},${smtrust},${cstrust}'." fi # Import all certificates with trust args to the java cacerts.p12 file if test "${WITH_P12}" == "1"; then # Remove existing certificate "${KEYTOOL}" -delete -noprompt -alias "${certname}" \ -keystore "${TEMPDIR}/ssl/java/cacerts.p12" \ -storepass 'changeit' 2>&1> /dev/null # Determine ExtendedKeyUsage EKU="" EKUVAL="" if test "${satrust}" == "C"; then EKU="serverAuth"; fi if test "${smtrust}" == "C"; then if test "${EKU}" == ""; then EKU="clientAuth" else EKU="${EKU},clientAuth" fi fi if test "${cstrust}" == "C"; then if test "${EKU}" == ""; then EKU="codeSigning" else EKU="${EKU},codeSigning" fi fi if test "${EKU}" != ""; then EKUVAL="-ext EKU=${EKU}" "${KEYTOOL}" -importcert -file tempfile.crt -storetype PKCS12 \ -noprompt -alias "${certname}" -storepass 'changeit' \ -keystore "${TEMPDIR}/ssl/java/cacerts.p12" $EKUVAL \ 2>&1> /dev/null | \ sed -e "s@Certificate was a@A@" \ -e 's@keystore@Java cacerts (PKCS#12) with trust '${satrust},${smtrust},${cstrust}'.@' \ | sed 's@p@@' unset EKU unset EKUVAL fi fi # Clean up the directory and environment as we go rm -f tempfile.crt unset keyhash subject count certname unset trustlist rejectlist satrust smtrust cstrust catrust p11label anchrorfile unset p11trust p11oid p11value trustp11 echo -e "\n" done unset tempfile # Install anchors in $ANCHORDIR test -d "${DESTDIR}${ANCHORDIR}" && rm -rf "${DESTDIR}${ANCHORDIR}" install -dm755 "${DESTDIR}${ANCHORDIR}" 2>&1>/dev/null install -m644 "${TEMPDIR}"/pki/anchors/*.pem "${DESTDIR}${ANCHORDIR}" # Install NSS Shared DB if test "${WITH_NSS}" == "1"; then sed -e "s@${TEMPDIR}/pki/nssdb@${NSSDB}@" \ -e 's/library=/library=libnsssysinit.so/' \ -e 's/Flags=internal/Flags=internal,moduleDBOnly/' \ -i "${TEMPDIR}/pki/nssdb/pkcs11.txt" test -d "${DESTDIR}${NSSDB}" && rm -rf "${DESTDIR}${NSSDB}" install -dm755 "${DESTDIR}${NSSDB}" 2>&1>/dev/null install -m644 "${TEMPDIR}"/pki/nssdb/{cert9.db,key4.db,pkcs11.txt} \ "${DESTDIR}${NSSDB}" fi # Install Java cacerts.p12 in ${KEYSTORE} if test "${WITH_P12}" == "1"; then test -f "${DESTDIR}${KEYSTORE}.p12" && rm -f "${DESTDIR}${KEYSTORE}.p12" install -dm644 "${TEMPDIR}/ssl/java/cacerts.p12" "${DESTDIR}${KEYSTORE}.p12" fi # Import any certs in $LOCALDIR # Don't do any checking, just trust the admin if test -d "${LOCALDIR}"; then echo "Processing local certificates..." for cert in `find "${LOCALDIR}" -name "*.pem"`; do # Get some information about the certificate keyhash=$("${OPENSSL}" x509 -noout -in "${cert}" -hash) subject=$("${OPENSSL}" x509 -noout -in "${cert}" -subject) count=1 while test "${count}" -lt 10; do echo "${subject}" | cut -d "/" -f "${count}" | grep "CN=" >/dev/null \ && break let count++ done certname=$(echo "${subject}" | cut -d "/" -f "${count}" | sed 's@CN=@@') echo "Certificate: ${certname}" echo "Keyhash: ${keyhash}" # Get trust information trustlist=$("${OPENSSL}" x509 -in "${cert}" -text -trustout | \ grep -A1 "Trusted Uses") satrust="" smtrust="" cstrust="" catrust="" satrust=$(echo "${trustlist}" | \ grep "TLS Web Server" 2>&1> /dev/null && echo "C") smtrust=$(echo "${trustlist}" | \ grep "E-mail Protection" 2>&1 >/dev/null && echo "C") cstrust=$(echo "${trustlist}" | \ grep "Code Signing" 2>&1 >/dev/null && echo "C") catrust=$(echo "${trustlist}" | \ grep "Client Auth" 2>&1 >/dev/null && echo "C") # Get reject information rejectlist=$("${OPENSSL}" x509 -in "${cert}" -text -trustout | \ grep -A1 "Rejected Uses") if test "${satrust}" == ""; then satrust=$(echo "${rejectlist}" | \ grep "TLS Web Server" 2>&1> /dev/null && echo "p"); fi if test "${smtrust}" == ""; then smtrust=$(echo "${rejectlist}" | \ grep "E-mail Protection" 2>&1> /dev/null && echo "p"); fi if test "${cstrust}" == ""; then cstrust=$(echo "${rejectlist}" | \ grep "Code Signing" 2>&1> /dev/null && echo "p"); fi if test "${catrust}" == ""; then catrust=$(echo "${rejectlist}" | \ grep "Client Auth" 2>&1> /dev/null && echo "p"); fi # Get individual values for certificates certkey="$(${OPENSSL} x509 -in ${cert} -noout -pubkey)" certcer="$(${OPENSSL} x509 -in ${cert})" certtxt="$(${OPENSSL} x509 -in ${cert} -noout -text)" # Place certificate into trust anchors dir p11label="$(grep -m1 "Issuer" ${cert} | grep -o CN=.*$ | \ cut -d ',' -f 1 | sed 's@CN=@@')" # if distrusted at all, x-distrusted if test "${satrust}" == "p" -o "${smtrust}" == "p" -o "${cstrust}" == "p" then # if any distrusted, x-distrusted p11trust="x-distrusted: true" p11oid="1.3.6.1.4.1.3319.6.10.1" p11value="0.%06%0a%2b%06%01%04%01%99w%06%0a%01%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03" else p11trust="trusted: true" p11oid="2.5.29.37" trustp11="p11" if test "${satrust}" == "C"; then trustp11="${trustp11}sa" fi if test "${smtrust}" == "C"; then trustp11="${trustp11}sm" fi if test "${cstrust}" == "C"; then trustp11="${trustp11}cs" fi get-p11-val "${trustp11}" fi anchorfile="${DESTDIR}${ANCHORDIR}/${keyhash}.pem" echo "[p11-kit-object-v1]" >> "${anchorfile}" echo "label: \"${p11label}\"" >> "${anchorfile}" echo "class: x-certificate-extension" >> "${anchorfile}" echo "object-id: ${p11oid}" >> "${anchorfile}" echo "value: \"${p11value}\"" >> "${anchorfile}" echo "modifiable: false" >> "${anchorfile}" echo "${certkey}" >> "${anchorfile}" echo "" >> "${anchorfile}" echo "[p11-kit-object-v1]" >> "${anchorfile}" echo "label: \"${p11label}\"" >> "${anchorfile}" echo "${p11trust}" >> "${anchorfile}" echo "modifiable: false" >> "${anchorfile}" echo "${certcer}" >> "${anchorfile}" echo "${certtxt}" | sed 's@^@#@' >> "${anchorfile}" echo "Added to p11-kit anchor directory with trust '${satrust},${smtrust},${cstrust}'." # Add to Shared NSS DB if test "${WITH_NSS}" == "1"; then "${OPENSSL}" x509 -in "${cert}" -text -fingerprint | \ "${CERTUTIL}" -d "sql:${DESTDIR}${NSSDB}" -A \ -t "${satrust},${smtrust},${cstrust}" \ -n "${certname}" echo "Added to NSS shared DB with trust '${satrust},${smtrust},${cstrust}'." fi # Import certificate (with trust args) into the java cacerts.p12 file if test "${WITH_P12}" == "1"; then # Remove existing certificate "${KEYTOOL}" -delete -noprompt -alias "${certname}" \ -keystore "${DESTDIR}${KEYSTORE}/cacerts.p12" \ -storepass 'changeit' 2>&1> /dev/null # Determing ExtendedKeyUsage EKU="" if test "${satrust}" == "C"; then EKU="serverAuth"; fi if test "${catrust}" == "C"; then if test "${EKU}" == ""; then EKU="clientAuth" else EKU="${EKU},clientAuth" fi fi if test "${cstrust}" == "C"; then if test "${EKU}" == ""; then EKU="codeSigning" else EKU="${EKU},codeSigning" fi fi if test "${EKU}" != ""; then EKUVAL="-ext EKU=${EKU}" "${OPENSSL}" x509 -in "${cert}" -text -fingerprint \ -setalias "${certname}" > "${TEMPDIR}/tempcert.pem" "${KEYTOOL}" -importcert -noprompt -alias "${certname}" \ -keystore "${DESTDIR}${KEYSTORE}/cacerts.p12" \ -storepass 'changeit' $EKUVAL \ -file "${TEMPDIR}/tempcert.pem" \ 2>&1> /dev/null | \ sed -e "s@Certificate was a@A@" \ -e 's@keystore@Java cacerts (PKCS#12) with trust '${satrust},${smtrust},${cstrust}'.@' \ | sed 's@p@@' rm -f "${TEMPDIR}/tempcert.pem" unset EKU unset EKUVAL fi fi unset keyhash subject count certname unset trustlist rejectlist satrust smtrust cstrust catrust p11label anchrorfile unset p11trust p11oid p11value trustp11 echo "" done unset cert fi # Install certdata.txt if test "${REBUILD}" == "0"; then install -vdm755 "${DESTDIR}${SSLDIR}" install -m644 "${WORKDIR}/certdata.txt" "${DESTDIR}${SSLDIR}/certdata.txt" fi # Clean up the mess rm -rf "${TEMPDIR}" # Build alternate formats using p11-kit trust (if not using DESTDIR) if test "x${DESTDIR}" == "x"; then mkdir -p /etc/ssl/{certs,java} echo -n "Extracting OpenSSL certificates to ${CERTDIR}..." "${TRUST}" extract --filter=certificates --format=openssl-directory \ --overwrite --comment "${CERTDIR}" \ && echo "Done!" || echo "Failed!!!" echo -n "Extracting GNUTLS server auth certificates to ${CABUNDLE}..." "${TRUST}" extract --filter=ca-anchors --format=pem-bundle \ --purpose server-auth --overwrite --comment "${CABUNDLE}" \ && echo "Done!" || echo "Failed!!!" echo -n "Extracting GNUTLS S-Mime certificates to ${SMBUNDLE}..." "${TRUST}" extract --filter=ca-anchors --format=pem-bundle \ --purpose email --overwrite --comment "${SMBUNDLE}" \ && echo "Done!" || echo "Failed!!!" echo -n "Extracting GNUTLS code signing certificates to ${CSBUNDLE}..." "${TRUST}" extract --filter=ca-anchors --format=pem-bundle \ --purpose code-signing --overwrite --comment \ "${CSBUNDLE}" && echo "Done!" || echo "Failed!!!" echo -n "Extracting Java cacerts (JKS) to ${KEYSTORE}..." "${TRUST}" extract --filter=ca-anchors --format=java-cacerts \ --purpose server-auth --overwrite --comment "${KEYSTORE}" \ && echo "Done!" || echo "Failed!!!" # Remove compatibility symlink for 0.8 at 0.10 ln -sf cacerts "${KEYSTORE}.jks" fi # End /usr/sbin/make-ca