summaryrefslogtreecommitdiff
path: root/usr.sbin/certctl
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2019-10-02 01:05:53 +0000
committerKyle Evans <kevans@FreeBSD.org>2019-10-02 01:05:53 +0000
commitccdcb388ba6deff15ab24b8775cbd2efd29b7790 (patch)
tree6aceb5dc1c062f0c927ae51cc73bf02b78e33c9e /usr.sbin/certctl
parentf27f39db77d253836070f5d83a5759c3da44a0c1 (diff)
downloadsrc-test-ccdcb388ba6deff15ab24b8775cbd2efd29b7790.tar.gz
src-test-ccdcb388ba6deff15ab24b8775cbd2efd29b7790.zip
[2/3] Add certctl(8)
This is a simple utility to hash all trusted on the system into /etc/ssl/certs. It also allows the user to blacklist certificates they do not trust. This work was done primarily by allanjude@, with minor contributions by myself. No objection from: secteam Differential Revision: https://reviews.freebsd.org/D16857
Notes
Notes: svn path=/head/; revision=352949
Diffstat (limited to 'usr.sbin/certctl')
-rw-r--r--usr.sbin/certctl/Makefile6
-rw-r--r--usr.sbin/certctl/certctl.8119
-rwxr-xr-xusr.sbin/certctl/certctl.sh230
3 files changed, 355 insertions, 0 deletions
diff --git a/usr.sbin/certctl/Makefile b/usr.sbin/certctl/Makefile
new file mode 100644
index 0000000000000..ea10cdf77e6cf
--- /dev/null
+++ b/usr.sbin/certctl/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+SCRIPTS=certctl.sh
+MAN= certctl.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/certctl/certctl.8 b/usr.sbin/certctl/certctl.8
new file mode 100644
index 0000000000000..0a3e5ed3eb9aa
--- /dev/null
+++ b/usr.sbin/certctl/certctl.8
@@ -0,0 +1,119 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+.\"
+.\" Copyright 2018 Allan Jude <allanjude@freebsd.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted providing that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 19, 2019
+.Dt CERTCTL 8
+.Os
+.Sh NAME
+.Nm certctl
+.Nd "tool for managing trusted and blacklist TLS certificates"
+.Sh SYNOPSIS
+.Nm
+.Op Fl v
+.Ic list
+.Nm
+.Op Fl v
+.Ic blacklisted
+.Nm
+.Op Fl nv
+.Ic rehash
+.Nm
+.Op Fl nv
+.Ic blacklist Ar file
+.Nm
+.Op Fl nv
+.Ic unblacklist Ar file
+.Sh DESCRIPTION
+The
+.Nm
+utility manages the list of TLS Certificate Authorities that are trusted by
+applications that use OpenSSL.
+.Pp
+Flags:
+.Bl -tag -width 4n
+.It Fl n
+No-Op mode, do not actually perform any actions.
+.It Fl v
+be verbose, print details about actions before performing them.
+.El
+.Pp
+Primary command functions:
+.Bl -tag -width blacklisted
+.It Ic list
+List all currently trusted certificate authorities.
+.It Ic blacklisted
+List all currently blacklisted certificates.
+.It Ic rehash
+Rebuild the list of trusted certificate authorities by scanning all directories
+in
+.Ev TRUSTPATH
+and all blacklisted certificates in
+.Ev BLACKLISTPATH .
+A symbolic link to each trusted certificate is placed in
+.Ev CERTDESTDIR
+and each blacklisted certificate in
+.Ev BLACKLISTDESTDIR .
+.It Ic blacklist
+Add the specified file to the blacklist.
+.It Ic unblacklist
+Remove the specified file from the blacklist.
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width BLACKLISTDESTDIR
+.It Ev DESTDIR
+Alternate destination directory to operate on.
+.It Ev TRUSTPATH
+List of paths to search for trusted certificates.
+Default:
+.Pa <DESTDIR>/usr/share/certs/trusted
+.Pa <DESTDIR>/usr/local/share/certs <DESTDIR>/usr/local/etc/ssl/certs
+.It Ev BLACKLISTPATH
+List of paths to search for blacklisted certificates.
+Default:
+.Pa <DESTDIR>/usr/share/certs/blacklisted
+.Pa <DESTDIR>/usr/local/etc/ssl/blacklisted
+.It Ev CERTDESTDIR
+Destination directory for symbolic links to trusted certificates.
+Default:
+.Pa <DESTDIR>/etc/ssl/certs
+.It Ev BLACKLISTDESTDIR
+Destination directory for symbolic links to blacklisted certificates.
+Default:
+.Pa <DESTDIR>/etc/ssl/blacklisted
+.It Ev EXTENSIONS
+List of file extensions to read as certificate files.
+Default: *.pem *.crt *.cer *.crl *.0
+.El
+.Sh SEE ALSO
+.Xr openssl 1
+.Sh HISTORY
+.Nm
+first appeared in
+.Fx 12.0
+.Sh AUTHORS
+.An Allan Jude Aq Mt allanjude@freebsd.org
diff --git a/usr.sbin/certctl/certctl.sh b/usr.sbin/certctl/certctl.sh
new file mode 100755
index 0000000000000..cab9c7deeaf5f
--- /dev/null
+++ b/usr.sbin/certctl/certctl.sh
@@ -0,0 +1,230 @@
+#!/bin/sh
+#-
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright 2018 Allan Jude <allanjude@freebsd.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted providing that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# $FreeBSD$
+
+############################################################ CONFIGURATION
+
+: ${DESTDIR:=}
+: ${TRUSTPATH:=${DESTDIR}/usr/share/certs/trusted:${DESTDIR}/usr/local/share/certs:${DESTDIR}/usr/local/etc/ssl/certs}
+: ${BLACKLISTPATH:=${DESTDIR}/usr/share/certs/blacklisted:${DESTDIR}/usr/local/etc/ssl/blacklisted}
+: ${CERTDESTDIR:=${DESTDIR}/etc/ssl/certs}
+: ${BLACKLISTDESTDIR:=${DESTDIR}/etc/ssl/blacklisted}
+: ${EXTENSIONS:="*.pem *.crt *.cer *.crl *.0"}
+: ${VERBOSE:=0}
+
+############################################################ GLOBALS
+
+SCRIPTNAME="${0##*/}"
+ERRORS=0
+NOOP=0
+
+############################################################ FUNCTIONS
+
+do_hash()
+{
+ local hash
+
+ if hash=$( openssl x509 -noout -subject_hash -in "$1" ); then
+ echo "$hash"
+ return 0
+ else
+ echo "Error: $1" >&2
+ ERRORS=$(( $ERRORS + 1 ))
+ return 1
+ fi
+}
+
+create_trusted_link()
+{
+ local hash
+
+ hash=$( do_hash "$1" ) || return
+ if [ -e "$BLACKLISTDESTDIR/$hash.0" ]; then
+ echo "Skipping blacklisted certificate $1 ($BLACKLISTDESTDIR/$hash.0)"
+ return 1
+ fi
+ [ $VERBOSE -gt 0 ] && echo "Adding $hash.0 to trust store"
+ [ $NOOP -eq 0 ] && ln -fs "$1" "$CERTDESTDIR/$hash.0"
+}
+
+create_blacklisted()
+{
+ local hash
+
+ hash=$( do_hash "$1" ) || return
+ [ $VERBOSE -gt 0 ] && echo "Adding $hash.0 to blacklist"
+ [ $NOOP -eq 0 ] && ln -fs "$1" "$BLACKLISTDESTDIR/$hash.0"
+}
+
+do_scan()
+{
+ local CFUNC CSEARCH CPATH CFILE
+ local oldIFS="$IFS"
+ CFUNC="$1"
+ CSEARCH="$2"
+
+ IFS=:
+ set -- $CSEARCH
+ IFS="$oldIFS"
+ for CPATH in "$@"; do
+ [ -d "$CPATH" ] || continue
+ echo "Scanning $CPATH for certificates..."
+ cd "$CPATH"
+ for CFILE in $EXTENSIONS; do
+ [ -e "$CFILE" ] || continue
+ [ $VERBOSE -gt 0 ] && echo "Reading $CFILE"
+ "$CFUNC" "$CPATH/$CFILE"
+ done
+ cd -
+ done
+}
+
+do_list()
+{
+ local CFILE subject
+
+ if [ -e "$1" ]; then
+ cd "$1"
+ for CFILE in *.0; do
+ if [ ! -s "$CFILE" ]; then
+ echo "Unable to read $CFILE" >&2
+ ERRORS=$(( $ERRORS + 1 ))
+ continue
+ fi
+ subject=
+ if [ $VERBOSE -eq 0 ]; then
+ subject=$( openssl x509 -noout -subject -nameopt multiline -in "$CFILE" |
+ sed -n '/commonName/s/.*= //p' )
+ fi
+ [ "$subject" ] ||
+ subject=$( openssl x509 -noout -subject -in "$CFILE" )
+ printf "%s\t%s\n" "$CFILE" "$subject"
+ done
+ cd -
+ fi
+}
+
+cmd_rehash()
+{
+
+ [ $NOOP -eq 0 ] && rm -rf "$CERTDESTDIR"
+ [ $NOOP -eq 0 ] && mkdir -p "$CERTDESTDIR"
+ [ $NOOP -eq 0 ] && mkdir -p "$BLACKLISTDESTDIR"
+
+ do_scan create_blacklisted "$BLACKLISTPATH"
+ do_scan create_trusted_link "$TRUSTPATH"
+}
+
+cmd_list()
+{
+ echo "Listing Trusted Certificates:"
+ do_list "$CERTDESTDIR"
+}
+
+cmd_blacklist()
+{
+ local BPATH
+
+ shift # verb
+ [ $NOOP -eq 0 ] && mkdir -p "$BLACKLISTDESTDIR"
+ for BFILE in "$@"; do
+ echo "Adding $BFILE to blacklist"
+ create_blacklisted "$BFILE"
+ done
+}
+
+cmd_unblacklist()
+{
+ local BFILE hash
+
+ shift # verb
+ for BFILE in "$@"; do
+ if [ -s "$BFILE" ]; then
+ hash=$( do_hash "$BFILE" )
+ echo "Removing $hash.0 from blacklist"
+ [ $NOOP -eq 0 ] && rm -f "$BLACKLISTDESTDIR/$hash.0"
+ elif [ -e "$BLACKLISTDESTDIR/$BFILE" ]; then
+ echo "Removing $BFILE from blacklist"
+ [ $NOOP -eq 0 ] && rm -f "$BLACKLISTDESTDIR/$BFILE"
+ else
+ echo "Cannot find $BFILE" >&2
+ ERRORS=$(( $ERRORS + 1 ))
+ fi
+ done
+}
+
+cmd_blacklisted()
+{
+ echo "Listing Blacklisted Certificates:"
+ do_list "$BLACKLISTDESTDIR"
+}
+
+usage()
+{
+ exec >&2
+ echo "Manage the TLS trusted certificates on the system"
+ echo " $SCRIPTNAME [-v] list"
+ echo " List trusted certificates"
+ echo " $SCRIPTNAME [-v] blacklisted"
+ echo " List blacklisted certificates"
+ echo " $SCRIPTNAME [-nv] rehash"
+ echo " Generate hash links for all certificates"
+ echo " $SCRIPTNAME [-nv] blacklist <file>"
+ echo " Add <file> to the list of blacklisted certificates"
+ echo " $SCRIPTNAME [-nv] unblacklist <file>"
+ echo " Remove <file> from the list of blacklisted certificates"
+ exit 64
+}
+
+############################################################ MAIN
+
+while getopts nv flag; do
+ case "$flag" in
+ n) NOOP=1 ;;
+ v) VERBOSE=$(( $VERBOSE + 1 )) ;;
+ esac
+done
+shift $(( $OPTIND - 1 ))
+
+[ $# -gt 0 ] || usage
+case "$1" in
+list) cmd_list ;;
+rehash) cmd_rehash ;;
+blacklist) cmd_blacklist "$@" ;;
+unblacklist) cmd_unblacklist "$@" ;;
+blacklisted) cmd_blacklisted ;;
+*) usage # NOTREACHED
+esac
+
+retval=$?
+[ $ERRORS -gt 0 ] && echo "Encountered $ERRORS errors" >&2
+exit $retval
+
+################################################################################
+# END
+################################################################################