Skip to content

Commit f2609ab

Browse files
authored
Merge pull request #2010 from MVrachev/tap15-final-design
2 parents c89cb50 + c6488f0 commit f2609ab

13 files changed

Lines changed: 609 additions & 110 deletions

docs/api/tuf.api.metadata.supporting.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ones (Root, Timestamp, Snapshot, Targets):
1313
tuf.api.metadata.MetaFile
1414
tuf.api.metadata.Role
1515
tuf.api.metadata.TargetFile
16+
tuf.api.metadata.SuccinctRoles
1617

1718
.. autoclass:: tuf.api.metadata.DelegatedRole
1819

@@ -25,3 +26,5 @@ ones (Root, Timestamp, Snapshot, Targets):
2526
.. autoclass:: tuf.api.metadata.Role
2627

2728
.. autoclass:: tuf.api.metadata.TargetFile
29+
30+
.. autoclass:: tuf.api.metadata.SuccinctRoles

docs/repository-library-design.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ are found, in the python-tuf library):
6363
```python
6464
with repository.edit(“targets”) as targets:
6565
# adds a key for role1 (as an example, arbitrary edits are allowed)
66-
targets.add_key(“role1”, key)
66+
targets.add_key(key, “role1”)
6767
```
6868

6969
This code loads current targets metadata for editing, adds the key to a role,

examples/repo_example/basic_repo.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def _in(days: float) -> datetime:
157157
for name in ["targets", "snapshot", "timestamp", "root"]:
158158
keys[name] = generate_ed25519_key()
159159
roles["root"].signed.add_key(
160-
name, Key.from_securesystemslib_key(keys[name])
160+
Key.from_securesystemslib_key(keys[name]), name
161161
)
162162

163163
# NOTE: We only need the public part to populate root, so it is possible to use
@@ -173,7 +173,7 @@ def _in(days: float) -> datetime:
173173
# required signature threshold.
174174
another_root_key = generate_ed25519_key()
175175
roles["root"].signed.add_key(
176-
"root", Key.from_securesystemslib_key(another_root_key)
176+
Key.from_securesystemslib_key(another_root_key), "root"
177177
)
178178
roles["root"].signed.roles["root"].threshold = 2
179179

@@ -343,9 +343,9 @@ def _in(days: float) -> datetime:
343343
# remains in place, it can be used to count towards the old and new threshold.
344344
new_root_key = generate_ed25519_key()
345345

346-
roles["root"].signed.remove_key("root", keys["root"]["keyid"])
346+
roles["root"].signed.revoke_key(keys["root"]["keyid"], "root")
347347
roles["root"].signed.add_key(
348-
"root", Key.from_securesystemslib_key(new_root_key)
348+
Key.from_securesystemslib_key(new_root_key), "root"
349349
)
350350
roles["root"].signed.version += 1
351351

examples/repo_example/hashed_bin_delegation.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ def find_hash_bin(path: str) -> str:
162162
# 10-17 10 11 12 13 14 15 16 17
163163
# ... ...
164164
# f8-ff f8 f9 fa fb fc fd fe ff
165+
assert roles["bins"].signed.delegations.roles is not None
165166
for bin_n_name, bin_n_hash_prefixes in generate_hash_bins():
166167
# Update delegating targets role (bins) with delegation details for each
167168
# delegated targets role (bin_n).

