[packages/ca-certificates] Rel 3; sync hashed CApath against a manifest instead of handing /etc/openssl/certs to trust extract
arekm
arekm at pld-linux.org
Wed Jul 29 08:06:45 CEST 2026
commit 716ec8ac31f58b25a187089970e99c5472561c3d
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Wed Jul 29 07:16:53 2026 +0200
Rel 3; sync hashed CApath against a manifest instead of handing /etc/openssl/certs to trust extract
ca-certificates-p11-kit.patch | 115 +++++++++++++++++++++++++++++++++++++++---
ca-certificates.spec | 14 ++++-
2 files changed, 120 insertions(+), 9 deletions(-)
---
diff --git a/ca-certificates.spec b/ca-certificates.spec
index fad885d..84fe8e0 100644
--- a/ca-certificates.spec
+++ b/ca-certificates.spec
@@ -13,7 +13,7 @@ Summary(pl.UTF-8): Pliki PEM popularnych certyfikatów CA
Name: ca-certificates
%define ver_date 20260601
Version: %{ver_date}
-Release: 2
+Release: 3
License: GPL v2 (scripts), MPL v2 (mozilla certs), distributable (other certs)
Group: Base
Source0: https://ftp.debian.org/debian/pool/main/c/ca-certificates/%{name}_%{version}.tar.xz
@@ -50,8 +50,11 @@ Patch3: %{name}-DESTDIR.patch
Patch4: %{name}.d.patch
Patch5: %{name}-p11-kit.patch
URL: https://packages.debian.org/sid/ca-certificates
+Requires: findutils
+Requires: grep
Requires: mktemp
Requires: p11-kit
+Requires: sed
BuildRequires: openssl-tools
BuildRequires: python3
BuildRequires: python3-cryptography
@@ -210,7 +213,14 @@ rm -rf $RPM_BUILD_ROOT
%{_sbindir}/update-ca-certificates --fresh || :
%postun
-/usr/bin/find "%{openssldir}" -xtype l -delete || :
+# remove only what update-ca-certificates installed; local admin files stay
+if [ "$1" = "0" ] && [ -f %{openssldir}/.manifest ]; then
+ while IFS= read -r f; do
+ case "$f" in ''|*/*) continue ;; esac
+ rm -f "%{openssldir}/$f"
+ done < %{openssldir}/.manifest
+ rm -f %{openssldir}/.manifest
+fi
%pretrans -p <lua>
local mode = posix.stat("/etc/ssl/certs")
diff --git a/ca-certificates-p11-kit.patch b/ca-certificates-p11-kit.patch
index de37fbe..0a35021 100644
--- a/ca-certificates-p11-kit.patch
+++ b/ca-certificates-p11-kit.patch
@@ -1,6 +1,15 @@
--- ca-certificates/sbin/update-ca-certificates.orig
+++ ca-certificates/sbin/update-ca-certificates
-@@ -104,49 +104,20 @@
+@@ -95,6 +95,8 @@
+ rm -f "$TEMPBUNDLE"
+ rm -f "$ADDED"
+ rm -f "$REMOVED"
++ [ -z "$STAGING" ] || chmod u+w "$STAGING" 2>/dev/null || :
++ rm -rf "$STAGING" "$OURS" "$NEW" "$LIVE"
+ }
+ trap cleanup 0
+
+@@ -104,49 +106,20 @@
ADDED="$(mktemp -p "${TMPDIR:-/tmp}" "ca-certificates.tmp.XXXXXX")"
REMOVED="$(mktemp -p "${TMPDIR:-/tmp}" "ca-certificates.tmp.XXXXXX")"
@@ -54,7 +63,7 @@
echo "Updating certificates in $ETCCERTSDIR..."
# Add default certificate authorities if requested
-@@ -186,26 +157,6 @@
+@@ -186,26 +159,6 @@
ADDED_CNT=$(wc -l < "$ADDED")
REMOVED_CNT=$(wc -l < "$REMOVED")
@@ -81,7 +90,7 @@
# chmod and mv only if TEMPBUNDLE exists or install may fail, #996005
if [ -f "$TEMPBUNDLE" ]
then
-@@ -215,6 +166,18 @@
+@@ -215,6 +168,110 @@
[ -x /sbin/restorecon ] && /sbin/restorecon "$CERTBUNDLE" >/dev/null 2>&1
fi
@@ -89,12 +98,104 @@
+# p11-kit computes the hashes itself, so ca-certificates stays off the
+# openssl -> ca-certificates dependency cycle. Skipped under --destdir
+# because trust reads the live system trust module, not the buildroot.
++# The extraction goes to a staging directory (trust extract --overwrite
++# unlinks everything in its target it did not write itself) and is synced
++# to ETCCERTSDIR against a manifest of what we installed before, so files
++# the local admin drops here are never deleted.
+if [ -z "$DESTDIR" ]
+then
-+ # drop stale symlinks (incl. the legacy openssl-rehash layout) first;
-+ # trust extract leaves foreign symlinks in place otherwise
-+ find "$ETCCERTSDIR" -maxdepth 1 -type l -delete 2>/dev/null || :
-+ trust extract --format=openssl-directory --filter=ca-anchors --overwrite "$ETCCERTSDIR"
++ MANIFEST="$ETCCERTSDIR/.manifest"
++ STAGING="$(mktemp -d -p "${TMPDIR:-/tmp}" "ca-certificates.stage.XXXXXX")"
++ OURS="$(mktemp -p "${TMPDIR:-/tmp}" "ca-certificates.tmp.XXXXXX")"
++ NEW="$(mktemp -p "${TMPDIR:-/tmp}" "ca-certificates.tmp.XXXXXX")"
++ LIVE="$(mktemp -p "${TMPDIR:-/tmp}" "ca-certificates.tmp.XXXXXX")"
++
++ trust extract --format=openssl-directory --filter=ca-anchors --overwrite "$STAGING"
++
++ mkdir -p "$ETCCERTSDIR"
++ chmod 755 "$ETCCERTSDIR"
++
++ find "$STAGING" -maxdepth 1 \( -type f -o -type l \) -printf '%f\n' | sort > "$NEW"
++
++ if [ -f "$MANIFEST" ]
++ then
++ sort "$MANIFEST" > "$OURS"
++ else
++ # No manifest yet: claim what earlier layouts generated -- hash links,
++ # symlinks into the cert stores or dangling ones (openssl-rehash
++ # layout) and TRUSTED CERTIFICATE files (direct p11-kit extraction).
++ # Anything else was placed by the local admin and is left alone.
++ {
++ find "$ETCCERTSDIR" -maxdepth 1 -type l \
++ \( -name '[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].*' \
++ -o -lname "$CERTSDIR/*" -o -lname "$LOCALCERTSDIR/*" -o -xtype l \) \
++ -printf '%f\n'
++ grep -sl -- '-----BEGIN TRUSTED CERTIFICATE-----' "$ETCCERTSDIR"/*.pem | sed 's,.*/,,'
++ echo README
++ } | sort -u > "$OURS"
++ fi
++
++ # entries we installed on a previous run and which are gone from the new set;
++ # never step outside the directory, whatever a damaged manifest claims
++ comm -23 "$OURS" "$NEW" | while IFS= read -r f
++ do
++ case "$f" in ''|*/*) continue ;; esac
++ rm -f "$ETCCERTSDIR/$f"
++ done
++
++ same_entry() {
++ if [ -L "$1" ] || [ -L "$2" ]
++ then
++ [ -L "$1" ] && [ -L "$2" ] && [ "$(readlink "$1")" = "$(readlink "$2")" ]
++ else
++ [ "$(md5sum < "$1")" = "$(md5sum < "$2")" ]
++ fi
++ }
++
++ # install the new set; identical entries are left as they are, a name
++ # collision with a differing foreign file is resolved in our favour and
++ # the foreign file is kept next to it as <name>.local
++ while IFS= read -r f
++ do
++ if [ -e "$ETCCERTSDIR/$f" ] || [ -L "$ETCCERTSDIR/$f" ]
++ then
++ if same_entry "$STAGING/$f" "$ETCCERTSDIR/$f"
++ then
++ continue
++ fi
++ if ! grep -qxF -- "$f" "$OURS"
++ then
++ echo "W: $ETCCERTSDIR/$f is in the generated namespace, keeping it as $f.local" >&2
++ mv -f "$ETCCERTSDIR/$f" "$ETCCERTSDIR/$f.local"
++ fi
++ fi
++ cp -a --remove-destination "$STAGING/$f" "$ETCCERTSDIR/$f"
++ done < "$NEW"
++
++ cat > "$ETCCERTSDIR/README" <<'EOF'
++This directory is generated by update-ca-certificates(8) from the
++/etc/certs/ca-certificates.crt bundle. Entries listed in .manifest are
++rewritten on every run; other files are left alone, but OpenSSL ignores
++them -- a certificate is only consulted here through its hash link, and
++those all come from the trust store.
++
++To trust a local CA system wide, put its certificate in /etc/certs, list
++the file name in a /etc/ca-certificates.d/*.conf file and run
++update-ca-certificates. It then shows up here with its hash link.
++
++To give a certificate to a single application only, keep it outside this
++directory and point that application at it directly.
++EOF
++
++ { cat "$NEW"; echo README; } > "$MANIFEST"
++
++ # files this script does not manage look trusted but are dead weight
++ find "$ETCCERTSDIR" -maxdepth 1 \( -type f -o -type l \) -printf '%f\n' | sort > "$LIVE"
++ { cat "$MANIFEST"; echo .manifest; } | sort | comm -13 - "$LIVE" | while IFS= read -r f
++ do
++ echo "W: $ETCCERTSDIR/$f is not part of the trust store and is ignored by OpenSSL, see $ETCCERTSDIR/README" >&2
++ done
++
+fi
+
echo "$ADDED_CNT added, $REMOVED_CNT removed; done."
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/ca-certificates.git/commitdiff/716ec8ac31f58b25a187089970e99c5472561c3d
More information about the pld-cvs-commit
mailing list