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

Support for RSA-PKCS1v15-HASH_ID scheme #173

Merged

Conversation

danixeee
Copy link
Contributor

@danixeee danixeee commented Aug 12, 2019

Add support for RSA-PKCS1v15 signatures, as well as other supported openssl hash algorithms.

Description of the changes being introduced by the pull request:

Allow passing one of the following schemes, when generating keys and creating/verifying signatures:

  • rsassa-pss-HASH_ID
  • rsa-pkcs1v15-HASH_ID

Where HASH_ID is one of: md5, sha1, sha224, sha256, sha384 and sha512.

HASH_ID is picked from a scheme, so changes are backwards compatible.

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

@danixeee
Copy link
Contributor Author

Hi @lukpueh, I didn't see that you are working on gpg transition on your fork. I was looking at branches that belongs to this repository, but now I can see that our work does not overlap, which is great. :)

I guess we should continue the conversation from #163 here.

Note that I didn't adapt SIGNATURE_SCHEMA in #174 as you did here, because it felt like a bigger change. I'd rather do this in a separate PR, maybe as part of a broader formats/schema revision. Do you think you can work around this by adding something like below to your taf.formats and patching append_signature accordingly?

Do you think I should merge your work (#174) to mine (#173) and update things that you have proposed in this PR?

Copy link
Member

@lukpueh lukpueh left a comment

Choose a reason for hiding this comment

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

Thanks for the solid PR, @danixeee! I have a few minor comments inline and two style wishes below. Please consider addressing them and we should be able to merge this rather soon.

minor style wishes:

  • Would you mind removing the trailing whitespace you added in hash.py (see e.g. git diff --check)?
  • Would you please revert the alignments of continued lines in pyca_crypto_keys.py that are unrelated to this PR (was that your IDE?)?
    In general, I think our code style is in favor of hanging indent, although not strictly according to pep8, i.e. arguments on the first line are okay. IMO vertical alignment is okay, but it shouldn't exceed the max line length of 80 characters.


'RSA_SCHEME_SCHEMA_PKCS1v15_4': (securesystemslib.formats.RSA_SCHEME_SCHEMA,
'rsa-pkcs1v15-sha512'),

Copy link
Member

Choose a reason for hiding this comment

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

Just for completeness the sake of completeness, could you add two more lines for sha384?

'rsa-pkcs1v15-sha256',
'rsa-pkcs1v15-sha512',
]

Copy link
Member

Choose a reason for hiding this comment

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

Are the sha384 variants left out on purpose?

Copy link
Member

Choose a reason for hiding this comment

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

On an unrelated side-note: I really think securesystemslib should have a constants module that's also used to define schemas in the formats module, so that we don't re-define the same string constants in the different places. We can leave it like it is here, but I'll follow up with an issue about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I left it accidentally, thanks.


# Dictionary of `pyca/cryptography` supported hash algorithms.
PYCA_DIGEST_OBJECTS_CACHE = {hash_algo.name: hash_algo
for hash_algo in cryptography.hazmat.primitives.hashes.HashAlgorithm._abc_registry}
Copy link
Member

Choose a reason for hiding this comment

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

This is pretty neat but it has a few downsides:

  1. Just by looking at it we don't know what hash algos we get here,
  2. We actually get a lot more algos than we "support" (or test for):
    >>> list(PYCA_DIGEST_OBJECTS_CACHE.keys())
    ['sha224', 'md5', 'sha1', 'sha3-224', 'blake2s', 'sha384', 'shake256', 'sha3-256', 'blake2b', 'sha512-224', 'sha256', 
    'sha3-512', 'sha512-256', 'sha3-384', 'shake128', 'sha512']
    
  3. abc.ABC._abc_registry is not officially documented and e.g. won't be available in Python 3.7.

So for the sake of readability and explicitness I suggest a less neat solution, e.g.:

import cryptography.hazmat.primitives.hashes as _pyca_hashes
PYCA_DIGEST_OBJECTS_CACHE = {
  "md5":  pyca_hashes.MD5,
  "sha1": _pyca_hashes.SHA1,
  "sha224": _pyca_hashes.SHA224,
  "sha256": _pyca_hashes.SHA256,
  "sha384": _pyca_hashes.SHA384,
  "sha512": _pyca_hashes.SHA512
}

