Skip to content

Commit ec09778

Browse files
committed
ngclient,tests,examples: Use new verify_delegate()
Avoid Metadata.verify_delegate() now that it's deprecated. Note that this commit does not try to make any code cleanups that are now possible: this is the minimal change to use the new API. Future improvements can make code in TrustedMetadataSet and Updater slightly easier to read: as an example there's no need for TrustedMetadataSet to actually store or expose actual Metadata in its cache -- Signed is all that's needed. Signed-off-by: Jussi Kukkonen <[email protected]>
1 parent 9d8891e commit ec09778

File tree

3 files changed

+64
-26
lines changed

3 files changed

+64
-26
lines changed

examples/repository/_simplerepo.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,7 @@ def submit_role(self, role: str, data: bytes) -> bool:
177177
if not targetpath.startswith(f"{role}/"):
178178
raise ValueError(f"targets allowed under {role}/ only")
179179

180-
targets_md = self.open("targets")
181-
targets_md.verify_delegate(role, md)
180+
self.targets().verify_delegate(role, md)
182181

183182
if md.signed.version != self.targets(role).version + 1:
184183
raise ValueError("Invalid version {md.signed.version}")

tests/test_api.py

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -345,44 +345,83 @@ def test_metadata_verify_delegate(self) -> None:
345345
with self.assertRaises(ValueError):
346346
role2.verify_delegate("role1", role1)
347347

348+
# pylint: disable=too-many-locals,too-many-statements
349+
def test_signed_verify_delegate(self) -> None:
350+
root_path = os.path.join(self.repo_dir, "metadata", "root.json")
351+
root_md = Metadata[Root].from_file(root_path)
352+
root = root_md.signed
353+
snapshot_path = os.path.join(self.repo_dir, "metadata", "snapshot.json")
354+
snapshot_md = Metadata[Snapshot].from_file(snapshot_path)
355+
snapshot = snapshot_md.signed
356+
targets_path = os.path.join(self.repo_dir, "metadata", "targets.json")
357+
targets_md = Metadata[Targets].from_file(targets_path)
358+
targets = targets_md.signed
359+
role1_path = os.path.join(self.repo_dir, "metadata", "role1.json")
360+
role1_md = Metadata[Targets].from_file(role1_path)
361+
role1 = role1_md.signed
362+
role2_path = os.path.join(self.repo_dir, "metadata", "role2.json")
363+
role2_md = Metadata[Targets].from_file(role2_path)
364+
role2 = role2_md.signed
365+
366+
# test the expected delegation tree
367+
root.verify_delegate(Root.type, root_md)
368+
root.verify_delegate(Snapshot.type, snapshot_md)
369+
root.verify_delegate(Targets.type, targets_md)
370+
targets.verify_delegate("role1", role1_md)
371+
role1.verify_delegate("role2", role2_md)
372+
373+
# only root and targets can verify delegates
374+
with self.assertRaises(AttributeError):
375+
snapshot.verify_delegate(Snapshot.type, snapshot_md)
376+
# verify fails for roles that are not delegated by delegator
377+
with self.assertRaises(ValueError):
378+
root.verify_delegate("role1", role1_md)
379+
with self.assertRaises(ValueError):
380+
targets.verify_delegate(Targets.type, targets_md)
381+
# verify fails when delegator has no delegations
382+
with self.assertRaises(ValueError):
383+
role2.verify_delegate("role1", role1_md)
384+
348385
# verify fails when delegate content is modified
349-
expires = snapshot.signed.expires
350-
snapshot.signed.expires = expires + timedelta(days=1)
386+
expires = snapshot.expires
387+
snapshot.expires = expires + timedelta(days=1)
351388
with self.assertRaises(exceptions.UnsignedMetadataError):
352-
root.verify_delegate(Snapshot.type, snapshot)
353-
snapshot.signed.expires = expires
389+
root.verify_delegate(Snapshot.type, snapshot_md)
390+
snapshot.expires = expires
354391

355392
# verify fails if sslib verify fails with VerificationError
356393
# (in this case signature is malformed)
357-
keyid = next(iter(root.signed.roles[Snapshot.type].keyids))
358-
good_sig = snapshot.signatures[keyid].signature
359-
snapshot.signatures[keyid].signature = "foo"
394+
keyid = next(iter(root.roles[Snapshot.type].keyids))
395+
good_sig = snapshot_md.signatures[keyid].signature
396+
snapshot_md.signatures[keyid].signature = "foo"
360397
with self.assertRaises(exceptions.UnsignedMetadataError):
361-
root.verify_delegate(Snapshot.type, snapshot)
362-
snapshot.signatures[keyid].signature = good_sig
398+
root.verify_delegate(Snapshot.type, snapshot_md)
399+
snapshot_md.signatures[keyid].signature = good_sig
363400

