1import ./make-test-python.nix (
2 { lib, pkgs, ... }:
3 {
4 name = "systemd-credentials-tpm2";
5
6 meta = {
7 maintainers = with pkgs.lib.maintainers; [ tmarkus ];
8 };
9
10 nodes.machine =
11 { pkgs, ... }:
12 {
13 virtualisation.tpm.enable = true;
14 environment.systemPackages = with pkgs; [ diffutils ];
15 };
16
17 testScript = ''
18 CRED_NAME = "testkey"
19 CRED_RAW_FILE = f"/root/{CRED_NAME}"
20 CRED_FILE = f"/root/{CRED_NAME}.cred"
21
22 def systemd_run(machine, cmd):
23 machine.log(f"Executing command (via systemd-run): \"{cmd}\"")
24
25 (status, out) = machine.execute( " ".join([
26 "systemd-run",
27 "--service-type=exec",
28 "--quiet",
29 "--wait",
30 "-E PATH=\"$PATH\"",
31 "-p StandardOutput=journal",
32 "-p StandardError=journal",
33 f"-p LoadCredentialEncrypted={CRED_NAME}:{CRED_FILE}",
34 f"$SHELL -c '{cmd}'"
35 ]) )
36
37 if status != 0:
38 raise Exception(f"systemd_run failed (status {status})")
39
40 machine.log("systemd-run finished successfully")
41
42 machine.wait_for_unit("multi-user.target")
43
44 with subtest("Check whether TPM device exists"):
45 machine.succeed("test -e /dev/tpm0")
46 machine.succeed("test -e /dev/tpmrm0")
47
48 with subtest("Check whether systemd-creds detects TPM2 correctly"):
49 cmd = "systemd-creds has-tpm2"
50 machine.log(f"Running \"{cmd}\"")
51 (status, _) = machine.execute(cmd)
52
53 # Check exit code equals 0 or 1 (1 means firmware support is missing, which is OK here)
54 if status != 0 and status != 1:
55 raise Exception("systemd-creds failed to detect TPM2")
56
57 with subtest("Encrypt credential using systemd-creds"):
58 machine.succeed(f"dd if=/dev/urandom of={CRED_RAW_FILE} bs=1k count=16")
59 machine.succeed(f"systemd-creds --with-key=host+tpm2 encrypt --name=testkey {CRED_RAW_FILE} {CRED_FILE}")
60
61 with subtest("Write provided credential and check for equality"):
62 CRED_OUT_FILE = f"/root/{CRED_NAME}.out"
63 systemd_run(machine, f"systemd-creds cat testkey > {CRED_OUT_FILE}")
64 machine.succeed(f"cmp --silent -- {CRED_RAW_FILE} {CRED_OUT_FILE}")
65
66 with subtest("Check whether systemd service can see credential in systemd-creds list"):
67 systemd_run(machine, f"systemd-creds list | grep {CRED_NAME}")
68
69 with subtest("Check whether systemd service can access credential in $CREDENTIALS_DIRECTORY"):
70 systemd_run(machine, f"cmp --silent -- $CREDENTIALS_DIRECTORY/{CRED_NAME} {CRED_RAW_FILE}")
71 '';
72 }
73)