From 81a090f89a413487bb8a8677eff9bb4fb8bfbf71 Mon Sep 17 00:00:00 2001 From: Frantisek Krenzelok Date: Tue, 25 Jun 2024 10:04:28 +0200 Subject: [PATCH] update-ca-trust: Support --output and non-root operation Related: RHEL-44988 original issue - FC-986 Add the --output option to update-ca-trust so that trust stores can be written to a different output directory. This is useful to prepare trust store directories that can be used in containers. Additionally, fix running update-ca-trust as non-root user (specifically, without CAP_DAC_OVERRIDE) which was previously required to create two symbolic links. Quote all uses of $DEST since a user-specified path could contain spaces. --- ca-certificates.spec | 3 + update-ca-trust | 126 ++++++++++++++++++++++++++++++++++++++---- update-ca-trust.8.txt | 26 ++++++--- 3 files changed, 135 insertions(+), 20 deletions(-) diff --git a/ca-certificates.spec b/ca-certificates.spec index 5fafc50..9dbe0e1 100644 --- a/ca-certificates.spec +++ b/ca-certificates.spec @@ -395,6 +395,9 @@ fi %changelog +* Fri Sep 29 2023 Clemens Lang - 2024.2.68_v8.0.302-91.0 +- update-ca-trust: Support --output and non-root operation (rhbz#2241240) + *Thu Sep 07 2023 Robert Relyea - 2024.2.68_v8.0.302-91.0 - update License: field to SPDX diff --git a/update-ca-trust b/update-ca-trust index fe03ed2..4c27e82 100644 --- a/update-ca-trust +++ b/update-ca-trust @@ -1,10 +1,10 @@ #!/bin/sh #set -vx +set -eu -# At this time, while this script is trivial, we ignore any parameters given. -# However, for backwards compatibility reasons, future versions of this script must -# support the syntax "update-ca-trust extract" trigger the generation of output +# For backwards compatibility reasons, future versions of this script must +# support the syntax "update-ca-trust extract" trigger the generation of output # files in $DEST. DEST=/etc/pki/ca-trust/extracted @@ -12,11 +12,115 @@ DEST=/etc/pki/ca-trust/extracted # Prevent p11-kit from reading user configuration files. export P11_KIT_NO_USER_CONFIG=1 -# OpenSSL PEM bundle that includes trust flags -# (BEGIN TRUSTED CERTIFICATE) -/usr/bin/p11-kit extract --format=openssl-bundle --filter=certificates --overwrite --comment $DEST/openssl/ca-bundle.trust.crt -/usr/bin/p11-kit extract --format=pem-bundle --filter=ca-anchors --overwrite --comment --purpose server-auth $DEST/pem/tls-ca-bundle.pem -/usr/bin/p11-kit extract --format=pem-bundle --filter=ca-anchors --overwrite --comment --purpose email $DEST/pem/email-ca-bundle.pem -/usr/bin/p11-kit extract --format=pem-bundle --filter=ca-anchors --overwrite --comment --purpose code-signing $DEST/pem/objsign-ca-bundle.pem -/usr/bin/p11-kit extract --format=java-cacerts --filter=ca-anchors --overwrite --purpose server-auth $DEST/java/cacerts -/usr/bin/p11-kit extract --format=edk2-cacerts --filter=ca-anchors --overwrite --purpose=server-auth $DEST/edk2/cacerts.bin +usage() { + fold -s -w 76 >&2 <<-EOF + Usage: $0 [extract] [-o DIR|--output=DIR] + + Update the system trust store in $DEST. + + COMMANDS + (absent/empty command): Same as the extract command described below. + + extract: Instruct update-ca-trust to scan the source configuration in + /usr/share/pki/ca-trust-source and /etc/pki/ca-trust/source and produce + updated versions of the consolidated configuration files stored below + the $DEST directory hierarchy. + + EXTRACT OPTIONS + -o DIR, --output=DIR: Write the extracted trust store into the given + directory instead of updating $DEST. + EOF +} + +extract() { + USER_DEST= + + if ! TEMP=$(getopt -o "ho:" --long "help,output:" -n "$0" -- "$@"); then + echo >&2 "" + usage + exit 1 + fi + eval set -- "$TEMP" + unset TEMP + + while true; do + case "$1" in + "-o"|"--output") + USER_DEST=$2 + shift 2 + continue + ;; + "--") + shift + break + ;; + *) + usage + exit 1 + ;; + esac + done + if [ $# -ne 0 ]; then + echo >&2 "Error: Unexpected positional arguments:" "$@" + echo >&2 + usage + exit + fi + + if [ -n "$USER_DEST" ]; then + DEST=$USER_DEST + fi + + # Attempt to create the directories if they do not exist yet (rhbz#2241240) + mkdir -p \ + "$DEST"/openssl \ + "$DEST"/pem \ + "$DEST"/java \ + "$DEST"/edk2 + + # OpenSSL PEM bundle that includes trust flags + # (BEGIN TRUSTED CERTIFICATE) + /usr/bin/p11-kit extract --format=openssl-bundle --filter=certificates --overwrite --comment "$DEST/openssl/ca-bundle.trust.crt" + /usr/bin/p11-kit extract --format=pem-bundle --filter=ca-anchors --overwrite --comment --purpose server-auth "$DEST/pem/tls-ca-bundle.pem" + /usr/bin/p11-kit extract --format=pem-bundle --filter=ca-anchors --overwrite --comment --purpose email "$DEST/pem/email-ca-bundle.pem" + /usr/bin/p11-kit extract --format=pem-bundle --filter=ca-anchors --overwrite --comment --purpose code-signing "$DEST/pem/objsign-ca-bundle.pem" + /usr/bin/p11-kit extract --format=java-cacerts --filter=ca-anchors --overwrite --purpose server-auth "$DEST/java/cacerts" + /usr/bin/p11-kit extract --format=edk2-cacerts --filter=ca-anchors --overwrite --purpose=server-auth "$DEST/edk2/cacerts.bin" + # Hashed directory of BEGIN TRUSTED-style certs (usable as OpenSSL CApath and + # by GnuTLS) + /usr/bin/p11-kit extract --format=pem-directory-hash --filter=ca-anchors --overwrite --purpose server-auth "$DEST/pem/directory-hash" + + # p11-kit extract will have made this directory unwritable; when run with + # CAP_DAC_OVERRIDE this does not matter, but in container use cases that may + # not be the case. See rhbz#2241240. + chmod u+w "$DEST/pem/directory-hash" + + # Debian compatibility: their /etc/ssl/certs has this bundle + /usr/bin/ln -s ../tls-ca-bundle.pem "$DEST/pem/directory-hash/ca-certificates.crt" + # Backwards compatibility: RHEL/Fedora provided a /etc/ssl/certs/ca-bundle.crt + # since https://bugzilla.redhat.com/show_bug.cgi?id=572725 + /usr/bin/ln -s ../tls-ca-bundle.pem "$DEST/pem/directory-hash/ca-bundle.crt" + + # Remove write permissions again + chmod u-w "$DEST/pem/directory-hash" +} + +if [ "$#" -lt 1 ]; then + set -- extract +fi +case "$1" in + "extract") + shift + extract "$@" + ;; + "--"*|"-"*) + # First parameter seems to be an option, assume the command is 'extract' + extract "$@" + ;; + *) + echo >&2 "Error: Unknown command: $1" + echo >&2 + usage + exit 1 + ;; +esac diff --git a/update-ca-trust.8.txt b/update-ca-trust.8.txt index 5886cb5..51ed02b 100644 --- a/update-ca-trust.8.txt +++ b/update-ca-trust.8.txt @@ -27,7 +27,7 @@ certificates and associated trust SYNOPSIS -------- -*update-ca-trust* ['COMMAND'] +*update-ca-trust* [extract] [-o 'DIR'|--output='DIR'] DESCRIPTION @@ -214,15 +214,23 @@ server authentication. COMMANDS -------- -(absent/empty command):: - Same as the *extract* command described below. (However, the command may - print fewer warnings, as this command is being run during rpm package - installation, where non-fatal status output is undesired.) +(absent/empty command) +~~~~~~~~~~~~~~~~~~~~~~ +Same as the *extract* command described below. (However, the command may print +fewer warnings, as this command is being run during rpm package installation, +where non-fatal status output is undesired.) -*extract*:: - Instruct update-ca-trust to scan the <> and produce - updated versions of the consolidated configuration files stored below - the /etc/pki/ca-trust/extracted directory hierarchy. +extract +~~~~~~~ +Instruct update-ca-trust to scan the <> and +produce updated versions of the consolidated configuration files stored below +the /etc/pki/ca-trust/extracted directory hierarchy. + +EXTRACT OPTIONS +^^^^^^^^^^^^^^^ +*-o DIR*, *--output=DIR*:: + Write the extracted trust store into the given directory instead of + updating /etc/pki/ca-trust/extracted. FILES -----