Skip to content

Commit 6ada96c

Browse files
committed
Load trusted root in a separate private method
Add an additional private method for loading the initial trusted root metadata. The public method update_root() is now used only externally for updating the intiial root. The 'root' property is used only after its initialization in the constructor and is not longer optional which makes mypy happy. This split results in cleaner code and the ability to annotate the 'root' property as non-optional at the cost of some code duplication. Signed-off-by: Teodora Sechkova <[email protected]>
1 parent 4f57ae4 commit 6ada96c

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

tuf/ngclient/_internal/trusted_metadata_set.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def __init__(self, root_data: bytes):
9898
# Load and validate the local root metadata. Valid initial trusted root
9999
# metadata is required
100100
logger.debug("Updating initial trusted root")
101-
self.update_root(root_data)
101+
self._load_trusted_root(root_data)
102102

103103
def __getitem__(self, role: str) -> Metadata:
104104
"""Returns current Metadata for 'role'"""
@@ -161,15 +161,15 @@ def update_root(self, data: bytes) -> None:
161161
f"Expected 'root', got '{new_root.signed.type}'"
162162
)
163163

164-
if self._trusted_set.get("root") is not None:
165-
# We are not loading initial trusted root: verify the new one
166-
self.root.verify_delegate("root", new_root)
164+
# Verify that new root is signed by trusted root
165+
self.root.verify_delegate("root", new_root)
167166

168-
if new_root.signed.version != self.root.signed.version + 1:
169-
raise exceptions.ReplayedMetadataError(
170-
"root", new_root.signed.version, self.root.signed.version
171-
)
167+
if new_root.signed.version != self.root.signed.version + 1:
168+
raise exceptions.ReplayedMetadataError(
169+
"root", new_root.signed.version, self.root.signed.version
170+
)
172171

172+
# Verify that new root is signed by itself
173173
new_root.verify_delegate("root", new_root)
174174

175175
self._trusted_set["root"] = new_root
@@ -409,3 +409,24 @@ def update_delegated_targets(
409409

410410
self._trusted_set[role_name] = new_delegate
411411
logger.debug("Updated %s delegated by %s", role_name, delegator_name)
412+
413+
def _load_trusted_root(self, data: bytes) -> None:
414+
"""Verifies and loads 'data' as trusted root metadata.
415+
416+
Note that an expired initial root is considered valid: expiry is
417+
only checked for the final root in update_timestamp().
418+
"""
419+
try:
420+
new_root = Metadata[Root].from_bytes(data)
421+
except DeserializationError as e:
422+
raise exceptions.RepositoryError("Failed to load root") from e
423+
424+
if new_root.signed.type != "root":
425+
raise exceptions.RepositoryError(
426+
f"Expected 'root', got '{new_root.signed.type}'"
427+
)
428+
429+
new_root.verify_delegate("root", new_root)
430+
431+
self._trusted_set["root"] = new_root
432+
logger.debug("Loaded trusted root")

0 commit comments

Comments
 (0)