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

Golang-style salt lengths to verify RSA PSS sigs #262

Conversation

trishankatdatadog
Copy link
Contributor

Signed-off-by: Trishank Karthik Kuppusamy [email protected]

Fixes issue #:

N/A

Description of the changes being introduced by the pull request:

Golang-style salt lengths to allow us to verify RSA PSS signatures produced in Go-based software such as Hashicorp Vault.

Please verify and check that the pull request fulfils 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

@coveralls
Copy link

coveralls commented Jul 21, 2020

Coverage Status

Coverage decreased (-0.04%) to 98.746% when pulling 7edc11f on trishankatdatadog:trishankatdatadog/options-for-rsa-pss-salt-length into bbf1505 on secure-systems-lab:master.

securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
@shibumi
Copy link

shibumi commented Jul 31, 2020

Coverage Status

Coverage decreased (-98.9%) to 0.0% when pulling d148b64 on trishankatdatadog:trishankatdatadog/options-for-rsa-pss-salt-length into 6f88f63 on secure-systems-lab:master.

Lol.. this sounds odd.

Copy link
Collaborator

@joshuagl joshuagl left a comment

Choose a reason for hiding this comment

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

This looks like a solid change, thanks @trishankatdatadog.

Travis is failing because coverage dropped to 98% with the addition of the code, could you please add some test coverage for SaltLength? Testing the Go compatible PSSSaltLengthAuto would be excellent.

securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
@trishankatdatadog
Copy link
Contributor Author

trishankatdatadog commented Aug 4, 2020

@shibumi @joshuagl Addressed your comments by adding tests and documentation.

I'm not happy with fixing the RSA-PSS salt length in the code, instead of as part of signed metadata on how to use the public key. We need to design a more sensible key distribution format going forward instead of using a single scheme string to encode hashing+signing+marshaling algorithms+etc.

Copy link
Collaborator

@joshuagl joshuagl left a comment

Choose a reason for hiding this comment

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

Nice work @trishankatdatadog. I have some minor comments in-line, but otherwise this PR looks good to me.

securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
tests/test_rsa_keys.py Outdated Show resolved Hide resolved
tests/test_rsa_keys.py Outdated Show resolved Hide resolved
tests/test_rsa_keys.py Outdated Show resolved Hide resolved
@shibumi shibumi mentioned this pull request Aug 5, 2020
pylintrc Outdated Show resolved Hide resolved
pylintrc Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Show resolved Hide resolved
tests/test_rsa_keys.py Outdated Show resolved Hide resolved
tests/test_rsa_keys.py Outdated Show resolved Hide resolved
tests/test_rsa_keys.py Outdated Show resolved Hide resolved
securesystemslib/rsa_keys.py Outdated Show resolved Hide resolved
tox.ini Outdated Show resolved Hide resolved
@trishankatdatadog
Copy link
Contributor Author

Done. Let me know if there are major issues. Any major objections @lukpueh?

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.

Many thanks for the enhancements, @trishankatdatadog! Here are some high-level observations:

  • Tests need to pass
  • Could you please move the linter configuration and hence resulting style/format fixes to a separate PR?
  • Could you please squash your commits as appropriate and add a bit more info about the changes to the commit messages?
  • There should be no merge commits in PRs.

@trishankatdatadog trishankatdatadog force-pushed the trishankatdatadog/options-for-rsa-pss-salt-length branch 2 times, most recently from bb248a9 to deb1cb1 Compare August 21, 2020 14:48
@trishankatdatadog
Copy link
Contributor Author

Many thanks for the enhancements, @trishankatdatadog! Here are some high-level observations:

Is this OK?

@lukpueh
Copy link
Member

lukpueh commented Aug 24, 2020

Thanks for the updates! More details in the commit message would still be nice.

Previously, the securesystemslib RSA-PSS signature creation and
verification code was fixed at using a salt length equal to the hash
output length.

This commit changes that to allow end-users to use a salt length that is
the maximum available. The original motivation for this commit was to be
able to verify RSA-PSS signatures generated by the Golang crypto RSA
package, which defaults to the maximum salt length. For more information
on how Golang crypto and Python cryptography handle salt lengths, please
see:

https://github.com/golang/go/blob/11f92e9dae96939c2d784ae963fa7763c300660b/src/crypto/rsa/pss.go#L225-L232
https://cryptography.io/en/3.1/hazmat/primitives/asymmetric/rsa/#cryptography.hazmat.primitives.asymmetric.padding.PSS.MAX_LENGTH