I could also see a compromise of neat and explicit like...

import cryptography.hazmat.primitives.hashes
SUPPORTED_HASH_ALGOS = ["md5", "sha1"] # ...

PYCA_DIGEST_OBJECTS_CACHE = {
  algo: vars(cryptography.hazmat.primitives.hashes)[algo.upper()] for algo
  in SUPPORTED_HASH_ALGOS}

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, I think that explicit way is the most readable. I had similar code already (https://github.com/openlawlibrary/securesystemslib/blob/e5051e610a6e6d3c58c9b72d3d79e1ed955ea188/securesystemslib/pyca_crypto_keys.py#L159), not sure why I changed it. :)

pass
elif hash_library == 'pyca_crypto' and hash_library in SUPPORTED_LIBRARIES:
try:
global PYCA_DIGEST_OBJECTS_CACHE
Copy link
Member

Choose a reason for hiding this comment

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

I don't think you need the global keyword here.

hash_algorithm = PYCA_DIGEST_OBJECTS_CACHE[algorithm]()
return Pyca_Diggest_Wrapper(
cryptography.hazmat.primitives.hashes.Hash(hash_algorithm,
cryptography.hazmat.backends.default_backend()))
Copy link
Member

Choose a reason for hiding this comment

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

Please double indent continued lines.


SUPPORTED_LIBRARIES.append('pyca_crypto')

class Pyca_Diggest_Wrapper(object):
Copy link
Member

Choose a reason for hiding this comment

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

Minor nit: We usually use UpperCamelCase for classes

# Get hash algorithm from rsa scheme (hash algorithm id is specified after
# the last dash; e.g. rsassa-pss-sha256 -> sha256)
hash_algorithm = scheme.split('-')[-1]
return digest(hash_algorithm, hash_library)
Copy link
Member

Choose a reason for hiding this comment

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

Please add newline

@@ -302,51 +305,56 @@ def create_rsa_signature(private_key, data, scheme='rsassa-pss-sha256'):
# 'private_key' has variable size and can be an empty string.
if len(private_key):
Copy link
Member

Choose a reason for hiding this comment

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

Since you already nicely re-wrote most of this function, would you mind changing above to:

if not len(private_key):
  raise ValueError('The required private key is unset.')

... and move the "try/except/except/except" block on indentation level inwards. I think this makes quite a difference in terms of readability. :)

@lukpueh
Copy link
Member

lukpueh commented Aug 14, 2019

Do you think I should merge your work (#174) to mine (#173) and update things that you have proposed in this PR?

No need to do that. Let's treat them separately while reviewing, and rebase the pending one, once the other one gets merged. I suspect your's will be merged sooner than mine, so I'll do the rebase on my side. :)

@danixeee
Copy link
Contributor Author

@lukpueh I think that I have addressed all your comments for now, thank you for the fast review!

Would you please revert the alignments of continued lines in pyca_crypto_keys.py that are unrelated to this PR (was that your IDE?)?

It was, I am using VS Code but I disabled all formatters, not sure why it changed those alignments. It should be fine now.

Do you think I should merge your work (#174) to mine (#173) and update things that you have proposed in this PR?

I asked this because I will need gpg formats from your PR in order to change schemas. Should I copy them manually then?

@coveralls
Copy link

coveralls commented Aug 14, 2019

Coverage Status

Coverage remained the same at 100.0% when pulling 3116ee2 on openlawlibrary:danixeee/rsa-pkcs1v15-scheme into 6ef6c61 on secure-systems-lab:master.

Copy link
Member

@lukpueh lukpueh left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks! :)

@lukpueh
Copy link
Member

lukpueh commented Aug 14, 2019

I asked this because I will need gpg formats from your PR in order to change schemas. Should I copy them manually then?

I'll merge this PR now and will rebase my lukpueh:add-gpg from #174 onto master. I suggest you work on top of lukpueh:add-gpg then. It shouldn't change a lot, because the logic has already been reviewed in in-toto. However, it still needs someone to take a look at it before we merge it here (cc @SantiagoTorres, @mnm678).

@lukpueh lukpueh merged commit d6227b4 into secure-systems-lab:master Aug 14, 2019
@danixeee danixeee deleted the danixeee/rsa-pkcs1v15-scheme branch August 21, 2019 11:49
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.

3 participants