]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: add coverage for kernel keyring in TEST-50-DISSECT
authorLuca Boccassi <luca.boccassi@gmail.com>
Fri, 8 Aug 2025 21:59:45 +0000 (22:59 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 3 Sep 2025 10:10:48 +0000 (12:10 +0200)
Use the kernel keyring to verify images in the dissect test.
The userspace keyring is still covered by the DDI and mountfsd tests.

(cherry picked from commit 208ba34a43c5372131406329bccf026abef026ed)

mkosi/mkosi.finalize
test/integration-tests/TEST-50-DISSECT/meson.build
test/units/TEST-50-DISSECT.dissect.sh
test/units/TEST-50-DISSECT.sh

index bb7ad2d9ea717f14f24869f73e114f3b662a1b4d..99c9d7c7620dcb6812e5a4d7e23d69d0f5a55ef6 100755 (executable)
@@ -13,3 +13,6 @@ if [ -n "$EFI_ARCHITECTURE" ]; then
         --secureboot-certificate "$SRCDIR/mkosi/mkosi.crt" \
         --secureboot-private-key "$SRCDIR/mkosi/mkosi.key"
 fi
+
+# Used to sign artifacts verified by kernel platform keyring
+cp "$SRCDIR/mkosi/mkosi.crt" "$SRCDIR/mkosi/mkosi.key" "$BUILDROOT/usr/share/"
index 77370ce4588c492616a081a23117e5b55dce4f3b..d7634debca3ea8ad7b6f6324a837b3e07eef1283 100644 (file)
@@ -4,5 +4,6 @@ integration_tests += [
         integration_test_template + {
                 'name' : fs.name(meson.current_source_dir()),
                 'vm' : true,
+                'firmware' : 'auto',
         },
 ]
index f2b4db5133bd03dc72b342bc843806213d2ce42a..126d658a77118b51034cedeff449df646e091231 100755 (executable)
@@ -9,6 +9,18 @@ set -o pipefail
 # shellcheck source=test/units/util.sh
 . "$(dirname "$0")"/util.sh
 
+# Requires kernel built with certain kconfigs, as listed in README:
+# https://oracle.github.io/kconfigs/?config=UTS_RELEASE&config=DM_VERITY_VERIFY_ROOTHASH_SIG&config=DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING&config=DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING&config=IMA_ARCH_POLICY&config=INTEGRITY_MACHINE_KEYRING
+if grep -q "$(openssl x509 -noout -subject -in /usr/share/mkosi.crt | sed 's/^.*CN=//')" /proc/keys && \
+        ( . /etc/os-release; [ "$ID" != "centos" ] || systemd-analyze compare-versions "$VERSION_ID" ge 10 ) && \
+        ( . /etc/os-release; [ "$ID" != "debian" ] || systemd-analyze compare-versions "$VERSION_ID" ge 13 ) && \
+        ( . /etc/os-release; [ "$ID" != "ubuntu" ] || systemd-analyze compare-versions "$VERSION_ID" ge 24.04 ) && \
+        systemd-analyze compare-versions "$(cryptsetup --version | sed 's/^cryptsetup \([0-9]*\.[0-9]*\.[0-9]*\) .*/\1/')" ge 2.3.0; then
+    verity_sig_supported=1
+else
+    verity_sig_supported=0
+fi
+
 systemd-dissect --json=short "$MINIMAL_IMAGE.raw" | \
     grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
 systemd-dissect "$MINIMAL_IMAGE.raw" | grep -q -F "MARKER=1"
@@ -71,6 +83,10 @@ if [[ "$verity_count" -lt 1 ]]; then
     echo "Verity device $MINIMAL_IMAGE.raw not found in /dev/mapper/"
     exit 1
 fi
+# Ensure the kernel is verifying the signature if the mkosi key is in the keyring
+if [ "$verity_sig_supported" -eq 1 ]; then
+    veritysetup status "$(cat "$MINIMAL_IMAGE.roothash")-verity" | grep -q "verified (with signature)"
+fi
 systemd-dissect --umount "$IMAGE_DIR/mount"
 systemd-dissect --umount "$IMAGE_DIR/mount2"
 
index 38bafa545fc53e5c80823e87d6c0bda480426810..0efea0fc1808b54a1c8e1779dc9e1e1efed83c98 100755 (executable)
@@ -110,17 +110,9 @@ install_extension_images
 
 OS_RELEASE="$(test -e /etc/os-release && echo /etc/os-release || echo /usr/lib/os-release)"
 
-if systemctl --version | grep -q -- +OPENSSL ; then
-    # The openssl binary is installed conditionally. If we have OpenSSL support enabled and openssl is
-    # missing, fail early with a proper error message.
-    if ! command -v openssl &>/dev/null; then
-        echo "openssl binary is missing" >/failed
-        exit 1
-    fi
-
-    OPENSSL_CONFIG="$(mktemp)"
-    # Unfortunately OpenSSL insists on reading some config file, hence provide one with mostly placeholder contents
-    cat >"${OPENSSL_CONFIG:?}" <<EOF
+OPENSSL_CONFIG="$(mktemp)"
+# Unfortunately OpenSSL insists on reading some config file, hence provide one with mostly placeholder contents
+cat >"${OPENSSL_CONFIG:?}" <<EOF
 [ req ]
 prompt = no
 distinguished_name = req_distinguished_name
@@ -134,7 +126,6 @@ OU = Org Unit Name
 CN = Common Name
 emailAddress = test@email.com
 EOF
-fi
 
 # Make a GPT disk on the fly, with the squashfs as partition 1 and the verity hash tree as partition 2
 #
@@ -154,25 +145,17 @@ fi
 verity_size="$((verity_size * 2))KiB"
 signature_size="$((signature_size * 2))KiB"
 
-if [[ -n "${OPENSSL_CONFIG:-}" ]]; then
-    # Create key pair
-    openssl req -config "$OPENSSL_CONFIG" -new -x509 -newkey rsa:1024 \
-                -keyout "$MINIMAL_IMAGE.key" -out "$MINIMAL_IMAGE.crt" -days 365 -nodes
-    # Sign Verity root hash with it
-    openssl smime -sign -nocerts -noattr -binary \
-                  -in "$MINIMAL_IMAGE.roothash" \
-                  -inkey "$MINIMAL_IMAGE.key" \
-                  -signer "$MINIMAL_IMAGE.crt" \
-                  -outform der \
-                  -out "$MINIMAL_IMAGE.roothash.p7s"
-    # Generate signature partition JSON data
-    echo '{"rootHash":"'"$MINIMAL_IMAGE_ROOTHASH"'","signature":"'"$(base64 -w 0 <"$MINIMAL_IMAGE.roothash.p7s")"'"}' >"$MINIMAL_IMAGE.verity-sig"
-    # Pad it
-    truncate -s "$signature_size" "$MINIMAL_IMAGE.verity-sig"
-    # Register certificate in the (userspace) verity key ring
-    mkdir -p /run/verity.d
-    ln -s "$MINIMAL_IMAGE.crt" /run/verity.d/ok.crt
-fi
+# Sign Verity root hash with mkosi key
+openssl smime -sign -nocerts -noattr -binary \
+                -in "$MINIMAL_IMAGE.roothash" \
+                -inkey /usr/share/mkosi.key \
+                -signer /usr/share/mkosi.crt \
+                -outform der \
+                -out "$MINIMAL_IMAGE.roothash.p7s"
+# Generate signature partition JSON data
+echo '{"rootHash":"'"$MINIMAL_IMAGE_ROOTHASH"'","signature":"'"$(base64 -w 0 <"$MINIMAL_IMAGE.roothash.p7s")"'"}' >"$MINIMAL_IMAGE.verity-sig"
+# Pad it
+truncate -s "$signature_size" "$MINIMAL_IMAGE.verity-sig"
 
 # Construct a UUID from hash
 # input:  11111111222233334444555566667777
@@ -181,30 +164,23 @@ uuid="$(head -c 32 "$MINIMAL_IMAGE.roothash" | sed -r 's/(.{8})(.{4})(.{4})(.{4}
 echo -e "label: gpt\nsize=$root_size, type=$ROOT_GUID, uuid=$uuid" | sfdisk "$MINIMAL_IMAGE.gpt"
 uuid="$(tail -c 32 "$MINIMAL_IMAGE.roothash" | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.+)/\1-\2-\3-\4-\5/')"
 echo -e "size=$verity_size, type=$VERITY_GUID, uuid=$uuid" | sfdisk "$MINIMAL_IMAGE.gpt" --append
-if [[ -n "${OPENSSL_CONFIG:-}" ]]; then
-    echo -e "size=$signature_size, type=$SIGNATURE_GUID" | sfdisk "$MINIMAL_IMAGE.gpt" --append
-fi
+echo -e "size=$signature_size, type=$SIGNATURE_GUID" | sfdisk "$MINIMAL_IMAGE.gpt" --append
+
 sfdisk --part-label "$MINIMAL_IMAGE.gpt" 1 "Root Partition"
 sfdisk --part-label "$MINIMAL_IMAGE.gpt" 2 "Verity Partition"
-if [[ -n "${OPENSSL_CONFIG:-}" ]]; then
-    sfdisk --part-label "$MINIMAL_IMAGE.gpt" 3 "Signature Partition"
-fi
+sfdisk --part-label "$MINIMAL_IMAGE.gpt" 3 "Signature Partition"
 loop="$(losetup --show -P -f "$MINIMAL_IMAGE.gpt")"
 partitions=(
     "${loop:?}p1"
     "${loop:?}p2"
+    "${loop:?}p3"
 )
-if [[ -n "${OPENSSL_CONFIG:-}" ]]; then
-    partitions+=("${loop:?}p3")
-fi
 # The kernel sometimes(?) does not emit "add" uevent for loop block partition devices.
 # Let's not expect the devices to be initialized.
 udevadm wait --timeout=60 --settle --initialized=no "${partitions[@]}"
 udevadm lock --timeout=60 --device="${loop}p1" dd if="$MINIMAL_IMAGE.raw" of="${loop}p1"
 udevadm lock --timeout=60 --device="${loop}p2" dd if="$MINIMAL_IMAGE.verity" of="${loop}p2"
-if [[ -n "${OPENSSL_CONFIG:-}" ]]; then
-    udevadm lock --timeout=60 --device="${loop}p3" dd if="$MINIMAL_IMAGE.verity-sig" of="${loop}p3"
-fi
+udevadm lock --timeout=60 --device="${loop}p3" dd if="$MINIMAL_IMAGE.verity-sig" of="${loop}p3"
 losetup -d "$loop"
 udevadm settle --timeout=60