|
1 |
| -from tuf.api.metadata import Targets |
| 1 | +import pytest |
| 2 | +from tuf.api.metadata import TargetFile, Targets |
2 | 3 |
|
3 | 4 | from tuf_conformance.client_runner import ClientRunner
|
| 5 | +from tuf_conformance.repository_simulator import Artifact |
4 | 6 | from tuf_conformance.simulator_server import SimulatorServer
|
5 | 7 |
|
6 | 8 |
|
@@ -169,3 +171,65 @@ def test_multiple_changes_to_target(
|
169 | 171 |
|
170 | 172 | # Check that the client did not download the malicious file
|
171 | 173 | assert client.get_downloaded_target_bytes() == expected_downloads
|
| 174 | + |
| 175 | + |
| 176 | +hash_algos = [ |
| 177 | + ["sha256"], |
| 178 | + ["sha512"], |
| 179 | + ["sha256", "sha512"], |
| 180 | +] |
| 181 | + |
| 182 | + |
| 183 | +@pytest.mark.parametrize("hashes", hash_algos) |
| 184 | +def test_download_with_hash_algorithms( |
| 185 | + client: ClientRunner, server: SimulatorServer, hashes: list[str] |
| 186 | +) -> None: |
| 187 | + """Test support of hash algorithms. The specification does not require any |
| 188 | + specific algorithms, and only mentions sha256. |
| 189 | +
|
| 190 | + Clients can use --expected-failures to mark tests that fail because of algorithms |
| 191 | + they do not intend to support.""" |
| 192 | + init_data, repo = server.new_test(client.test_name) |
| 193 | + |
| 194 | + # Create a legitimate test artifact |
| 195 | + target_path = "target_file.txt" |
| 196 | + target_content = b"target file contents" |
| 197 | + |
| 198 | + # Add target manually and not with repo.add_artifact() so we can choose hashes |
| 199 | + target = TargetFile.from_data(target_path, target_content, hashes) |
| 200 | + repo.targets.targets[target_path] = target |
| 201 | + repo.artifacts[target_path] = Artifact(target_content, target) |
| 202 | + |
| 203 | + assert client.init_client(init_data) == 0 |
| 204 | + assert client.download_target(init_data, target_path) == 0 |
| 205 | + |
| 206 | + # downloading using any of the hashes repository advertized is accepted: |
| 207 | + possible_dls = [(target_path, h) for h in target.hashes.values()] |
| 208 | + assert len(repo.artifact_statistics) == 1 |
| 209 | + assert repo.artifact_statistics[0] in possible_dls |
| 210 | + assert client.get_downloaded_target_bytes() == [target_content] |
| 211 | + |
| 212 | + |
| 213 | +def test_download_with_unknown_hash_algorithm( |
| 214 | + client: ClientRunner, server: SimulatorServer |
| 215 | +) -> None: |
| 216 | + """Use an unknown hash algorithm: client should not accept the artifact""" |
| 217 | + init_data, repo = server.new_test(client.test_name) |
| 218 | + |
| 219 | + # Create a legitimate test artifact |
| 220 | + target_path = "target_file.txt" |
| 221 | + target_content = b"target file contents" |
| 222 | + |
| 223 | + # Add target manually, use a hash algorithm that does not exist |
| 224 | + # Use repo.add_artifact() so we can modify hashes |
| 225 | + target = TargetFile.from_data(target_path, target_content, ["sha512"]) |
| 226 | + target.hashes["unknown-hash"] = target.hashes["sha512"] |
| 227 | + del target.hashes["sha512"] |
| 228 | + repo.targets.targets[target_path] = target |
| 229 | + repo.artifacts[target_path] = Artifact(target_content, target) |
| 230 | + |
| 231 | + assert client.init_client(init_data) == 0 |
| 232 | + # Note that we allow the client to actually download the artifact from repo |
| 233 | + # and only then realize hash cannot be verified |
| 234 | + assert client.download_target(init_data, target_path) == 1 |
| 235 | + assert client.get_downloaded_target_bytes() == [] |
0 commit comments