mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-03-26 21:33:25 +00:00
luks_device: add support for tpm2 and keyslot priority (#972)
* luks_device: add support for tpm2 and fido2 devices * Update documentation per code review comments Co-authored-by: Felix Fontein <felix@fontein.de> * Add support for keyslot priority * Add changelog fragment. * Remove fido2 support. Add idempotency for remove-tpm2 * Fix testing * Fix testing again * Fix formatting * Fix format * Apply suggestions from code review Co-authored-by: Felix Fontein <felix@fontein.de> * Add required_by and fix formatting * vscode did something stupid... * Address code review comments --------- Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
@@ -98,7 +98,6 @@ LUKS_CREATE_DATA: list[
|
||||
("dummy", "key", None, "present", False, None, "dummy", "dummy", True),
|
||||
(None, "key", None, "present", False, None, "dummy", "dummy", False),
|
||||
(None, "key", None, "present", False, "labelName", "dummy", "dummy", True),
|
||||
("dummy", None, None, "present", False, None, "dummy", "dummy", False),
|
||||
("dummy", "key", None, "absent", False, None, "dummy", "dummy", False),
|
||||
("dummy", "key", None, "opened", True, None, "dummy", "dummy", False),
|
||||
("dummy", "key", None, "closed", True, None, "dummy", "dummy", False),
|
||||
@@ -106,7 +105,6 @@ LUKS_CREATE_DATA: list[
|
||||
("dummy", None, "foo", "present", False, None, "dummy", "dummy", True),
|
||||
(None, None, "bar", "present", False, None, "dummy", "dummy", False),
|
||||
(None, None, "baz", "present", False, "labelName", "dummy", "dummy", True),
|
||||
("dummy", None, None, "present", False, None, "dummy", "dummy", False),
|
||||
("dummy", None, "quz", "absent", False, None, "dummy", "dummy", False),
|
||||
("dummy", None, "qux", "opened", True, None, "dummy", "dummy", False),
|
||||
("dummy", None, "quux", "closed", True, None, "dummy", "dummy", False),
|
||||
@@ -114,6 +112,11 @@ LUKS_CREATE_DATA: list[
|
||||
("dummy", "key", None, "present", False, None, None, None, True),
|
||||
("dummy", "key", None, "present", False, None, None, "dummy", True),
|
||||
("dummy", "key", None, "present", False, None, "dummy", None, True),
|
||||
("dummy", None, None, "present", False, None, "dummy", None, "exception"),
|
||||
("dummy", None, None, "opened", False, None, "dummy", None, "exception"),
|
||||
("dummy", None, None, "closed", False, None, "dummy", None, "exception"),
|
||||
("dummy", None, None, "absent", False, None, "dummy", None, False),
|
||||
("dummy", None, None, "opened", True, None, "dummy", None, False),
|
||||
]
|
||||
|
||||
# device, state, is_luks, expected
|
||||
@@ -131,34 +134,35 @@ LUKS_REMOVE_DATA: list[
|
||||
("dummy", "absent", False, False),
|
||||
]
|
||||
|
||||
# device, key, passphrase, state, name, name_by_dev, expected
|
||||
# device, key, passphrase, tpm2_device, state, name, name_by_dev, expected
|
||||
LUKS_OPEN_DATA: list[
|
||||
tuple[
|
||||
str | None,
|
||||
str | None,
|
||||
str | None,
|
||||
str | None,
|
||||
t.Literal["present", "absent", "opened", "closed"],
|
||||
str | None,
|
||||
str | None,
|
||||
bool | t.Literal["exception"],
|
||||
]
|
||||
] = [
|
||||
("dummy", "key", None, "present", "name", None, False),
|
||||
("dummy", "key", None, "absent", "name", None, False),
|
||||
("dummy", "key", None, "closed", "name", None, False),
|
||||
("dummy", "key", None, "opened", "name", None, True),
|
||||
(None, "key", None, "opened", "name", None, False),
|
||||
("dummy", None, None, "opened", "name", None, False),
|
||||
("dummy", "key", None, "opened", "name", "name", False),
|
||||
("dummy", "key", None, "opened", "beer", "name", "exception"),
|
||||
("dummy", None, "foo", "present", "name", None, False),
|
||||
("dummy", None, "bar", "absent", "name", None, False),
|
||||
("dummy", None, "baz", "closed", "name", None, False),
|
||||
("dummy", None, "qux", "opened", "name", None, True),
|
||||
(None, None, "quux", "opened", "name", None, False),
|
||||
("dummy", None, None, "opened", "name", None, False),
|
||||
("dummy", None, "quuz", "opened", "name", "name", False),
|
||||
("dummy", None, "corge", "opened", "beer", "name", "exception"),
|
||||
("dummy", "key", None, None, "present", "name", None, False),
|
||||
("dummy", "key", None, None, "absent", "name", None, False),
|
||||
("dummy", "key", None, None, "closed", "name", None, False),
|
||||
("dummy", "key", None, None, "opened", "name", None, True),
|
||||
(None, "key", None, None, "opened", "name", None, False),
|
||||
("dummy", "key", None, None, "opened", "name", "name", False),
|
||||
("dummy", "key", None, None, "opened", "beer", "name", "exception"),
|
||||
("dummy", None, "foo", None, "present", "name", None, False),
|
||||
("dummy", None, "bar", None, "absent", "name", None, False),
|
||||
("dummy", None, "baz", None, "closed", "name", None, False),
|
||||
("dummy", None, "qux", None, "opened", "name", None, True),
|
||||
(None, None, "quux", None, "opened", "name", None, False),
|
||||
("dummy", None, "quuz", None, "opened", "name", "name", False),
|
||||
("dummy", None, "corge", None, "opened", "beer", "name", "exception"),
|
||||
("dummy", None, None, None, "opened", "name", None, "exception"),
|
||||
("dummy", None, None, "auto", "opened", "name", None, True),
|
||||
]
|
||||
|
||||
# device, dev_by_name, name, name_by_dev, state, label, expected
|
||||
@@ -237,6 +241,42 @@ LUKS_REMOVE_KEY_DATA: list[
|
||||
("dummy", None, "foo", None, "absent", None, "exception"),
|
||||
]
|
||||
|
||||
# device, new_tpm2, new_tpm2_pcrs, remove_tpm2, existing_tpm2, expected
|
||||
SYSTEMD_CRYPTENROLL_DATA: list[
|
||||
tuple[
|
||||
str | None,
|
||||
str | None,
|
||||
str | None,
|
||||
bool,
|
||||
bool,
|
||||
bool | t.Literal["exception"],
|
||||
]
|
||||
] = [
|
||||
("dummy", None, None, False, False, False),
|
||||
("dummy", None, None, False, True, False),
|
||||
("dummy", None, None, True, False, False),
|
||||
("dummy", None, None, True, True, True),
|
||||
("dummy", "auto", "0+1", False, False, True),
|
||||
("dummy", "auto", "0+1", True, False, True),
|
||||
("dummy", "auto", None, False, False, "exception"),
|
||||
]
|
||||
|
||||
# device, keyslot_priority, existing_priority, expected
|
||||
LUKS_CONFIG_DATA: list[
|
||||
tuple[str | None, str | None, int | None, bool | t.Literal["exception"]]
|
||||
] = [
|
||||
("dummy", "prefer", 0, True),
|
||||
("dummy", "prefer", None, True),
|
||||
("dummy", "prefer", 2, False),
|
||||
("dummy", "normal", 0, True),
|
||||
("dummy", "normal", None, False),
|
||||
("dummy", "normal", 2, True),
|
||||
("dummy", "ignore", 0, False),
|
||||
("dummy", "ignore", None, True),
|
||||
("dummy", "ignore", 2, True),
|
||||
(None, "normal", 0, False),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device, keyfile, passphrase, state, is_luks, " + "label, cipher, hash_, expected",
|
||||
@@ -307,13 +347,14 @@ def test_luks_remove(
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device, keyfile, passphrase, state, name, name_by_dev, expected",
|
||||
((d[0], d[1], d[2], d[3], d[4], d[5], d[6]) for d in LUKS_OPEN_DATA),
|
||||
"device, keyfile, passphrase, tpm2_device, state, name, name_by_dev, expected",
|
||||
((d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]) for d in LUKS_OPEN_DATA),
|
||||
)
|
||||
def test_luks_open(
|
||||
device: str | None,
|
||||
keyfile: str | None,
|
||||
passphrase: str | None,
|
||||
tpm2_device: str | None,
|
||||
state: t.Literal["present", "absent", "opened", "closed"],
|
||||
name: str | None,
|
||||
name_by_dev: str | None,
|
||||
@@ -324,6 +365,7 @@ def test_luks_open(
|
||||
module.params["device"] = device
|
||||
module.params["keyfile"] = keyfile
|
||||
module.params["passphrase"] = passphrase
|
||||
module.params["tpm2_device"] = tpm2_device
|
||||
module.params["passphrase_encoding"] = "text"
|
||||
module.params["state"] = state
|
||||
module.params["name"] = name
|
||||
@@ -468,3 +510,86 @@ def test_luks_remove_key(
|
||||
assert conditions.luks_remove_key() == expected
|
||||
except ValueError:
|
||||
assert expected == "exception"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device, new_tpm2, new_tpm2_pcrs, remove_tpm2, existing_tpm2, expected",
|
||||
((d[0], d[1], d[2], d[3], d[4], d[5]) for d in SYSTEMD_CRYPTENROLL_DATA),
|
||||
)
|
||||
def test_systemd_cryptenroll(
|
||||
device: str | None,
|
||||
new_tpm2: str | None,
|
||||
new_tpm2_pcrs: str | None,
|
||||
remove_tpm2: bool,
|
||||
existing_tpm2: bool,
|
||||
expected: bool | t.Literal["exception"],
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
module = DummyModule()
|
||||
|
||||
module.params["device"] = device
|
||||
module.params["passphrase_encoding"] = "text"
|
||||
module.params["new_tpm2"] = new_tpm2
|
||||
module.params["new_tpm2_pcrs"] = new_tpm2_pcrs
|
||||
module.params["remove_tpm2"] = remove_tpm2
|
||||
|
||||
crypt = luks_device.CryptHandler(module) # type: ignore
|
||||
|
||||
def mock_luks_dump_json_metadata(
|
||||
self: luks_device.CryptHandler, device: str
|
||||
) -> dict[str, t.Any]:
|
||||
return (
|
||||
{"tokens": {"0": {"type": "systemd-tpm2"}}}
|
||||
if existing_tpm2
|
||||
else {"tokens": {}}
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
luks_device.CryptHandler,
|
||||
"luks_dump_json_metadata",
|
||||
mock_luks_dump_json_metadata,
|
||||
)
|
||||
|
||||
try:
|
||||
conditions = luks_device.ConditionsHandler(module, crypt) # type: ignore
|
||||
assert conditions.systemd_cryptenroll() == expected
|
||||
except ValueError:
|
||||
assert expected == "exception"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device, keyslot_priority, existing_priority, expected",
|
||||
((d[0], d[1], d[2], d[3]) for d in LUKS_CONFIG_DATA),
|
||||
)
|
||||
def test_luks_config(
|
||||
device: str | None,
|
||||
keyslot_priority: str | None,
|
||||
existing_priority: int | None,
|
||||
expected: bool | t.Literal["exception"],
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
module = DummyModule()
|
||||
|
||||
module.params["device"] = device
|
||||
module.params["passphrase_encoding"] = "text"
|
||||
module.params["keyslot"] = 1
|
||||
module.params["keyslot_priority"] = keyslot_priority
|
||||
|
||||
crypt = luks_device.CryptHandler(module) # type: ignore
|
||||
|
||||
def mock_luks_dump_json_metadata(
|
||||
self: luks_device.CryptHandler, device: str
|
||||
) -> dict[str, t.Any]:
|
||||
return {"keyslots": {"1": {"priority": existing_priority}}}
|
||||
|
||||
monkeypatch.setattr(
|
||||
luks_device.CryptHandler,
|
||||
"luks_dump_json_metadata",
|
||||
mock_luks_dump_json_metadata,
|
||||
)
|
||||
|
||||
try:
|
||||
conditions = luks_device.ConditionsHandler(module, crypt) # type: ignore
|
||||
assert conditions.luks_config() == expected
|
||||
except ValueError:
|
||||
assert expected == "exception"
|
||||
|
||||
Reference in New Issue
Block a user