Changeset View
Standalone View
security/ca_root_nss/files/ca-merge.sh.in
- This file was added.
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:executable | null | * \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
#!/bin/sh | |||||
# Utility to merge internal CAs into system trust stores | |||||
# Created By: Mark Felder <feld@FreeBSD.org> | |||||
CAPATH=%%PREFIX%%/etc/ssl/ca-trust/source | |||||
TMPDIR=$(mktemp -d -t ca-merge) | |||||
if [ $(id -u) -ne 0 ]; then | |||||
echo "Error: $0 requires root access to run." | |||||
matthew: Use the ':' trick to allow reading CAPATH from the environment?
```… | |||||
exit 1 | |||||
Done Inline ActionsNo test for whether mktemp(1) succeeded? You're overloading the meaning of TMPDIR here. That's probably fine though. trap _clean EXIT INT KILL so the temporary directory gets cleaned up if the process is killed. matthew: No test for whether mktemp(1) succeeded?
You're overloading the meaning of TMPDIR here. | |||||
fi | |||||
_usage() | |||||
{ | |||||
cat <<HELP | |||||
usage: ${0} | |||||
Done Inline ActionsOutput diagnostic to stderr? >&2 romain: Output diagnostic to stderr? `>&2` | |||||
Options: | |||||
-d Debugging enabled | |||||
-h Help | |||||
-p Specify a custom CA file search path (ignores default) | |||||
This utility automatically merges CA files of PEM or DER format found in | |||||
the %%PREFIX%%/etc/ssl/ca-trust/source/ search path. | |||||
${0}: 2018, feld@FreeBSD.org | |||||
HELP | |||||
} | |||||
_merge() | |||||
{ | |||||
# OpenSSL runs first as Mono and Java | |||||
# utilize the resulting PEM. | |||||
_merge_openssl | |||||
_merge_mono | |||||
_merge_jks | |||||
_clean | |||||
exit $? | |||||
} | |||||
Done Inline ActionsIt looks like you properly exit each time it's appropriate, and _clean never return any value, so $? should always be 0. I't rather exit 0 at the end of the script instead of this end of this function if needed. romain: It looks like you properly `exit` each time it's appropriate, and `_clean` never `return` any… | |||||
Done Inline ActionsIf you add the trap as suggested above, no need to call _clean explicitly matthew: If you add the trap as suggested above, no need to call _clean explicitly | |||||
_merge_openssl() | |||||
{ | |||||
cp %%PREFIX%%/%%CERTDIR%%/ca-root-nss.crt ${TMPDIR} | |||||
michaeloUnsubmitted Done Inline ActionsI dislike that the temp file is still ca-root-nss especially because your commit message says that never modify this file michaelo: I dislike that the temp file is still ca-root-nss especially because your commit message says… | |||||
feldAuthorUnsubmitted Done Inline ActionsI can agree that it would be less confusing if we operate on a "cert.pem" in ${TMPDIR} instead. feld: I can agree that it would be less confusing if we operate on a "cert.pem" in ${TMPDIR} instead. | |||||
# Merge in a temporary directory if we have work to do | |||||
if [ -d "${CAPATH}" ]; then | |||||
for i in "${CAPATH}"/*; do | |||||
openssl verify ${i} 2>&1 >/dev/null | |||||
if [ $? -eq 0 ]; then | |||||
echo "Appending ${i} to trusted roots" | |||||
echo "### Internal CA from ${i} below here ###" >> ${TMPDIR}/ca-root-nss.crt | |||||
openssl x509 -in ${i} -text >> ${TMPDIR}/ca-root-nss.crt | |||||
else | |||||
echo "${i} is invalid. Skipping." | |||||
michaeloUnsubmitted Done Inline ActionsThis should go to stderr. michaelo: This should go to stderr. | |||||
fi | |||||
Not Done Inline Actions"CA" > "CA(s)" since there couple be multiple ones on one file. michaelo: "CA" > "CA(s)" since there couple be multiple ones on one file. | |||||
done | |||||
Not Done Inline ActionsThis one does not work if the input file contains more than one cert. Intermediate CAs require the Root CA to be present in the same file before otherwise 'verify' will fail upfront. The line shall read "openssl crl2pkcs7 -nocrl -certfile ${i} | openssl pkcs7 -print_certs -text >> ${TMPDIR}/cert.pem". michaelo: This one **does not** work if the input file contains more than one cert. Intermediate CAs… | |||||
fi | |||||
# Merging complete. Now validate final root before installing. | |||||
# Note, this does not validate each cert within is valid. We have | |||||
# to trust that our earlier validation caught those issues. | |||||
# This merely validates that the format of the final concatenated | |||||
# ca-root-nss.crt is valid. | |||||
[ ${DEBUG} ] && echo "Verifying final root CA file" | |||||
openssl verify ${TMPDIR}/ca-root-nss.crt 2>&1 >/dev/null | |||||
if [ $? -eq 0 ]; then | |||||
# OK, passed the smell test. | |||||
install -o root -g wheel -m 644 ${TMPDIR}/ca-root-nss.crt %%PREFIX%%/etc/ssl/cert.pem | |||||
else | |||||
# Something went wrong. We have no choice but to install the default roots and report | |||||
Done Inline ActionsComment does not match code: you're not actually calculating a checksum here, but directly comparing the files. matthew: Comment does not match code: you're not actually calculating a checksum here, but directly… | |||||
# and error happened. | |||||
feldAuthorUnsubmitted Done Inline Actionsand -> an feld: and -> an | |||||
install -o root -g wheel -m 644 %%PREFIX%%/%%CERTDIR%%/ca-root-nss.crt %%PREFIX%%/etc/ssl/cert.pem | |||||
export FAILED=1 | |||||
fi | |||||
} | |||||
_merge_mono() | |||||
{ | |||||
Done Inline ActionsSo, if I already have a /etc/ssl/cert.pem with my locally added custom certs this overwrites them with the generic ca-root-nss.crt which will not make me a happy bunny. Wouldn't the safer strategy here be to just exit leaving the existing trusted cert store alone but loudly flagging up problems. matthew: So, if I already have a `/etc/ssl/cert.pem` with my locally added custom certs this overwrites… | |||||
Not Done Inline ActionsHow do you intend to detect that? michaelo: How do you intend to detect that? | |||||
if [ -x %%LOCALBASE%%/bin/cert-sync ]; then | |||||
%%LOCALBASE%%/bin/cert-sync --quiet /etc/ssl/cert.pem | |||||
fi | |||||
} | |||||
_merge_jks() | |||||
{ | |||||
# Do nothing yet | |||||
} | |||||
_clean() | |||||
{ | |||||
# Cleanup | |||||
if [ -d "${TMPDIR}" ] && [ ! ${DEBUG} ]; then | |||||
rm -rf "${TMPDIR}" | |||||
fi | |||||
if [ ${DEBUG} ]; then | |||||
echo "Temporary files can be found in ${TMPDIR}" | |||||
Done Inline ActionsDEBUG (and FAILED) are not initialized on startup, so some variable may already exist in the users' environment, causing inconsistencies here. Initializing them to 0 (FAILED=0) at the beginning of the script and comparing values to integer ([ $DEBUG -eq 1 ]) may help avoid this. romain: DEBUG (and FAILED) are not initialized on startup, so some variable may already exist in the… | |||||
fi | |||||
if [ ${FAILED} ]; then | |||||
Done Inline Actionscsplit(1) ? matthew: csplit(1) ?
| |||||
echo "WARNING: an error occurred merging the CAs. The default trusted CAs have been installed." | |||||
exit 1 | |||||
fi | |||||
} | |||||
while getopts "dhp:" opt; do | |||||
case ${opt} in | |||||
d) DEBUG=1 | |||||
;; | |||||
h) _usage | |||||
exit 0 | |||||
;; | |||||
p) CAPATH=${OPTARG} | |||||
_merge | |||||
feldAuthorUnsubmitted Done Inline ActionsThis should be removed or _merge will run twice. Leftover from previous variations of the script. feld: This should be removed or _merge will run twice. Leftover from previous variations of the… | |||||
;; | |||||
esac | |||||
done | |||||
shift $(($OPTIND - 1)) | |||||
_merge |
Use the ':' trick to allow reading CAPATH from the environment?