Skip to content

Commit 8e04c96

Browse files
committed
Address Jussi's comment
Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
1 parent eab8dc6 commit 8e04c96

File tree

1 file changed

+50
-82
lines changed

1 file changed

+50
-82
lines changed

tests/test_trusted_metadata_set.py

Lines changed: 50 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
from datetime import datetime
99

1010
from tuf import exceptions
11-
from tuf.api.metadata import Metadata, MetaFile
11+
from tuf.api.metadata import Metadata
1212
from tuf.ngclient._internal.trusted_metadata_set import(
13-
TrustedMetadataSet,
14-
verify_with_threshold
13+
TrustedMetadataSet
1514
)
1615
from securesystemslib import hash as sslib_hash
1716
from securesystemslib.signer import SSlibSigner
18-
from securesystemslib.interface import import_ed25519_privatekey_from_file
17+
from securesystemslib.interface import(
18+
import_ed25519_privatekey_from_file,
19+
import_rsa_privatekey_from_file
20+
)
1921

2022
from tests import utils
2123

@@ -35,7 +37,12 @@ def setUpClass(cls):
3537

3638
keystore_dir = os.path.join(os.getcwd(), 'repository_data', 'keystore')
3739
cls.keystore = {}
38-
for role in ['delegation', 'snapshot', 'targets', 'timestamp']:
40+
root_key_dict = import_rsa_privatekey_from_file(
41+
os.path.join(keystore_dir, "root" + '_key'),
42+
password="password"
43+
)
44+
cls.keystore["root"] = SSlibSigner(root_key_dict)
45+
for role in ["delegation", "snapshot", "targets", "timestamp"]:
3946
key_dict = import_ed25519_privatekey_from_file(
4047
os.path.join(keystore_dir, role + '_key'),
4148
password="password"
@@ -45,6 +52,19 @@ def setUpClass(cls):
4552
def setUp(self) -> None:
4653
self.trusted_set = TrustedMetadataSet(self.metadata["root"])
4754

55+
def _setup_update_snapshot_or_timestamp_test(self):
56+
self.trusted_set.root_update_finished()
57+
self.trusted_set.update_timestamp(self.metadata["timestamp"])
58+
59+
def _setup_update_snapshot_after_successful_update_test(self):
60+
self._setup_update_snapshot_or_timestamp_test()
61+
self.trusted_set.update_snapshot(self.metadata["snapshot"])
62+
63+
def _setup_update_targets_test(self):
64+
self.trusted_set.root_update_finished()
65+
self.trusted_set.update_timestamp(self.metadata["timestamp"])
66+
self.trusted_set.update_snapshot(self.metadata["snapshot"])
67+
4868
def test_update(self):
4969
self.trusted_set.root_update_finished()
5070
self.trusted_set.update_timestamp(self.metadata["timestamp"])
@@ -150,16 +170,6 @@ def test_update_with_invalid_json(self):
150170

151171
update_func(metadata)
152172

153-
def test_update_root_invalid_type(self):
154-
# new_root data with invalid snapshot type
155-
invalid_type_data = json.loads(self.metadata["root"])
156-
invalid_type_data["signed"]["_type"] = "snapshot"
157-
invalid_type_data["signed"]["meta"] = {"file1.txt": {"version": 1}}
158-
invalid_type_data = json.dumps(invalid_type_data).encode()
159-
# RepositoryError is thrown during new_root deserialization.
160-
# It's not thrown when checking new_root.signed.type != "root"
161-
with self.assertRaises(exceptions.RepositoryError):
162-
self.trusted_set.update_root(invalid_type_data)
163173

164174
def test_update_root_new_root_cannot_be_verified_with_threshold(self):
165175
# new_root data with threshold which cannot be verified.
@@ -175,15 +185,6 @@ def test_update_root_new_root_ver_same_as_trusted_root_ver(self):
175185
with self.assertRaises(exceptions.ReplayedMetadataError):
176186
self.trusted_set.update_root(self.metadata["root"])
177187

178-
def test_root_update_finished_expired(self):
179-
# call root_update_finished when trusted root has expired
180-
expired_datetime = datetime.strptime(
181-
"1970-01-01T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ"
182-
)
183-
self.trusted_set.root.signed.expires = expired_datetime
184-
with self.assertRaises(exceptions.ExpiredMetadataError):
185-
self.trusted_set.root_update_finished()
186-
187188
def _sign_modified_obj(
188189
self,
189190
role:str,
@@ -193,10 +194,16 @@ def _sign_modified_obj(
193194
signature = metadata_obj.sign(sslib_signer)
194195
return signature.to_dict()
195196

197+
def test_root_update_finished_expired(self):
198+
root_obj = Metadata.from_bytes(self.metadata["root"])
199+
root_obj.signed.expires = datetime(1970, 1, 1)
200+
self._sign_modified_obj("root", root_obj)
201+
modified_root_data = json.dumps(root_obj.to_dict()).encode()
202+
tmp_trusted_set = TrustedMetadataSet(modified_root_data)
203+
# call root_update_finished when trusted root has expired
204+
with self.assertRaises(exceptions.ExpiredMetadataError):
205+
tmp_trusted_set.root_update_finished()
196206

197-
def _setup_update_snapshot_or_timestamp_test(self):
198-
self.trusted_set.root_update_finished()
199-
self.trusted_set.update_timestamp(self.metadata["timestamp"])
200207

201208
def test_update_timestamp_new_timestamp_ver_below_trusted_ver(self):
202209
self._setup_update_snapshot_or_timestamp_test()
@@ -216,28 +223,13 @@ def test_update_timestamp_snapshot_ver_below_trusted_snapshot_ver(self):
216223
self._setup_update_snapshot_or_timestamp_test()
217224
# new_timestamp has expired
218225
timestamp = Metadata.from_bytes(self.metadata["timestamp"])
219-
timestamp.signed.expires = datetime.strptime(
220-
"1970-01-01T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ"
221-
)
226+
timestamp.signed.expires = datetime(1970, 1, 1)
222227
self._sign_modified_obj("timestamp", timestamp)
223228
new_timestamp_byte_data = json.dumps(timestamp.to_dict()).encode()
224229
with self.assertRaises(exceptions.ExpiredMetadataError):
225230
self.trusted_set.update_timestamp(new_timestamp_byte_data)
226231

227232

228-
def _calculate_modified_hashes(
229-
self, true_hashes,
230-
data: bytes
231-
) -> Dict[str, str]:
232-
modified_hashes = {}
233-
# Calculate hashes on modified data in order to pass hashes verification.
234-
for algo in true_hashes.keys():
235-
digest_object = sslib_hash.digest(algo)
236-
digest_object.update(data)
237-
observed_hash = digest_object.hexdigest()
238-
modified_hashes[algo] = observed_hash
239-
return modified_hashes
240-
241233
def test_update_snapshot_after_targets_updated(self):
242234
self._setup_update_snapshot_or_timestamp_test()
243235
# cannot update snapshot after targets update completes or targets != None
@@ -248,8 +240,9 @@ def test_update_snapshot_after_targets_updated(self):
248240

249241
def test_update_snapshot_cannot_verify_snapshot_with_threshold(self):
250242
self._setup_update_snapshot_or_timestamp_test()
251-
# root data with threshold which cannot be verified for new_snapshot
252-
self.trusted_set.root.signed.roles["snapshot"].threshold = 2
243+
# remove signature for snapshot from root data
244+
self.trusted_set.root.signed.roles["snapshot"].keyids = []
245+
# self.trusted_set.snapshot.signatures = {}
253246
with self.assertRaises(exceptions.UnsignedMetadataError):
254247
self.trusted_set.update_snapshot(self.metadata["snapshot"])
255248
self.trusted_set.root.signed.roles["snapshot"].threshold = 1
@@ -263,71 +256,48 @@ def test_update_snapshot_version_different_timestamp_snapshot_version(self):
263256
self.trusted_set.timestamp.signed.meta["snapshot.json"].version = 1
264257

265258

266-
def _setup_update_snapshot_after_successful_update_test(self):
267-
self._setup_update_snapshot_or_timestamp_test()
268-
self.trusted_set.update_snapshot(self.metadata["snapshot"])
269-
270259
def test_update_snapshot_after_successful_update_new_snapshot_no_meta(self):
271260
self._setup_update_snapshot_after_successful_update_test()
272261
# Test removing a meta_file in new_snapshot compared to the old snapshot
273262
snapshot_obj = Metadata.from_bytes(self.metadata["snapshot"])
274263
snapshot_obj.signed.meta = {}
275-
# prepare timestamp.meta["snapshot"].hashes
276264
self._sign_modified_obj("snapshot", snapshot_obj)
277-
timestamp_meta = self.trusted_set.timestamp.signed.meta["snapshot.json"]
278-
true_hashes = timestamp_meta.hashes or {}
265+
self.trusted_set.timestamp.signed.meta["snapshot.json"].hashes = None
266+
self.trusted_set.timestamp.signed.meta["snapshot.json"].length = None
279267
modified_snapshot_data = json.dumps(snapshot_obj.to_dict()).encode()
280-
modified_hashes = self._calculate_modified_hashes(
281-
true_hashes, modified_snapshot_data
282-
)
283-
self.trusted_set.timestamp.signed.meta["snapshot.json"].hashes = modified_hashes
284-
285268
with self.assertRaises(exceptions.RepositoryError):
286269
self.trusted_set.update_snapshot(modified_snapshot_data)
287270

288271
def test_update_snapshot_after_succesfull_update_new_snapshot_meta_version_different(self):
289272
self._setup_update_snapshot_after_successful_update_test()
290273
# snapshot.meta["project1"].version != new_snapshot.meta["project1"].version
291-
for meta_file_path in self.trusted_set.snapshot.signed.meta.keys():
292-
self.trusted_set.snapshot.signed.meta[meta_file_path].version = 2
274+
for metafile in self.trusted_set.snapshot.signed.meta.values():
275+
metafile.version += 1
293276
with self.assertRaises(exceptions.BadVersionNumberError):
294277
self.trusted_set.update_snapshot(self.metadata["snapshot"])
295278

296279
def test_update_snapshot_after_succesfull_expired_new_snapshot(self):
297280
self._setup_update_snapshot_after_successful_update_test()
298281
# new_snapshot has expired
299282
snapshot_obj = Metadata.from_bytes(self.metadata["snapshot"])
300-
snapshot_obj.signed.expires = datetime.strptime(
301-
"1970-01-01T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ"
302-
)
283+
snapshot_obj.signed.expires = datetime(1970, 1, 1)
303284
self._sign_modified_obj("snapshot", snapshot_obj)
304-
modified_snapshot_data = json.dumps(snapshot_obj.to_dict()).encode()
305-
timestamp_meta = self.trusted_set.timestamp.signed.meta["snapshot.json"]
306-
true_hashes = timestamp_meta.hashes or {}
307-
modified_hashes = self._calculate_modified_hashes(
308-
true_hashes, modified_snapshot_data
309-
)
310-
self.trusted_set.timestamp.signed.meta["snapshot.json"].hashes = modified_hashes
311-
# remove length so it doesn't intervene the validation.
285+
self.trusted_set.timestamp.signed.meta["snapshot.json"].hashes = None
312286
self.trusted_set.timestamp.signed.meta["snapshot.json"].length = None
287+
modified_snapshot_data = json.dumps(snapshot_obj.to_dict()).encode()
313288
with self.assertRaises(exceptions.ExpiredMetadataError):
314289
self.trusted_set.update_snapshot(modified_snapshot_data)
315290

316291

317-
def setup_update_targets_test(self):
318-
self.trusted_set.root_update_finished()
319-
self.trusted_set.update_timestamp(self.metadata["timestamp"])
320-
self.trusted_set.update_snapshot(self.metadata["snapshot"])
321-
322292
def test_update_targets_no_meta_in_snapshot(self):
323-
self.setup_update_targets_test()
293+
self._setup_update_targets_test()
324294
# remove meta information with information about targets from snapshot
325295
self.trusted_set.snapshot.signed.meta = {}
326296
with self.assertRaises(exceptions.RepositoryError):
327297
self.trusted_set.update_targets(self.metadata["targets"])
328298

329299
def test_update_targets_hash_different_than_snapshot_meta_hash(self):
330-
self.setup_update_targets_test()
300+
self._setup_update_targets_test()
331301
# observed_hash != stored hash in snapshot meta for targets
332302
true_hashes = {}
333303
for target_path, meta_file in self.trusted_set.snapshot.signed.meta.items():
@@ -337,20 +307,18 @@ def test_update_targets_hash_different_than_snapshot_meta_hash(self):
337307
self.trusted_set.update_targets(self.metadata["targets"])
338308

339309
def test_update_targets_version_different_snapshot_meta_version(self):
340-
self.setup_update_targets_test()
310+
self._setup_update_targets_test()
341311
# new_delegate.signed.version != meta.version stored in snapshot
342312
for target_path in self.trusted_set.snapshot.signed.meta.keys():
343313
self.trusted_set.snapshot.signed.meta[target_path].version = 2
344314
with self.assertRaises(exceptions.BadVersionNumberError):
345315
self.trusted_set.update_targets(self.metadata["targets"])
346316

347317
def test_update_targets_expired_new_target(self):
348-
self.setup_update_targets_test()
318+
self._setup_update_targets_test()
349319
# new_delegated_target has expired
350320
targets_obj = Metadata.from_bytes(self.metadata["targets"])
351-
targets_obj.signed.expires = datetime.strptime(
352-
"1970-01-01T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ"
353-
)
321+
targets_obj.signed.expires = datetime(1970, 1, 1)
354322
self._sign_modified_obj("targets", targets_obj)
355323
modified_targets_data = json.dumps(targets_obj.to_dict()).encode()
356324
with self.assertRaises(exceptions.ExpiredMetadataError):

0 commit comments

Comments
 (0)