364401
# verify fails if roles keys do not sign the metadata
365402
with self.assertRaises(exceptions.UnsignedMetadataError):
366-
root.verify_delegate(Timestamp.type, snapshot)
403+
root.verify_delegate(Timestamp.type, snapshot_md)
367404

368405
# Add a key to snapshot role, make sure the new sig fails to verify
369-
ts_keyid = next(iter(root.signed.roles[Timestamp.type].keyids))
370-
root.signed.add_key(root.signed.keys[ts_keyid], Snapshot.type)
371-
snapshot.signatures[ts_keyid] = Signature(ts_keyid, "ff" * 64)
406+
ts_keyid = next(iter(root.roles[Timestamp.type].keyids))
407+
root.add_key(root.keys[ts_keyid], Snapshot.type)
408+
snapshot_md.signatures[ts_keyid] = Signature(ts_keyid, "ff" * 64)
372409

373410
# verify succeeds if threshold is reached even if some signatures
374411
# fail to verify
375-
root.verify_delegate(Snapshot.type, snapshot)
412+
root.verify_delegate(Snapshot.type, snapshot_md)
376413

377414
# verify fails if threshold of signatures is not reached
378-
root.signed.roles[Snapshot.type].threshold = 2
415+
root.roles[Snapshot.type].threshold = 2
379416
with self.assertRaises(exceptions.UnsignedMetadataError):
380-
root.verify_delegate(Snapshot.type, snapshot)
417+
root.verify_delegate(Snapshot.type, snapshot_md)
381418

382419
# verify succeeds when we correct the new signature and reach the
383420
# threshold of 2 keys
384-
snapshot.sign(SSlibSigner(self.keystore[Timestamp.type]), append=True)
385-
root.verify_delegate(Snapshot.type, snapshot)
421+
snapshot_md.sign(
422+
SSlibSigner(self.keystore[Timestamp.type]), append=True
423+
)
424+
root.verify_delegate(Snapshot.type, snapshot_md)
386425

387426
def test_key_class(self) -> None:
388427
# Test if from_securesystemslib_key removes the private key from keyval

tuf/ngclient/_internal/trusted_metadata_set.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def update_root(self, data: bytes) -> Metadata[Root]:
161161
)
162162

163163
# Verify that new root is signed by trusted root
164-
self.root.verify_delegate(Root.type, new_root)
164+
self.root.signed.verify_delegate(Root.type, new_root)
165165

166166
if new_root.signed.version != self.root.signed.version + 1:
167167
raise exceptions.BadVersionNumberError(
@@ -170,7 +170,7 @@ def update_root(self, data: bytes) -> Metadata[Root]:
170170
)
171171

172172
# Verify that new root is signed by itself
173-
new_root.verify_delegate(Root.type, new_root)
173+
new_root.signed.verify_delegate(Root.type, new_root)
174174

175175
self._trusted_set[Root.type] = new_root
176176
logger.debug("Updated root v%d", new_root.signed.version)
@@ -215,7 +215,7 @@ def update_timestamp(self, data: bytes) -> Metadata[Timestamp]:
215215
f"Expected 'timestamp', got '{new_timestamp.signed.type}'"
216216
)
217217

218-
self.root.verify_delegate(Timestamp.type, new_timestamp)
218+
self.root.signed.verify_delegate(Timestamp.type, new_timestamp)
219219

220220
# If an existing trusted timestamp is updated,
221221
# check for a rollback attack
@@ -310,7 +310,7 @@ def update_snapshot(
310310
f"Expected 'snapshot', got '{new_snapshot.signed.type}'"
311311
)
312312

313-
self.root.verify_delegate(Snapshot.type, new_snapshot)
313+
self.root.signed.verify_delegate(Snapshot.type, new_snapshot)
314314

315315
# version not checked against meta version to allow old snapshot to be
316316
# used in rollback protection: it is checked when targets is updated
@@ -418,7 +418,7 @@ def update_delegated_targets(
418418
f"Expected 'targets', got '{new_delegate.signed.type}'"
419419
)
420420

421-
delegator.verify_delegate(role_name, new_delegate)
421+
delegator.signed.verify_delegate(role_name, new_delegate)
422422

423423
version = new_delegate.signed.version
424424
if version != meta.version:
@@ -447,7 +447,7 @@ def _load_trusted_root(self, data: bytes) -> None:
447447
f"Expected 'root', got '{new_root.signed.type}'"
448448
)
449449

450-
new_root.verify_delegate(Root.type, new_root)
450+
new_root.signed.verify_delegate(Root.type, new_root)
451451

452452
self._trusted_set[Root.type] = new_root
453453
logger.debug("Loaded trusted root v%d", new_root.signed.version)

0 commit comments

Comments
 (0)