commit 01b55604fcb4ca0de227ecaec69912ae8d97d898 Author: DJ Lucas Date: Wed Sep 13 18:51:26 2017 -0500 Initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3a21de9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,300 @@ +Creative Commons License + +Creative Commons Legal Code + +Attribution-NonCommercial-ShareAlike 2.0 + +CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT +PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN +ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN +"AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION +PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. + +License + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE +BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS +CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +CONDITIONS. + + +Definitions + + "Collective Work" means a work, such as a periodical issue, anthology or + encyclopedia, in which the Work in its entirety in unmodified form, along + with a number of other contributions, constituting separate and independent + works in themselves, are assembled into a collective whole. A work that + constitutes a Collective Work will not be considered a Derivative Work (as + defined below) for the purposes of this License. + + "Derivative Work" means a work based upon the Work or upon + the Work and other pre-existing works, such as a translation, musical + arrangement, dramatization, fictionalization, motion picture version, sound + recording, art reproduction, abridgment, condensation, or any other form in + which the Work may be recast, transformed, or adapted, except that a work + that constitutes a Collective Work will not be considered a Derivative Work + for the purpose of this License. For the avoidance of doubt, where the Work + is a musical composition or sound recording, the synchronization of the Work + in timed-relation with a moving image ("synching") will be considered a + Derivative Work for the purpose of this License. + + "Licensor" means the individual or entity that offers the + Work under the terms of this License. + + "Original Author" means the individual or entity who created + the Work. + + "Work" means the copyrightable work of authorship offered + under the terms of this License. + + "You" means an individual or entity exercising rights under + this License who has not previously violated the terms of this License with + respect to the Work, or who has received express permission from the + Licensor to exercise rights under this License despite a previous + violation. + + "License Elements" means the following high-level license + attributes as selected by Licensor and indicated in the title of this + License: Attribution, Noncommercial, ShareAlike. + + +Fair Use Rights. Nothing in this license is intended to reduce, +limit, or restrict any rights arising from fair use, first sale or other +limitations on the exclusive rights of the copyright owner under copyright law +or other applicable laws. + + +License Grant. Subject to the terms and conditions of this +License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +perpetual (for the duration of the applicable copyright) license to exercise +the rights in the Work as stated below: + + to reproduce the Work, to incorporate the Work into one or + more Collective Works, and to reproduce the Work as incorporated in the + Collective Works; + + to create and reproduce Derivative Works; + + to distribute copies or phonorecords of, display publicly, + perform publicly, and perform publicly by means of a digital audio + transmission the Work including as incorporated in Collective + Works; + + to distribute copies or phonorecords of, display publicly, + perform publicly, and perform publicly by means of a digital audio + transmission Derivative Works; + + +The above rights may be exercised in all media and formats whether now +known or hereafter devised. The above rights include the right to make such +modifications as are technically necessary to exercise the rights in other +media and formats. All rights not expressly granted by Licensor are hereby +reserved, including but not limited to the rights set forth in Sections 4(e) +and 4(f). + + +Restrictions.The license granted in Section 3 above is +expressly made subject to and limited by the following +restrictions: + + You may distribute, publicly display, publicly perform, or publicly + digitally perform the Work only under the terms of this License, and + You must include a copy of, or the Uniform Resource Identifier for, this + License with every copy or phonorecord of the Work You distribute, publicly + display, publicly perform, or publicly digitally perform. You may not offer + or impose any terms on the Work that alter or restrict the terms of this + License or the recipients' exercise of the rights granted hereunder. You + may not sublicense the Work. You must keep intact all notices that refer to + this License and to the disclaimer of warranties. You may not distribute, + publicly display, publicly perform, or publicly digitally perform the Work + with any technological measures that control access or use of the Work in + a manner inconsistent with the terms of this License Agreement. The above + applies to the Work as incorporated in a Collective Work, but this does not + require the Collective Work apart from the Work itself to be made subject + to the terms of this License. If You create a Collective Work, upon notice + from any Licensor You must, to the extent practicable, remove from the + Collective Work any reference to such Licensor or the Original Author, as + requested. If You create a Derivative Work, upon notice from any Licensor + You must, to the extent practicable, remove from the Derivative Work any + reference to such Licensor or the Original Author, as requested. + + You may distribute, publicly display, publicly perform, or + publicly digitally perform a Derivative Work only under the terms of this + License, a later version of this License with the same License Elements as + this License, or a Creative Commons iCommons license that contains the same + License Elements as this License (e.g. Attribution-NonCommercial-ShareAlike + 2.0 Japan). You must include a copy of, or the Uniform Resource Identifier + for, this License or other license specified in the previous sentence with + every copy or phonorecord of each Derivative Work You distribute, publicly + display, publicly perform, or publicly digitally perform. You may not offer + or impose any terms on the Derivative Works that alter or restrict the + terms of this License or the recipients' exercise of the rights granted + hereunder, and You must keep intact all notices that refer to this License + and to the disclaimer of warranties. You may not distribute, publicly + display, publicly perform, or publicly digitally perform the Derivative + Work with any technological measures that control access or use of the Work + in a manner inconsistent with the terms of this License Agreement. The + above applies to the Derivative Work as incorporated in a Collective Work, + but this does not require the Collective Work apart from the Derivative + Work itself to be made subject to the terms of this License. + + You may not exercise any of the rights granted to You in + Section 3 above in any manner that is primarily intended for or directed + toward commercial advantage or private monetary compensation. The exchange + of the Work for other copyrighted works by means of digital file-sharing or + otherwise shall not be considered to be intended for or directed toward + commercial advantage or private monetary compensation, provided there is no + payment of any monetary compensation in connection with the exchange of + copyrighted works. + + If you distribute, publicly display, publicly perform, or + publicly digitally perform the Work or any Derivative Works or Collective + Works, You must keep intact all copyright notices for the Work and give the + Original Author credit reasonable to the medium or means You are utilizing + by conveying the name (or pseudonym if applicable) of the Original Author + if supplied; the title of the Work if supplied; to the extent reasonably + practicable, the Uniform Resource Identifier, if any, that Licensor + specifies to be associated with the Work, unless such URI does not refer + to the copyright notice or licensing information for the Work; and in the + case of a Derivative Work, a credit identifying the use of the Work in the + Derivative Work (e.g., "French translation of the Work by Original Author," + or "Screenplay based on original Work by Original Author"). Such credit may + be implemented in any reasonable manner; provided, however, that in the + case of a Derivative Work or Collective Work, at a minimum such credit will + appear where any other comparable authorship credit appears and in a manner + at least as prominent as such other comparable authorship credit. + + For the avoidance of doubt, where the Work is a musical composition: + Performance Royalties Under Blanket Licenses. Licensor + reserves the exclusive right to collect, whether individually or via a + performance rights society (e.g. ASCAP, BMI, SESAC), royalties for the + public performance or public digital performance (e.g. webcast) of the + Work if that performance is primarily intended for or directed toward + commercial advantage or private monetary compensation. + + Mechanical Rights and Statutory Royalties. Licensor + reserves the exclusive right to collect, whether individually or via a + music rights agency or designated agent (e.g. Harry Fox Agency), + royalties for any phonorecord You create from the Work ("cover + version") and distribute, subject to the compulsory license created + by 17 USC Section 115 of the US Copyright Act (or the equivalent in + other jurisdictions), if Your distribution of such cover version is + primarily intended for or directed toward commercial advantage or + private monetary compensation. + + Webcasting Rights and Statutory Royalties. + For the avoidance of doubt, where the Work is a sound recording, Licensor + reserves the exclusive right to collect, whether individually or via a + performance-rights society (e.g. SoundExchange), royalties for the public + digital performance (e.g. webcast) of the Work, subject to the compulsory + license created by 17 USC Section 114 of the US Copyright Act (or the + equivalent in other jurisdictions), if Your public digital performance is + primarily intended for or directed toward commercial advantage or private + monetary compensation. + + + Webcasting Rights and Statutory Royalties. For the + avoidance of doubt, where the Work is a sound recording, Licensor reserves + the exclusive right to collect, whether individually or via a + performance-rights society (e.g. SoundExchange), royalties for the public + digital performance (e.g. webcast) of the Work, subject to the compulsory + license created by 17 USC Section 114 of the US Copyright Act (or the + equivalent in other jurisdictions), if Your public digital performance is + primarily intended for or directed toward commercial advantage or private + monetary compensation. + + +Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND +CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, +WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A +PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, +ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. +SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH +EXCLUSION MAY NOT APPLY TO YOU. + + + +Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY +APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY +FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES +ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + +Termination + + This License and the rights granted hereunder will terminate + automatically upon any breach by You of the terms of this License. + Individuals or entities who have received Derivative Works or Collective + Works from You under this License, however, will not have their licenses + terminated provided such individuals or entities remain in full compliance + with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any + termination of this License. + + Subject to the above terms and conditions, the license + granted here is perpetual (for the duration of the applicable copyright in + the Work). Notwithstanding the above, Licensor reserves the right to + release the Work under different license terms or to stop distributing the + Work at any time; provided, however that any such election will not serve + to withdraw this License (or any other license that has been, or is + required to be, granted under the terms of this License), and this License + will continue in full force and effect unless terminated as stated above. + + +Miscellaneous + + Each time You distribute or publicly digitally perform the + Work or a Collective Work, the Licensor offers to the recipient a license + to the Work on the same terms and conditions as the license granted to You + under this License. + + Each time You distribute or publicly digitally perform a + Derivative Work, Licensor offers to the recipient a license to the original + Work on the same terms and conditions as the license granted to You under + this License. + + If any provision of this License is invalid or unenforceable + under applicable law, it shall not affect the validity or enforceability of + the remainder of the terms of this License, and without further action by + the parties to this agreement, such provision shall be reformed to the + minimum extent necessary to make such provision valid and enforceable. + + No term or provision of this License shall be deemed waived + and no breach consented to unless such waiver or consent shall be in + writing and signed by the party to be charged with such waiver or consent. + + This License constitutes the entire agreement between the + parties with respect to the Work licensed here. There are no + understandings, agreements or representations with respect to the Work not + specified here. Licensor shall not be bound by any additional provisions + that may appear in any communication from You. This License may not be + modified without the mutual written agreement of the Licensor and You. + + +Creative Commons is not a party to this License, and makes no warranty +whatsoever in connection with the Work. Creative Commons will not be liable to +You or any party on any legal theory for any damages whatsoever, including +without limitation any general, special, incidental or consequential damages +arising in connection to this license. Notwithstanding the foregoing two (2) +sentences, if Creative Commons has expressly identified itself as the Licensor +hereunder, it shall have all rights and obligations of Licensor. + +Except for the limited purpose of indicating to the public that the Work is +licensed under the CCPL, neither party will use the trademark "Creative +Commons" or any related trademark or logo of Creative Commons without the prior +written consent of Creative Commons. Any permitted use will be in compliance +with Creative Commons' then-current trademark usage guidelines, as may be +published on its website or otherwise made available upon request from time to +time. + +Creative Commons may be contacted at http://creativecommons.org/. + + diff --git a/README b/README new file mode 100644 index 0000000..d5eab9b --- /dev/null +++ b/README @@ -0,0 +1,6 @@ +make-ca.sh is a script to deliver a complete PKI setup for linux workstaitons +using only bash, coreutils, and openssl, and optionally for OpenJDK, NSS, and +p11-kit if already installed, from the upstream Mozilla cacerts.txt. It was +developed for use with Linux From Scratch to minimize dependencies for early +system build, but has been written to be generic enough for any Linux +distribution. diff --git a/make-ca.sh b/make-ca.sh new file mode 100644 index 0000000..3751fb4 --- /dev/null +++ b/make-ca.sh @@ -0,0 +1,546 @@ +#!/bin/sh +# Begin /usr/sbin/make-ca.sh +# +# Script to create OpenSSL certs directory, GnuTLS certificate bundle, NSS +# shared DB, and Java cacerts from upstream certdata.txt and local sources +# +# The file certdata.txt must exist in the local directory +# Version number is obtained from the version of the data +# +# Authors: DJ Lucas +# Bruce Dubbs +# +# Version 20161124 + +# Set defaults +CERTDATA="certdata.txt" +PKIDIR="/etc/pki" +SSLDIR="/etc/ssl" +CERTUTIL="/usr/bin/certutil" +KEYTOOL="/opt/jdk/bin/keytool" +OPENSSL="/usr/bin/openssl" +ANCHORDIR="${PKIDIR}/anchors" +CABUNDLE="${SSLDIR}/ca-bundle.crt" +CERTDIR="${SSLDIR}/certs" +KEYSTORE="${SSLDIR}/java/cacerts" +NSSDB="${PKIDIR}/nssdb" +LOCALDIR="${SSLDIR}/local" + +# Some data in the certs have UTF-8 characters +export LANG=en_US.utf8 + +TEMPDIR=$(mktemp -d) +WORKDIR="${TEMPDIR}/work" +WITH_NSS=1 +WITH_JAVA=1 +FORCE=0 + +function get_args(){ + while test -n "${1}" ; do + case "${1}" in + -C | --certdata) + check_arg $1 $2 + CERTDATA="${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 + ;; + -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 + ;; + -k | --keytool) + check_arg $1 $2 + KEYTOOL="${2}" + shift 2 + ;; + -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 + ;; + *) + 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}` converts certdata.txt (provided by the Mozilla Foundation)" + echo "into a complete PKI distribution for use with LFS or like distributions." + echo "" + echo " -C --certdata The certdata.txt file (provided by Mozilla)" + echo " Default: ./certdata.txt" + echo "" + echo " -P --pkidir The output PKI directory - Cannot be used with" + echo " the -a/--anchordir or -n/--nssdb switches" + echo " Default: /etc/pki" + echo "" + echo " -S --ssldir The output SSL root direcotry - Cannot be used" + echo " with the -c/--cafile, -d/--cadir, or" + echo " -j/--javacerts switches" + echo " Defualt: /etc/ssl" + echo "" + echo " -a --anchordir The output directory for OpenSSL trusted" + echo " CA certificates used as trust anchors." + echo " Default: \$PKIDIR/anchors" + echo "" + echo " -c --cafile The output filename for the PEM formated bundle" + echo " Default: \$SSLDIR/ca-bundle.crt" + echo "" + echo " -d --cadir The output directory for the OpenSSL trusted" + echo " CA certificates" + echo " Deault: \$SSLDIR/certs/" + echo "" + echo " -j --javacerts The output path for the Java cacerts file" + echo " Default: \$SSLDIR/java/cacerts" + echo "" + echo " -l --localdir The path to a local set of OpenSSL trusted" + echo " certificates to include in the output" + echo " Default: \$SSLDIR/local" + echo "" + echo " -n --nssdb The output path for the shared NSS DB" + echo " Default: \$PKDIR/nssdb" + echo "" + echo " -k --keytool The path to the java keytool utility" + echo "" + echo " -s --openssl The path to the openssl utility" + echo "" + echo " -t --certutil The path the certutil utility" + echo "" + echo " -f --force Force run, even if source is not newer" + echo "" + echo " -h --help Show this help message 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" + ;; + esac + ;; + p) + case $2 in + sa) + echo "-addreject serverAuth" + ;; + sm) + echo "-addreject emailProtection" + ;; + cs) + echo "-addreject codeSigning" + ;; + esac + ;; + *) + echo "" + ;; + esac +} + +# Process command line arguments +get_args $@ + +if test ! -r "${CERTDATA}"; then + echo "${CERTDATA} was not found. The certdata.txt file must be in the local" + echo "directory, or speficied with the --certdata switch." + exit 1 +fi + +test -f "${CERTUTIL}" || WITH_NSS=0 +test -f "${KEYTOOL}" || WITH_JAVA=0 + +VERSION=$(grep CVS_ID "${CERTDATA}" | cut -d " " -f 8) + +if test "${VERSION}x" == "x"; then + echo "WARNING! ${CERTDATA} has no 'Revision' in CVS_ID" + echo "Will run conversion unconditionally." + sleep 2 + VERSION="$(date -u +%Y%m%d-%H%M)" +else + if test "${FORCE}" == "1"; then + echo "Output forced. Will run conversion unconditionally." + sleep 2 + else + test -f "${CABUNDLE}" && + OLDVERSION=$(grep "^VERSION:" "${CABUNDLE}" | cut -d ":" -f 2) + fi +fi + +if test "${OLDVERSION}x" == "${VERSION}x"; then + echo "No update required!" + exit 0 +fi + +mkdir -p "${TEMPDIR}"/{certs,ssl/{certs,java},pki/nssdb,work} +cp "${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`)" + + # Get args for OpenSSL trust settings + saarg="$(convert_trust_arg "${satrust}" sa)" + smarg="$(convert_trust_arg "${smtrust}" sm)" + csarg="$(convert_trust_arg "${cstrust}" cs)" + + # 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 a hash for the cert + keyhash=$("${OPENSSL}" x509 -noout -in tempfile.crt -hash) + + # Print information about cert + echo "Certificate: ${certname}" + echo "Keyhash: ${keyhash}" + + # Import certificates trusted for SSL/TLS into the Java keystore and + # GnuTLS certificate bundle + if test "${satrust}x" == "Cx"; then + # Java keystore + if test "${WITH_JAVA}" == "1"; then + "${KEYTOOL}" -import -noprompt -alias "${certname}" \ + -keystore "${TEMPDIR}/ssl/java/cacerts" \ + -storepass 'changeit' -file tempfile.crt \ + 2>&1> /dev/null | \ + sed -e 's@Certificate was a@A@' -e 's@keystore@Java keystore.@' + fi + + # GnuTLS certificate bundle + cat tempfile.crt >> "${TEMPDIR}/ssl/ca-bundle.crt.tmp" + echo "Added to GnuTLS ceritificate bundle." + fi + + # 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 + + # Clean up the directory and environment as we go + rm -f tempfile.crt + unset certname satrust smtrust cstrust + echo -e "\n" +done +unset tempfile + +# Sanity check +count=$(ls "${TEMPDIR}"/ssl/certs/*.pem | wc -l) +# Historically there have been between 152 and 165 certs +# A minimum of 140 should be safe for a rudimentry sanity check +if test "${count}" -lt "140" ; 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 + +# Generate the bundle +bundlefile=`basename "${CABUNDLE}"` +bundledir=`echo "${CABUNDLE}" | sed "s@/${bundlefile}@@"` +install -vdm755 "${bundledir}" +test -f "${CABUNDLE}" && mv "${CABUNDLE}" "${CABUNDLE}.old" +echo "VERSION:${VERSION}" > "${CABUNDLE}" +cat "${TEMPDIR}/ssl/ca-bundle.crt.tmp" >> "${CABUNDLE}" && +rm -f "${CABUNDLE}.old" +unset bundlefile bundledir + +# Install Java Cacerts +if test "${WITH_JAVA}" == "1"; then + javafile=`basename "${KEYSTORE}"` + javadir=`echo "${KEYSTORE}" | sed "s@/${javafile}@@"` + install -vdm755 "${javadir}" + test -f "${KEYSTORE}" && mv "${KEYSTORE}" "${KEYSTORE}.old" + install -m644 "${TEMPDIR}/ssl/java/cacerts" "${KEYSTORE}" && + rm -f "${KEYSTORE}.old" + unset javafile javadir +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 "${NSSDB}" && mv "${NSSDB}" "${NSSDB}.old" + install -dm755 "${NSSDB}" + install -m644 "${TEMPDIR}"/pki/nssdb/{cert9.db,key4.db,pkcs11.txt} \ + "${NSSDB}" && + rm -rf "${NSSDB}.old" +fi + +# Install certificates in $CERTDIR +test -d "${CERTDIR}" && mv "${CERTDIR}" "${CERTDIR}.old" +install -dm755 "${CERTDIR}" +install -m644 "${TEMPDIR}"/ssl/certs/*.pem "${CERTDIR}" && +rm -rf "${CERTDIR}.old" + +# Import any certs in $LOCALDIR +# Don't do any checking, just trust the admin +if test -d "${LOCALDIR}"; then + 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="" + 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") + + # 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 + + # Install in Java keystore + if test "${WITH_JAVA}" == "1" -a "${satrust}x" == "Cx"; then + "${KEYTOOL}" -import -noprompt -alias "${certname}" \ + -keystore "${KEYSTORE}" \ + -storepass 'changeit' -file "${cert}" 2>&1> /dev/null | \ + sed -e 's@Certificate was a@A@' -e 's@keystore@Java keystore.@' + fi + + # Append to the bundle - source should have trust info, process with + # openssl x509 to strip + if test "${satrust}x" == "Cx"; then + "${OPENSSL}" x509 -in "${cert}" -text -fingerprint \ + >> "${CABUNDLE}" + echo "Added to GnuTLS certificate bundle." + fi + + # Install into OpenSSL certificate store + "${OPENSSL}" x509 -in "${cert}" -text -fingerprint \ + -setalias "${certname}" \ + >> "${CERTDIR}/${keyhash}.pem" + echo "Added to OpenSSL certificate directory." + + # Add to Shared NSS DB + if test "${WITH_NSS}" == "1"; then + "${OPENSSL}" x509 -in "${cert}" -text -fingerprint | \ + "${CERTUTIL}" -d "sql:${NSSDB}" -A \ + -t "${satrust},${smtrust},${cstrust}" \ + -n "${certname}" + echo "Added to NSS shared DB with trust '${satrust},${smtrust},${cstrust}'." + fi + + unset keyhash subject count certname + unset trustlist rejectlist satrust smtrust cstrust + echo "" + + done + unset cert +fi + +# We cannot use $CERTDIR directly as the trust anchor because of +# c_rehash usage for OpenSSL (every entry is duplicated) +# Populate a duplicate anchor directory +test -d "${ANCHORDIR}" && mv "${ANCHORDIR}" "${ANCHORDIR}.old" +cp -R "${CERTDIR}" "${ANCHORDIR}" +rm -rf "${ANCHORDIR}.old" + +/usr/bin/c_rehash "${CERTDIR}" 2>&1>/dev/null +popd > /dev/null + +# Clean up the mess +rm -rf "${TEMPDIR}" + +# End /usr/sbin/make-ca.sh