base-images/tests/ca-trust.sh
Joseph Marrero Corchado 436ea4309c standard: Focus boot-time regeneration on CA trust
Rename the service to atomic-update-ca-trust, remove the legacy extract argument, and defer crypto-policy regeneration. Document early-boot and initramfs limitations and keep regeneration failures visible without preventing boot.

Add standard-image regression coverage for stale bundles, vendor CA changes, local trust and distrust, repeated refreshes, and service activation.
2026-10-31 16:44:10 -04:00

96 lines
3.9 KiB
Bash

#!/bin/bash
set -xeuo pipefail
# This test modifies system trust. Only run it in the disposable test image.
systemd-detect-virt --quiet --container
fixtures=$(mktemp -d)
trap 'rm -rf "$fixtures"' EXIT
vendor=/usr/share/pki/ca-trust-source/anchors
local_anchors=/etc/pki/ca-trust/source/anchors
local_blocklist=/etc/pki/ca-trust/source/blocklist
mkdir -p "$vendor" "$local_anchors" "$local_blocklist"
cat > "$fixtures/server.ext" <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
extendedKeyUsage=serverAuth
subjectAltName=DNS:atomic-ca-trust-test.invalid
EOF
for name in vendor-old vendor-new vendor-blocked local; do
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -noenc \
-days 1 -subj "/CN=atomic-ca-trust-test-${name}/" \
-addext 'basicConstraints=critical,CA:TRUE' \
-addext 'keyUsage=critical,keyCertSign,cRLSign' \
-keyout "$fixtures/$name.key" -out "$fixtures/$name.pem"
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -noenc \
-subj '/CN=atomic-ca-trust-test.invalid/' \
-keyout "$fixtures/$name-server.key" -out "$fixtures/$name-server.csr"
openssl x509 -req -in "$fixtures/$name-server.csr" \
-CA "$fixtures/$name.pem" -CAkey "$fixtures/$name.key" \
-set_serial 1 -days 1 -extfile "$fixtures/server.ext" \
-out "$fixtures/$name-server.pem"
done
# Exercise the command from the installed unit. Image tests have no running
# systemd manager; the rootfs test separately checks service enablement.
# This unit uses a simple executable/argument list without systemd expansions.
read -r -a refresh_command < <(sed -n 's/^ExecStart=//p' \
/usr/lib/systemd/system/atomic-update-ca-trust.service)
test "${#refresh_command[@]}" -gt 0
assert_trust() {
local name=$1 expected=$2 bundle
for bundle in /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \
/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt; do
if openssl verify -purpose sslserver -no-CApath -no-CAstore -CAfile "$bundle" \
"$fixtures/$name-server.pem" > "$fixtures/verify.log" 2>&1; then
if [ "$expected" != trusted ]; then
echo "Unexpected trust for $name in $bundle" >&2
exit 1
fi
elif [ "$expected" = trusted ]; then
cat "$fixtures/verify.log" >&2
echo "Missing trust for $name in $bundle" >&2
exit 1
fi
done
}
# Initially the machine has a private CA and explicitly distrusts a vendor CA.
cp "$fixtures/vendor-old.pem" "$vendor/atomic-test-old.pem"
cp "$fixtures/vendor-blocked.pem" "$vendor/atomic-test-blocked.pem"
cp "$fixtures/local.pem" "$local_anchors/atomic-test-local.pem"
cp "$fixtures/vendor-blocked.pem" "$local_blocklist/atomic-test-blocked.pem"
"${refresh_command[@]}"
assert_trust vendor-old trusted
assert_trust vendor-new untrusted
assert_trust local trusted
assert_trust vendor-blocked untrusted
# Model the state after an upgrade has changed vendor inputs but preserved
# locally generated /etc bundles. Demonstrate the stale result before refresh.
rm "$vendor/atomic-test-old.pem"
cp "$fixtures/vendor-new.pem" "$vendor/atomic-test-new.pem"
assert_trust vendor-old trusted
assert_trust vendor-new untrusted
# Refresh must apply vendor changes while retaining both kinds of local policy.
# Repeat to cover refreshing an already-current bundle on a subsequent boot.
for iteration in 1 2; do
echo "Checking refresh $iteration"
"${refresh_command[@]}"
assert_trust vendor-old untrusted
assert_trust vendor-new trusted
assert_trust local trusted
assert_trust vendor-blocked untrusted
done
# Removing local policy must be reflected as well.
rm "$local_anchors/atomic-test-local.pem" "$local_blocklist/atomic-test-blocked.pem"
"${refresh_command[@]}"
assert_trust vendor-old untrusted
assert_trust vendor-new trusted
assert_trust local untrusted
assert_trust vendor-blocked trusted