Skip to content

Commit cb09097

Browse files
committed
Drop legacy signature verification code (DO NOT MERGE!)
IMPORTANT NOTE: - This is a massive breaking change, which I suggest to hold off for 1.0.0, after the keys refactor is finished. - The commit is mostly to visualize how much more lightweight the new implementation is. - It might be worth to skim the removed tests, if we are removing any interesting cases that we should port to test_signer. - python-tuf should not be affected, because it already uses the signer API - in-toto definitely is (see in-toto/in-toto#532) Signed-off-by: Lukas Puehringer <[email protected]>
1 parent a78288e commit cb09097

File tree

11 files changed

+13
-1010
lines changed

11 files changed

+13
-1010
lines changed

README.rst

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -181,29 +181,6 @@ cryptographic operations.
181181
>>> signature = create_signature(ecdsa_key, data)
182182

183183

184-
Verify ECDSA, Ed25519, and RSA Signatures
185-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
186-
187-
::
188-
189-
# Continuing from the previous sections . . .
190-
191-
>>> data = b'The quick brown fox jumps over the lazy dog'
192-
>>> ed25519_key = generate_ed25519_key()
193-
>>> signature = create_signature(ed25519_key, data)
194-
>>> verify_signature(ed25519_key, signature, data)
195-
True
196-
>>> verify_signature(ed25519_key, signature, 'bad_data')
197-
False
198-
>>> rsa_key = generate_rsa_key()
199-
>>> signature = create_signature(rsa_key, data)
200-
>>> verify_signature(rsa_key, signature, data)
201-
True
202-
>>> ecdsa_key = generate_ecdsa_key()
203-
>>> signature = create_signature(ecdsa_key, data)
204-
>>> verify_signature(ecdsa_key, signature, data)
205-
True
206-
207184

208185
Miscellaneous functions
209186
~~~~~~~~~~~~~~~~~~~~~~~

securesystemslib/ecdsa_keys.py

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
'securesystemslib.ecdsa_keys.py' calls the 'cryptography' library to perform
2323
all of the ecdsa-related operations.
2424
25-
The ecdsa-related functions included here are generate(), create_signature()
26-
and verify_signature(). The 'cryptography' library is used by ecdsa_keys.py
25+
The ecdsa-related functions included here are generate() and create_signature().
26+
The 'cryptography' library is used by ecdsa_keys.py
2727
to perform the actual ECDSA computations, and the functions listed above can
2828
be viewed as an easy-to-use public interface.
2929
"""
@@ -34,13 +34,12 @@
3434
CRYPTO = True
3535
NO_CRYPTO_MSG = "ECDSA key support requires the cryptography library"
3636
try:
37-
from cryptography.exceptions import InvalidSignature, UnsupportedAlgorithm
37+
from cryptography.exceptions import UnsupportedAlgorithm
3838
from cryptography.hazmat.backends import default_backend
3939
from cryptography.hazmat.primitives import hashes, serialization
4040
from cryptography.hazmat.primitives.asymmetric import ec
4141
from cryptography.hazmat.primitives.serialization import (
4242
load_pem_private_key,
43-
load_pem_public_key,
4443
)
4544

4645
_SCHEME_HASHER = {
@@ -260,89 +259,6 @@ def create_signature(
260259
return signature, scheme
261260

262261

263-
def verify_signature(public_key, scheme, signature, data):
264-
"""
265-
<Purpose>
266-
Verify that 'signature' was produced by the private key associated with
267-
'public_key'.
268-
269-
>>> scheme = 'ecdsa-sha2-nistp256'
270-
>>> public, private = generate_public_and_private(scheme)
271-
>>> data = b'The quick brown fox jumps over the lazy dog'
272-
>>> signature, scheme = create_signature(public, private, data, scheme)
273-
>>> verify_signature(public, scheme, signature, data)
274-
True
275-
>>> verify_signature(public, scheme, signature, b'bad data')
276-
False
277-
278-
<Arguments>
279-
public_key:
280-
The ECDSA public key in PEM format. The public key is needed to verify
281-
'signature'.
282-
283-
scheme:
284-
The signature scheme used to generate 'signature'. For example:
285-
'ecdsa-sha2-nistp256'.
286-
287-
signature:
288-
The signature to be verified, which should have been generated by
289-
the private key associated with 'public_key'. 'data'.
290-
291-
data:
292-
Byte data that was used by create_signature() to generate 'signature'.
293-
294-
<Exceptions>
295-
securesystemslib.exceptions.FormatError, if any of the arguments are
296-
improperly formatted.
297-
298-
securesystemslib.exceptions.UnsupportedAlgorithmError, if 'scheme' is
299-
not one of the supported signature schemes.
300-
301-
securesystemslib.exceptions.UnsupportedLibraryError, if the cryptography
302-
module is not available.
303-
304-
<Side Effects>
305-
None.
306-
307-
<Returns>
308-
Boolean, indicating whether the 'signature' of data was generated by
309-
the private key associated with 'public_key'.
310-
"""
311-
312-
if not CRYPTO: # pragma: no cover
313-
raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)
314-
315-
# Are the arguments properly formatted?
316-
# If not, raise 'securesystemslib.exceptions.FormatError'.
317-
formats.PEMECDSA_SCHEMA.check_match(public_key)
318-
formats.ECDSA_SCHEME_SCHEMA.check_match(scheme)
319-
formats.ECDSASIGNATURE_SCHEMA.check_match(signature)
320-
321-
try:
322-
ecdsa_key = load_pem_public_key(
323-
public_key.encode("utf-8"), backend=default_backend()
324-
)
325-
except ValueError as e:
326-
raise exceptions.FormatError(
327-
f"Failed to load PEM key {public_key}"
328-
) from e
329-
330-
if not isinstance(ecdsa_key, ec.EllipticCurvePublicKey):
331-
raise exceptions.FormatError(
332-
"Invalid ECDSA public" " key: " + repr(public_key)
333-
)
334-
logger.debug("Loaded a valid ECDSA public key.")
335-
336-
# verify() raises an 'InvalidSignature' exception if 'signature'
337-
# is invalid.
338-
try:
339-
ecdsa_key.verify(signature, data, _SCHEME_HASHER[scheme])
340-
return True
341-
342-
except (TypeError, InvalidSignature):
343-
return False
344-
345-
346262
def create_ecdsa_public_and_private_from_pem(pem, password=None):
347263
"""
348264
<Purpose>

securesystemslib/ed25519_keys.py

Lines changed: 3 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
http://nacl.cr.yp.to/
3838
https://github.com/pyca/ed25519
3939
40-
The ed25519-related functions included here are generate(), create_signature()
41-
and verify_signature(). The 'ed25519' and PyNaCl (i.e., 'nacl') modules used
40+
The ed25519-related functions included here are generate() and create_signature().
41+
The 'ed25519' and PyNaCl (i.e., 'nacl') modules used
4242
by ed25519_keys.py perform the actual ed25519 computations and the functions
4343
listed above can be viewed as an easy-to-use public interface.
4444
"""
@@ -67,18 +67,13 @@
6767
# avoid conflicts with own exceptions of same name
6868
from nacl import exceptions as nacl_exceptions
6969
from nacl.encoding import RawEncoder
70-
from nacl.signing import SigningKey, VerifyKey
70+
from nacl.signing import SigningKey
7171
except ImportError:
7272
NACL = False
7373

7474
# pylint: disable=wrong-import-position
7575
from securesystemslib import exceptions, formats
7676

77-
# The optimized pure Python implementation of Ed25519. If
78-
# PyNaCl cannot be imported and an attempt to use is made in this module, a
79-
# 'securesystemslib.exceptions.UnsupportedLibraryError' exception is raised.
80-
from securesystemslib._vendor.ed25519 import ed25519 as python_ed25519
81-
8277
# pylint: enable=wrong-import-position
8378

8479
# Supported ed25519 signing schemes: 'ed25519'. The pure Python implementation
@@ -248,112 +243,6 @@ def create_signature(public_key, private_key, data, scheme):
248243
return signature, scheme
249244

250245

251-
def verify_signature(public_key, scheme, signature, data):
252-
"""
253-
<Purpose>
254-
Determine whether the private key corresponding to 'public_key' produced
255-
'signature'. verify_signature() will use the public key, the 'scheme' and
256-
'sig', and 'data' arguments to complete the verification.
257-
258-
>>> public, private = generate_public_and_private()
259-
>>> data = b'The quick brown fox jumps over the lazy dog'
260-
>>> scheme = 'ed25519'
261-
>>> signature, scheme = \
262-
create_signature(public, private, data, scheme)
263-
>>> verify_signature(public, scheme, signature, data)
264-
True
265-
>>> bad_data = b'The sly brown fox jumps over the lazy dog'
266-
>>> bad_signature, scheme = \
267-
create_signature(public, private, bad_data, scheme)
268-
>>> verify_signature(public, scheme, bad_signature, data)
269-
False
270-
271-
<Arguments>
272-
public_key:
273-
The public key is a 32-byte string.
274-
275-
scheme:
276-
'ed25519' signature scheme used by either the pure python
277-
implementation (i.e., ed25519.py) or PyNacl (i.e., 'nacl').
278-
279-
signature:
280-
The signature is a 64-byte string.
281-
282-
data:
283-
Data object used by securesystemslib.ed25519_keys.create_signature() to
284-
generate 'signature'. 'data' is needed here to verify the signature.
285-
286-
<Exceptions>
287-
securesystemslib.exceptions.UnsupportedAlgorithmError. Raised if the
288-
signature scheme 'scheme' is not one supported by
289-
securesystemslib.ed25519_keys.create_signature().
290-
291-
securesystemslib.exceptions.FormatError. Raised if the arguments are
292-
improperly formatted.
293-
294-
<Side Effects>
295-
nacl.signing.VerifyKey.verify() called if available, otherwise
296-
securesystemslib._vendor.ed25519.ed25519.checkvalid() called to do the
297-
verification.
298-
299-
<Returns>
300-
Boolean. True if the signature is valid, False otherwise.
301-
"""
302-
303-
# Does 'public_key' have the correct format?
304-
# This check will ensure 'public_key' conforms to
305-
# 'securesystemslib.formats.ED25519PUBLIC_SCHEMA', which must have length 32
306-
# bytes. Raise 'securesystemslib.exceptions.FormatError' if the check fails.
307-
formats.ED25519PUBLIC_SCHEMA.check_match(public_key)
308-
309-
# Is 'scheme' properly formatted?
310-
formats.ED25519_SIG_SCHEMA.check_match(scheme)
311-
312-
# Is 'signature' properly formatted?
313-
formats.ED25519SIGNATURE_SCHEMA.check_match(signature)
314-
315-
# Verify 'signature'. Before returning the Boolean result, ensure 'ed25519'
316-
# was used as the signature scheme.
317-
public = public_key
318-
valid_signature = False
319-
320-
if scheme in _SUPPORTED_ED25519_SIGNING_SCHEMES:
321-
if NACL:
322-
try:
323-
nacl_verify_key = VerifyKey(public)
324-
nacl_verify_key.verify(data, signature)
325-
valid_signature = True
326-
327-
except nacl_exceptions.BadSignatureError:
328-
pass
329-
330-
# Verify 'ed25519' signature with the pure Python implementation.
331-
else:
332-
try:
333-
python_ed25519.checkvalid(signature, data, public)
334-
valid_signature = True
335-
336-
# The pure Python implementation raises 'Exception' if 'signature' is
337-
# invalid.
338-
except Exception: # pylint: disable=broad-except # nosec
339-
pass
340-
341-
# This is a defensive check for a valid 'scheme', which should have already
342-
# been validated in the ED25519_SIG_SCHEMA.check_match(scheme) above.
343-
else: # pragma: no cover
344-
message = (
345-
"Unsupported ed25519 signature scheme: "
346-
+ repr(scheme)
347-
+ ".\n"
348-
+ "Supported schemes: "
349-
+ repr(_SUPPORTED_ED25519_SIGNING_SCHEMES)
350-
+ "."
351-
)
352-
raise exceptions.UnsupportedAlgorithmError(message)
353-
354-
return valid_signature
355-
356-
357246
if __name__ == "__main__":
358247
# The interactive sessions of the documentation strings can
359248
# be tested by running 'ed25519_keys.py' as a standalone module.

0 commit comments

Comments
 (0)