test: cover the io.systemd.CryptEnroll Varlink interface

Extend the existing systemd-cryptenroll test with varlinkctl invocations
equivalent to the command line ones: enrolling a recovery key and passwords
(unlocking via a key file by path and via a passed file descriptor), listing
slots, combining enrollment with a type-based wipe, and the negative cases
(ListSlots without 'more', and the pkcs11/tpm2 mechanisms that are not part of
the EnrollMechanism allowlist).
This commit is contained in:
Lennart Poettering
2026-05-28 14:23:04 +02:00
parent 47dc8abf8b
commit 2d691049ae

View File

@@ -12,7 +12,7 @@ cryptenroll_wipe_and_check() {(
)}
at_exit() {
rm -f "${IMAGE:-}" /tmp/cryptenroll.out /tmp/password
rm -f "${IMAGE:-}" "${VL_IMAGE:-}" /tmp/cryptenroll.out /tmp/password
}
trap at_exit EXIT
@@ -101,3 +101,43 @@ PIN=4321 systemd-cryptenroll --unlock-tpm2-device=auto --recovery-key "$IMAGE"
(! systemd-cryptenroll --fido2-device=auto --unlock-fido2-device=auto "$IMAGE")
rm -f "$IMAGE"
# Exercise the io.systemd.CryptEnroll Varlink interface with calls equivalent to the command line ones above.
CRYPTENROLL="$(command -v systemd-cryptenroll)"
VL_ADDRESS="exec:$CRYPTENROLL"
VL_IMAGE="$(mktemp /tmp/systemd-cryptenroll-varlink-XXX.image)"
truncate -s 20M "$VL_IMAGE"
cryptsetup luksFormat -q --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --use-urandom "$VL_IMAGE" /tmp/password
# Enroll a recovery key, unlocking via key file (cf. systemd-cryptenroll --unlock-key-file= --recovery-key)
varlinkctl call "$VL_ADDRESS" io.systemd.CryptEnroll.Enroll \
"{\"node\":\"$VL_IMAGE\",\"mechanism\":\"recovery\",\"unlockKeyFile\":\"/tmp/password\"}" | grep recoveryKey >/dev/null
# Enroll a password, unlocking via key file (cf. NEWPASSWORD=… systemd-cryptenroll --unlock-key-file= --password)
varlinkctl call "$VL_ADDRESS" io.systemd.CryptEnroll.Enroll \
"{\"node\":\"$VL_IMAGE\",\"mechanism\":\"password\",\"unlockKeyFile\":\"/tmp/password\",\"password\":\"varlinkpassword\"}"
# Enroll a password, unlocking via the key file passed as a file descriptor instead of a path
varlinkctl --push-fd=3 call "$VL_ADDRESS" io.systemd.CryptEnroll.Enroll \
"{\"node\":\"$VL_IMAGE\",\"mechanism\":\"password\",\"unlockKeyFileDescriptor\":0,\"password\":\"fdpassword\"}" 3</tmp/password
# List enrolled slots (must be called with 'more'); we should see the password and recovery slots
varlinkctl call --more "$VL_ADDRESS" io.systemd.CryptEnroll.ListSlots "{\"node\":\"$VL_IMAGE\"}" | grep '"type":"recovery"' >/dev/null
varlinkctl call --more "$VL_ADDRESS" io.systemd.CryptEnroll.ListSlots "{\"node\":\"$VL_IMAGE\"}" | grep '"type":"password"' >/dev/null
# Enroll combined with a wipe of the recovery key slot (cf. systemd-cryptenroll --wipe-slot=recovery --password).
# The recovery key slot just got wiped, so it should be reported back in the (non-empty) wipedSlots output.
varlinkctl call "$VL_ADDRESS" io.systemd.CryptEnroll.Enroll \
"{\"node\":\"$VL_IMAGE\",\"mechanism\":\"password\",\"unlockKeyFile\":\"/tmp/password\",\"password\":\"wipepassword\",\"wipeTypes\":[\"recovery\"]}" | grep -E '"wipedSlots":\[[0-9]+(,[0-9]+)*\]' >/dev/null
(! varlinkctl call --more "$VL_ADDRESS" io.systemd.CryptEnroll.ListSlots "{\"node\":\"$VL_IMAGE\"}" | grep '"type":"recovery"' >/dev/null)
# ListSlots without 'more' is refused
(! varlinkctl call "$VL_ADDRESS" io.systemd.CryptEnroll.ListSlots "{\"node\":\"$VL_IMAGE\"}")
# PKCS#11 and TPM2 cannot be enrolled via this interface, so the Enroll() handler rejects them as invalid parameters
(! varlinkctl call "$VL_ADDRESS" io.systemd.CryptEnroll.Enroll \
"{\"node\":\"$VL_IMAGE\",\"mechanism\":\"tpm2\",\"unlockKeyFile\":\"/tmp/password\"}")
(! varlinkctl call "$VL_ADDRESS" io.systemd.CryptEnroll.Enroll \
"{\"node\":\"$VL_IMAGE\",\"mechanism\":\"pkcs11\",\"unlockKeyFile\":\"/tmp/password\"}")
rm -f "$VL_IMAGE"