diff --git a/securesystemslib/formats.py b/securesystemslib/formats.py index 401525fb..70d7feb2 100755 --- a/securesystemslib/formats.py +++ b/securesystemslib/formats.py @@ -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 @@ -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), diff --git a/securesystemslib/interface.py b/securesystemslib/interface.py index 38ed68a0..98fcf721 100755 --- a/securesystemslib/interface.py +++ b/securesystemslib/interface.py @@ -848,13 +848,6 @@ def import_ecdsa_publickey_from_file(filepath): ecdsa_key, junk = \ securesystemslib.keys.format_metadata_to_key(ecdsa_key_metadata) - # Raise an exception if an unexpected key type is imported. Redundant - # validation of 'keytype'. 'securesystemslib.keys.format_metadata_to_key()' - # should have fully validated 'ecdsa_key_metadata'. - if ecdsa_key['keytype'] != 'ecdsa-sha2-nistp256': # pragma: no cover - message = 'Invalid key type loaded: ' + repr(ecdsa_key['keytype']) - raise securesystemslib.exceptions.FormatError(message) - return ecdsa_key @@ -888,7 +881,7 @@ def import_ecdsa_privatekey_from_file(filepath, password=None, 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. @@ -938,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) diff --git a/securesystemslib/keys.py b/securesystemslib/keys.py index b5e287f9..b5c5ca02 100755 --- a/securesystemslib/keys.py +++ b/securesystemslib/keys.py @@ -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': '', @@ -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 @@ -687,8 +687,9 @@ 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 - # defined in `securesystemslib.keys.RSA_SIGNATURE_SCHEMES`. + # currently supported are: 'ed25519', 'ecdsa-sha2-nistp256', + # 'ecdsa-sha2-nistp384' 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 # optimized, pure python implementation of Ed25519. @@ -716,7 +717,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) @@ -860,7 +863,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) @@ -1637,7 +1640,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-----', @@ -1696,7 +1699,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 @@ -1740,7 +1743,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----- ...', @@ -1801,7 +1804,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 @@ -1882,7 +1885,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 diff --git a/tests/check_public_interfaces.py b/tests/check_public_interfaces.py index c021975f..dcec9c00 100644 --- a/tests/check_public_interfaces.py +++ b/tests/check_public_interfaces.py @@ -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): @@ -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'} diff --git a/tests/test_keys.py b/tests/test_keys.py index dd13867c..0a05bc7d 100755 --- a/tests/test_keys.py +++ b/tests/test_keys.py @@ -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'] @@ -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'. @@ -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.