Skip to content

Commit

Permalink
Load trusted root in a separate private method
Browse files Browse the repository at this point in the history
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 <tsechkova@vmware.com>
  • Loading branch information
sechkova committed Aug 26, 2021
1 parent eb3fc66 commit 6a624f1
Showing 1 changed file with 29 additions and 8 deletions.
37 changes: 29 additions & 8 deletions tuf/ngclient/_internal/trusted_metadata_set.py
Expand Up @@ -98,7 +98,7 @@ def __init__(self, root_data: bytes):
# Load and validate the local root metadata. Valid initial trusted root
# metadata is required
logger.debug("Updating initial trusted root")
self.update_root(root_data)
self._load_trusted_root(root_data)

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

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

if new_root.signed.version != self.root.signed.version + 1:
raise exceptions.ReplayedMetadataError(
"root", new_root.signed.version, self.root.signed.version
)
if new_root.signed.version != self.root.signed.version + 1:
raise exceptions.ReplayedMetadataError(
"root", new_root.signed.version, self.root.signed.version
)

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

self._trusted_set["root"] = new_root
Expand Down Expand Up @@ -409,3 +409,24 @@ def update_delegated_targets(

self._trusted_set[role_name] = new_delegate
logger.debug("Updated %s delegated by %s", role_name, delegator_name)

def _load_trusted_root(self, data: bytes) -> None:
"""Verifies and loads 'data' as trusted root metadata.
Note that an expired initial root is considered valid: expiry is
only checked for the final root in update_timestamp().
"""
try:
new_root = Metadata[Root].from_bytes(data)
except DeserializationError as e:
raise exceptions.RepositoryError("Failed to load root") from e

if new_root.signed.type != "root":
raise exceptions.RepositoryError(
f"Expected 'root', got '{new_root.signed.type}'"
)

new_root.verify_delegate("root", new_root)

self._trusted_set["root"] = new_root
logger.debug("Loaded trusted root")

0 comments on commit 6a624f1

Please sign in to comment.