tests/generated_data/generate_md.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ def generate_all_files(
8989
md_snapshot = Metadata(Snapshot(expires=EXPIRY))
9090
md_targets = Metadata(Targets(expires=EXPIRY))
9191

92-
md_root.signed.add_key("root", keys["ed25519_0"])
93-
md_root.signed.add_key("timestamp", keys["ed25519_1"])
94-
md_root.signed.add_key("snapshot", keys["ed25519_2"])
95-
md_root.signed.add_key("targets", keys["ed25519_3"])
92+
md_root.signed.add_key(keys["ed25519_0"], "root")
93+
md_root.signed.add_key(keys["ed25519_1"], "timestamp")
94+
md_root.signed.add_key(keys["ed25519_2"], "snapshot")
95+
md_root.signed.add_key(keys["ed25519_3"], "targets")
9696

9797
for i, md in enumerate([md_root, md_timestamp, md_snapshot, md_targets]):
9898
assert isinstance(md, Metadata)

tests/repository_simulator.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
MetaFile,
6868
Root,
6969
Snapshot,
70+
SuccinctRoles,
7071
TargetFile,
7172
Targets,
7273
Timestamp,
@@ -169,7 +170,7 @@ def rotate_keys(self, role: str) -> None:
169170
self.signers[role].clear()
170171
for _ in range(0, self.root.roles[role].threshold):
171172
key, signer = self.create_key()
172-
self.root.add_key(role, key)
173+
self.root.add_key(key, role)
173174
self.add_signer(role, signer)
174175

175176
def _initialize(self) -> None:
@@ -182,7 +183,7 @@ def _initialize(self) -> None:
182183

183184
for role in TOP_LEVEL_ROLE_NAMES:
184185
key, signer = self.create_key()
185-
self.md_root.signed.add_key(role, key)
186+
self.md_root.signed.add_key(key, role)
186187
self.add_signer(role, signer)
187188

188189
self.publish_root()
@@ -334,12 +335,16 @@ def update_snapshot(self) -> None:
334335
self.snapshot.version += 1
335336
self.update_timestamp()
336337

338+
def _get_delegator(self, delegator_name: str) -> Targets:
339+
"""Given a delegator name return, its corresponding Targets object."""
340+
if delegator_name == Targets.type:
341+
return self.targets
342+
343+
return self.md_delegates[delegator_name].signed
344+
337345
def add_target(self, role: str, data: bytes, path: str) -> None:
338346
"""Create a target from data and add it to the target_files."""
339-
if role == Targets.type:
340-
targets = self.targets
341-
else:
342-
targets = self.md_delegates[role].signed
347+
targets = self._get_delegator(role)
343348

344349
target = TargetFile.from_data(path, data, ["sha256"])
345350
targets.targets[path] = target
@@ -349,26 +354,63 @@ def add_delegation(
349354
self, delegator_name: str, role: DelegatedRole, targets: Targets
350355
) -> None:
351356
"""Add delegated target role to the repository."""
352-
if delegator_name == Targets.type:
353-
delegator = self.targets
354-
else:
355-
delegator = self.md_delegates[delegator_name].signed
357+
delegator = self._get_delegator(delegator_name)
358+
359+
if (
360+
delegator.delegations is not None
361+
and delegator.delegations.succinct_roles is not None
362+
):
363+
raise ValueError("Can't add a role when succinct_roles is used")
356364

357365
# Create delegation
358366
if delegator.delegations is None:
359-
delegator.delegations = Delegations({}, {})
367+
delegator.delegations = Delegations({}, roles={})
368+
369+
assert delegator.delegations.roles is not None
360370
# put delegation last by default
361371
delegator.delegations.roles[role.name] = role
362372

363373
# By default add one new key for the role
364374
key, signer = self.create_key()
365-
delegator.add_key(role.name, key)
375+
delegator.add_key(key, role.name)
366376
self.add_signer(role.name, signer)
367377

368378
# Add metadata for the role
369379
if role.name not in self.md_delegates:
370380
self.md_delegates[role.name] = Metadata(targets, {})
371381

382+
def add_succinct_roles(
383+
self, delegator_name: str, bit_length: int, name_prefix: str
384+
) -> None:
385+
"""Add succinct roles info to a delegator with name "delegator_name".
386+
387+
Note that for each delegated role represented by succinct roles an empty
388+
Targets instance is created.
389+
"""
390+
delegator = self._get_delegator(delegator_name)
391+
392+
if (
393+
delegator.delegations is not None
394+
and delegator.delegations.roles is not None
395+
):
396+
raise ValueError(
397+
"Can't add a succinct_roles when delegated roles are used"
398+
)
399+
400+
key, signer = self.create_key()
401+
succinct_roles = SuccinctRoles([], 1, bit_length, name_prefix)
402+
delegator.delegations = Delegations({}, None, succinct_roles)
403+
404+
# Add targets metadata for all bins.
405+
for delegated_name in succinct_roles.get_roles():
406+
self.md_delegates[delegated_name] = Metadata(
407+
Targets(expires=self.safe_expiry)
408+
)
409+
410+
self.add_signer(delegated_name, signer)
411+
412+
delegator.add_key(key)
413+
372414
def write(self) -> None:
373415
"""Dump current repository metadata to self.dump_dir
374416

0 commit comments

Comments
 (0)