From f5bf6b0784a3ed585df4677a23df6ae008d88caa Mon Sep 17 00:00:00 2001 From: Kairo de Araujo Date: Mon, 22 Nov 2021 16:33:06 +0100 Subject: [PATCH] Prevents delegate role name as top-level role name This commit adds the validation in the ``metadata.Delegations`` to prevent that one of the delegate role names given is a top-level role name. A ``ValueError`` will be raised if one of the roles names in the list given to as delegated contains the role name as one of the top-level roles. Signed-off-by: Kairo de Araujo --- tests/test_metadata_serialization.py | 37 ++++++++++++++++++++++++++++ tuf/api/metadata.py | 6 +++++ 2 files changed, 43 insertions(+) diff --git a/tests/test_metadata_serialization.py b/tests/test_metadata_serialization.py index 9275b8b8..fbeb8e40 100644 --- a/tests/test_metadata_serialization.py +++ b/tests/test_metadata_serialization.py @@ -360,6 +360,43 @@ def test_delegation_serialization(self, test_case_data: str): delegation = Delegations.from_dict(copy.deepcopy(case_dict)) self.assertDictEqual(case_dict, delegation.to_dict()) + valid_delegations: utils.DataSet = { + "using root as delegate role name": '{"keys": { \ + "keyid1" : {"keytype": "rsa", "scheme": "rsassa-pss-sha256", "keyval": {"public": "foo"}}}, \ + "roles": [ \ + {"keyids": ["keyid"], "name": "root", "terminating": true, "paths": ["fn1"], "threshold": 3}] \ + }', + "using snapshot as delegate role name": '{"keys": { \ + "keyid1" : {"keytype": "rsa", "scheme": "rsassa-pss-sha256", "keyval": {"public": "foo"}}}, \ + "roles": [ \ + {"keyids": ["keyid"], "name": "snapshot", "terminating": true, "paths": ["fn1"], "threshold": 3}] \ + }', + "using targets as delegate role name": '{"keys": { \ + "keyid1" : {"keytype": "rsa", "scheme": "rsassa-pss-sha256", "keyval": {"public": "foo"}}}, \ + "roles": [ \ + {"keyids": ["keyid"], "name": "targets", "terminating": true, "paths": ["fn1"], "threshold": 3}] \ + }', + "using timestamp as delegate role name": '{"keys": { \ + "keyid1" : {"keytype": "rsa", "scheme": "rsassa-pss-sha256", "keyval": {"public": "foo"}}}, \ + "roles": [ \ + {"keyids": ["keyid"], "name": "root", "terminating": true, "paths": ["fn1"], "threshold": 3}] \ + }', + "using valid and top-level role name": '{"keys": { \ + "keyid1" : {"keytype": "rsa", "scheme": "rsassa-pss-sha256", "keyval": {"public": "foo"}}, \ + "keyid2" : {"keytype": "ed25519", "scheme": "ed25519", "keyval": {"public": "bar"}}}, \ + "roles": [ \ + {"keyids": ["keyid"], "name": "b", "terminating": true, "paths": ["fn1"], "threshold": 3}, \ + {"keyids": ["keyid2"], "name": "root", "terminating": true, "paths": ["fn2"], "threshold": 4} ] \ + }', + } + + @utils.run_sub_tests_with_dataset(valid_delegations) + def test_delegation_top_role_names(self, test_case_data: str): + case_dict = json.loads(test_case_data) + with self.assertRaises(ValueError): + Delegations.from_dict(copy.deepcopy(case_dict)) + + invalid_targetfiles: utils.DataSet = { "no hashes": '{"length": 1}', "no length": '{"hashes": {"sha256": "abc"}}' diff --git a/tuf/api/metadata.py b/tuf/api/metadata.py index 25f14fe7..7b5fcbea 100644 --- a/tuf/api/metadata.py +++ b/tuf/api/metadata.py @@ -1213,6 +1213,12 @@ def __init__( unrecognized_fields: Optional[Mapping[str, Any]] = None, ): self.keys = keys + if [role for role in set(roles) if role in TOP_LEVEL_ROLE_NAMES]: + raise ValueError( + "A delegated role can not use top-level role names (" + f"{', '.join(TOP_LEVEL_ROLE_NAMES)})" + ) + self.roles = roles self.unrecognized_fields = unrecognized_fields or {}