From 1b2edf660319781a09113b3ece9aeb4f583c5042 Mon Sep 17 00:00:00 2001 From: Lukas Puehringer Date: Thu, 30 Mar 2023 16:09:58 +0200 Subject: [PATCH 1/4] test: refactor gracefully verify failure test Make test table driven to easily add other Key implementations. Signed-off-by: Lukas Puehringer --- tests/check_public_interfaces.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/check_public_interfaces.py b/tests/check_public_interfaces.py index 0ff1ba7b..5d4c7a3c 100644 --- a/tests/check_public_interfaces.py +++ b/tests/check_public_interfaces.py @@ -317,13 +317,21 @@ def test_gpg_functions(self): securesystemslib.gpg.functions.export_pubkey("f00") self.assertEqual(expected_error_msg, str(ctx.exception)) - def test_signer(self): + def test_signer_verify(self): """Assert generic VerificationError from UnsupportedLibraryError.""" - key = GPGKey("aa", "rsa", "pgp+rsa-pkcsv1.5", {"public": "val"}) - sig = Signature("aa", "aaaaaaa", {"other_headers": "aaaaaa"}) - with self.assertRaises(VerificationError) as ctx: - key.verify_signature(sig, b"data") - self.assertIsInstance(ctx.exception.__cause__, UnsupportedLibraryError) + keyid = "aa" + sig = Signature(keyid, "aaaaaaaa", {"other_headers": "aaaaaa"}) + + keys = [ + GPGKey(keyid, "rsa", "pgp+rsa-pkcsv1.5", {"public": "val"}), + ] + + for key in keys: + with self.assertRaises(VerificationError) as ctx: + key.verify_signature(sig, b"data") + self.assertIsInstance( + ctx.exception.__cause__, UnsupportedLibraryError + ) if __name__ == "__main__": From b42c8157c44177b3b9ee4eb9fb8dfa41cbb6d2cb Mon Sep 17 00:00:00 2001 From: Lukas Puehringer Date: Thu, 30 Mar 2023 17:39:57 +0200 Subject: [PATCH 2/4] test: add ed25519 pure python signing test Signed-off-by: Lukas Puehringer --- tests/check_public_interfaces.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/check_public_interfaces.py b/tests/check_public_interfaces.py index 5d4c7a3c..57f6f964 100644 --- a/tests/check_public_interfaces.py +++ b/tests/check_public_interfaces.py @@ -43,7 +43,7 @@ UnsupportedLibraryError, VerificationError, ) -from securesystemslib.signer import GPGKey, Signature +from securesystemslib.signer import GPGKey, Key, Signature class TestPublicInterfaces( @@ -333,6 +333,35 @@ def test_signer_verify(self): ctx.exception.__cause__, UnsupportedLibraryError ) + def test_signer_ed25519_fallback(self): + """Assert ed25519 signature verification works in pure Python.""" + data = b"The quick brown fox jumps over the lazy dog" + keyid = "aaa" + sig = Signature.from_dict( + { + "keyid": keyid, + "sig": "2ec7a5e295fa6265e10f3da7f1a432e7742f041f081b4faecab3a12bf0fc8f366c919c90c267e9ed1dfdeb7a7556b959a96dd0dcfea17da358622d39af36bf09", + } + ) + + key = Key.from_dict( + keyid, + { + "keytype": "ed25519", + "scheme": "ed25519", + "keyval": { + "public": "beb75c268206554e963c45dcbf3c004140d1cb69bbfe9370ef736f19388c9b26" + }, + }, + ) + + self.assertIsNone(key.verify_signature(sig, data)) + + with self.assertRaises( + securesystemslib.exceptions.UnverifiedSignatureError + ): + key.verify_signature(sig, b"NOT DATA") + if __name__ == "__main__": unittest.main(verbosity=1, buffer=True) From e6529cd31ad11642a42eb1c4a4005c613bffc56b Mon Sep 17 00:00:00 2001 From: Lukas Puehringer Date: Thu, 30 Mar 2023 17:33:06 +0200 Subject: [PATCH 3/4] signer: fix SSlibKey error handling in verify Key.verify_signature implementations should only raise UnverifiedSignatureError or VerificationError, even if an optional dependency is missing. This commit changes SSlibKey.verify_signature to re-raise UnsupportedLibrarError as VerificationError. Signed-off-by: Lukas Puehringer --- securesystemslib/signer/_key.py | 1 + 1 file changed, 1 insertion(+) diff --git a/securesystemslib/signer/_key.py b/securesystemslib/signer/_key.py index 24508d78..6cd52b4a 100644 --- a/securesystemslib/signer/_key.py +++ b/securesystemslib/signer/_key.py @@ -175,6 +175,7 @@ def verify_signature(self, signature: Signature, data: bytes) -> None: exceptions.CryptoError, exceptions.FormatError, exceptions.UnsupportedAlgorithmError, + exceptions.UnsupportedLibraryError, ) as e: logger.info("Key %s failed to verify sig: %s", self.keyid, str(e)) raise exceptions.VerificationError( From b1cf437cba158257154eaf002352825e70100c16 Mon Sep 17 00:00:00 2001 From: Lukas Puehringer Date: Thu, 30 Mar 2023 17:35:46 +0200 Subject: [PATCH 4/4] test: check all Key.verify_sign fail gracefully Test SSlibKey and SigstoreKey in addition to already tested GPGKey. Signed-off-by: Lukas Puehringer --- tests/check_public_interfaces.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/check_public_interfaces.py b/tests/check_public_interfaces.py index 57f6f964..ea330e88 100644 --- a/tests/check_public_interfaces.py +++ b/tests/check_public_interfaces.py @@ -43,7 +43,8 @@ UnsupportedLibraryError, VerificationError, ) -from securesystemslib.signer import GPGKey, Key, Signature +from securesystemslib.signer import GPGKey, Key, Signature, SSlibKey +from securesystemslib.signer._sigstore_signer import SigstoreKey class TestPublicInterfaces( @@ -324,13 +325,21 @@ def test_signer_verify(self): keys = [ GPGKey(keyid, "rsa", "pgp+rsa-pkcsv1.5", {"public": "val"}), + SSlibKey(keyid, "rsa", "rsa-pkcs1v15-sha512", {"public": "val"}), + SigstoreKey( + keyid, + "sigstore-oidc", + "Fulcio", + {"identity": "val", "issuer": "val"}, + ), ] for key in keys: with self.assertRaises(VerificationError) as ctx: key.verify_signature(sig, b"data") + self.assertIsInstance( - ctx.exception.__cause__, UnsupportedLibraryError + ctx.exception.__cause__, (UnsupportedLibraryError, ImportError) ) def test_signer_ed25519_fallback(self):