diff --git a/setup.py b/setup.py index 7984d2d662..10aa219248 100755 --- a/setup.py +++ b/setup.py @@ -113,7 +113,7 @@ python_requires="~=3.6", install_requires = [ 'requests>=2.19.1', - 'securesystemslib>=0.18.0', + 'securesystemslib>=0.20.0', 'six>=1.11.0' ], packages = find_packages(exclude=['tests']), diff --git a/tests/test_api.py b/tests/test_api.py index ec7d182b79..20e3e38f43 100755 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -153,8 +153,9 @@ def test_sign_verify(self): self.assertTrue(metadata_obj.verify( self.keystore['targets']['public'])) + sslib_signer = SSlibSigner(self.keystore['snapshot']['private']) # Append a new signature with the unrelated key and assert that ... - metadata_obj.sign(self.keystore['snapshot']['private'], append=True) + metadata_obj.sign(sslib_signer, append=True) # ... there are now two signatures, and self.assertTrue(len(metadata_obj.signatures) == 2) # ... both are valid for the corresponding keys. @@ -163,8 +164,9 @@ def test_sign_verify(self): self.assertTrue(metadata_obj.verify( self.keystore['snapshot']['public'])) + sslib_signer.key_dict = self.keystore['timestamp']['private'] # Create and assign (don't append) a new signature and assert that ... - metadata_obj.sign(self.keystore['timestamp']['private'], append=False) + metadata_obj.sign(sslib_signer, append=False) # ... there now is only one signature, self.assertTrue(len(metadata_obj.signatures) == 1) # ... valid for that key. @@ -172,7 +174,7 @@ def test_sign_verify(self): self.keystore['timestamp']['public'])) # Assert exception if there are more than one signatures for a key - metadata_obj.sign(self.keystore['timestamp']['private'], append=True) + metadata_obj.sign(sslib_signer, append=True) with self.assertRaises(tuf.exceptions.Error) as ctx: metadata_obj.verify(self.keystore['timestamp']['public']) self.assertTrue( diff --git a/tuf/api/metadata.py b/tuf/api/metadata.py index a747be6d13..dacc088b44 100644 --- a/tuf/api/metadata.py +++ b/tuf/api/metadata.py @@ -19,7 +19,8 @@ persist_temp_file ) from securesystemslib.storage import StorageBackendInterface -from securesystemslib.keys import create_signature, verify_signature +from securesystemslib.keys import verify_signature +from securesystemslib.signer import Signer, Signature import tuf.formats import tuf.exceptions @@ -92,12 +93,17 @@ class also that has a 'from_dict' factory method. (Currently this is else: raise ValueError(f'unrecognized metadata type "{_type}"') + signatures = [] + for signature in metadata['signatures']: + new_signature = Signature(signature['keyid'], signature['sig']) + signatures.append(new_signature) + # NOTE: If Signature becomes a class, we should iterate over # metadata['signatures'], call Signature.from_dict for each item, and # pass a list of Signature objects to the Metadata constructor intead. return cls( signed=inner_cls.from_dict(metadata['signed']), - signatures=metadata['signatures']) + signatures=signatures) @classmethod @@ -146,8 +152,13 @@ def from_json_file( # Serialization. def to_dict(self) -> JsonDict: """Returns the JSON-serializable dictionary representation of self. """ + + signatures = [] + for sig in self.signatures: + signatures.append(sig.to_dict()) + return { - 'signatures': self.signatures, + 'signatures': signatures, 'signed': self.signed.to_dict() } @@ -184,11 +195,12 @@ def to_json_file( # Signatures. - def sign(self, key: JsonDict, append: bool = False) -> JsonDict: + def sign(self, signer: Signer, append: bool = False) -> JsonDict: """Creates signature over 'signed' and assigns it to 'signatures'. Arguments: - key: A securesystemslib-style private key object used for signing. + singer: An object implementing the securesystemslib.signer.Signer + interface. append: A boolean indicating if the signature should be appended to the list of signatures or replace any existing signatures. The default behavior is to replace signatures. @@ -203,7 +215,7 @@ def sign(self, key: JsonDict, append: bool = False) -> JsonDict: A securesystemslib-style signature object. """ - signature = create_signature(key, self.signed.to_canonical_bytes()) + signature = signer.sign(self.signed.to_canonical_bytes()) if append: self.signatures.append(signature) @@ -232,7 +244,7 @@ def verify(self, key: JsonDict) -> bool: """ signatures_for_keyid = list(filter( - lambda sig: sig['keyid'] == key['keyid'], self.signatures)) + lambda sig: sig.keyid == key['keyid'], self.signatures)) if not signatures_for_keyid: raise tuf.exceptions.Error( @@ -244,7 +256,7 @@ def verify(self, key: JsonDict) -> bool: f'{key["keyid"]}, not sure which one to verify.') return verify_signature( - key, signatures_for_keyid[0], + key, signatures_for_keyid[0].to_dict(), self.signed.to_canonical_bytes())