make-ca/make-ca
DJ Lucas ca103899f6 Move bundle defaults to /etc/pki/tls/certs/
Fix invalid test cases on command line processing
Remove -c/--cadir flags, replace with -b/--bindledir to store all bundles in same location
2018-12-01 16:03:19 -06:00

887 lines
29 KiB
Bash

#!/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="1.0"
# 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"
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.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}"
CERTDIR="${SSLDIR}/certs"
LOCALDIR="${SSLDIR}/local"
echo "${@}" | grep -e "-d " -e "--cadir" 2>&1> /dev/null
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" 2>&1> /dev/null
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
CADIR="${2}"
echo "$@" | grep -e "-S" -e "--ssldir" 2>&1 > /dev/null
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}"
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 -d / --cadir switch"
echo ""
echo " -a, --anchordir [\$PKIDIR/anchors]"
echo " The output directory for OpenSSL trusted"
echo " CA certificates used as trust anchors"
echo ""
echo " -b, --bundledir [\$PKIDIR/certs]"
echo " The output direcotry for the PEM formated 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 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 sources and provide system local"
echo " certifiates"
echo ""
echo " -m, --java-p12"
echo " Export Java PKCS#12 store - 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 " -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 "<i>" "${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 "<i>" "${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}/cacerts.p12" &&
rm -f "${DESTDIR}${KEYSTORE}/cacerts.p12"
install -dm644 "${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
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 "${BUNDLEDIR}" "${KEYSTORE}"
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}/cacerts..."
"${TRUST}" extract --filter=ca-anchors --format=java-cacerts \
--purpose server-auth --overwrite \
--comment "${KEYSTORE}/cacerts" \
&& echo "Done!" || echo "Failed!!!"
fi
# End /usr/sbin/make-ca