git: 986c43bd80e7 - stable/14 - certctl: Add an option to copy files.

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Thu, 24 Jul 2025 13:03:01 UTC
The branch stable/14 has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=986c43bd80e750937d02966883b3182ded828c97

commit 986c43bd80e750937d02966883b3182ded828c97
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-07-17 18:10:56 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-07-24 13:02:45 +0000

    certctl: Add an option to copy files.
    
    This is slower than linking but is the only method that works for all
    cases, including running certctl from outside a jail that does not
    contain the raw certificate data.
    
    While here, fix a bug that occurs in unprivileged mode if DESTDIR
    is unset or the root directory.
    
    MFC after:      1 week
    Reviewed by:    dfr
    Differential Revision:  https://reviews.freebsd.org/D51373
    
    (cherry picked from commit 92b9f43c788da24d2d8376a50953ef67c2303ba7)
---
 usr.sbin/certctl/certctl.8  | 10 ++++++----
 usr.sbin/certctl/certctl.sh | 22 +++++++++++-----------
 2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/usr.sbin/certctl/certctl.8 b/usr.sbin/certctl/certctl.8
index 4ce61916d79a..569bd0f85d55 100644
--- a/usr.sbin/certctl/certctl.8
+++ b/usr.sbin/certctl/certctl.8
@@ -24,7 +24,7 @@
 .\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 13, 2022
+.Dd July 17, 2025
 .Dt CERTCTL 8
 .Os
 .Sh NAME
@@ -38,15 +38,15 @@
 .Op Fl v
 .Ic untrusted
 .Nm
-.Op Fl nUv
+.Op Fl cnUv
 .Op Fl D Ar destdir
 .Op Fl M Ar metalog
 .Ic rehash
 .Nm
-.Op Fl nv
+.Op Fl cnv
 .Ic untrust Ar file
 .Nm
-.Op Fl nv
+.Op Fl cnv
 .Ic trust Ar file
 .Sh DESCRIPTION
 The
@@ -56,6 +56,8 @@ applications that use OpenSSL.
 .Pp
 Flags:
 .Bl -tag -width 4n
+.It Fl c
+Copy certificates instead of linking to them.
 .It Fl D Ar destdir
 Specify the DESTDIR (overriding values from the environment).
 .It Fl d Ar distbase
diff --git a/usr.sbin/certctl/certctl.sh b/usr.sbin/certctl/certctl.sh
index 458f5c53682f..2bde651de126 100755
--- a/usr.sbin/certctl/certctl.sh
+++ b/usr.sbin/certctl/certctl.sh
@@ -36,6 +36,7 @@ set -u
 ############################################################ GLOBALS
 
 SCRIPTNAME="${0##*/}"
+LINK=-lrs
 ERRORS=0
 NOOP=false
 UNPRIV=false
@@ -110,7 +111,6 @@ create_trusted()
 {
 	local hash certhash otherfile otherhash
 	local suffix
-	local link=${2:+-lrs}
 
 	hash=$(do_hash "$1") || return
 	certhash=$(openssl x509 -sha1 -in "$1" -noout -fingerprint)
@@ -130,7 +130,7 @@ create_trusted()
 	done
 	suffix=$(get_decimal "$CERTDESTDIR" "$hash")
 	verbose "Adding $hash.$suffix to trust store"
-	perform install ${INSTALLFLAGS} -m 0444 ${link} \
+	perform install ${INSTALLFLAGS} -m 0444 ${LINK} \
 		"$(realpath "$1")" "$CERTDESTDIR/$hash.$suffix"
 }
 
@@ -159,7 +159,6 @@ resolve_certname()
 create_untrusted()
 {
 	local srcfile filename
-	local link=${2:+-lrs}
 
 	set -- $(resolve_certname "$1")
 	srcfile=$1
@@ -170,7 +169,7 @@ create_untrusted()
 	fi
 
 	verbose "Adding $filename to untrusted list"
-	perform install ${INSTALLFLAGS} -m 0444 ${link} \
+	perform install ${INSTALLFLAGS} -m 0444 ${LINK} \
 		"$srcfile" "$UNTRUSTDESTDIR/$filename"
 }
 
@@ -190,7 +189,7 @@ do_scan()
 		0)
 			;;
 		1)
-			"$CFUNC" "$CFILE" link
+			"$CFUNC" "$CFILE"
 			;;
 		*)
 			verbose "Multiple certificates found, splitting..."
@@ -303,19 +302,20 @@ usage()
 	echo "		List trusted certificates"
 	echo "	$SCRIPTNAME [-v] untrusted"
 	echo "		List untrusted certificates"
-	echo "	$SCRIPTNAME [-nUv] [-D <destdir>] [-d <distbase>] [-M <metalog>] rehash"
-	echo "		Generate hash links for all certificates"
-	echo "	$SCRIPTNAME [-nv] untrust <file>"
+	echo "	$SCRIPTNAME [-cnUv] [-D <destdir>] [-d <distbase>] [-M <metalog>] rehash"
+	echo "		Rehash all trusted and untrusted certificates"
+	echo "	$SCRIPTNAME [-cnv] untrust <file>"
 	echo "		Add <file> to the list of untrusted certificates"
-	echo "	$SCRIPTNAME [-nv] trust <file>"
+	echo "	$SCRIPTNAME [-cnv] trust <file>"
 	echo "		Remove <file> from the list of untrusted certificates"
 	exit 64
 }
 
 ############################################################ MAIN
 
-while getopts D:d:M:nUv flag; do
+while getopts cD:d:M:nUv flag; do
 	case "$flag" in
+	c) LINK=-c ;;
 	D) DESTDIR=${OPTARG} ;;
 	d) DISTBASE=${OPTARG} ;;
 	M) METALOG=${OPTARG} ;;
@@ -334,7 +334,7 @@ fi
 : ${METALOG:=${DESTDIR}/METALOG}
 INSTALLFLAGS=
 if "$UNPRIV" ; then
-	INSTALLFLAGS="-U -M ${METALOG} -D ${DESTDIR} -o root -g wheel"
+	INSTALLFLAGS="-U -M ${METALOG} -D ${DESTDIR:-/} -o root -g wheel"
 fi
 : ${LOCALBASE:=$(sysctl -n user.localbase)}
 : ${TRUSTPATH:=${DESTDIR}${DISTBASE}/usr/share/certs/trusted:${DESTDIR}${LOCALBASE}/share/certs:${DESTDIR}${LOCALBASE}/etc/ssl/certs}