Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition to the newest version of TUF #561

Open
wants to merge 95 commits into
base: master
Choose a base branch
from

Conversation

renatav
Copy link
Collaborator

@renatav renatav commented Oct 29, 2024

Description (e.g. "Related to ...", etc.)

Closes #274

Also implemented/addressed:
Closes #501
Closes #555
Closes #560

Code review checklist (for code reviewer to complete)

  • Pull request represents a single change (i.e. not fixing disparate/unrelated things in a single PR)
  • Title summarizes what is changing
  • Commit messages are meaningful (see this for details)
  • Tests have been included and/or updated, as appropriate
  • Docstrings have been included and/or updated, as appropriate
  • Changelog has been updated, as needed (see CHANGELOG.md)

lukpueh and others added 30 commits August 28, 2024 12:06
Remove unused pyopenssl

Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
Implements basic primitives, defined by the python-tuf Repository
abstraction, to read and edit metadata on disk, handling version and
expiry bumps, and signature creation, and facilitating snapshot and
timestamp creation.

And adds exemplary API methods that use these primitives while
preserving consistent repo states:
- create
- add_target_files
- add_keys

Can be tested with:
```
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest --noconftest taf/tests/tuf/
```

More detailed usage docs + migration path TBD...

Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
The original design aimed at separating the concepts of delegation
(adding public keys) and signing (using private keys).

Since the MetadataRepository assumes that metadata can be signed
rightaway after edit (e.g. after having added a delegation), which in
turn requires private keys to be available, we might as well conflate
these two concepts.

The advantage is that the signer cache does not have to be managed
independently and is more likely to stay in sync with the delegations.

Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
This should really happen upstream (see linked issue)

Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
YkSigner provides a minimal compatibility layer over `taf.yubikey`
module functions for use with MetadataRepository.

Even though a yubikey signer implementation (HSMSigner) based on
pykcs11 is available in securesystemslib, YkSigner was added for the
following reasons:

- TAF requires rsa support for yubikeys, but HSMSigner only supports
  ecdsa. Adding rsa support to HSMSigner, or providing a custom
  pykcs11-based RSAHSMSigner is feasible, and seems desirable, but
  requires more effort than this YkSigner did.

- TAF provides a few additional features, like setting up a Yubikey,
  changing pins, etc., which will not be added to securesystemslib.
  This means the current Yubikey infrastructure based on yubikey-manager
  needs to be preserved for the time being. Thus it made sense to
  re-use the existing implementation for YkSigner.

- YkSigner show-cases the new Signer API and might be used as blue print
  for future Signer implementations in TAF.

This commit adds basic tests with fake and real Yubikey:

```
REAL_YK=1 PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 \
    pytest --noconftest  taf/tests/tuf/ taf/tests/tuf/test_yk.py -s
```

Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
This allows running previously added YkSigner tests, but breaks
other things, which need change anyway in the course of upgrading to
latest tuf/securesystemslib.

Signed-off-by: Lukas Puehringer <lukas.puehringer@nyu.edu>
Add alternative TUF metadata repo implementation (WIP)
@renatav renatav force-pushed the feature/tuf-repositoty branch from ebd033a to 3000095 Compare November 29, 2024 20:55
@renatav renatav force-pushed the feature/tuf-repositoty branch from 61919f0 to 385a0be Compare November 30, 2024 04:05
@renatav renatav force-pushed the feature/tuf-repositoty branch from 385a0be to ff146df Compare November 30, 2024 04:07
@renatav renatav changed the base branch from dev to master November 30, 2024 04:19
@renatav renatav changed the title Feature/tuf repositoty Transition to the newest version of TUF Nov 30, 2024
@renatav renatav self-assigned this Nov 30, 2024
@renatav renatav marked this pull request as ready for review November 30, 2024 04:50
@renatav renatav requested review from n-dusan and sale3 November 30, 2024 04:50
@renatav renatav force-pushed the feature/tuf-repositoty branch 2 times, most recently from 6ee2279 to ada9ead Compare December 4, 2024 20:52
@renatav renatav force-pushed the feature/tuf-repositoty branch from ada9ead to 6410f52 Compare December 4, 2024 21:12
Copy link
Contributor

@n-dusan n-dusan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've done a really great job with this PR. The amount of organization and work are impressive!

As for next steps, I'll be reviewing the tests and testing framework in more depth with @sale3. For now, I've left a handful of mostly non-substantial comments that you can take a look at.

are many delegations.
Returns:
Defined delegated paths of delegate target role or * in case of targets
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: why is '*' is returned in case of targets? adding a sentence here would be useful

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main targets role is simply a catch-all. This is an old string, but I can update it

taf/tuf/keys.py Outdated
Comment on lines 33 to 34
def create_signer(priv, pub):
return CryptoSigner(priv, _from_crypto(pub))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: adding a docstring would be useful here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not even used, I'll remove it

Comment on lines 313 to 319
def get_keyids_of_role(self, role_name):
role_obj = self._role_obj(role_name)
return role_obj.keyids

def get_delegations_of_role(self, role_name):
signed_obj = self._signed_obj(role_name)
return signed_obj.delegations.roles
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: adding docstrings for all methods in MetadataRepository class that don't already have it would be useful

Comment on lines 27 to 28
# Convert to string if necessary, or use it as a Path object
return full_path
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question(nitpick): Is this inline comment correct? it doesn't seem to convert as the comment says it should?

custom1 = {"custom_attr1": "custom_val1"}
custom2 = {"custom_attr2": "custom_val2"}

"delegated role's targets"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: are these strings supposed to be comments?

commit = None

@contextmanager
def get(self, filepath: str):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: docstring for GitStorageBackend methods would be helpful

Comment on lines 58 to 60
def __new__(cls, *args, **kwargs):
return super(FilesystemBackend, cls).__new__(cls, *args, **kwargs) # Bypass singleton

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: expanding on the reason why we needed to bypass the singleton as a docstring would be very much useful

Comment on lines +15 to +24
@contextmanager
def transactional_execution(auth_repo):
initial_commit = auth_repo.head_commit_sha()
try:
yield
except PushFailedError:
pass
except Exception:
auth_repo.reset_to_commit(initial_commit, hard=True)
raise
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function makes a lot of sense!

question: would moving it to auth_repo.py be a better place for it? I could see us wanting to use it in platform at some point

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is not reason why we wouldn't want to import anything from the api package imo

files are read and written. To instantiate a `MetadataRepository` class with a custom storage interface, use the
`storage` keyword argument. If not specified, TUF's default `FilesystemBackend` will be used.

This class is used extensively to implement API functions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: adding an overview of GitStorageBackend here seems like it would be useful as well.

inside the `targets` folder are tracked and secured by TUF.
This class is derived from `GitRepository`, and indirectly from `MetadataRepository`. Authentication repositories are
expected to contain TUF metadata and target files, but are also Git repositories. It is important to note that only
files inside the `targets` folder are tracked and secured by TUF.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: secured by TUF -> secured by both TAF and TUF?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, just TUF makes more sense. Storing hashes and lengths of target files in signed metadata files is what TUF does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants