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

Refactor signature code #5

Merged
merged 11 commits into from
Apr 24, 2017
Merged

Refactor signature code #5

merged 11 commits into from
Apr 24, 2017

Conversation

awwad
Copy link
Owner

@awwad awwad commented Apr 14, 2017

Separate low-level signing code from encoding and formatting code once and for all. (:

This makes the code more readable and less confusing, and also makes life a lot easier for Uptane upstream.

This Uptane PR should be applied in tandem.

I was originally going to wait until after the Great Merge of the TUF Forks for this, but after more lost time debugging, I got pretty sick of all of the optional arguments I had to add to tuf.keys, and the edge cases requiring coordination.... It was time to do this.

tuf.keys.create_signature and tuf.keys.verify_signature should have
no awareness of the encodings of the data fed to them. They should
receive bytes, sign those or validate the signatures on those, and
return signatures or validity booleans. They shouldn't need to
deal with ASN.1 or DER or JSON or even encoding things as utf-8.

Future commits will capture those needs in higher level code.
Allow code to expect tuf.keys.create_signature to take bytes without
lots of special flags.
that will deal with metadata encoding to sig.py. These can be
called from code that would previously have had to worry about
ASN.1/DER/JSON/utf-8.
repository_lib functions and sig.get_signature_status can now
forget all about encoding and format and use the new functions
in sig.
@@ -278,13 +278,7 @@ def convert_signed_metadata_to_der(
# Now sign the metadata. (This signs a cryptographic hash of the metadata.)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I like how you refer to a specific function when discussing what is returned and given as input (see line 281). In contrast, the comment that starts on line 278 uses words like this, which might lead to confusion.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Fixing

utf-8 encode the data, because it cannot necessarily be encoded as utf-8
and in any case is already encoded.

This should be bytes(). If it is a string, it should already be encoded
Copy link
Collaborator

Choose a reason for hiding this comment

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

What happens if the string isn't in bytes? What error should the caller expect?

Copy link
Owner Author

@awwad awwad Apr 18, 2017

Choose a reason for hiding this comment

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

At the moment, in Python2, it works (is encoded automatically), and in Python3, lower-level crypto libraries (e.g. PyNaCl) are likely to choke on it, which results in an error reraised as a tuf.CryptoError (e.g. An "ed25519" signature could not be created with PyNaCl.initializer for ctype 'unsigned char *' must be a bytes or list or tuple, not str)

I want to produce a reliable error message in both cases, not allow it to work in one Python version and not another. That can result in mistakes or accidental incompatibilities in code using tuf.keys.

I'm not sure how best to do that, though. It's unpythonic to do this:
if python2 and isinstance(data, unicode) or python3 and not isinstance(data, bytes)

Copy link
Collaborator

Choose a reason for hiding this comment

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

After meeting in-person to discuss this issue, we settled on:

tuf.formats.DATA_SCHEMA.check_match(data)

tuf/sig.py Outdated
key_dict, data,
metadata_format=tuf.conf.METADATA_FORMAT):
"""
Higher level function that wraps tuf.keys.create_signature, and works
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where are the labels? Return type, exceptions raises, etc.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We should also keep up the habit of updating the units tests and maintaining code coverage. The pull request to upstream will fail if code coverage is less than a certain percent.

Copy link
Owner Author

Choose a reason for hiding this comment

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

I agree in general. Fixing testing on this fork is a task that I do not think is worth the energy right now, as it would be time-consuming and require re-working in the merge anyway. (I could be wrong - lmk if you disagree.)

As for the labels, the docstring directs one to the lower level create_signature docstring... but you're entirely right; this is inadequate. I'll add proper documentation.

create_signature and verify_signature only take binary data
as their 'data' argument, so this commit checks that argument
for the correct format.
Non-binary data must raise tuf.FormatError when provided to
create_signature or verify_signature.

Also fixes test_keys tests for new expectations: binary only.
sign_over_metadata and verify_signature_over_metadata
and have testing use the new sign_over_metadata function.
(Testing will already use the other new function,
verify_signature_over_metadata, because it is called
indirectly by tuf.sig.verify.)

tuf.keys only deals with binary data now.
@awwad
Copy link
Owner Author

awwad commented Apr 18, 2017

I think that handles all your comments. I also fixed test_keys and test_sig to work with the new tuf.keys and tuf.sig code, since it was easy enough and provided a bit of reassurance. I also expanded testing slightly to cover binary data expectations in tuf.keys.

# Ensure that tuf.FormatError is raised if non-binary data is passed to
# verify_signature:
self.assertRaises(tuf.FormatError, KEYS.verify_signature, self.rsakey_dict,
rsa_signature, u'unicode_string')
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's helpful to incorporate these edits to the unit tests, will be easier when porting to TUF.

@awwad
Copy link
Owner Author

awwad commented Apr 24, 2017

Comments addressed, I think. Could you take a final look?

tuf/sig.py Outdated
@@ -485,19 +485,6 @@ def verify_signature_over_metadata(

See tuf.keys.verify_signature for lower level details.

>>> data = 'The quick brown fox jumps over the lazy dog'
Copy link
Collaborator

Choose a reason for hiding this comment

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

If it's easy and doable, we should include doctests.

@vladimir-v-diaz
Copy link
Collaborator

Okay, I'm done reviewing this PR.

@awwad awwad merged commit 36dbb7b into develop Apr 24, 2017
awwad added a commit that referenced this pull request Jul 24, 2018
test_repository_lib fix:
Some time ago in PR #5 #5
I changed signature code such that tuf.keys.create_signature
and verify_signature accept already-encoded bytes instead of
assuming what the encodings should look like, and moved
encoding up a bit in the stack (often to tuf.sig). This
test wasn't updated at that point, and now it is being
updated to deal with this (by encoding first, then calling
the tuf.keys.create_signature function).

test_mix_and_match_attack fix:
A fix to the way that role files are retained if validation
fails (possibly from #13 )
broke this test, I think, though I'm not certain. In any
event, this demonstrates passable behavior for now, with the
role info loaded correctly.

These tests in the TUF fork are not regarded as critical,
given that testing occurs at the Uptane level and Uptane will
be migrating to the main TUF repository when possible;
however, these fixes may be helpful in the interim.

Signed-off-by: Sebastien Awwad <sebastien.awwad@gmail.com>
@awwad awwad deleted the refactor_signature_code branch March 4, 2019 19:42
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.

2 participants