#!/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 # Graham Weldon # Douglas Reno shopt -s extglob; VERSION="1.16.1" MAKE_CA_CONF="/etc/make-ca.conf" # CA root for hg.mozilla.org MOZILLA_CA_ROOT="/etc/make-ca/ISRG_Root_X1.pem" # Get/set defaults if test -f "${MAKE_CA_CONF}"; then . "${MAKE_CA_CONF}" else CERTDATA="certdata.txt" PKIDIR="/etc/pki" SSLDIR="/etc/ssl" CERTUTIL="/usr/bin/certutil" KEYTOOL="${JAVA_HOME}/bin/keytool" MD5SUM="/usr/bin/md5sum" OPENSSL="/usr/bin/openssl" TRUST="/usr/bin/trust" ANCHORDIR="${PKIDIR}/anchors" ANCHORLIST="${PKIDIR}/anchors.md5sums" BUNDLEDIR="${PKIDIR}/tls/certs" CABUNDLE="${BUNDLEDIR}/ca-bundle.crt" SMBUNDLE="${BUNDLEDIR}/email-ca-bundle.crt" CSBUNDLE="${BUNDLEDIR}/objsign-ca-bundle.crt" CERTDIR="${SSLDIR}/certs" KEYSTORE="${PKIDIR}/tls/java" NSSDB="${PKIDIR}/nssdb" LOCALDIR="${SSLDIR}/local" DESTDIR="" URL="https://hg-edge.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt" fi # 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 WITH_CS=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}" echo ${DESTDIR} | grep -q "^\." && DESTDIR="${PWD}/${DESTDIR}" 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}" CERTDIR="${SSLDIR}/certs" LOCALDIR="${SSLDIR}/local" echo "${@}" | grep -e "-d " -e "--cadir" > /dev/null 2>&1 if test "${?}" == "0"; then echo "Error! ${1} cannot be used with the -d/--cadir switch." echo "" exit 3 fi shift 2 ;; -a | --anchordir) check_arg $1 $2 ANCHORDIR="${2}" echo "${@}" | grep -e "-P " -e "--pkidir" > /dev/null 2>&1 if test "${?}" == "0"; then echo "Error! ${1} cannot be used with the -P/--pkidir switch." echo "" exit 3 fi shift 2 ;; -b | --bundledir) check_arg $1 $2 BUNDLEDIR="${2}" shift 2 ;; -d | --cadir) check_arg $1 $2 CERTDIR="${2}" echo "$@" | grep -e "-S" -e "--ssldir" > /dev/null 2>&1 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 ;; -i | --mscodesign) WITH_CS="1" shift 1 ;; -j | --javacerts) check_arg $1 $2 KEYSTORE="${2}" 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 ;; # Handle getopt style short args (use extglob instead of loop) -+([a-z,A-Z])) # split up the arguments and call recursively with trailing break arg="${1}" newargs=$( echo ${1} | sed 's@-@@' | \ sed 's/.\{1\}/& /g' | \ sed 's/[^ ]* */-&/g') newargs="${newargs} $(echo ${@} | sed "s@${arg}@@")" get_args ${newargs} break; ;; *) showhelp exit 1 ;; esac done } function check_arg(){ echo "${2}" | grep "^-" > /dev/null if [ "$?" == "0" -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 workstations and servers using only standard GNU utilities, OpenSSL, and" echo "P11-Kit. It will optionally generate keystores for 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 root directory - Cannot be used" echo " with the -a / --anchordir or" echo " -n / --nssdb switches" echo "" echo " -S, --ssldir [/etc/ssl]" echo " The output SSL root direcotry - Cannot be used" echo " with the -d / --cadir switch" echo "" echo " -a, --anchordir [\$PKIDIR/anchors]" echo " The output directory for .p11-kit trust anchors" echo "" echo " -b, --bundledir [\$PKIDIR/certs]" echo " The output direcotry for the PEM formated" echo " bundles" echo "" echo " -d, --cadir [\$SSLDIR/certs]" echo " The output directory for the OpenSSL trusted" echo " CA certificates" echo "" echo " -j, --javacerts [\$PKIDIR/java/cacerts]" echo " The output directory for the Java cacerts" echo " file(s)" 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 source and provide system local" echo " certifiates" echo "" echo " -m, --java-p12" echo " Export Java PKCS#12 store - this will default to" echo " \$PKIDIR/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 " -i, --mscodesign" echo " Use Microsoft's trust values for code singing" echo " You must copy /etc/make-ca/CS.txt to \$SSLDIR" 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 entire 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_moz_distrust(){ # SERVER val=$(grep "CKA_NSS_SERVER_DISTRUST_AFTER" "${1}" | cut -d " " -f 2) if test "${val}" == "CK_BBOOL"; then val=$(grep "CKA_NSS_SERVER_DISTRUST_AFTER" "${1}" | cut -d " " -f 3) if test "${val}" == "CK_FALSE"; then mozsadistrust="%00" else mozsadistrust="UNKNOWN" fi elif test "${val}" == "MULTILINE_OCTAL"; then mozsadistrust=`printf $(grep -A1 "CKA_NSS_SERVER_DISTRUST_AFTER" "${1}" | tail -n1)` else mozsadistrust="UNKNOWN" fi # EMAIL val=$(grep "CKA_NSS_EMAIL_DISTRUST_AFTER" "${1}" | cut -d " " -f 2) if test "${val}" == "CK_BBOOL"; then val=$(grep "CKA_NSS_EMAIL_DISTRUST_AFTER" "${1}" | cut -d " " -f 3) if test "${val}" == "CK_FALSE"; then mozsmdistrust="%00" else mozsmdistrust="UNKNOWN" fi elif test "${val}" == "MULTILINE_OCTAL"; then mozsmdistrust=`printf $(grep -A1 "CKA_NSS_EMAIL_DISTRUST_AFTER" "${1}" | tail -n1)` else mozsmdistrust="UNKNOWN" fi unset val } 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) function 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 } function get_p11_label() { # $1 == individual nss certificate extracted from certdata.txt # or x509 certificate with OpenSSL text values # Start with the label assigned by Mozilla p11label=$(grep -m1 "^CKA_LABEL" ${1} | cut -d '"' -f 2 | sed 's@"@@g') # If not coming from certdata.txt, get from x509 Subject line if [ "${p11label}" == "" ]; then # Get the subject line for any certs and do some early normalization subjectline=$(grep -m1 "Subject:" ${1} | sed -e 's@\s*=\s*@=@g' \ -e "s@(@ - @g" -e "s@)@ - @g" -e 's@\\@-@g' ) # Try for CN Next (and further normalize) if not from certdata.txt p11label="$(echo ${subjectline} | grep -o "CN=.*$" | cut -d '=' -f 2 | \ sed -e 's@[A-Z]*$@@g' -e 's@, $@@' -e 's@"@@g' \ -e 's@,@@g' -e 's@ $@@')" # Fallback to the last OU value if CN does not exeist in Subject string ## Special case for GlobalSign certs if [ "${p11label}" == "" ]; then p11label="$(echo ${subjectline} | grep -o "OU=.*$" | \ sed 's@OU=.*, OU=@OU=@g'| cut -d '=' -f 2 | \ sed -e 's@[A-Z]*$@@' -e 's@, $@@' -e 's@"@@g' \ -e 's@,@@g' -e 's@ $@@')" # If still empty, fall back to Object value as a last resort if [ "${p11label}" == "" ]; then p11label="$(echo ${subjectline} | grep -o "O=.*$" | \ cut -d '=' -f 2 | sed -e 's@[A-Z]*$@@g' \ -e 's@, $@@' -e 's@"@@g' \ -e 's@,@@g' -e 's@ $@@')" fi fi fi } function get_trust_values() { # $1 == individual certificate extracted from NSS certdata.txt # Determine certificate trust values for SSL/TLS, S/MIME, and Code Signing satrust="$(convert_trust `grep '^CKA_TRUST_SERVER_AUTH' ${1} | \ cut -d " " -f 3`)" smtrust="$(convert_trust `grep '^CKA_TRUST_EMAIL_PROTECTION' ${1} | \ cut -d " " -f 3`)" cstrust="$(convert_trust `grep '^CKA_TRUST_CODE_SIGNING' ${1} | \ cut -d " " -f 3`)" if test "${WITH_CS}" -eq "1"; then if test "${cstrust}" == ""; then cstrust=$(grep -q "^${keyhash}" "${SSLDIR}/CS.txt" && echo "C") fi fi # Not currently included in NSS certdata.txt #catrust="$(convert_trust `grep '^CKA_TRUST_CLIENT_AUTH' ${1} | \ # cut -d " " -f 3`)" # Determine distrust values convert_moz_distrust ${1} } function get_p11_trust() { # 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 } function write_anchor() { 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: ${moz_trust}" >> "${anchorfile}" echo "modifiable: false" >> "${anchorfile}" if test "${mozsadistrust}" != "UNKNOWN"; then echo "nss-server-distrust-after: \"${mozsadistrust}\"" >> "${anchorfile}" fi if test "${mozsmdistrust}" != "UNKNOWN"; then echo "nss-email-distrust-after: \"${mozsmdistrust}\"" >> "${anchorfile}" fi echo "${certcer}" >> "${anchorfile}" echo "${certtxt}" | sed 's@^@#@' >> "${anchorfile}" echo "Added to p11-kit anchor directory with trust '${satrust},${smtrust},${cstrust}'." } function write_nss_db() { # $1 == NSS database # $2 == x509 certificate in PEM format "${CERTUTIL}" -d "sql:${1}" -A \ -t "${satrust},${smtrust},${cstrust}" \ -n "${p11label}" -i "${2}" > /dev/null 2>&1 echo "Added to NSS shared DB with trust '${satrust},${smtrust},${cstrust}'." } function write_java_p12() { # $1 == cacerts.p12 file # $2 == x509 certificate in PEM format # Remove existing certificate "${KEYTOOL}" -delete -noprompt -alias "${p11label}" \ -keystore "${1}" \ -storepass 'changeit' > /dev/null 2>&1 # 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 "${2}" -storetype PKCS12 \ -noprompt -alias "${p11label}" -storepass 'changeit' \ -keystore "${1}" $EKUVAL \ > /dev/null 2>&1 echo "Added to Java cacerts (PKCS#12) with trust '${satrust},${smtrust},${cstrust}'." unset EKU unset EKUVAL fi } # 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 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 if test "${WITH_CS}" -eq "1"; then test ! -f "${SSLDIR}/CS.txt" && \ echo "List of hashes not found at ${SSLDIR}/CS.txt. Exiting..." && exit 1 fi # Download certdata.txt if selected if test "${GET}" == "1"; then echo -n "Checking for new version of certdata.txt..." HOST=$(echo "${URL}" | /usr/bin/cut -d / -f 3) _url=$(echo "${URL}" | sed 's@raw-file@log@') SARGS="-ign_eof -connect ${HOST}:443 -verifyCAfile ${MOZILLA_CA_ROOT}" if test -d /etc/ssl/certs; then SARGS="${SARGS} -verifyCApath ${CERTDIR}" fi SARGS="${SARGS} -verify_return_error" if test "${PROXY}x" != "x"; then SARGS="${SARGS} -proxy ${PROXY}" fi printf "GET ${_url} HTTP/1.1\nConnection: no-keep-alive\n\n" | \ ${OPENSSL} s_client ${SARGS} 2> /dev/null > "${TEMPDIR}/certdata.txt.log" unset _url echo "done." # Error out here if we couldn't get the file grep -m1 "" "${TEMPDIR}/certdata.txt.log" > /dev/null 2>&1 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 -n "Downloading certdata.txt..." printf "GET ${URL} HTTP/1.1\nConnection: no-keep-alive\n\n" | \ ${OPENSSL} s_client ${SARGS} 2> /dev/null >> "${CERTDATA}" _line=$(( $(grep -n -m 1 "^#$" "${CERTDATA}" | cut -d ":" -f 1) - 1)) sed -e "1,${_line}d" -i "${CERTDATA}" sed "1i # Revision:${REVISION}" -i "${CERTDATA}" mv "${CERTDATA}" "${CERTDATA}.tmp" head -n -33 "${CERTDATA}.tmp" > "${CERTDATA}" rm "${CERTDATA}.tmp" echo "done." 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 2>&1 # 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 tmpcrtbeg=$(mktemp -p ${TEMPDIR}/certs -t make-ca.XXXXXXXX.tmp) awk "NR==$certbegin,/^CKA_TRUST_STEP_UP_APPROVED/" "${WORKDIR}/certdata.txt" \ > $tmpcrtbeg done unset CERTBEGINLIST certbegin for tempfile in ${TEMPDIR}/certs/*.tmp; do # Convert to a PEM formated certificate tempcrt=${tempfile%.tmp}.pem printf $(awk '/^CKA_VALUE/{flag=1;next}/^END/{flag=0}flag{printf $0}' \ "${tempfile}") | "${OPENSSL}" x509 -in /dev/stdin -text -inform DER -fingerprint \ > "${tempcrt}" # Get individual values for certificates certkey="$(${OPENSSL} x509 -in ${tempcrt} -noout -pubkey)" certcer="$(${OPENSSL} x509 -in ${tempcrt})" certtxt="$(${OPENSSL} x509 -in ${tempcrt} -noout -text)" keyhash="$(${OPENSSL} x509 -noout -in ${tempcrt} -hash)" # Get trust values for the certifcate get_trust_values "${tempfile}" # Get p11-kit label, oid, and values get_p11_label "${tempfile}" # Get p11 trust and OID values get_p11_trust # Print information about cert echo "Certificate: ${p11label}" echo "Keyhash: ${keyhash}" # Place certificate into trust anchors dir anchorfile="${TEMPDIR}/pki/anchors/${keyhash}.p11-kit" moz_trust="true" write_anchor # Import all certificates with trust args to the temporary NSS DB if test "${WITH_NSS}" == "1"; then write_nss_db ${TEMPDIR}/pki/nssdb ${tempcrt} fi # Import all certificates with trust args to the java cacerts.p12 file if test "${WITH_P12}" == "1"; then write_java_p12 "${TEMPDIR}/ssl/java/cacerts.p12" ${tempcrt} fi # Clean up the directory and environment as we go rm -f ${tempcrt} unset tempcrt unset keyhash subject count unset mozsadistrust mozsmdistrust anchorfile moz_trust unset trustlist rejectlist satrust smtrust cstrust catrust unset p11trust p11oid p11value trustp11 p11label echo -e "\n" done unset tempfile # Backup any anchors with PKIX extensions - any object-id that is not 2.5.29.37 # only do if anchordir already exists if test -d "${DESTDIR}${ANCHORDIR}"; then mkdir -p ${TEMPDIR}/override for file in $( grep -r "^object-id: 2\.5\.29\.[0-9]" "${DESTDIR}${ANCHORDIR}" | \ grep -v "2\.5\.29\.37" | cut -d ":" -f 1); do cp "${file}" "${TEMPDIR}/override/" done fi # Install anchors in $ANCHORDIR if test -d "${DESTDIR}${ANCHORDIR}"; then rm -rf "${DESTDIR}${ANCHORDIR}" fi install -dm755 "${DESTDIR}${ANCHORDIR}" install -m644 "${TEMPDIR}"/pki/anchors/*.p11-kit "${DESTDIR}${ANCHORDIR}" # Restore anchors with PKIX extensions if test -f "${TEMPDIR}"/override/*.p11-kit; then cp "${TEMPDIR}"override/*.p11-kit "${DESTDIR}${ANCHORDIR}" fi # 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}" > /dev/null 2>&1 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}/cacerts.p12" && rm -f "${DESTDIR}${KEYSTORE}/cacerts.p12" install -m644 "${TEMPDIR}/ssl/java/cacerts.p12" \ "${DESTDIR}${KEYSTORE}/cacerts.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 get_p11_label ${cert} keyhash=$("${OPENSSL}" x509 -noout -in "${cert}" -hash) subject=$("${OPENSSL}" x509 -noout -in "${cert}" -subject) if test "${p11label}" == ""; then # This will always be OpenSSL, values will be separated by spaces p11label=$( echo "${subject}" | grep -o "CN = .*" | sed 's@CN = @@' | cut -d "," -f 1) fi echo "Certificate: ${p11label}" 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" > /dev/null 2>&1 && echo "C") smtrust=$(echo "${trustlist}" | \ grep "E-mail Protection" > /dev/null 2>&1 && echo "C") cstrust=$(echo "${trustlist}" | \ grep "Code Signing" > /dev/null 2>&1 && echo "C") if test "${WITH_CS}" -eq "1"; then if test "${cstrust}" == ""; then cstrust=$(grep -q "^${keyhash}" "${SSLDIR}/CS.txt" && echo "C") fi fi catrust=$(echo "${trustlist}" | \ grep "Client Auth" > /dev/null 2>&1 && 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" > /dev/null 2>&1 && echo "p"); fi if test "${smtrust}" == ""; then smtrust=$(echo "${rejectlist}" | \ grep "E-mail Protection" > /dev/null 2>&1 && echo "p"); fi if test "${cstrust}" == ""; then cstrust=$(echo "${rejectlist}" | \ grep "Code Signing" > /dev/null 2>&1 && echo "p"); fi if test "${catrust}" == ""; then catrust=$(echo "${rejectlist}" | \ grep "Client Auth" > /dev/null 2>&1 && 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)" # Get p11 trust and OID values get_p11_trust # Place certificate into trust anchors dir anchorfile="${DESTDIR}${ANCHORDIR}/${keyhash}.p11-kit" moz_trust="false" mozsadistrust="UNKNOWN" mozsmdistrust="UNKNOWN" write_anchor # Generate working copy tempcert=$(mktemp -p ${TEMPDIR}/certs -t make-ca.XXXXXXXX.pem) "${OPENSSL}" x509 -in "${cert}" -text -fingerprint > ${tempcert} # Add to Shared NSS DB if test "${WITH_NSS}" == "1"; then write_nss_db "${DESTDIR}${NSSDB}" ${tempcert} fi # Import certificate (with trust args) into the java cacerts.p12 file if test "${WITH_P12}" == "1"; then write_java_p12 "${DESTDIR}${KEYSTORE}/cacerts.p12" ${tempcert} fi rm -f ${tempcert} unset tempcert unset keyhash subject count unset mozsadistrust mozsmdistrust anchorfile moz_trust unset trustlist rejectlist satrust smtrust cstrust catrust unset p11trust p11oid p11value trustp11 p11label echo -e "\n" done unset cert fi # Install certdata.txt if test "${REBUILD}" == "0"; then install -dm755 "${DESTDIR}${SSLDIR}" install -m644 "${WORKDIR}/certdata.txt" "${DESTDIR}${SSLDIR}/certdata.txt" fi # Clean up the mess popd > /dev/null 2>&1 rm -rf "${TEMPDIR}" # Build ANCHORLIST "${MD5SUM}" "${DESTDIR}${ANCHORDIR}"/* > "${DESTDIR}${ANCHORLIST}" # Build alternate formats using p11-kit trust install -dm755 "${DESTDIR}${CERTDIR}" "${DESTDIR}${BUNDLEDIR}" "${DESTDIR}${KEYSTORE}" echo "Extracting OpenSSL certificates to:" echo -n "${DESTDIR}${CERTDIR}..." "${TRUST}" extract --filter=ca-anchors --format=openssl-directory \ --overwrite --comment "${DESTDIR}${CERTDIR}" \ && echo "Done!" || echo "Failed!!!" echo "Extracting GNUTLS server auth certificates to:" echo -n "${DESTDIR}${CABUNDLE}..." "${TRUST}" extract --filter=ca-anchors --format=pem-bundle \ --purpose server-auth --overwrite --comment "${DESTDIR}${CABUNDLE}" \ && echo "Done!" || echo "Failed!!!" echo "Extracting GNUTLS S-Mime certificates to:" echo -n "${DESTDIR}${SMBUNDLE}..." "${TRUST}" extract --filter=ca-anchors --format=pem-bundle \ --purpose email --overwrite --comment "${DESTDIR}${SMBUNDLE}" \ && echo "Done!" || echo "Failed!!!" echo "Extracting GNUTLS code signing certificates to:" echo -n "${DESTDIR}${CSBUNDLE}..." "${TRUST}" extract --filter=ca-anchors --format=pem-bundle \ --purpose code-signing --overwrite --comment \ "${DESTDIR}${CSBUNDLE}" && echo "Done!" || echo "Failed!!!" echo "Extracting Java cacerts (JKS) to:" echo -n "${DESTDIR}${KEYSTORE}/cacerts..." "${TRUST}" extract --filter=ca-anchors --format=java-cacerts \ --purpose server-auth --overwrite \ --comment "${DESTDIR}${KEYSTORE}/cacerts" \ && echo "Done!" || echo "Failed!!!" # End /usr/sbin/make-ca