svn commit: r365681 - in stable: 11/usr.sbin/certctl 12/usr.sbin/certctl

Kyle Evans kevans at FreeBSD.org
Sun Sep 13 01:09:23 UTC 2020


Author: kevans
Date: Sun Sep 13 01:09:22 2020
New Revision: 365681
URL: https://svnweb.freebsd.org/changeset/base/365681

Log:
  MFC r365500: certctl: fix hashed link generation with duplicate subjects
  
  Currently, certctl rehash will just keep clobbering .0 rather than
  incrementing the suffix upon encountering a duplicate. Do this, and do it
  for blacklisted certs as well.
  
  This also improves the situation with the blacklist to be a little less
  flakey, comparing cert fingerprints for all certs with a matching subject
  hash in the blacklist to determine if the cert we're looking at can be
  installed.
  
  Future work needs to completely revamp the blacklist to align more with how
  it's described in PR 246614. In particular, /etc/ssl/blacklisted should go
  away to avoid potential confusion -- OpenSSL will not read it, it's
  basically certctl internal.
  
  PR:		246614

Modified:
  stable/11/usr.sbin/certctl/certctl.sh
Directory Properties:
  stable/11/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/12/usr.sbin/certctl/certctl.sh
Directory Properties:
  stable/12/   (props changed)

Modified: stable/11/usr.sbin/certctl/certctl.sh
==============================================================================
--- stable/11/usr.sbin/certctl/certctl.sh	Sun Sep 13 01:08:18 2020	(r365680)
+++ stable/11/usr.sbin/certctl/certctl.sh	Sun Sep 13 01:09:22 2020	(r365681)
@@ -30,7 +30,7 @@
 ############################################################ CONFIGURATION
 
 : ${DESTDIR:=}
-: ${FILEPAT:="\.pem$|\.crt$|\.cer$|\.crl$|\.0$"}
+: ${FILEPAT:="\.pem$|\.crt$|\.cer$|\.crl$"}
 : ${VERBOSE:=0}
 
 ############################################################ GLOBALS
@@ -56,31 +56,58 @@ do_hash()
 	fi
 }
 
+get_decimal()
+{
+	local checkdir hash decimal
+
+	checkdir=$1
+	hash=$2
+	decimal=0
+
+	while [ -e "$checkdir/$hash.$decimal" ]; do
+		decimal=$((decimal + 1))
+	done
+
+	echo ${decimal}
+	return 0
+}
+
 create_trusted_link()
 {
-	local hash
+	local blisthash certhash hash
+	local suffix
 
 	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 ] && install ${INSTALLFLAGS} -lrs $(realpath "$1") "$CERTDESTDIR/$hash.0"
+	certhash=$( openssl x509 -sha1 -in "$1" -noout -fingerprint )
+	for blistfile in $(find $BLACKLISTDESTDIR -name "$hash.*"); do
+		blisthash=$( openssl x509 -sha1 -in "$blistfile" -noout -fingerprint )
+		if [ "$certhash" = "$blisthash" ]; then
+			echo "Skipping blacklisted certificate $1 ($blistfile)"
+			return 1
+		fi
+	done
+	suffix=$(get_decimal "$CERTDESTDIR" "$hash")
+	[ $VERBOSE -gt 0 ] && echo "Adding $hash.$suffix to trust store"
+	[ $NOOP -eq 0 ] && \
+		install ${INSTALLFLAGS} -lrs $(realpath "$1") "$CERTDESTDIR/$hash.$suffix"
 }
 
 create_blacklisted()
 {
 	local hash srcfile filename
+	local suffix
 
 	# If it exists as a file, we'll try that; otherwise, we'll scan
 	if [ -e "$1" ]; then
 		hash=$( do_hash "$1" ) || return
 		srcfile=$(realpath "$1")
-		filename="$hash.0"
+		suffix=$(get_decimal "$BLACKLISTDESTDIR" "$hash")
+		filename="$hash.$suffix"
 	elif [ -e "${CERTDESTDIR}/$1" ];  then
 		srcfile=$(realpath "${CERTDESTDIR}/$1")
-		filename="$1"
+		hash=$(echo "$1" | sed -Ee 's/\.([0-9])+$//')
+		suffix=$(get_decimal "$BLACKLISTDESTDIR" "$hash")
+		filename="$hash.$suffix"
 	else
 		return
 	fi
@@ -115,7 +142,7 @@ do_list()
 
 	if [ -e "$1" ]; then
 		cd "$1"
-		for CFILE in *.0; do
+		for CFILE in *.[0-9]; do
 			if [ ! -s "$CFILE" ]; then
 				echo "Unable to read $CFILE" >&2
 				ERRORS=$(( $ERRORS + 1 ))
@@ -174,14 +201,20 @@ cmd_blacklist()
 
 cmd_unblacklist()
 {
-	local BFILE hash
+	local BFILE blisthash certhash 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"
+			certhash=$( openssl x509 -sha1 -in "$BFILE" -noout -fingerprint )
+			for BLISTEDFILE in $(find $BLACKLISTDESTDIR -name "$hash.*"); do
+				blisthash=$( openssl x509 -sha1 -in "$BLISTEDFILE" -noout -fingerprint )
+				if [ "$certhash" = "$blisthash" ]; then
+					echo "Removing $(basename "$BLISTEDFILE") from blacklist"
+					[ $NOOP -eq 0 ] && rm -f $BLISTEDFILE
+				fi
+			done
 		elif [ -e "$BLACKLISTDESTDIR/$BFILE" ]; then
 			echo "Removing $BFILE from blacklist"
 			[ $NOOP -eq 0 ] && rm -f "$BLACKLISTDESTDIR/$BFILE"


More information about the svn-src-all mailing list