|
15 | 15 | import unittest
|
16 | 16 | from copy import copy, deepcopy
|
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,
|
@@ -1144,6 +1146,95 @@ def test_delegations_get_delegated_role(self) -> None:
|
1144 | 1146 | )
|
1145 | 1147 |
|
1146 | 1148 |
|
| 1149 | +class TestSimpleEnvelope(unittest.TestCase): |
| 1150 | + """Tests for public API in 'tuf/api/dsse.py'.""" |
| 1151 | + |
| 1152 | + @classmethod |
| 1153 | + def setUpClass(cls) -> None: |
| 1154 | + repo_data_dir = Path(utils.TESTS_DIR) / "repository_data" |
| 1155 | + cls.metadata_dir = repo_data_dir / "repository" / "metadata" |
| 1156 | + cls.signer_store = {} |
| 1157 | + for role in [Snapshot, Targets, Timestamp]: |
| 1158 | + key_path = repo_data_dir / "keystore" / f"{role.type}_key" |
| 1159 | + key = import_ed25519_privatekey_from_file( |
| 1160 | + str(key_path), |
| 1161 | + password="password", |
| 1162 | + ) |
| 1163 | + cls.signer_store[role.type] = SSlibSigner(key) |
| 1164 | + |
| 1165 | + def test_serialization(self) -> None: |
| 1166 | + """Basic de/serialization test. |
| 1167 | +
|
| 1168 | + 1. Load test metadata for each role |
| 1169 | + 2. Wrap metadata payloads in envelope serializing the payload |
| 1170 | + 3. Serialize envelope |
| 1171 | + 4. De-serialize envelope |
| 1172 | + 5. De-serialize payload |
| 1173 | +
|
| 1174 | + """ |
| 1175 | + for role in [Root, Timestamp, Snapshot, Targets]: |
| 1176 | + metadata_path = self.metadata_dir / f"{role.type}.json" |
| 1177 | + metadata = Metadata.from_file(str(metadata_path)) |
| 1178 | + self.assertIsInstance(metadata.signed, role) |
| 1179 | + |
| 1180 | + envelope = SimpleEnvelope.from_signed(metadata.signed) |
| 1181 | + envelope_bytes = envelope.to_bytes() |
| 1182 | + |
| 1183 | + envelope2 = SimpleEnvelope.from_bytes(envelope_bytes) |
| 1184 | + payload = envelope2.get_signed() |
| 1185 | + self.assertEqual(metadata.signed, payload) |
| 1186 | + |
| 1187 | + def test_fail_envelope_serialization(self) -> None: |
| 1188 | + envelope = SimpleEnvelope(b"foo", "bar", ["baz"]) |
| 1189 | + with self.assertRaises(SerializationError): |
| 1190 | + envelope.to_bytes() |
| 1191 | + |
| 1192 | + def test_fail_envelope_deserialization(self) -> None: |
| 1193 | + with self.assertRaises(DeserializationError): |
| 1194 | + SimpleEnvelope.from_bytes(b"[") |
| 1195 | + |
| 1196 | + def test_fail_payload_serialization(self) -> None: |
| 1197 | + with self.assertRaises(SerializationError): |
| 1198 | + SimpleEnvelope.from_signed("foo") # type: ignore |
| 1199 | + |
| 1200 | + def test_fail_payload_deserialization(self) -> None: |
| 1201 | + payloads = [b"[", b'{"_type": "foo"}'] |
| 1202 | + for payload in payloads: |
| 1203 | + envelope = SimpleEnvelope(payload, "bar", []) |
| 1204 | + with self.assertRaises(DeserializationError): |
| 1205 | + envelope.get_signed() |
| 1206 | + |
| 1207 | + def test_verify_delegate(self) -> None: |
| 1208 | + """Basic verification test. |
| 1209 | +
|
| 1210 | + 1. Load test metadata for each role |
| 1211 | + 2. Wrap non-root payloads in envelope serializing the payload |
| 1212 | + 3. Sign with correct delegated key |
| 1213 | + 4. Verify delegate with root |
| 1214 | +
|
| 1215 | + """ |
| 1216 | + root_path = self.metadata_dir / "root.json" |
| 1217 | + root = Metadata[Root].from_file(str(root_path)).signed |
| 1218 | + |
| 1219 | + for role in [Timestamp, Snapshot, Targets]: |
| 1220 | + metadata_path = self.metadata_dir / f"{role.type}.json" |
| 1221 | + metadata = Metadata.from_file(str(metadata_path)) |
| 1222 | + self.assertIsInstance(metadata.signed, role) |
| 1223 | + |
| 1224 | + signer = self.signer_store[role.type] |
| 1225 | + self.assertIn( |
| 1226 | + signer.key_dict["keyid"], root.roles[role.type].keyids |
| 1227 | + ) |
| 1228 | + |
| 1229 | + envelope = SimpleEnvelope.from_signed(metadata.signed) |
| 1230 | + envelope.sign(signer) |
| 1231 | + self.assertTrue(len(envelope.signatures) == 1) |
| 1232 | + |
| 1233 | + root.verify_delegate( |
| 1234 | + role.type, envelope.pae(), envelope.signatures_dict |
| 1235 | + ) |
| 1236 | + |
| 1237 | + |
1147 | 1238 | # Run unit test.
|
1148 | 1239 | if __name__ == "__main__":
|
1149 | 1240 | utils.configure_test_logging(sys.argv)
|
|
0 commit comments