-
Notifications
You must be signed in to change notification settings - Fork 50
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
Implement TAP 9 (Mandatory metadata signing schemes) #48
Implement TAP 9 (Mandatory metadata signing schemes) #48
Conversation
The create_signature() functions for keys.py and the specific library modules (e.g., pyca_crypto_keys.py) should be refactored to accept a 'scheme' argument
create_rsa_signature() and verify_rsa_signature() refactored to accept scheme argument
Also update its unit tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignored pycrypto related diff, which is removed in #62.
@@ -179,12 +179,19 @@ def create_signature(public_key, private_key, data): | |||
data: | |||
Byte data used by create_signature() to generate the signature returned. | |||
|
|||
scheme: | |||
The signature scheme used to generate the signature. For example: | |||
'ecesa-sha2-nistp256'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ecdsa-sha2-nistp256
<Exceptions> | ||
securesystemslib.exceptions.FormatError, if the arguments are improperly | ||
formatted. | ||
|
||
securesystemslib.exceptions.CryptoError, if a signature cannot be created. | ||
|
||
securesystemslib.exceptions.UnsupportedAlgorithmError, if 'scheme' is | ||
an not one of the supported signature schemes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-an
@@ -126,21 +126,21 @@ def generate_public_and_private(algorithm='ecdsa-sha2-nistp256'): | |||
# supported ECDSA algorithms. It must conform to | |||
# 'securesystemslib.formats.ECDSAALGORITHMS_SCHEMA'. Raise | |||
# 'securesystemslib.exceptions.FormatError' if the check fails. | |||
securesystemslib.formats.ECDSAALGORITHMS_SCHEMA.check_match(algorithm) | |||
securesystemslib.formats.ECDSA_SIG_SCHEMA.check_match(scheme) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be ECDSA_SIG_SCHEME_SCHEMA
now? (just kidding)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's actually not purely a joke. Currently the schemas for signatures and signature schemes are not really distinguishable by their names. So *_SIG_SCHEME_SCHEMA
might not be the worst of ideas? Especially since there already is a SIG_SCHEME_SCHEMA
. :)
password=None, backend=default_backend()) | ||
# A defensive check for a valid 'scheme'. The check_match() above | ||
# should have already validated it... | ||
if scheme == 'ecdsa-sha2-nistp256': #pragma: no cover |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a reason for doing the exact same check twice in a row. I don't see a big problem either, but it feels strange to me to redo what ECDSA_SIG_SCHEMA.check_match(scheme)
already does.
However, I would definitely remove the #pragma: no cover
here, because that disables the decreased coverage alert when you remove tests that touch code inside the if-block.
Also, I'm not sure if it is a good idea to fail with different errors FormatError
vs. UnsupportedAlgorithmError
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you can wrapECDSA_SIG_SCHEMA.check_match(scheme)
in a try/except block and raise UnsupportedAlgorithmError
on FormatError
?
@@ -126,21 +126,21 @@ def generate_public_and_private(algorithm='ecdsa-sha2-nistp256'): | |||
# supported ECDSA algorithms. It must conform to | |||
# 'securesystemslib.formats.ECDSAALGORITHMS_SCHEMA'. Raise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are still a couple of mentionings of algorithm that probably should be scheme now in comments, also the UnsupportedAlgorithmError
is still used for unsupported schemes. I guess this is not a big deal.
keyid = KEYID_SCHEMA, | ||
keyid_hash_algorithms = SCHEMA.Optional(HASHALGORITHMS_SCHEMA), | ||
keyval = KEYVAL_SCHEMA) | ||
|
||
# ECDSA signature schemes. | ||
ECDSA_SIG_SCHEMA = SCHEMA.OneOf([SCHEMA.String('ecdsa-sha2-nistp256')]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ECDSA_SIG_SCHEMA is already assigned in L187
# Is 'scheme' one of the supported ECDSA signature schemes? A defensive | ||
# check for a valid 'scheme'. The check_match() above should have validated | ||
# it... | ||
if scheme in _SUPPORTED_ECDSA_SCHEMES: #pragma: no cover |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment above about redundant checks with different Errors and #pragma: no cover
. Btw. it seems that this comment applies to various places throughout the PR.
The ECDSA algorithm. By default, ECDSA NIST P-256 is used, with SHA256 | ||
for hashing. | ||
|
||
<Exceptions> | ||
securesystemslib.exceptions.FormatError, if 'algorithm' is improperly or invalid | ||
(i.e., not one of the supported ECDSA algorithms). | ||
securesystemslib.exceptions.FormatError, if 'algorithm' is improperly or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/algorithm/scheme/ (not only here)
# encrypted, or if the key was encrypted but no password was supplied. | ||
# Note: A passphrase or password is not used when generating | ||
# 'private_key', since it should not be encrypted. | ||
except TypeError: #pragma: no cover |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason for the #pragma: no cover
here and with the ValueError
above?
# encrypted with a symmetric cipher that is not supported by the backend. | ||
except cryptography.exceptions.UnsupportedAlgorithm: #pragma: no cover | ||
raise securesystemslib.exceptions.CryptoError('The private key is' | ||
' encrypted with a unsupported algorithm.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+n
Address review of pull request #48
TAP 9 removes the
method
attribute from signed metadata to prevent malicious actors from controlling it. Instead, the signature scheme is now specified in the "signed" portion of metadata.This pull request refactors a few functions to accept a signature scheme argument. In addition, the signature scheme is now included in the "keys" field of signed metadata.
TAP 9 and this implementation are backwards incompatible.