diff --git a/tests/test_api.py b/tests/test_api.py index e0b57114b2..07bb9408a7 100755 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -181,6 +181,11 @@ def test_sign_verify(self): with self.assertRaises(exceptions.UnsignedMetadataError): snapshot_key.verify_signature(metadata_obj) + # Test verifying with explicitly set serializer + targets_key.verify_signature(metadata_obj, CanonicalJSONSerializer()) + with self.assertRaises(exceptions.UnsignedMetadataError): + targets_key.verify_signature(metadata_obj, JSONSerializer()) + sslib_signer = SSlibSigner(self.keystore['snapshot']) # Append a new signature with the unrelated key and assert that ... metadata_obj.sign(sslib_signer, append=True) @@ -200,6 +205,32 @@ def test_sign_verify(self): with self.assertRaises(exceptions.UnsignedMetadataError): targets_key.verify_signature(metadata_obj) + # Test failure on unknown scheme (securesystemslib UnsupportedAlgorithmError) + scheme = timestamp_key.scheme + timestamp_key.scheme = "foo" + with self.assertRaises(exceptions.UnsignedMetadataError): + timestamp_key.verify_signature(metadata_obj) + timestamp_key.scheme = scheme + + # Test failure on broken public key data (securesystemslib CryptoError) + public = timestamp_key.keyval["public"] + timestamp_key.keyval["public"] = "ffff" + with self.assertRaises(exceptions.UnsignedMetadataError): + timestamp_key.verify_signature(metadata_obj) + timestamp_key.keyval["public"] = public + + # Test failure with invalid signature (securesystemslib FormatError) + sig = metadata_obj.signatures[timestamp_keyid] + correct_sig = sig.signature + sig.signature = "foo" + with self.assertRaises(exceptions.UnsignedMetadataError): + timestamp_key.verify_signature(metadata_obj) + + # Test failure with valid but incorrect signature + sig.signature = "ff"*64 + with self.assertRaises(exceptions.UnsignedMetadataError): + timestamp_key.verify_signature(metadata_obj) + sig.signature = correct_sig def test_metadata_base(self): # Use of Snapshot is arbitrary, we're just testing the base class features diff --git a/tuf/api/metadata.py b/tuf/api/metadata.py index 73f221a04e..dc30b2465d 100644 --- a/tuf/api/metadata.py +++ b/tuf/api/metadata.py @@ -33,6 +33,7 @@ Union, ) +from securesystemslib import exceptions as sslib_exceptions from securesystemslib import hash as sslib_hash from securesystemslib import keys as sslib_keys from securesystemslib.signer import Signature, Signer @@ -483,8 +484,6 @@ def verify_signature( Raises: UnsignedMetadataError: The signature could not be verified for a variety of possible reasons: see error message. - TODO: Various other errors currently bleed through from lower - level components: Issue #1351 """ try: signature = metadata.signatures[self.keyid] @@ -500,15 +499,25 @@ def verify_signature( signed_serializer = CanonicalJSONSerializer() - if not sslib_keys.verify_signature( - self.to_securesystemslib_key(), - signature.to_dict(), - signed_serializer.serialize(metadata.signed), - ): + try: + if not sslib_keys.verify_signature( + self.to_securesystemslib_key(), + signature.to_dict(), + signed_serializer.serialize(metadata.signed), + ): + raise exceptions.UnsignedMetadataError( + f"Failed to verify {self.keyid} signature", + metadata.signed, + ) + except ( + sslib_exceptions.CryptoError, + sslib_exceptions.FormatError, + sslib_exceptions.UnsupportedAlgorithmError, + ) as e: raise exceptions.UnsignedMetadataError( - f"Failed to verify {self.keyid} signature for metadata", + f"Failed to verify {self.keyid} signature", metadata.signed, - ) + ) from e class Role: