Merge pull request #203449 from yaxitech/azure-quote-provider

Sandro c8c8ac5c 33371086

Changed files
+210 -33
nixos
modules
services
security
tests
pkgs
os-specific
linux
sgx
azure-dcap-client
psw
top-level
+18 -3
nixos/modules/services/security/aesmd.nix
···
default = false;
description = lib.mdDoc "Whether to build the PSW package in debug mode.";
};
+
environment = mkOption {
+
type = with types; attrsOf str;
+
default = { };
+
description = mdDoc "Additional environment variables to pass to the AESM service.";
+
# Example environment variable for `sgx-azure-dcap-client` provider library
+
example = {
+
AZDCAP_COLLATERAL_VERSION = "v2";
+
AZDCAP_DEBUG_LOG_LEVEL = "INFO";
+
};
+
};
+
quoteProviderLibrary = mkOption {
+
type = with types; nullOr path;
+
default = null;
+
example = literalExpression "pkgs.sgx-azure-dcap-client";
+
description = lib.mdDoc "Custom quote provider library to use.";
+
};
settings = mkOption {
description = lib.mdDoc "AESM configuration";
default = { };
···
storeAesmFolder = "${sgx-psw}/aesm";
# Hardcoded path AESM_DATA_FOLDER in psw/ae/aesm_service/source/oal/linux/aesm_util.cpp
aesmDataFolder = "/var/opt/aesmd/data";
-
aesmStateDirSystemd = "%S/aesmd";
in
{
description = "Intel Architectural Enclave Service Manager";
···
environment = {
NAME = "aesm_service";
AESM_PATH = storeAesmFolder;
-
LD_LIBRARY_PATH = storeAesmFolder;
-
};
+
LD_LIBRARY_PATH = makeLibraryPath [ cfg.quoteProviderLibrary ];
+
} // cfg.environment;
# Make sure any of the SGX application enclave devices is available
unitConfig.AssertPathExists = [
+68 -28
nixos/tests/aesmd.nix
···
{ pkgs, lib, ... }: {
name = "aesmd";
meta = {
-
maintainers = with lib.maintainers; [ veehaitch ];
+
maintainers = with lib.maintainers; [ trundle veehaitch ];
};
nodes.machine = { lib, ... }: {
···
# 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 = ''
-
with subtest("aesmd.service starts"):
-
machine.wait_for_unit("aesmd.service")
-
status, main_pid = machine.systemctl("show --property MainPID --value aesmd.service")
-
assert status == 0, "Could not get MainPID of aesmd.service"
-
main_pid = main_pid.strip()
+
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 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("aesmd.service starts"):
+
machine.wait_for_unit("aesmd.service")
-
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}")
+
main_pid = get_aesmd_pid()
-
with subtest("Copies white_list_cert_to_be_verify.bin"):
-
whitelist_path = "/var/opt/aesmd/data/white_list_cert_to_be_verify.bin"
-
whitelist_perms = machine.succeed(
-
f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/stat -c '%a' {whitelist_path}"
-
).strip()
-
assert "644" == whitelist_perms, f"white_list_cert_to_be_verify.bin has permissions {whitelist_perms}"
+
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("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")
+
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}")
-
assert aesmd_config == "whitelist url = http://nixos.org\nproxy type = direct\ndefault quoting type = ecdsa_256\n", "aesmd.conf differs"
-
'';
+
with subtest("Copies white_list_cert_to_be_verify.bin"):
+
whitelist_path = "/var/opt/aesmd/data/white_list_cert_to_be_verify.bin"
+
whitelist_perms = machine.succeed(
+
f"nsenter -m -t {main_pid} ${pkgs.coreutils}/bin/stat -c '%a' {whitelist_path}"
+
).strip()
+
assert "644" == whitelist_perms, f"white_list_cert_to_be_verify.bin has permissions {whitelist_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")
+
+
assert aesmd_config == "whitelist url = http://nixos.org\nproxy type = direct\ndefault quoting type = ecdsa_256\n", "aesmd.conf differs"
+
+
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"
+
'';
}
+1 -1
nixos/tests/all-tests.nix
···
_3proxy = runTest ./3proxy.nix;
acme = runTest ./acme.nix;
adguardhome = runTest ./adguardhome.nix;
-
aesmd = runTest ./aesmd.nix;
+
aesmd = runTestOn ["x86_64-linux"] ./aesmd.nix;
agate = runTest ./web-servers/agate.nix;
agda = handleTest ./agda.nix {};
airsonic = handleTest ./airsonic.nix {};
+93
pkgs/os-specific/linux/sgx/azure-dcap-client/default.nix
···
+
{ stdenv
+
, fetchFromGitHub
+
, fetchurl
+
, lib
+
, curl
+
, nlohmann_json
+
, openssl
+
, pkg-config
+
, linkFarmFromDrvs
+
, callPackage
+
}:
+
+
let
+
# Although those headers are also included in the source of `sgx-psw`, the `azure-dcap-client` build needs specific versions
+
filterSparse = list: ''
+
cp -r "$out"/. .
+
find "$out" -mindepth 1 -delete
+
cp ${lib.concatStringsSep " " list} "$out/"
+
'';
+
headers = linkFarmFromDrvs "azure-dcpa-client-intel-headers" [
+
(fetchFromGitHub rec {
+
name = "${repo}-headers";
+
owner = "intel";
+
repo = "SGXDataCenterAttestationPrimitives";
+
rev = "0436284f12f1bd5da7e7a06f6274d36b4c8d39f9";
+
sparseCheckout = [ "QuoteGeneration/quote_wrapper/common/inc/sgx_ql_lib_common.h" ];
+
hash = "sha256-ipKpYHbiwjCUXF/pCArJZy5ko1YX2wqMMdSnMUzhkgY=";
+
postFetch = filterSparse sparseCheckout;
+
})
+
(fetchFromGitHub rec {
+
name = "${repo}-headers";
+
owner = "intel";
+
repo = "linux-sgx";
+
rev = "1ccf25b64abd1c2eff05ead9d14b410b3c9ae7be";
+
hash = "sha256-WJRoS6+NBVJrFmHABEEDpDhW+zbWFUl65AycCkRavfs=";
+
sparseCheckout = [
+
"common/inc/sgx_report.h"
+
"common/inc/sgx_key.h"
+
"common/inc/sgx_attributes.h"
+
];
+
postFetch = filterSparse sparseCheckout;
+
})
+
];
+
in
+
stdenv.mkDerivation rec {
+
pname = "azure-dcap-client";
+
version = "1.11.2";
+
+
src = fetchFromGitHub {
+
owner = "microsoft";
+
repo = pname;
+
rev = version;
+
hash = "sha256-EYj3jnzTyJRl6N7avNf9VrB8r9U6zIE6wBNeVsMtWCA=";
+
};
+
+
nativeBuildInputs = [
+
pkg-config
+
];
+
+
buildInputs = [
+
curl
+
nlohmann_json
+
openssl
+
];
+
+
postPatch = ''
+
mkdir -p src/Linux/ext/intel
+
find -L '${headers}' -type f -exec ln -s {} src/Linux/ext/intel \;
+
+
substitute src/Linux/Makefile{.in,} \
+
--replace '##CURLINC##' '${curl.dev}/include/curl/' \
+
--replace '$(TEST_SUITE): $(PROVIDER_LIB) $(TEST_SUITE_OBJ)' '$(TEST_SUITE): $(TEST_SUITE_OBJ)'
+
'';
+
+
NIX_CFLAGS_COMPILE = "-Wno-deprecated-declarations";
+
+
makeFlags = [
+
"-C src/Linux"
+
"prefix=$(out)"
+
];
+
+
# Online test suite; run with
+
# $(nix-build -A sgx-azure-dcap-client.tests.suite)/bin/tests
+
passthru.tests.suite = callPackage ./test-suite.nix { };
+
+
meta = with lib; {
+
description = "Interfaces between SGX SDKs and the Azure Attestation SGX Certification Cache";
+
homepage = "https://github.com/microsoft/azure-dcap-client";
+
maintainers = with maintainers; [ trundle veehaitch ];
+
platforms = [ "x86_64-linux" ];
+
license = [ licenses.mit ];
+
};
+
}
+27
pkgs/os-specific/linux/sgx/azure-dcap-client/test-suite.nix
···
+
{ lib
+
, sgx-azure-dcap-client
+
, gtest
+
, makeWrapper
+
}:
+
sgx-azure-dcap-client.overrideAttrs (oldAttrs: {
+
nativeBuildInputs = oldAttrs.nativeBuildInputs ++ [
+
makeWrapper
+
gtest
+
];
+
+
buildFlags = [
+
"tests"
+
];
+
+
installPhase = ''
+
runHook preInstall
+
+
install -D ./src/Linux/tests "$out/bin/tests"
+
+
runHook postInstall
+
'';
+
+
postFixup = ''
+
wrapProgram "$out/bin/tests" --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ sgx-azure-dcap-client ]}"
+
'';
+
})
+1 -1
pkgs/os-specific/linux/sgx/psw/default.nix
···
mkdir $out/bin
makeWrapper $out/aesm/aesm_service $out/bin/aesm_service \
-
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ protobuf ]}:$out/aesm \
+
--suffix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ protobuf ]}:$out/aesm \
--chdir "$out/aesm"
# Make sure we didn't forget to handle any files
+2
pkgs/top-level/all-packages.nix
···
seturgent = callPackage ../os-specific/linux/seturgent { };
+
sgx-azure-dcap-client = callPackage ../os-specific/linux/sgx/azure-dcap-client { };
+
sgx-sdk = callPackage ../os-specific/linux/sgx/sdk { };
sgx-ssl = callPackage ../os-specific/linux/sgx/ssl { };