Skip to content

Commit

Permalink
Merge pull request #316 from jku/vendoring-compatible-imports
Browse files Browse the repository at this point in the history
Vendoring-compatible imports
  • Loading branch information
lukpueh authored Feb 17, 2021
2 parents 2397007 + 25f112b commit 3bc866c
Show file tree
Hide file tree
Showing 19 changed files with 563 additions and 592 deletions.
52 changes: 26 additions & 26 deletions securesystemslib/ecdsa_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
from cryptography.hazmat.primitives.serialization import load_pem_public_key
from cryptography.hazmat.primitives.serialization import load_pem_private_key

import cryptography.exceptions
from cryptography.exceptions import (InvalidSignature, UnsupportedAlgorithm)

_SCHEME_HASHER = {
'ecdsa-sha2-nistp256': ec.ECDSA(hashes.SHA256()),
Expand All @@ -62,8 +62,8 @@
CRYPTO = False

# Perform object format-checking and add ability to handle/raise exceptions.
import securesystemslib.formats
import securesystemslib.exceptions
from securesystemslib import exceptions
from securesystemslib import formats

_SUPPORTED_ECDSA_SCHEMES = ['ecdsa-sha2-nistp256']

Expand Down Expand Up @@ -131,14 +131,14 @@ def generate_public_and_private(scheme='ecdsa-sha2-nistp256'):
"""

if not CRYPTO: # pragma: no cover
raise securesystemslib.exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)
raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)

# Does 'scheme' have the correct format?
# Verify that 'scheme' is of the correct type, and that it's one of the
# supported ECDSA . It must conform to
# 'securesystemslib.formats.ECDSA_SCHEME_SCHEMA'. Raise
# 'securesystemslib.exceptions.FormatError' if the check fails.
securesystemslib.formats.ECDSA_SCHEME_SCHEMA.check_match(scheme)
formats.ECDSA_SCHEME_SCHEMA.check_match(scheme)

public_key = None
private_key = None
Expand All @@ -153,7 +153,7 @@ def generate_public_and_private(scheme='ecdsa-sha2-nistp256'):
# The ECDSA_SCHEME_SCHEMA.check_match() above should have detected any
# invalid 'scheme'. This is a defensive check.
else: #pragma: no cover
raise securesystemslib.exceptions.UnsupportedAlgorithmError('An unsupported'
raise exceptions.UnsupportedAlgorithmError('An unsupported'
' scheme specified: ' + repr(scheme) + '.\n Supported'
' algorithms: ' + repr(_SUPPORTED_ECDSA_SCHEMES))

Expand Down Expand Up @@ -220,19 +220,19 @@ def create_signature(public_key, private_key, data, scheme='ecdsa-sha2-nistp256'
"""

if not CRYPTO: # pragma: no cover
raise securesystemslib.exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)
raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)

# Do 'public_key' and 'private_key' have the correct format?
# This check will ensure that the arguments conform to
# 'securesystemslib.formats.PEMECDSA_SCHEMA'. Raise
# 'securesystemslib.exceptions.FormatError' if the check fails.
securesystemslib.formats.PEMECDSA_SCHEMA.check_match(public_key)
formats.PEMECDSA_SCHEMA.check_match(public_key)

# Is 'private_key' properly formatted?
securesystemslib.formats.PEMECDSA_SCHEMA.check_match(private_key)
formats.PEMECDSA_SCHEMA.check_match(private_key)

# Is 'scheme' properly formatted?
securesystemslib.formats.ECDSA_SCHEME_SCHEMA.check_match(scheme)
formats.ECDSA_SCHEME_SCHEMA.check_match(scheme)

