diff --git a/taf/tests/tuf/test_create_edit_repo/conftest.py b/taf/tests/tuf/test_create_edit_repo/conftest.py index 574a3d30..a7bff043 100644 --- a/taf/tests/tuf/test_create_edit_repo/conftest.py +++ b/taf/tests/tuf/test_create_edit_repo/conftest.py @@ -1,3 +1,6 @@ +import shutil + +from taf.utils import on_rm_error import pytest from taf.models.converter import from_dict from taf.models.types import RolesKeysData @@ -12,3 +15,4 @@ def tuf_repo( roles_keys_data = from_dict(with_delegations_no_yubikeys_input, RolesKeysData) repo.create(roles_keys_data, signers_with_delegations) yield repo + shutil.rmtree(tuf_repo_path, onerror=on_rm_error) diff --git a/taf/tests/tuf/test_create_edit_repo/test_keys.py b/taf/tests/tuf/test_create_edit_repo/test_keys.py deleted file mode 100644 index 718a826a..00000000 --- a/taf/tests/tuf/test_create_edit_repo/test_keys.py +++ /dev/null @@ -1,252 +0,0 @@ -from taf.tuf.keys import _get_legacy_keyid - - -def test_add_metadata_keys(tuf_repo, signers_with_delegations, public_keys): - - # there public keys were loaded from a different keystore - # (are used to instantiate a repositoru with no delegations) - - new_targets_key = public_keys["targets"][0] - new_snapshot_key = public_keys["snapshot"][0] - new_delegated_key = new_targets_key - - roles_keys = { - "targets": [new_targets_key], - "delegated_role": [new_delegated_key], - "snapshot": [new_snapshot_key], - } - - tuf_repo.add_signers_to_cache(signers_with_delegations) - added_keys, already_added_keys, invalid_keys = tuf_repo.add_metadata_keys( - roles_keys - ) - assert len(added_keys) == 3 - assert len(already_added_keys) == 0 - assert len(invalid_keys) == 0 - - assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().roles["targets"].keyids - assert ( - _get_legacy_keyid(new_snapshot_key) in tuf_repo.root().roles["snapshot"].keyids - ) - assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().keys - assert _get_legacy_keyid(new_snapshot_key) in tuf_repo.root().keys - assert ( - _get_legacy_keyid(new_delegated_key) - in tuf_repo._role_obj("delegated_role").keyids - ) - assert tuf_repo.root().version == 2 - assert tuf_repo.targets().version == 2 - - assert tuf_repo.snapshot().version == 1 - assert tuf_repo._signed_obj("delegated_role").version == 1 - assert tuf_repo.timestamp().snapshot_meta.version == 1 - assert tuf_repo.snapshot().meta["root.json"].version == 1 - assert tuf_repo.snapshot().meta["targets.json"].version == 1 - - tuf_repo.update_snapshot_and_timestamp() - assert tuf_repo.snapshot().version == 2 - assert tuf_repo._signed_obj("delegated_role").version == 1 - assert tuf_repo.timestamp().snapshot_meta.version == 2 - assert tuf_repo.snapshot().meta["root.json"].version == 2 - assert tuf_repo.snapshot().meta["targets.json"].version == 2 - - new_root_key = public_keys["root"][0] - roles_keys = { - "root": [new_root_key], - } - # assert add new root key and version bumps (all but targets) - tuf_repo.add_metadata_keys(roles_keys) - - assert _get_legacy_keyid(new_root_key) in tuf_repo.root().roles["root"].keyids - assert _get_legacy_keyid(new_root_key) in tuf_repo.root().keys - assert tuf_repo.root().version == 3 - assert tuf_repo.targets().version == 2 - - assert tuf_repo.snapshot().version == 2 - assert tuf_repo.timestamp().snapshot_meta.version == 2 - assert tuf_repo.snapshot().meta["root.json"].version == 2 - assert tuf_repo.snapshot().meta["targets.json"].version == 2 - - tuf_repo.update_snapshot_and_timestamp() - assert tuf_repo.snapshot().version == 3 - assert tuf_repo.timestamp().snapshot_meta.version == 3 - assert tuf_repo.snapshot().meta["root.json"].version == 3 - assert tuf_repo.snapshot().meta["targets.json"].version == 2 - - # assert add new timestamp key and version bumps (all but targets) - new_timestamp_key = public_keys["timestamp"][0] - roles_keys = { - "timestamp": [new_timestamp_key], - } - # assert add new root key and version bumps (all but targets) - tuf_repo.add_metadata_keys(roles_keys) - tuf_repo.update_snapshot_and_timestamp() - - assert ( - _get_legacy_keyid(new_timestamp_key) - in tuf_repo.root().roles["timestamp"].keyids - ) - assert _get_legacy_keyid(new_timestamp_key) in tuf_repo.root().keys - assert tuf_repo.root().version == 4 - assert tuf_repo.timestamp().version == 4 - assert tuf_repo.snapshot().version == 4 - assert tuf_repo.targets().version == 2 - assert tuf_repo.timestamp().snapshot_meta.version == 4 - assert tuf_repo.snapshot().meta["root.json"].version == 4 - assert tuf_repo.snapshot().meta["targets.json"].version == 2 - - # assert add new timestamp key and version bumps (all but targets) - new_snapshot_key = public_keys["timestamp"][ - 0 - ] # make sure this key was not already added - roles_keys = { - "snapshot": [new_snapshot_key], - } - # assert add new root key and version bumps (all but targets) - tuf_repo.add_metadata_keys(roles_keys) - tuf_repo.update_snapshot_and_timestamp() - - assert ( - _get_legacy_keyid(new_snapshot_key) in tuf_repo.root().roles["snapshot"].keyids - ) - assert _get_legacy_keyid(new_snapshot_key) in tuf_repo.root().keys - assert tuf_repo.root().version == 5 - assert tuf_repo.snapshot().version == 5 - assert tuf_repo.snapshot().version == 5 - assert tuf_repo.targets().version == 2 - assert tuf_repo.snapshot().meta["root.json"].version == 5 - assert tuf_repo.snapshot().meta["targets.json"].version == 2 - - # assert add new timestamp key and version bumps (all but targets) - new_targets_key = public_keys["root"][1] - roles_keys = { - "targets": [new_targets_key], - } - # assert add new root key and version bumps (all but targets) - tuf_repo.add_metadata_keys(roles_keys) - tuf_repo.update_snapshot_and_timestamp() - - assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().roles["targets"].keyids - assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().keys - assert tuf_repo.root().version == 6 - assert tuf_repo.timestamp().version == 6 - assert tuf_repo.snapshot().version == 6 - assert tuf_repo.targets().version == 2 - assert tuf_repo.snapshot().meta["root.json"].version == 6 - assert tuf_repo.snapshot().meta["targets.json"].version == 2 - - # try adding again, the metadata should not be updated - tuf_repo.add_metadata_keys(roles_keys) - tuf_repo.update_snapshot_and_timestamp() - - assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().roles["targets"].keyids - assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().keys - assert tuf_repo.root().version == 6 - assert tuf_repo.timestamp().version == 7 - assert tuf_repo.snapshot().version == 7 - assert tuf_repo.targets().version == 2 - assert tuf_repo.snapshot().meta["root.json"].version == 6 - assert tuf_repo.snapshot().meta["targets.json"].version == 2 - - -def test_revoke_metadata_key( - tuf_repo, signers_with_delegations, public_keys_with_delegations, public_keys -): - tuf_repo.add_signers_to_cache(signers_with_delegations) - targets_key1 = public_keys_with_delegations["targets"][0] - targets_key2 = public_keys_with_delegations["targets"][1] - targets_key1_id = _get_legacy_keyid(targets_key1) - targets_key2_id = _get_legacy_keyid(targets_key2) - - assert targets_key1_id in tuf_repo.root().roles["targets"].keyids - assert targets_key1_id in tuf_repo.root().keys - - ( - removed_from_roles, - not_added_roles, - less_than_threshold_roles, - ) = tuf_repo.revoke_metadata_key(targets_key1_id, ["targets"]) - assert len(removed_from_roles) == 1 - assert len(not_added_roles) == 0 - assert len(less_than_threshold_roles) == 0 - - assert targets_key1_id not in tuf_repo.root().roles["targets"].keyids - assert targets_key1_id not in tuf_repo.root().keys - assert len(tuf_repo._role_obj("targets").keyids) == 1 - assert tuf_repo.root().version == 2 - assert tuf_repo.targets().version == 1 - - assert tuf_repo.timestamp().version == 1 - assert tuf_repo.snapshot().version == 1 - - tuf_repo.update_snapshot_and_timestamp() - assert tuf_repo.timestamp().version == 2 - assert tuf_repo.snapshot().version == 2 - # the second key cannot be removed because there is only one key left now - ( - removed_from_roles, - not_added_roles, - less_than_threshold_roles, - ) = tuf_repo.revoke_metadata_key(targets_key2_id, ["targets"]) - - assert targets_key2_id in tuf_repo.root().roles["targets"].keyids - assert targets_key2_id in tuf_repo.root().keys - assert len(removed_from_roles) == 0 - assert len(not_added_roles) == 0 - assert len(less_than_threshold_roles) == 1 - - # try to remove key - # will not be possible, number == threshold - delegated_key1 = public_keys_with_delegations["delegated_role"][0] - delegated_key1_id = _get_legacy_keyid(delegated_key1) - - assert tuf_repo.root().version == 2 - assert tuf_repo.timestamp().version == 2 - assert tuf_repo.snapshot().version == 2 - assert tuf_repo.targets().version == 1 - - assert delegated_key1_id in tuf_repo._role_obj("delegated_role").keyids - ( - removed_from_roles, - not_added_roles, - less_than_threshold_roles, - ) = tuf_repo.revoke_metadata_key(delegated_key1_id, ["delegated_role"]) - assert len(removed_from_roles) == 0 - assert len(not_added_roles) == 0 - assert len(less_than_threshold_roles) == 1 - assert delegated_key1_id in tuf_repo._role_obj("delegated_role").keyids - - # add a key - new_delegated_key = public_keys["targets"][0] - - roles_keys = { - "delegated_role": [new_delegated_key], - } - new_delegated_key_id = _get_legacy_keyid(new_delegated_key) - - tuf_repo.add_metadata_keys(roles_keys) - tuf_repo.update_snapshot_and_timestamp() - assert new_delegated_key_id in tuf_repo._role_obj("delegated_role").keyids - - assert tuf_repo.root().version == 2 - assert tuf_repo.timestamp().version == 3 - assert tuf_repo.snapshot().version == 3 - assert tuf_repo.targets().version == 2 - - assert delegated_key1_id in tuf_repo._role_obj("delegated_role").keyids - # now try removing one of delegated keys again - ( - removed_from_roles, - not_added_roles, - less_than_threshold_roles, - ) = tuf_repo.revoke_metadata_key(delegated_key1_id, ["delegated_role"]) - tuf_repo.update_snapshot_and_timestamp() - assert len(removed_from_roles) == 1 - assert len(not_added_roles) == 0 - assert len(less_than_threshold_roles) == 0 - assert delegated_key1_id not in tuf_repo._role_obj("delegated_role").keyids - - assert tuf_repo.root().version == 2 - assert tuf_repo.timestamp().version == 4 - assert tuf_repo.snapshot().version == 4 - assert tuf_repo.targets().version == 3 diff --git a/taf/tests/tuf/test_create_edit_repo/test_update.py b/taf/tests/tuf/test_create_edit_repo/test_update.py index 7f182bcb..f212b343 100644 --- a/taf/tests/tuf/test_create_edit_repo/test_update.py +++ b/taf/tests/tuf/test_create_edit_repo/test_update.py @@ -1,6 +1,7 @@ import datetime from taf.models.types import TargetsRole +from taf.tuf.keys import _get_legacy_keyid def test_update_expiration_date(tuf_repo, signers_with_delegations): @@ -81,3 +82,254 @@ def test_remove_delegated_paths(tuf_repo): path not in tuf_repo.get_delegations_of_role("targets")["delegated_role"].paths ) + + +def test_add_metadata_keys(tuf_repo, signers_with_delegations, public_keys): + + # there public keys were loaded from a different keystore + # (are used to instantiate a repositoru with no delegations) + + new_targets_key = public_keys["targets"][0] + new_snapshot_key = public_keys["snapshot"][0] + new_delegated_key = new_targets_key + + roles_keys = { + "targets": [new_targets_key], + "delegated_role": [new_delegated_key], + "snapshot": [new_snapshot_key], + } + + tuf_repo.add_signers_to_cache(signers_with_delegations) + added_keys, already_added_keys, invalid_keys = tuf_repo.add_metadata_keys( + roles_keys + ) + assert len(added_keys) == 3 + assert len(already_added_keys) == 0 + assert len(invalid_keys) == 0 + + assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().roles["targets"].keyids + assert ( + _get_legacy_keyid(new_snapshot_key) in tuf_repo.root().roles["snapshot"].keyids + ) + assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().keys + assert _get_legacy_keyid(new_snapshot_key) in tuf_repo.root().keys + assert ( + _get_legacy_keyid(new_delegated_key) + in tuf_repo._role_obj("delegated_role").keyids + ) + assert tuf_repo.root().version == 2 + assert tuf_repo.targets().version == 2 + + assert tuf_repo.snapshot().version == 1 + assert tuf_repo._signed_obj("delegated_role").version == 1 + assert tuf_repo.timestamp().snapshot_meta.version == 1 + assert tuf_repo.snapshot().meta["root.json"].version == 1 + assert tuf_repo.snapshot().meta["targets.json"].version == 1 + + tuf_repo.update_snapshot_and_timestamp() + assert tuf_repo.snapshot().version == 2 + assert tuf_repo._signed_obj("delegated_role").version == 1 + assert tuf_repo.timestamp().snapshot_meta.version == 2 + assert tuf_repo.snapshot().meta["root.json"].version == 2 + assert tuf_repo.snapshot().meta["targets.json"].version == 2 + + new_root_key = public_keys["root"][0] + roles_keys = { + "root": [new_root_key], + } + # assert add new root key and version bumps (all but targets) + tuf_repo.add_metadata_keys(roles_keys) + + assert _get_legacy_keyid(new_root_key) in tuf_repo.root().roles["root"].keyids + assert _get_legacy_keyid(new_root_key) in tuf_repo.root().keys + assert tuf_repo.root().version == 3 + assert tuf_repo.targets().version == 2 + + assert tuf_repo.snapshot().version == 2 + assert tuf_repo.timestamp().snapshot_meta.version == 2 + assert tuf_repo.snapshot().meta["root.json"].version == 2 + assert tuf_repo.snapshot().meta["targets.json"].version == 2 + + tuf_repo.update_snapshot_and_timestamp() + assert tuf_repo.snapshot().version == 3 + assert tuf_repo.timestamp().snapshot_meta.version == 3 + assert tuf_repo.snapshot().meta["root.json"].version == 3 + assert tuf_repo.snapshot().meta["targets.json"].version == 2 + + # assert add new timestamp key and version bumps (all but targets) + new_timestamp_key = public_keys["timestamp"][0] + roles_keys = { + "timestamp": [new_timestamp_key], + } + # assert add new root key and version bumps (all but targets) + tuf_repo.add_metadata_keys(roles_keys) + tuf_repo.update_snapshot_and_timestamp() + + assert ( + _get_legacy_keyid(new_timestamp_key) + in tuf_repo.root().roles["timestamp"].keyids + ) + assert _get_legacy_keyid(new_timestamp_key) in tuf_repo.root().keys + assert tuf_repo.root().version == 4 + assert tuf_repo.timestamp().version == 4 + assert tuf_repo.snapshot().version == 4 + assert tuf_repo.targets().version == 2 + assert tuf_repo.timestamp().snapshot_meta.version == 4 + assert tuf_repo.snapshot().meta["root.json"].version == 4 + assert tuf_repo.snapshot().meta["targets.json"].version == 2 + + # assert add new timestamp key and version bumps (all but targets) + new_snapshot_key = public_keys["timestamp"][ + 0 + ] # make sure this key was not already added + roles_keys = { + "snapshot": [new_snapshot_key], + } + # assert add new root key and version bumps (all but targets) + tuf_repo.add_metadata_keys(roles_keys) + tuf_repo.update_snapshot_and_timestamp() + + assert ( + _get_legacy_keyid(new_snapshot_key) in tuf_repo.root().roles["snapshot"].keyids + ) + assert _get_legacy_keyid(new_snapshot_key) in tuf_repo.root().keys + assert tuf_repo.root().version == 5 + assert tuf_repo.snapshot().version == 5 + assert tuf_repo.snapshot().version == 5 + assert tuf_repo.targets().version == 2 + assert tuf_repo.snapshot().meta["root.json"].version == 5 + assert tuf_repo.snapshot().meta["targets.json"].version == 2 + + # assert add new timestamp key and version bumps (all but targets) + new_targets_key = public_keys["root"][1] + roles_keys = { + "targets": [new_targets_key], + } + # assert add new root key and version bumps (all but targets) + tuf_repo.add_metadata_keys(roles_keys) + tuf_repo.update_snapshot_and_timestamp() + + assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().roles["targets"].keyids + assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().keys + assert tuf_repo.root().version == 6 + assert tuf_repo.timestamp().version == 6 + assert tuf_repo.snapshot().version == 6 + assert tuf_repo.targets().version == 2 + assert tuf_repo.snapshot().meta["root.json"].version == 6 + assert tuf_repo.snapshot().meta["targets.json"].version == 2 + + # try adding again, the metadata should not be updated + tuf_repo.add_metadata_keys(roles_keys) + tuf_repo.update_snapshot_and_timestamp() + + assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().roles["targets"].keyids + assert _get_legacy_keyid(new_targets_key) in tuf_repo.root().keys + assert tuf_repo.root().version == 6 + assert tuf_repo.timestamp().version == 7 + assert tuf_repo.snapshot().version == 7 + assert tuf_repo.targets().version == 2 + assert tuf_repo.snapshot().meta["root.json"].version == 6 + assert tuf_repo.snapshot().meta["targets.json"].version == 2 + + +def test_revoke_metadata_key( + tuf_repo, signers_with_delegations, public_keys_with_delegations, public_keys +): + tuf_repo.add_signers_to_cache(signers_with_delegations) + targets_key1 = public_keys_with_delegations["targets"][0] + targets_key2 = public_keys_with_delegations["targets"][1] + targets_key1_id = _get_legacy_keyid(targets_key1) + targets_key2_id = _get_legacy_keyid(targets_key2) + + assert targets_key1_id in tuf_repo.root().roles["targets"].keyids + assert targets_key1_id in tuf_repo.root().keys + + ( + removed_from_roles, + not_added_roles, + less_than_threshold_roles, + ) = tuf_repo.revoke_metadata_key(targets_key1_id, ["targets"]) + assert len(removed_from_roles) == 1 + assert len(not_added_roles) == 0 + assert len(less_than_threshold_roles) == 0 + + assert targets_key1_id not in tuf_repo.root().roles["targets"].keyids + assert targets_key1_id not in tuf_repo.root().keys + assert len(tuf_repo._role_obj("targets").keyids) == 1 + assert tuf_repo.root().version == 2 + assert tuf_repo.targets().version == 1 + + assert tuf_repo.timestamp().version == 1 + assert tuf_repo.snapshot().version == 1 + + tuf_repo.update_snapshot_and_timestamp() + assert tuf_repo.timestamp().version == 2 + assert tuf_repo.snapshot().version == 2 + # the second key cannot be removed because there is only one key left now + ( + removed_from_roles, + not_added_roles, + less_than_threshold_roles, + ) = tuf_repo.revoke_metadata_key(targets_key2_id, ["targets"]) + + assert targets_key2_id in tuf_repo.root().roles["targets"].keyids + assert targets_key2_id in tuf_repo.root().keys + assert len(removed_from_roles) == 0 + assert len(not_added_roles) == 0 + assert len(less_than_threshold_roles) == 1 + + # try to remove key + # will not be possible, number == threshold + delegated_key1 = public_keys_with_delegations["delegated_role"][0] + delegated_key1_id = _get_legacy_keyid(delegated_key1) + + assert tuf_repo.root().version == 2 + assert tuf_repo.timestamp().version == 2 + assert tuf_repo.snapshot().version == 2 + assert tuf_repo.targets().version == 1 + + assert delegated_key1_id in tuf_repo._role_obj("delegated_role").keyids + ( + removed_from_roles, + not_added_roles, + less_than_threshold_roles, + ) = tuf_repo.revoke_metadata_key(delegated_key1_id, ["delegated_role"]) + assert len(removed_from_roles) == 0 + assert len(not_added_roles) == 0 + assert len(less_than_threshold_roles) == 1 + assert delegated_key1_id in tuf_repo._role_obj("delegated_role").keyids + + # add a key + new_delegated_key = public_keys["targets"][0] + + roles_keys = { + "delegated_role": [new_delegated_key], + } + new_delegated_key_id = _get_legacy_keyid(new_delegated_key) + + tuf_repo.add_metadata_keys(roles_keys) + tuf_repo.update_snapshot_and_timestamp() + assert new_delegated_key_id in tuf_repo._role_obj("delegated_role").keyids + + assert tuf_repo.root().version == 2 + assert tuf_repo.timestamp().version == 3 + assert tuf_repo.snapshot().version == 3 + assert tuf_repo.targets().version == 2 + + assert delegated_key1_id in tuf_repo._role_obj("delegated_role").keyids + # now try removing one of delegated keys again + ( + removed_from_roles, + not_added_roles, + less_than_threshold_roles, + ) = tuf_repo.revoke_metadata_key(delegated_key1_id, ["delegated_role"]) + tuf_repo.update_snapshot_and_timestamp() + assert len(removed_from_roles) == 1 + assert len(not_added_roles) == 0 + assert len(less_than_threshold_roles) == 0 + assert delegated_key1_id not in tuf_repo._role_obj("delegated_role").keyids + + assert tuf_repo.root().version == 2 + assert tuf_repo.timestamp().version == 4 + assert tuf_repo.snapshot().version == 4 + assert tuf_repo.targets().version == 3 diff --git a/taf/tests/tuf/test_keys.py b/taf/tests/tuf/test_keys.py deleted file mode 100644 index 226c62b9..00000000 --- a/taf/tests/tuf/test_keys.py +++ /dev/null @@ -1,56 +0,0 @@ -import pytest - -from taf.tests.tuf import TEST_DATA_PATH -from taf.tuf.keys import load_public_key_from_file, load_signer_from_file -from tuf.api.metadata import Metadata, Root -from securesystemslib.exceptions import UnverifiedSignatureError - - -class TestKeys: - def test_keys(self): - """Smoke test for key functions. - - Test loading public and private keys, and compatiblity with existing - metadata: - - newly loaded keys can verify old signatures on metadata - - old keys in metadata can verify signatures from newly loaded signers - - """ - root_path = ( - TEST_DATA_PATH - / "repos" - / "test-repository-tool" - / "test-happy-path-pkcs1v15" - / "taf" - / "metadata" - / "root.json" - ) - - root = Metadata[Root].from_file(root_path) - store_path = TEST_DATA_PATH / "keystores" / "keystore" - for name in ["root1", "root2", "root3", "snapshot", "targets", "timestamp"]: - public_key = load_public_key_from_file(store_path / f"{name}.pub") - - # assert hard-coded scheme and correct legacy keyid - assert public_key.scheme == "rsa-pkcs1v15-sha256" - assert public_key.keyid in root.signed.keys - - signer = load_signer_from_file(store_path / name, None) - - # assert public key loaded from disk matches public key derived - # from private key loaded from disk - assert public_key == signer.public_key - - # assert existing keys verify new signatures - sig = signer.sign(b"DATA") - existing_key = root.signed.keys[public_key.keyid] - existing_key.verify_signature(sig, b"DATA") - with pytest.raises(UnverifiedSignatureError): - existing_key.verify_signature(sig, b"NOT DATA") - - # assert newly loaded keys verify existing signatures - if name.startswith("root"): # there are only root sigs on root metadata - existing_sig = root.signatures[public_key.keyid] - public_key.verify_signature(existing_sig, root.signed_bytes) - with pytest.raises(UnverifiedSignatureError): - existing_key.verify_signature(sig, b"NOT DATA") diff --git a/taf/tests/tuf/test_keys/conftest.py b/taf/tests/tuf/test_keys/conftest.py new file mode 100644 index 00000000..ae71d462 --- /dev/null +++ b/taf/tests/tuf/test_keys/conftest.py @@ -0,0 +1,18 @@ +import pytest +import shutil + +from taf.utils import on_rm_error +from taf.models.converter import from_dict +from taf.models.types import RolesKeysData +from taf.tuf.repository import MetadataRepository + + +@pytest.fixture(autouse=False) +def tuf_repo( + tuf_repo_path, signers_with_delegations, with_delegations_no_yubikeys_input +): + repo = MetadataRepository(tuf_repo_path) + roles_keys_data = from_dict(with_delegations_no_yubikeys_input, RolesKeysData) + repo.create(roles_keys_data, signers_with_delegations) + yield repo + shutil.rmtree(tuf_repo_path, onerror=on_rm_error) diff --git a/taf/tests/tuf/test_keys/test_keys.py b/taf/tests/tuf/test_keys/test_keys.py new file mode 100644 index 00000000..eb27649f --- /dev/null +++ b/taf/tests/tuf/test_keys/test_keys.py @@ -0,0 +1,51 @@ +import pytest +from tuf.api.metadata import Metadata, Root +from taf.tuf.keys import load_public_key_from_file, load_signer_from_file + +from securesystemslib.exceptions import UnverifiedSignatureError + + +def test_keys(tuf_repo, keystore_delegations): + """ + Test loading public and private keys, and compatiblity with existing + metadata: + - newly loaded keys can verify old signatures on metadata + - old keys in metadata can verify signatures from newly loaded signers + + """ + + root = Metadata[Root].from_file(tuf_repo.metadata_path / "root.json") + for name in [ + "root1", + "root2", + "root3", + "snapshot", + "targets1", + "targets2", + "timestamp", + ]: + public_key = load_public_key_from_file(keystore_delegations / f"{name}.pub") + + # assert hard-coded scheme and correct legacy keyid + assert public_key.scheme == "rsa-pkcs1v15-sha256" + assert public_key.keyid in root.signed.keys + + signer = load_signer_from_file(keystore_delegations / name, None) + + # assert public key loaded from disk matches public key derived + # from private key loaded from disk + assert public_key == signer.public_key + + # assert existing keys verify new signatures + sig = signer.sign(b"DATA") + existing_key = root.signed.keys[public_key.keyid] + existing_key.verify_signature(sig, b"DATA") + with pytest.raises(UnverifiedSignatureError): + existing_key.verify_signature(sig, b"NOT DATA") + + # assert newly loaded keys verify existing signatures + if name.startswith("root"): # there are only root sigs on root metadata + existing_sig = root.signatures[public_key.keyid] + public_key.verify_signature(existing_sig, root.signed_bytes) + with pytest.raises(UnverifiedSignatureError): + existing_key.verify_signature(sig, b"NOT DATA") diff --git a/taf/tests/tuf/test_keys/test_yk.py b/taf/tests/tuf/test_keys/test_yk.py new file mode 100644 index 00000000..30b8473d --- /dev/null +++ b/taf/tests/tuf/test_keys/test_yk.py @@ -0,0 +1,60 @@ +# """Test YkSigner""" + +# import os +# import pytest + +# from taf.tuf.keys import YkSigner + +# from securesystemslib.exceptions import UnverifiedSignatureError + + +# # Test data to sign +# _DATA = b"DATA" +# _NOT_DATA = b"NOT DATA" + +# # Test public key +# # >>> with open("taf/tests/data/keystores/keystore/root1.pub", "rb") as f: +# # >>> _PUB = f.read() +# _PUB = b"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5EGVh9xqVFFHnGGIofks\ncA3vHWFs1QP60QTX+ZJUPiUJdDb8wuJ6mu9d8bKojE3SEVHCLpJeV4+muMnLtZWq\nAipiuFUU9QDpOYaqQ5SD5n/9sZfiWDzjVsqZA4WMj0OCd/Bkn+umz3ljHFe0EJUE\nCxYRvmArC05UyJej7fCaQ/cD7QELrpmBaE2qLcG0Vfirz9NekaXixGiKNiIjHAj6\nYwIfES9SycVo42LEOskGFciqgfZJVtSaTIurW+KnOToStazEWY8okon91s+5ltIN\nOS68TtBLtph5PXcLhqSozE8SqMW3gZni6zXHHQtuouFLdGkgw+0V2YLX15Ka78zj\nhQIDAQAB\n-----END PUBLIC KEY-----" + +# # Test signature +# # >>> signer = load_signer_from_file("taf/tests/data/keystores/keystore/root1", None) +# # >>> sig = signer.sign(_DATA) +# # >>> _SIG = bytes.fromhex(sig.signature) +# _SIG = b"\xc1}\xaa\xec\xf6#;\xe6\x89\xc26\x81\x1a;\xd3\xb2\x7f\xce\xe3}\x9a6w}P\xe0d\x8d\xeb\xbcb\xba8\x8c\x96tS\xf2_\xf37\xe8Z\xc4\xf4\x1a\xaa\xdd\xdd%AB#w\x93\xc9\x0f\x8d\xe4\x93)\x9f\xa4)\x0b\xbb\xce\xf4\x9e\x8b\xaa\x1c\xda\xb8\x9ex\xe2\xc8\x9c\x02\\\xb7\x89\x88g\xd3\xb2\x0be\xf4S\x0c*\x0c\xce\xfe\x8aL=\x07\xfa\xe9\xa2\xe1\xed\x1cA\xf9\xbeZR\x91\xae@\x12\xfe\xbey`\x07 /)Z_\xd0\xca\x7f\xcey\xe6\x1ee~\x01\x0c\xcfQZ=a\xf6\xe9\xabm_\x12\x8e\xda\xb0\xd4\xaeb1W\x0e\xf0\x909\xae\x05}\x8f\xba\xf7\xa0\\Rx\xe9\x98\x0f4j86\x87\x17\xf5\xff\xc2U\x80oh\xad\xb2\xaf\xa5\x91\x9a\xafI,\xadj\xd5\x02$\xc6\xf8\xf2`y\xd2\xa6\xf3\xce[;\r\xb6y\xd4\xa5\x96y$}{!r\xc1\xfb@\x1e<\xd9\xa0\xe6\x7f\xf1\x17\xe5\x0c\x8e\xbd\xf3\xba" + + +# class TestYkSigner: +# """Test YkSigner""" + +# def test_fake_yk(self, monkeypatch): +# """Test public key export and signing with fake Yubikey.""" +# monkeypatch.setattr("taf.tuf.keys.export_piv_pub_key", lambda **kw: _PUB) +# monkeypatch.setattr("taf.tuf.keys.sign_piv_rsa_pkcs1v15", lambda *a, **kw: _SIG) + +# key = YkSigner.import_() +# signer = YkSigner(key, lambda sec: None) + +# sig = signer.sign(_DATA) +# key.verify_signature(sig, _DATA) +# with pytest.raises(UnverifiedSignatureError): +# key.verify_signature(sig, _NOT_DATA) + +# @pytest.mark.skipif( +# not os.environ.get("REAL_YK"), +# reason="Run test with REAL_YK=1 (test will prompt for pin)", +# ) +# def test_real_yk(self): +# """Test public key export and signing with real Yubikey.""" +# from getpass import getpass + +# def sec_handler(secret_name: str) -> str: +# return getpass(f"Enter {secret_name}: ") + +# key = YkSigner.import_() +# signer = YkSigner(key, sec_handler) + +# sig = signer.sign(_DATA) +# key.verify_signature(sig, _DATA) +# with pytest.raises(UnverifiedSignatureError): +# key.verify_signature(sig, _NOT_DATA) diff --git a/taf/tests/tuf/test_yk.py b/taf/tests/tuf/test_yk.py deleted file mode 100644 index 6b021a85..00000000 --- a/taf/tests/tuf/test_yk.py +++ /dev/null @@ -1,60 +0,0 @@ -"""Test YkSigner""" - -import os -import pytest - -from taf.tuf.keys import YkSigner - -from securesystemslib.exceptions import UnverifiedSignatureError - - -# Test data to sign -_DATA = b"DATA" -_NOT_DATA = b"NOT DATA" - -# Test public key -# >>> with open("taf/tests/data/keystores/keystore/root1.pub", "rb") as f: -# >>> _PUB = f.read() -_PUB = b"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5EGVh9xqVFFHnGGIofks\ncA3vHWFs1QP60QTX+ZJUPiUJdDb8wuJ6mu9d8bKojE3SEVHCLpJeV4+muMnLtZWq\nAipiuFUU9QDpOYaqQ5SD5n/9sZfiWDzjVsqZA4WMj0OCd/Bkn+umz3ljHFe0EJUE\nCxYRvmArC05UyJej7fCaQ/cD7QELrpmBaE2qLcG0Vfirz9NekaXixGiKNiIjHAj6\nYwIfES9SycVo42LEOskGFciqgfZJVtSaTIurW+KnOToStazEWY8okon91s+5ltIN\nOS68TtBLtph5PXcLhqSozE8SqMW3gZni6zXHHQtuouFLdGkgw+0V2YLX15Ka78zj\nhQIDAQAB\n-----END PUBLIC KEY-----" - -# Test signature -# >>> signer = load_signer_from_file("taf/tests/data/keystores/keystore/root1", None) -# >>> sig = signer.sign(_DATA) -# >>> _SIG = bytes.fromhex(sig.signature) -_SIG = b"\xc1}\xaa\xec\xf6#;\xe6\x89\xc26\x81\x1a;\xd3\xb2\x7f\xce\xe3}\x9a6w}P\xe0d\x8d\xeb\xbcb\xba8\x8c\x96tS\xf2_\xf37\xe8Z\xc4\xf4\x1a\xaa\xdd\xdd%AB#w\x93\xc9\x0f\x8d\xe4\x93)\x9f\xa4)\x0b\xbb\xce\xf4\x9e\x8b\xaa\x1c\xda\xb8\x9ex\xe2\xc8\x9c\x02\\\xb7\x89\x88g\xd3\xb2\x0be\xf4S\x0c*\x0c\xce\xfe\x8aL=\x07\xfa\xe9\xa2\xe1\xed\x1cA\xf9\xbeZR\x91\xae@\x12\xfe\xbey`\x07 /)Z_\xd0\xca\x7f\xcey\xe6\x1ee~\x01\x0c\xcfQZ=a\xf6\xe9\xabm_\x12\x8e\xda\xb0\xd4\xaeb1W\x0e\xf0\x909\xae\x05}\x8f\xba\xf7\xa0\\Rx\xe9\x98\x0f4j86\x87\x17\xf5\xff\xc2U\x80oh\xad\xb2\xaf\xa5\x91\x9a\xafI,\xadj\xd5\x02$\xc6\xf8\xf2`y\xd2\xa6\xf3\xce[;\r\xb6y\xd4\xa5\x96y$}{!r\xc1\xfb@\x1e<\xd9\xa0\xe6\x7f\xf1\x17\xe5\x0c\x8e\xbd\xf3\xba" - - -class TestYkSigner: - """Test YkSigner""" - - def test_fake_yk(self, monkeypatch): - """Test public key export and signing with fake Yubikey.""" - monkeypatch.setattr("taf.tuf.keys.export_piv_pub_key", lambda **kw: _PUB) - monkeypatch.setattr("taf.tuf.keys.sign_piv_rsa_pkcs1v15", lambda *a, **kw: _SIG) - - key = YkSigner.import_() - signer = YkSigner(key, lambda sec: None) - - sig = signer.sign(_DATA) - key.verify_signature(sig, _DATA) - with pytest.raises(UnverifiedSignatureError): - key.verify_signature(sig, _NOT_DATA) - - @pytest.mark.skipif( - not os.environ.get("REAL_YK"), - reason="Run test with REAL_YK=1 (test will prompt for pin)", - ) - def test_real_yk(self): - """Test public key export and signing with real Yubikey.""" - from getpass import getpass - - def sec_handler(secret_name: str) -> str: - return getpass(f"Enter {secret_name}: ") - - key = YkSigner.import_() - signer = YkSigner(key, sec_handler) - - sig = signer.sign(_DATA) - key.verify_signature(sig, _DATA) - with pytest.raises(UnverifiedSignatureError): - key.verify_signature(sig, _NOT_DATA)