For more information on salt lengths and how they relate to the proof of
the security of the RSA-PSS scheme, please see:

https://crypto.stackexchange.com/a/1222

This commit also includes test for the above changes, and some minor,
unrelated formatting changes for pylint so that tests pass.

Signed-off-by: Trishank Karthik Kuppusamy <[email protected]>
@trishankatdatadog trishankatdatadog force-pushed the trishankatdatadog/options-for-rsa-pss-salt-length branch from deb1cb1 to 7edc11f Compare November 23, 2020 08:01
@trishankatdatadog
Copy link
Contributor Author

Thanks for the updates! More details in the commit message would still be nice.

Finally done! Please take a last look...

@trishankatdatadog
Copy link
Contributor Author

Any news, please? @lukpueh

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.

Apologies for the late review. I think this looks quite good. I would probably implement it a bit differently, but I guess that's a matter of taste. Please remove unrelated changes and I can give it another pass.

# its crypto package.
# https://github.com/golang/go/blob/11f92e9dae96939c2d784ae963fa7763c300660b/src/crypto/rsa/pss.go#L225-L232
# FIXME: really, we should encode the salt length as part of the metadata on
# how to use the RSA-PSS public key.
Copy link
Member

Choose a reason for hiding this comment

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

👍 Agreed. Maybe configured via the "scheme" field? See #308.

Comment on lines +257 to +290
class SaltLengthType:
"""A class to represent common salt lengths for RSA-PSS."""

@classmethod
def get_salt_length(self, algorithm):
"""Get the salt length as integer."""
raise NotImplementedError





# NOTE: This is what used to be the standard behaviour.
class HashSaltLengthType(SaltLengthType):
"""Salt length to equal the length of the hash used in the signature."""

@classmethod
def get_salt_length(cls, algorithm):
"""Get the salt length as integer."""
return algorithm.digest_size





class MaxSaltLengthType(SaltLengthType):
"""Salt length in a PSS signature to be as large as possible when
signing, and to be auto-detected when verifying."""

@classmethod
def get_salt_length(cls, algorithm):
"""Get the salt length as integer."""
# NOTE: We disregard algorithm here.
return padding.PSS.MAX_LENGTH
Copy link
Member

Choose a reason for hiding this comment

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

Smart architecture. :) Do we expect other SaltLengthType implementations that warrant an interface? Wouldn't a simple if/elif switch akin to the go code you referenced be just as good and a little less "engineered"?



def create_rsa_signature(private_key, data, scheme='rsassa-pss-sha256',
salt_length_type=HashSaltLengthType):
Copy link
Member

@lukpueh lukpueh Feb 25, 2021

Choose a reason for hiding this comment

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

I'm a bit worried how this extra parameter will fit in with the regular securesystemslib usage patterns, where algorithmic specific sign functions are only called indirectly via securesystemslib.keys.create_signature, dispatching based on the signing scheme field of the private key. So encoding the salt length type in the key, as you suggested above, is probably the way to go. But we can do this in a follow-up PR.

@@ -278,6 +327,10 @@ def create_rsa_signature(private_key, data, scheme='rsassa-pss-sha256'):
scheme:
The signature scheme used to generate the signature.

salt_length_type:
The strategy for determining the length of the salt used in RSA-PSS, one of
Copy link
Member

Choose a reason for hiding this comment

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

It's a bit ironic that there are plenty of unrelated re-wraps in your diff to match the prescribed line length, but a line that you added exceeds it.

I wish it was the other way around. Could you please remove non-related style changes from this PR as requested in an earlier review.

@@ -381,7 +437,8 @@ def create_rsa_signature(private_key, data, scheme='rsassa-pss-sha256'):



def verify_rsa_signature(signature, signature_scheme, public_key, data):
def verify_rsa_signature(signature, signature_scheme, public_key, data,
salt_length_type=HashSaltLengthType):
Copy link
Member

Choose a reason for hiding this comment

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

Same as above, we usually just call securesystemslib.keys.verify_signature and use the key to dispatch to the algorithm specific function.

@trishankatdatadog
Copy link
Contributor Author

Thanks, Lukas, but I'm afraid I don't have the bandwidth to work on this PR anymore, especially since there are no plans to upstream my other PR which depends on this one. Should we just close this for now and revisit in the future?

@trishankatdatadog
Copy link
Contributor Author

Note to @woodruffw though: you will need something like this PR to finish your Vault-TUF (or is it Vault-securesystemslib) integration. Closing for now.

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.

5 participants