From 0c3131b4a2b2f9abb6c35d271e38db7ffa7ea18b Mon Sep 17 00:00:00 2001 From: Martin Vrachev Date: Thu, 22 Apr 2021 18:24:41 +0300 Subject: [PATCH] Make keyids in Role a set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the specification: "Clients MUST ensure that for any KEYID represented in this key list and in other files, only one unique key has that KEYID." The “only one unique key has that KEYID” is a requirement which can’t be achieved if two keyids are the same. So, in order to mandate that requirement it makes sense to use a set which will guarantee us the keyid’s uniqueness. Signed-off-by: Martin Vrachev --- tuf/api/metadata.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tuf/api/metadata.py b/tuf/api/metadata.py index 3115e6f7..f9c695ec 100644 --- a/tuf/api/metadata.py +++ b/tuf/api/metadata.py @@ -463,11 +463,17 @@ class Role: def __init__( self, - keyids: set, + keyids: list, threshold: int, unrecognized_fields: Optional[Mapping[str, Any]] = None, ) -> None: - self.keyids = keyids + keyids_set = set(keyids) + if len(keyids_set) != len(keyids): + raise ValueError( + f"keyids should be a list of unique strings," + f" instead got {keyids}" + ) + self.keyids = keyids_set self.threshold = threshold self.unrecognized_fields = unrecognized_fields or {} @@ -482,7 +488,7 @@ def from_dict(cls, role_dict: Mapping[str, Any]) -> "Role": def to_dict(self) -> Dict: """Returns the dictionary representation of self.""" return { - "keyids": self.keyids, + "keyids": list(self.keyids), "threshold": self.threshold, **self.unrecognized_fields, } @@ -570,7 +576,7 @@ def add_key( ) -> None: """Adds new key for 'role' and updates the key store.""" if keyid not in self.roles[role].keyids: - self.roles[role].keyids.append(keyid) + self.roles[role].keyids.add(keyid) self.keys[keyid] = key_metadata # Remove key for a role.