|
15 | 15 | import unittest |
16 | 16 | from copy import copy |
17 | 17 | from datetime import datetime, timedelta |
| 18 | +from pathlib import Path |
18 | 19 | from typing import Any, ClassVar, Dict, Optional |
19 | 20 |
|
20 | 21 | from securesystemslib import exceptions as sslib_exceptions |
|
33 | 34 |
|
34 | 35 | from tests import utils |
35 | 36 | from tuf.api import exceptions |
| 37 | +from tuf.api.dsse import SimpleEnvelope |
36 | 38 | from tuf.api.metadata import ( |
37 | 39 | TOP_LEVEL_ROLE_NAMES, |
38 | 40 | DelegatedRole, |
@@ -1009,6 +1011,95 @@ def test_get_roles_in_succinct_roles(self) -> None: |
1009 | 1011 | self.assertEqual(role_name, f"bin-{expected_bin_suffix}") |
1010 | 1012 |
|
1011 | 1013 |
|
| 1014 | +class TestSimpleEnvelope(unittest.TestCase): |
| 1015 | + """Tests for public API in 'tuf/api/dsse.py'.""" |
| 1016 | + |
| 1017 | + @classmethod |
| 1018 | + def setUpClass(cls) -> None: |
| 1019 | + repo_data_dir = Path(utils.TESTS_DIR) / "repository_data" |
| 1020 | + cls.metadata_dir = repo_data_dir / "repository" / "metadata" |
| 1021 | + cls.signer_store = {} |
| 1022 | + for role in [Snapshot, Targets, Timestamp]: |
| 1023 | + key_path = repo_data_dir / "keystore" / f"{role.type}_key" |
| 1024 | + key = import_ed25519_privatekey_from_file( |
| 1025 | + str(key_path), |
| 1026 | + password="password", |
| 1027 | + ) |
| 1028 | + cls.signer_store[role.type] = SSlibSigner(key) |
| 1029 | + |
| 1030 | + def test_serialization(self) -> None: |
| 1031 | + """Basic de/serialization test. |
| 1032 | +
|
| 1033 | + 1. Load test metadata for each role |
| 1034 | + 2. Wrap metadata payloads in envelope serializing the payload |
| 1035 | + 3. Serialize envelope |
| 1036 | + 4. De-serialize envelope |
| 1037 | + 5. De-serialize payload |
| 1038 | +
|
| 1039 | + """ |
| 1040 | + for role in [Root, Timestamp, Snapshot, Targets]: |
| 1041 | + metadata_path = self.metadata_dir / f"{role.type}.json" |
| 1042 | + metadata = Metadata.from_file(str(metadata_path)) |
| 1043 | + self.assertIsInstance(metadata.signed, role) |
| 1044 | + |
| 1045 | + envelope = SimpleEnvelope.from_signed(metadata.signed) |
| 1046 | + envelope_bytes = envelope.to_bytes() |
| 1047 | + |
| 1048 | + envelope2 = SimpleEnvelope.from_bytes(envelope_bytes) |
| 1049 | + payload = envelope2.get_signed() |
| 1050 | + self.assertEqual(metadata.signed, payload) |
| 1051 | + |
| 1052 | + def test_fail_envelope_serialization(self) -> None: |
| 1053 | + envelope = SimpleEnvelope(b"foo", "bar", ["baz"]) |
| 1054 | + with self.assertRaises(SerializationError): |
| 1055 | + envelope.to_bytes() |
| 1056 | + |
| 1057 | + def test_fail_envelope_deserialization(self) -> None: |
| 1058 | + with self.assertRaises(DeserializationError): |
| 1059 | + SimpleEnvelope.from_bytes(b"[") |
| 1060 | + |
| 1061 | + def test_fail_payload_serialization(self) -> None: |
| 1062 | + with self.assertRaises(SerializationError): |
| 1063 | + SimpleEnvelope.from_signed("foo") # type: ignore |
| 1064 | + |
| 1065 | + def test_fail_payload_deserialization(self) -> None: |
| 1066 | + payloads = [b"[", b'{"_type": "foo"}'] |
| 1067 | + for payload in payloads: |
| 1068 | + envelope = SimpleEnvelope(payload, "bar", []) |
| 1069 | + with self.assertRaises(DeserializationError): |
| 1070 | + envelope.get_signed() |
| 1071 | + |
| 1072 | + def test_verify_delegate(self) -> None: |
| 1073 | + """Basic verification test. |
| 1074 | +
|
| 1075 | + 1. Load test metadata for each role |
| 1076 | + 2. Wrap non-root payloads in envelope serializing the payload |
| 1077 | + 3. Sign with correct delegated key |
| 1078 | + 4. Verify delegate with root |
| 1079 | +
|
| 1080 | + """ |
| 1081 | + root_path = self.metadata_dir / "root.json" |
| 1082 | + root = Metadata[Root].from_file(str(root_path)).signed |
| 1083 | + |
| 1084 | + for role in [Timestamp, Snapshot, Targets]: |
| 1085 | + metadata_path = self.metadata_dir / f"{role.type}.json" |
| 1086 | + metadata = Metadata.from_file(str(metadata_path)) |
| 1087 | + self.assertIsInstance(metadata.signed, role) |
| 1088 | + |
| 1089 | + signer = self.signer_store[role.type] |
| 1090 | + self.assertIn( |
| 1091 | + signer.key_dict["keyid"], root.roles[role.type].keyids |
| 1092 | + ) |
| 1093 | + |
| 1094 | + envelope = SimpleEnvelope.from_signed(metadata.signed) |
| 1095 | + envelope.sign(signer) |
| 1096 | + self.assertTrue(len(envelope.signatures) == 1) |
| 1097 | + |
| 1098 | + root.verify_delegate( |
| 1099 | + role.type, envelope.pae(), envelope.signatures_dict |
| 1100 | + ) |
| 1101 | + |
| 1102 | + |
1012 | 1103 | # Run unit test. |
1013 | 1104 | if __name__ == "__main__": |
1014 | 1105 | utils.configure_test_logging(sys.argv) |
|
0 commit comments