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

Fix updater workflow #1101

Merged

Conversation

joshuagl
Copy link
Member

@joshuagl joshuagl commented Aug 6, 2020

Fixes issue #: N/A

Description of the changes being introduced by the pull request:
The updater was not adhering to the detailed client workflow. Specifically newly downloaded root metadata was not being verified with a threshold of signatures from itself.

Per the detailed client workflow in the specification step 1.2

Version N+1 of the root metadata file MUST have been signed by:
(1) a threshold of keys specified in the trusted root metadata file (version N), and
(2) a threshold of keys specified in the new root metadata file being validated (version N+1)."

This PR ensures that point two is verified by the updater.

Please verify and check that the pull request fulfills the following
requirements
:

  • The code follows the Code Style Guidelines
  • Tests have been added for the bug fix or new feature
  • Docs have been added for the bug fix or new feature

# The ANYKEY_SCHEMA check in verify_signature expects the keydict to
# include a keyid
key['keyid'] = keyid
valid_sig = securesystemslib.keys.verify_signature(key, signature, signed)
Copy link
Member

Choose a reason for hiding this comment

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

Should we bail on a single exception here? Feels like we need a try-catch...

Copy link
Member Author

Choose a reason for hiding this comment

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

_get_metadata_file has some logic to collect all exceptions and pack them into NoWorkingMirrorError, so I think this just continues the existing pattern?

tuf/client/updater.py Outdated Show resolved Hide resolved
# new threshold of new signatures contained within the downloaded root
# metadata object
if valid and metadata_role == 'root':
valid = self._verify_root_sigs(metadata_signable)
Copy link
Member

Choose a reason for hiding this comment

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

I also wouldn't call this function inside _verify_metadata_file(), because there is too much magic. Best to call it explicitly in the _update_root_metadata() code IMHO.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed, this does make _verify_metadata_file() much more magical. I opted to call it inside _verify_metadata_file() because this enable us to perform the check before the tempfile is persisted, and makes it easier to perform the check per download mirror.

If we do the check in _update_root_metadata() we need to clean up a file from the clients metadata directory and, perhaps less importantly, can only perform the check on a single file returned by _update_root_metadata()

Copy link
Member

Choose a reason for hiding this comment

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

+1. I think the point of never writing unverified files is critical and should probably be encoded in comments or docs... If we do not adhere to that it's almost impossible to ensure that our state of metadata stays valid.

Copy link
Member

Choose a reason for hiding this comment

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

Also, we want to make sure that other functions that depend on this function do the same thing. Let's leave the magic alone for now, but document clearly why it is there, and not somewhere else.

tuf/client/updater.py Show resolved Hide resolved
tests/test_updater_root_rotation_integration.py Outdated Show resolved Hide resolved



def test_root_rotation_unmet_new_threshold(self):
Copy link
Member

Choose a reason for hiding this comment

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

Lovely test, but there's some overlap between this test and the next. Maybe clarify that there is at least one successful intermediate rotation involved or something.

@joshuagl
Copy link
Member Author

I believe I've addressed all review comments. Once the PR is approved I'd like to squash some of the changes addressing review comments into the patches that introduced the changes.

Copy link
Member

@trishankatdatadog trishankatdatadog left a comment

Choose a reason for hiding this comment

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

LGTM

sechkova and others added 4 commits August 18, 2020 21:48
Co-authored-by: Joshua Lock <jlock@vmware.com>
Signed-off-by: Teodora Sechkova <tsechkova@vmware.com>
Signed-off-by: Joshua Lock <jlock@vmware.com>
We no longer handle compressed metadata files, so rename this method to be
shorter and less confusing:
_verify_uncompressed_metadata_file -> _verify_metadata_file

Signed-off-by: Joshua Lock <jlock@vmware.com>
This method is duplicating verification steps which have already been
completed before the file was written to disk.

Signed-off-by: Joshua Lock <jlock@vmware.com>
Per the detailed client workflow in the specification step 1.2

"Version N+1 of the root metadata file MUST have been signed by:
(1) a threshold of keys specified in the trusted root metadata file
(version N), and
(2) a threshold of keys specified in the new root metadata file being
validated (version N+1)."

Number 2 is implemented here as this step was not being performed by the
Updater. Unfortunately we can't use existing signature verification
methods in tuf.sig, because tuf.sig.signature_status() does not verify
signatures for keys which are not listed in keydb (and tuf.sig.verify
uses tuf.sig.signature_status)

Therefore this patch introduces a method for verifying signatures with
root keys listed in the signable being verified.

Signed-off-by: Joshua Lock <jlock@vmware.com>
@joshuagl joshuagl force-pushed the joshuagl/updater-verify-root branch from eab64ac to 2fc25ad Compare August 18, 2020 20:52
@joshuagl joshuagl merged commit e3ff011 into theupdateframework:develop Aug 18, 2020
@joshuagl joshuagl deleted the joshuagl/updater-verify-root branch August 18, 2020 22:02
joshuagl added a commit to joshuagl/tuf that referenced this pull request Nov 23, 2020
When verifying newly downloaded root metadata with the keys listed in the
root metadata being verified, multiple signatures with the same keyid
should not be counted towards the threshold. A keyid should only count
once towards the threshold.

This fixes the _verify_root_self_signed() method introduced in PR theupdateframework#1101 to
ensure that keyids are only counted once when verifying a threshold of new
root signatures.

Signed-off-by: Joshua Lock <jlock@vmware.com>
joshuagl added a commit to joshuagl/tuf that referenced this pull request Nov 24, 2020
When verifying newly downloaded root metadata with the keys listed in the
root metadata being verified, multiple signatures with the same keyid
should not be counted towards the threshold. A keyid should only count
once towards the threshold.

This fixes the _verify_root_self_signed() method introduced in PR theupdateframework#1101 to
ensure that keyids are only counted once when verifying a threshold of new
root signatures.

Signed-off-by: Joshua Lock <jlock@vmware.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants