summaryrefslogtreecommitdiffstats
path: root/nixos/tests/aesmd.nix
blob: 2d51f2400817761851e1859fce3bdc17835f2cd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
{ pkgs, lib, ... }:
{
  name = "aesmd";
  meta = {
    maintainers = with lib.maintainers; [
      veehaitch
    ];
  };

  nodes.machine =
    { lib, ... }:
    {
      services.aesmd = {
        enable = true;
        settings = {
          defaultQuotingType = "ecdsa_256";
          qplLogLevel = "info";
          proxyType = "direct";
        };
      };

      # Should have access to the AESM socket
      users.users."sgxtest" = {
        isNormalUser = true;
        extraGroups = [ "sgx" ];
      };

      # Should NOT have access to the AESM socket
      users.users."nosgxtest".isNormalUser = true;

      # We don't have a real SGX machine in NixOS tests
      systemd.services.aesmd.unitConfig.AssertPathExists = lib.mkForce [ ];

      specialisation = {
        withQuoteProvider.configuration =
          { ... }:
          {
            services.aesmd = {
              quoteProviderLibrary = pkgs.sgx-azure-dcap-client;
              environment = {
                AZDCAP_DEBUG_LOG_LEVEL = "INFO";
              };
            };
          };
      };
    };

  testScript =
    { nodes, ... }:
    let
      specialisations = "${nodes.machine.system.build.toplevel}/specialisation";
    in
    ''
      def get_aesmd_pid():
        status, main_pid = machine.systemctl("show --property MainPID --value aesmd.service")
        assert status == 0, "Could not get MainPID of aesmd.service"
        return main_pid.strip()

      with subtest("aesmd.service starts"):
        machine.wait_for_unit("aesmd.service")

      main_pid = get_aesmd_pid()

      with subtest("aesmd.service runtime directory permissions"):
        runtime_dir = "/run/aesmd";
        res = machine.succeed(f"stat -c '%a %U %G' {runtime_dir}").strip()
        assert "750 aesmd sgx" == res, f"{runtime_dir} does not have the expected permissions: {res}"

      with subtest("aesm.socket available on host"):
        socket_path = "/var/run/aesmd/aesm.socket"
        machine.wait_until_succeeds(f"test -S {socket_path}")
        machine.succeed(f"test 777 -eq $(stat -c '%a' {socket_path})")
        for op in [ "-r", "-w", "-x" ]:
          machine.succeed(f"sudo -u sgxtest test {op} {socket_path}")
          machine.fail(f"sudo -u nosgxtest test {op} {socket_path}")

      with subtest("Creates aesmd data directory"):
        data_dir = "/var/opt/aesmd/data"
        data_dir_perms = machine.succeed(
          f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/stat -c '%a' {data_dir}"
        ).strip()
        assert data_dir_perms == "755", f"{data_dir} has permissions {data_dir_perms}"

      with subtest("Writes and binds aesm.conf in service namespace"):
        aesmd_config = machine.succeed(f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/cat /etc/aesmd.conf")
        expected = "default quoting type = ecdsa_256\nqpl log level = info\nproxy type = direct\n"
        assert aesmd_config == expected, f"aesmd.conf\n\nactual:\n{aesmd_config}\n---\n\nexpected:\n{expected}"

      with subtest("aesmd.service without quote provider library has correct LD_LIBRARY_PATH"):
        status, environment = machine.systemctl("show --property Environment --value aesmd.service")
        assert status == 0, "Could not get Environment of aesmd.service"
        env_by_name = dict(entry.split("=", 1) for entry in environment.split())
        assert not env_by_name["LD_LIBRARY_PATH"], "LD_LIBRARY_PATH is not empty"

      with subtest("aesmd.service with quote provider library starts"):
        machine.succeed('${specialisations}/withQuoteProvider/bin/switch-to-configuration test')
        machine.wait_for_unit("aesmd.service")

      main_pid = get_aesmd_pid()

      with subtest("aesmd.service with quote provider library has correct LD_LIBRARY_PATH"):
        ld_library_path = machine.succeed(f"xargs -0 -L1 -a /proc/{main_pid}/environ | grep LD_LIBRARY_PATH")
        assert ld_library_path.startswith("LD_LIBRARY_PATH=${pkgs.sgx-azure-dcap-client}/lib:"), \
          "LD_LIBRARY_PATH is not set to the configured quote provider library"

      with subtest("aesmd.service with quote provider library has set AZDCAP_DEBUG_LOG_LEVEL"):
        azdcp_debug_log_level = machine.succeed(f"xargs -0 -L1 -a /proc/{main_pid}/environ | grep AZDCAP_DEBUG_LOG_LEVEL")
        assert azdcp_debug_log_level == "AZDCAP_DEBUG_LOG_LEVEL=INFO\n", "AZDCAP_DEBUG_LOG_LEVEL is not set to INFO"
    '';
}