# 'ecdsa-sha2-nistp256' is the only currently supported ECDSA scheme, so this
# if-clause isn't strictly needed. Nevertheless, the conditional statement
Expand All @@ -246,13 +246,13 @@ def create_signature(public_key, private_key, data, scheme='ecdsa-sha2-nistp256'
signature = private_key.sign(data, ec.ECDSA(hashes.SHA256()))

except TypeError as e:
raise securesystemslib.exceptions.CryptoError('Could not create'
raise exceptions.CryptoError('Could not create'
' signature: ' + str(e))

# A defensive check for an invalid 'scheme'. The
# ECDSA_SCHEME_SCHEMA.check_match() above should have already validated it.
else: #pragma: no cover
raise securesystemslib.exceptions.UnsupportedAlgorithmError('Unsupported'
raise exceptions.UnsupportedAlgorithmError('Unsupported'
' signature scheme is specified: ' + repr(scheme))

return signature, scheme
Expand Down Expand Up @@ -311,19 +311,19 @@ def verify_signature(public_key, scheme, signature, data):
"""

if not CRYPTO: # pragma: no cover
raise securesystemslib.exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)
raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)

# Are the arguments properly formatted?
# If not, raise 'securesystemslib.exceptions.FormatError'.
securesystemslib.formats.PEMECDSA_SCHEMA.check_match(public_key)
securesystemslib.formats.ECDSA_SCHEME_SCHEMA.check_match(scheme)
securesystemslib.formats.ECDSASIGNATURE_SCHEMA.check_match(signature)
formats.PEMECDSA_SCHEMA.check_match(public_key)
formats.ECDSA_SCHEME_SCHEMA.check_match(scheme)
formats.ECDSASIGNATURE_SCHEMA.check_match(signature)

ecdsa_key = load_pem_public_key(public_key.encode('utf-8'),
backend=default_backend())

if not isinstance(ecdsa_key, ec.EllipticCurvePublicKey):
raise securesystemslib.exceptions.FormatError('Invalid ECDSA public'
raise exceptions.FormatError('Invalid ECDSA public'
' key: ' + repr(public_key))

else:
Expand All @@ -335,7 +335,7 @@ def verify_signature(public_key, scheme, signature, data):
ecdsa_key.verify(signature, data, _SCHEME_HASHER[scheme])
return True

except (TypeError, cryptography.exceptions.InvalidSignature):
except (TypeError, InvalidSignature):
return False


Expand Down Expand Up @@ -394,15 +394,15 @@ def create_ecdsa_public_and_private_from_pem(pem, password=None):
"""

if not CRYPTO: # pragma: no cover
raise securesystemslib.exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)
raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)

# Does 'pem' have the correct format?
# This check will ensure 'pem' conforms to
# 'securesystemslib.formats.ECDSARSA_SCHEMA'.
securesystemslib.formats.PEMECDSA_SCHEMA.check_match(pem)
formats.PEMECDSA_SCHEMA.check_match(pem)

if password is not None:
securesystemslib.formats.PASSWORD_SCHEMA.check_match(password)
formats.PASSWORD_SCHEMA.check_match(password)
password = password.encode('utf-8')

else:
Expand All @@ -418,8 +418,8 @@ def create_ecdsa_public_and_private_from_pem(pem, password=None):
private = load_pem_private_key(pem.encode('utf-8'), password=password,
backend=default_backend())

except (ValueError, cryptography.exceptions.UnsupportedAlgorithm) as e:
raise securesystemslib.exceptions.CryptoError('Could not import private'
except (ValueError, UnsupportedAlgorithm) as e:
raise exceptions.CryptoError('Could not import private'
' PEM.\n' + str(e))

public = private.public_key()
Expand Down Expand Up @@ -481,14 +481,14 @@ def create_ecdsa_encrypted_pem(private_pem, passphrase):
"""

if not CRYPTO: # pragma: no cover
raise securesystemslib.exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)
raise exceptions.UnsupportedLibraryError(NO_CRYPTO_MSG)

# Does 'private_key' have the correct format?
# Raise 'securesystemslib.exceptions.FormatError' if the check fails.
securesystemslib.formats.PEMRSA_SCHEMA.check_match(private_pem)
formats.PEMRSA_SCHEMA.check_match(private_pem)

# Does 'passphrase' have the correct format?
securesystemslib.formats.PASSWORD_SCHEMA.check_match(passphrase)
formats.PASSWORD_SCHEMA.check_match(passphrase)

private = load_pem_private_key(private_pem.encode('utf-8'), password=None,
backend=default_backend())
Expand Down
49 changes: 25 additions & 24 deletions securesystemslib/ed25519_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,20 @@
NACL = True
NO_NACL_MSG = "ed25519 key support requires the nacl library"
try:
import nacl.signing
import nacl.encoding
from nacl.encoding import RawEncoder
from nacl.signing import (SigningKey, VerifyKey)
# avoid conflicts with own exceptions of same name
from nacl import exceptions as nacl_exceptions
except ImportError:
NACL = False

# The optimized pure Python implementation of Ed25519. If
# PyNaCl cannot be imported and an attempt to use is made in this module, a
# 'securesystemslib.exceptions.UnsupportedLibraryError' exception is raised.
import securesystemslib._vendor.ed25519.ed25519
from securesystemslib._vendor.ed25519 import ed25519 as python_ed25519

import securesystemslib.formats
import securesystemslib.exceptions
from securesystemslib import exceptions
from securesystemslib import formats

# Supported ed25519 signing schemes: 'ed25519'. The pure Python implementation
# (i.e., ed25519') and PyNaCl (i.e., 'nacl', libsodium + Python bindings)
Expand Down Expand Up @@ -130,7 +132,7 @@ def generate_public_and_private():
"""

if not NACL: # pragma: no cover
raise securesystemslib.exceptions.UnsupportedLibraryError(NO_NACL_MSG)
raise exceptions.UnsupportedLibraryError(NO_NACL_MSG)

# Generate ed25519's seed key by calling os.urandom(). The random bytes
# returned should be suitable for cryptographic use and is OS-specific.
Expand All @@ -142,8 +144,8 @@ def generate_public_and_private():

# Generate the public key. PyNaCl (i.e., 'nacl' module) performs the actual
# key generation.
nacl_key = nacl.signing.SigningKey(seed)
public = nacl_key.verify_key.encode(encoder=nacl.encoding.RawEncoder())
nacl_key = SigningKey(seed)
public = nacl_key.verify_key.encode(encoder=RawEncoder())

return public, seed

Expand Down Expand Up @@ -210,19 +212,19 @@ def create_signature(public_key, private_key, data, scheme):
"""

if not NACL: # pragma: no cover
raise securesystemslib.exceptions.UnsupportedLibraryError(NO_NACL_MSG)
raise exceptions.UnsupportedLibraryError(NO_NACL_MSG)

# Does 'public_key' have the correct format?
# This check will ensure 'public_key' conforms to
# 'securesystemslib.formats.ED25519PUBLIC_SCHEMA', which must have length 32
# bytes. Raise 'securesystemslib.exceptions.FormatError' if the check fails.
securesystemslib.formats.ED25519PUBLIC_SCHEMA.check_match(public_key)
formats.ED25519PUBLIC_SCHEMA.check_match(public_key)

# Is 'private_key' properly formatted?
securesystemslib.formats.ED25519SEED_SCHEMA.check_match(private_key)
formats.ED25519SEED_SCHEMA.check_match(private_key)

# Is 'scheme' properly formatted?
securesystemslib.formats.ED25519_SIG_SCHEMA.check_match(scheme)
formats.ED25519_SIG_SCHEMA.check_match(scheme)

# Signing the 'data' object requires a seed and public key.
# nacl.signing.SigningKey.sign() generates the signature.
Expand All @@ -233,18 +235,18 @@ def create_signature(public_key, private_key, data, scheme):
# statement to accommodate schemes that might be added in the future.
if scheme == 'ed25519':
try:
nacl_key = nacl.signing.SigningKey(private_key)
nacl_key = SigningKey(private_key)
nacl_sig = nacl_key.sign(data)
signature = nacl_sig.signature

except (ValueError, TypeError, nacl.exceptions.CryptoError) as e:
raise securesystemslib.exceptions.CryptoError('An "ed25519" signature'
except (ValueError, TypeError, nacl_exceptions.CryptoError) as e:
raise exceptions.CryptoError('An "ed25519" signature'
' could not be created with PyNaCl.' + str(e))

# This is a defensive check for a valid 'scheme', which should have already
# been validated in the check_match() above.
else: #pragma: no cover
raise securesystemslib.exceptions.UnsupportedAlgorithmError('Unsupported'
raise exceptions.UnsupportedAlgorithmError('Unsupported'
' signature scheme is specified: ' + repr(scheme))

return signature, scheme
Expand Down Expand Up @@ -309,13 +311,13 @@ def verify_signature(public_key, scheme, signature, data):
# This check will ensure 'public_key' conforms to
# 'securesystemslib.formats.ED25519PUBLIC_SCHEMA', which must have length 32
# bytes. Raise 'securesystemslib.exceptions.FormatError' if the check fails.
securesystemslib.formats.ED25519PUBLIC_SCHEMA.check_match(public_key)
formats.ED25519PUBLIC_SCHEMA.check_match(public_key)

# Is 'scheme' properly formatted?
securesystemslib.formats.ED25519_SIG_SCHEMA.check_match(scheme)
formats.ED25519_SIG_SCHEMA.check_match(scheme)

# Is 'signature' properly formatted?
securesystemslib.formats.ED25519SIGNATURE_SCHEMA.check_match(signature)
formats.ED25519SIGNATURE_SCHEMA.check_match(signature)

# Verify 'signature'. Before returning the Boolean result, ensure 'ed25519'
# was used as the signature scheme.
Expand All @@ -325,18 +327,17 @@ def verify_signature(public_key, scheme, signature, data):
if scheme in _SUPPORTED_ED25519_SIGNING_SCHEMES:
if NACL:
try:
nacl_verify_key = nacl.signing.VerifyKey(public)
nacl_verify_key = VerifyKey(public)
nacl_verify_key.verify(data, signature)
valid_signature = True

except nacl.exceptions.BadSignatureError:
except nacl_exceptions.BadSignatureError:
pass

# Verify 'ed25519' signature with the pure Python implementation.
else:
try:
securesystemslib._vendor.ed25519.ed25519.checkvalid(signature,
data, public)
python_ed25519.checkvalid(signature, data, public)
valid_signature = True

# The pure Python implementation raises 'Exception' if 'signature' is
Expand All @@ -349,7 +350,7 @@ def verify_signature(public_key, scheme, signature, data):
else: #pragma: no cover
message = 'Unsupported ed25519 signature scheme: ' + repr(scheme) + '.\n' + \
'Supported schemes: ' + repr(_SUPPORTED_ED25519_SIGNING_SCHEMES) + '.'
raise securesystemslib.exceptions.UnsupportedAlgorithmError(message)
raise exceptions.UnsupportedAlgorithmError(message)

return valid_signature

Expand Down
18 changes: 9 additions & 9 deletions securesystemslib/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@
import time
import six

import securesystemslib.schema as SCHEMA
import securesystemslib.exceptions
from securesystemslib import exceptions
from securesystemslib import schema as SCHEMA

# Note that in the schema definitions below, the 'SCHEMA.Object' types allow
# additional keys which are not defined. Thus, any additions to them will be
Expand Down Expand Up @@ -476,7 +476,7 @@ def datetime_to_unix_timestamp(datetime_object):
# Raise 'securesystemslib.exceptions.FormatError' if not.
if not isinstance(datetime_object, datetime.datetime):
message = repr(datetime_object) + ' is not a datetime.datetime() object.'
raise securesystemslib.exceptions.FormatError(message)
raise exceptions.FormatError(message)

unix_timestamp = calendar.timegm(datetime_object.timetuple())

Expand Down Expand Up @@ -554,7 +554,7 @@ def format_base64(data):
return binascii.b2a_base64(data).decode('utf-8').rstrip('=\n ')

except (TypeError, binascii.Error) as e:
raise securesystemslib.exceptions.FormatError('Invalid base64'
raise exceptions.FormatError('Invalid base64'
' encoding: ' + str(e))


Expand Down Expand Up @@ -583,7 +583,7 @@ def parse_base64(base64_string):

if not isinstance(base64_string, six.string_types):
message = 'Invalid argument: '+repr(base64_string)
raise securesystemslib.exceptions.FormatError(message)
raise exceptions.FormatError(message)

extra = len(base64_string) % 4
if extra:
Expand All @@ -594,7 +594,7 @@ def parse_base64(base64_string):
return binascii.a2b_base64(base64_string.encode('utf-8'))

except (TypeError, binascii.Error) as e:
raise securesystemslib.exceptions.FormatError('Invalid base64'
raise exceptions.FormatError('Invalid base64'
' encoding: ' + str(e))


Expand Down Expand Up @@ -661,7 +661,7 @@ def _encode_canonical(object, output_function):
_encode_canonical(value, output_function)
output_function("}")
else:
raise securesystemslib.exceptions.FormatError('I cannot encode '+repr(object))
raise exceptions.FormatError('I cannot encode '+repr(object))


def encode_canonical(object, output_function=None):
Expand Down Expand Up @@ -724,9 +724,9 @@ def encode_canonical(object, output_function=None):
try:
_encode_canonical(object, output_function)

except (TypeError, securesystemslib.exceptions.FormatError) as e:
except (TypeError, exceptions.FormatError) as e:
message = 'Could not encode ' + repr(object) + ': ' + str(e)
raise securesystemslib.exceptions.FormatError(message)
raise exceptions.FormatError(message)

# Return the encoded 'object' as a string.
# Note: Implies 'output_function' is None,
Expand Down
Loading

0 comments on commit 3bc866c

Please sign in to comment.