#!/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="Laclin-180505" # Get/set defaults CERTDATA="certdata.txt" PKIDIR="/etc/pki" SSLDIR="/etc/ssl" CERTUTIL=`which certutil` KEYTOOL=`which keytool` OPENSSL=`which openssl` 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" 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" # 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" WITH_NSS=1 WITH_JAVA=1 CERTDATAY=0 FORCE=0 GET=0 REBUILD=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" 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 ;; -l | --localdir) check_arg $1 $2 LOCALDIR="${2}" shift 2 ;; -n | --nssdb) check_arg $1 $2 NSSDB="${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 ;; -p | --proxy) check_arg $1 $2 PROXY="${2}" shift 2 ;; -k | --keytool) check_arg $1 $2 KEYTOOL="${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}" 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" echo " The output directory for the Java" echo " cacerts.{jks,p12} files" 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 " -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 [PATH]" echo " The path to the java keytool utility" echo "" echo " -s, --openssl [PATH]" echo " The path to the openssl utility" echo "" echo " -t, --certutil [PATH]" echo " The path the certutil 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 "${CERTUTIL}" || WITH_NSS=0 test -x "${KEYTOOL}" || WITH_JAVA=0 test ! -x "${OPENSSL}" && echo "OpenSSL not found at ${OPENSSL}. Exiting..." && exit 1 mkdir -p "${TEMPDIR}"/{certs,ssl/{certs,java},pki/{nssdb,anchors},work} # 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 if test "${WITH_NSS}" == "1"; then # Create a blank NSS DB "${CERTUTIL}" -N --empty-password -d "sql:${TEMPDIR}/pki/nssdb" fi # 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 certificate into the temporary certificate directory with # trust arguments "${OPENSSL}" x509 -in tempfile.crt -text -fingerprint \ -setalias "${certname}" ${saarg} ${smarg} ${csarg} \ > "${TEMPDIR}/ssl/certs/${keyhash}.pem" echo "Added to OpenSSL certificate 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_JAVA}" == "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 certname unset satrust smtrust cstrust catrust sarg smarg csarg caarg unset p11trust p11oid p11value trustp11 certkey certcer certtxt echo -e "\n" done unset tempfile # Sanity check count=$(ls "${TEMPDIR}"/ssl/certs/*.pem | wc -l) # Historically there have been between 152 and 190 certs # A minimum of 150 should be safe for a rudimentry sanity check if test "${count}" -lt "150" ; then echo "Error! Only ${count} certificates were generated!" echo "Exiting without update!" echo "" echo "${TEMPDIR} is the temporary working directory" exit 2 fi unset count # 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 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 certificates in $CERTDIR test -d "${DESTDIR}${CERTDIR}" && rm -rf "${DESTDIR}${CERTDIR}" install -dm755 "${DESTDIR}${CERTDIR}" 2>&1>/dev/null install -m644 "${TEMPDIR}"/ssl/certs/*.pem "${DESTDIR}${CERTDIR}" # Install Java cacerts.p12 in ${KEYSTORE} test -f "${DESTDIR}${KEYSTORE}/cacerts.p12" && rm -f "${DESTDIR}${KEYSTORE}/cacerts.p12" install -dm755 "${DESTDIR}${KEYSTORE}" install -m644 "${TEMPDIR}/ssl/java/cacerts.p12" "${DESTDIR}${KEYSTORE}" # 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 # 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}'." # Install into OpenSSL certificate store # 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)" "${OPENSSL}" x509 -in "${cert}" -text -fingerprint \ -setalias "${certname}" ${saarg} ${smarg} ${csarg} \ >> "${DESTDIR}${CERTDIR}/${keyhash}.pem" echo "Added to OpenSSL certificate directory with trust '${satrust},${smtrust},${cstrust},${catrust}'." # 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_JAVA}" == "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 unset p11trust p11oid p11value trustp11 certkey certcer certtxt echo "" done unset cert fi # Build cacerts.jks and ca-bundle.crt # Generate the bundle bundlefile=`basename "${CABUNDLE}"` bundledir=`echo "${CABUNDLE}" | sed "s@/${bundlefile}@@"` install -vdm755 "${DESTDIR}${bundledir}" 2>&1>/dev/null rm -f "${DESTDIR}${CABUNDLE}" rm -f "${DESTDIR}${SMBUNDLE}" rm -f "${DESTDIR}${CSBUNDLE}" rm -f "${DESTDIR}${KEYSTORE}/cacerts.jks" echo "# Revision:${REVISION}" > "${DESTDIR}${CABUNDLE}" echo "# Revision:${REVISION}" > "${DESTDIR}${SMBUNDLE}" echo "# Revision:${REVISION}" > "${DESTDIR}${CSBUNDLE}" echo "Processing certs for Java (JKS) and GNUTLS stores..." # Generate the bundle for cert in `find "${DESTDIR}${CERTDIR}" -name "*.pem"`; do # Get some information about the certificate keyhash=$("${OPENSSL}" x509 -noout -in "${cert}" -hash) certname=$(grep "Alias" "${cert}") # Get trust information trustlist=$("${OPENSSL}" x509 -in "${cert}" -text -trustout | \ grep -A1 "Trusted Uses") satrust="" smtrust="" cstrust="" 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") if test "${satrust}x" == "Cx"; then echo "" echo "${certname}" | sed 's@Alias:@Certificate: @' echo "Keyhash: ${keyhash}" # Append to the CA bundle "${OPENSSL}" x509 -in "${cert}" -text -fingerprint \ > "${TEMPDIR}/ssl/certs/${keyhash}.pem" cat "${TEMPDIR}/ssl/certs/${keyhash}.pem" >> "${DESTDIR}${CABUNDLE}" echo "Added to GnuTLS certificate bundle." # Add to Java keystore (JKS) if test "${WITH_JAVA}" == "1"; then # Remove certificate if it already exists "${KEYTOOL}" -delete -noprompt -alias "${certname}" \ -keystore "${DESTDIR}${KEYSTORE}/cacerts.jks" \ -storepass 'changeit' 2>&1> /dev/null # Import it "${KEYTOOL}" -importcert -file "${TEMPDIR}/ssl/certs/${keyhash}.pem" \ -noprompt -alias "${certname}" -storetype JKS \ -keystore "${DESTDIR}${KEYSTORE}/cacerts.jks" \ -storepass 'changeit' 2>&1> /dev/null | \ sed -e 's@Certificate was a@A@' -e 's@keystore@Java (JKS) keystore.@' fi fi if test "${smtrust}x" == "Cx"; then echo "" echo "${certname}" | sed 's@Alias:@Certificate: @' echo "Keyhash: ${keyhash}" # Append to the s-mime bundle "${OPENSSL}" x509 -in "${cert}" -text -fingerprint \ > "${TEMPDIR}/ssl/certs/${keyhash}.pem" cat "${TEMPDIR}/ssl/certs/${keyhash}.pem" >> "${DESTDIR}${SMBUNDLE}" echo "Added to s-mime certificate bundle." fi if test "${cstrust}x" == "Cx"; then echo "" echo "${certname}" | sed 's@Alias:@Certificate: @' echo "Keyhash: ${keyhash}" # Append to the code signing bundle "${OPENSSL}" x509 -in "${cert}" -text -fingerprint \ > "${TEMPDIR}/ssl/certs/${keyhash}.pem" cat "${TEMPDIR}/ssl/certs/${keyhash}.pem" >> "${DESTDIR}${CSBUNDLE}" echo "Added to code signing certificate bundle." fi done c_rehash "${DESTDIR}${CERTDIR}" 2>&1>/dev/null popd > /dev/null # Install certdata.txt if test "${REBUILD}" == "0"; then install -m644 "${WORKDIR}/certdata.txt" "${DESTDIR}${SSLDIR}/certdata.txt" fi # Clean up the mess rm -rf "${TEMPDIR}" # End /usr/sbin/make-ca