Skip to content

Commit

Permalink
Use ecdsa as the keytype for ECDSA keys
Browse files Browse the repository at this point in the history
Prior to this change ECDSA keys had a keytype that include their scheme.
Change this to simply 'ecdsa' for all ECDSA keys, regardless of scheme, to
better match other key types.

Continue to support reading keys of the old keytype+scheme format.

Signed-off-by: Joshua Lock <jlock@vmware.com>
  • Loading branch information
joshuagl committed Aug 18, 2020
1 parent abffc47 commit d14a64b
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 25 deletions.
5 changes: 3 additions & 2 deletions securesystemslib/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@

# Supported securesystemslib key types.
KEYTYPE_SCHEMA = SCHEMA.OneOf(
[SCHEMA.String('rsa'), SCHEMA.String('ed25519'),
[SCHEMA.String('rsa'), SCHEMA.String('ed25519'), SCHEMA.String('ecdsa'),
SCHEMA.RegularExpression(r'ecdsa-sha2-nistp(256|384)')])

# A generic securesystemslib key. All securesystemslib keys should be saved to
Expand Down Expand Up @@ -253,7 +253,8 @@
# An ECDSA securesystemslib key.
ECDSAKEY_SCHEMA = SCHEMA.Object(
object_name = 'ECDSAKEY_SCHEMA',
keytype = SCHEMA.RegularExpression(r'ecdsa-sha2-nistp(256|384)'),
keytype = SCHEMA.OneOf([SCHEMA.String('ecdsa'),
SCHEMA.RegularExpression(r'ecdsa-sha2-nistp(256|384)')]),
scheme = ECDSA_SCHEME_SCHEMA,
keyid = KEYID_SCHEMA,
keyid_hash_algorithms = SCHEMA.Optional(HASHALGORITHMS_SCHEMA),
Expand Down
9 changes: 7 additions & 2 deletions securesystemslib/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ def import_ecdsa_privatekey_from_file(filepath, password=None,
<Exceptions>
securesystemslib.exceptions.FormatError, if the arguments are improperly
formatted or the imported key object contains an invalid key type (i.e.,
not 'ecdsa-sha2-nistp256').
not 'ecdsa').
securesystemslib.exceptions.CryptoError, if 'filepath' cannot be decrypted.
Expand Down Expand Up @@ -931,7 +931,12 @@ def import_ecdsa_privatekey_from_file(filepath, password=None,
password)

# Raise an exception if an unexpected key type is imported.
if key_object['keytype'] != 'ecdsa-sha2-nistp256':
# NOTE: we support keytype's of ecdsa-sha2-nistp256 and ecdsa-sha2-nistp384
# in order to support key files generated with older versions of
# securesystemslib. At some point this backwards compatibility should be
# removed.
if key_object['keytype'] not in['ecdsa', 'ecdsa-sha2-nistp256',
'ecdsa-sha2-nistp384']:
message = 'Invalid key type loaded: ' + repr(key_object['keytype'])
raise securesystemslib.exceptions.FormatError(message)

Expand Down
22 changes: 12 additions & 10 deletions securesystemslib/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def generate_ecdsa_key(scheme='ecdsa-sha2-nistp256'):
ECDSA key is generated. The object returned conforms to
'securesystemslib.formats.ECDSAKEY_SCHEMA' and has the form:
{'keytype': 'ecdsa-sha2-nistp256',
{'keytype': 'ecdsa',
'scheme', 'ecdsa-sha2-nistp256',
'keyid': keyid,
'keyval': {'public': '',
Expand Down Expand Up @@ -260,7 +260,7 @@ def generate_ecdsa_key(scheme='ecdsa-sha2-nistp256'):

# Begin building the ECDSA key dictionary.
ecdsa_key = {}
keytype = 'ecdsa-sha2-nistp256'
keytype = 'ecdsa'
public = None
private = None

Expand Down Expand Up @@ -687,7 +687,7 @@ def create_signature(key_dict, data):
securesystemslib.formats.ANYKEY_SCHEMA.check_match(key_dict)

# Signing the 'data' object requires a private key. Signing schemes that are
# currently supported are: 'ed25519', 'ecdsa-sha2-nistp256', and rsa schemes
# currently supported are: 'ed25519', 'ecdsa', and rsa schemes
# defined in `securesystemslib.keys.RSA_SIGNATURE_SCHEMES`.
# RSASSA-PSS and RSA-PKCS1v15 keys and signatures can be generated and
# verified by rsa_keys.py, and Ed25519 keys by PyNaCl and PyCA's
Expand Down Expand Up @@ -716,7 +716,9 @@ def create_signature(key_dict, data):
sig, scheme = securesystemslib.ed25519_keys.create_signature(
public, private, data, scheme)

elif keytype == 'ecdsa-sha2-nistp256':
# Continue to support keytypes of ecdsa-sha2-nistp256 and ecdsa-sha2-nistp384
# for backwards compatibility with older securesystemslib releases
elif keytype in ['ecdsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384']:
sig, scheme = securesystemslib.ecdsa_keys.create_signature(
public, private, data, scheme)

Expand Down Expand Up @@ -860,7 +862,7 @@ def verify_signature(key_dict, signature, data):
raise securesystemslib.exceptions.UnsupportedAlgorithmError('Unsupported'
' signature scheme is specified: ' + repr(scheme))

elif keytype in ['ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384']:
elif keytype in ['ecdsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384']:
if scheme in ['ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384']:
valid_signature = securesystemslib.ecdsa_keys.verify_signature(public,
scheme, sig, data)
Expand Down Expand Up @@ -1637,7 +1639,7 @@ def import_ecdsakey_from_private_pem(pem, scheme='ecdsa-sha2-nistp256', password
a keyid identifier for the ECDSA key is generated. The object returned
conforms to:
{'keytype': 'ecdsa-sha2-nistp256',
{'keytype': 'ecdsa',
'scheme': 'ecdsa-sha2-nistp256',
'keyid': keyid,
'keyval': {'public': '-----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY-----',
Expand Down Expand Up @@ -1696,7 +1698,7 @@ def import_ecdsakey_from_private_pem(pem, scheme='ecdsa-sha2-nistp256', password

# Begin building the ECDSA key dictionary.
ecdsakey_dict = {}
keytype = 'ecdsa-sha2-nistp256'
keytype = 'ecdsa'
public = None
private = None

Expand Down Expand Up @@ -1740,7 +1742,7 @@ def import_ecdsakey_from_public_pem(pem, scheme='ecdsa-sha2-nistp256'):
for the ECDSA key is generated. The object returned conforms to
'securesystemslib.formats.ECDSAKEY_SCHEMA' and has the form:
{'keytype': 'ecdsa-sha2-nistp256',
{'keytype': 'ecdsa',
'scheme': 'ecdsa-sha2-nistp256',
'keyid': keyid,
'keyval': {'public': '-----BEGIN PUBLIC KEY----- ...',
Expand Down Expand Up @@ -1801,7 +1803,7 @@ def import_ecdsakey_from_public_pem(pem, scheme='ecdsa-sha2-nistp256'):

# Begin building the ECDSA key dictionary.
ecdsakey_dict = {}
keytype = 'ecdsa-sha2-nistp256'
keytype = 'ecdsa'

# Generate the keyid of the ECDSA key. 'key_value' corresponds to the
# 'keyval' entry of the 'ECDSAKEY_SCHEMA' dictionary. The private key
Expand Down Expand Up @@ -1882,7 +1884,7 @@ def import_ecdsakey_from_pem(pem, scheme='ecdsa-sha2-nistp256'):

# Begin building the ECDSA key dictionary.
ecdsakey_dict = {}
keytype = 'ecdsa-sha2-nistp256'
keytype = 'ecdsa'

# Generate the keyid of the ECDSA key. 'key_value' corresponds to the
# 'keyval' entry of the 'ECDSAKEY_SCHEMA' dictionary. The private key
Expand Down
4 changes: 2 additions & 2 deletions tests/check_public_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def test_keys(self):
securesystemslib.exceptions.UnsupportedLibraryError):
securesystemslib.keys.create_signature(keydict, data)

keydict['keytype'] = 'ecdsa-sha2-nistp256'
keydict['keytype'] = 'ecdsa'
keydict['scheme'] = 'ecdsa-sha2-nistp256'
with self.assertRaises(
securesystemslib.exceptions.UnsupportedLibraryError):
Expand All @@ -137,7 +137,7 @@ def test_keys(self):
securesystemslib.exceptions.UnsupportedLibraryError):
securesystemslib.keys.create_signature(keydict, data)

keydict['keytype'] = 'ecdsa-sha2-nistp256'
keydict['keytype'] = 'ecdsa'
keydict['scheme'] = 'ecdsa-sha2-nistp256'
sig = {'keyid': 'f00',
'sig': 'cfbce8e23eef478975a4339036de2335002d57c7b1632dd01e526a3bc52a5b261508ad50b9e25f1b819d61017e7347e912db1af019bf47ee298cc58bbdef9703'}
Expand Down
14 changes: 5 additions & 9 deletions tests/test_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,15 +276,11 @@ def test_create_signature(self):

# Creating a signature for 'DATA'.
ecdsa_signature = KEYS.create_signature(self.ecdsakey_dict, DATA)
ecdsa_signature = KEYS.create_signature(self.ecdsakey_dict, DATA)

# Check format of output.
self.assertEqual(None,
securesystemslib.formats.SIGNATURE_SCHEMA.check_match(ecdsa_signature),
FORMAT_ERROR_MSG)
self.assertEqual(None,
securesystemslib.formats.SIGNATURE_SCHEMA.check_match(ecdsa_signature),
FORMAT_ERROR_MSG)

# Removing private key from 'ecdsakey_dict' - should raise a TypeError.
private = self.ecdsakey_dict['keyval']['private']
Expand All @@ -304,8 +300,6 @@ def test_verify_signature(self):
# Creating a signature of 'DATA' to be verified.
rsa_signature = KEYS.create_signature(self.rsakey_dict, DATA)
ed25519_signature = KEYS.create_signature(self.ed25519key_dict, DATA)
ecdsa_signature = None

ecdsa_signature = KEYS.create_signature(self.ecdsakey_dict, DATA)

# Verifying the 'signature' of 'DATA'.
Expand All @@ -324,12 +318,14 @@ def test_verify_signature(self):
KEYS.verify_signature, self.ed25519key_dict, ed25519_signature, DATA)
self.ed25519key_dict['scheme'] = valid_scheme

# Verifying the 'ecdsa_signature' of 'DATA'.
verified = KEYS.verify_signature(self.ecdsakey_dict, ecdsa_signature, DATA)
self.assertTrue(verified, "Incorrect signature.")

# Verifying the 'ecdsa_signature' of 'DATA'.
verified = KEYS.verify_signature(self.ecdsakey_dict, ecdsa_signature,
DATA)
# Verifying the 'ecdsa_signature' of 'DATA' with an old-style key dict
old_key_dict = self.ecdsakey_dict.copy()
old_key_dict['keytype'] = 'ecdsa-sha2-nistp256'
verified = KEYS.verify_signature(old_key_dict, ecdsa_signature, DATA)
self.assertTrue(verified, "Incorrect signature.")

# Test for an invalid ecdsa signature scheme.
Expand Down

0 comments on commit d14a64b

Please sign in to comment.