11import logging
2- from typing import Optional , Union
2+ from typing import Optional , Union , Callable
33import os
44import sys
55import unittest
66from datetime import datetime
77
88from tuf import exceptions
9- from tuf .api .metadata import Metadata , MetaFile
9+ from tuf .api .metadata import Metadata , Signed , Timestamp , Snapshot , MetaFile
1010from tuf .ngclient ._internal .trusted_metadata_set import TrustedMetadataSet
1111
1212from securesystemslib .signer import SSlibSigner
@@ -84,41 +84,15 @@ def _update_all_besides_targets(
8484 snapshot_bytes = snapshot_bytes or self .metadata ["snapshot" ]
8585 self .trusted_set .update_snapshot (snapshot_bytes )
8686
87- def _modify_timestamp_meta (self , version : Optional [int ] = 1 ):
88- """Remove hashes and length from timestamp.meta["snapshot.json"].
89- Create a timestamp.meta["snapshot.json"] containing only version.
90-
91- Args:
92- version:
93- Version used when instantiating MetaFile for timestamp.meta.
94-
95- """
96- timestamp = Metadata .from_bytes (self .metadata ["timestamp" ])
97- timestamp .signed .meta ["snapshot.json" ] = MetaFile (version )
98- timestamp .sign (self .keystore ["timestamp" ])
99- return timestamp .to_bytes ()
100-
101- def _modify_snapshot_meta (
102- self , version : Union [int , None ] = 1 , length : Optional [int ]= None
103- ):
104- """Modify hashes and length from snapshot_meta.meta["snapshot.json"].
105- If version and length is None, then snapshot meta will be an empty dictionary.
106-
107- Args:
108- version:
109- Version used when instantiating MetaFile for snapshot.meta.
110- length:
111- Length used when instantiating MetaFile for snapshot.meta.
112-
113- """
114- snapshot = Metadata .from_bytes (self .metadata ["snapshot" ])
115- if version is None and length is None :
116- snapshot .signed .meta = {}
117- else :
118- for metafile_path in snapshot .signed .meta :
119- snapshot .signed .meta [metafile_path ] = MetaFile (version , length )
120- snapshot .sign (self .keystore ["snapshot" ])
121- return snapshot .to_bytes ()
87+ def modify_metadata (
88+ self , rolename : str , modification_func : Callable [["Signed" ], None ]
89+ ):
90+ """Instantiate metadata from rolename type, call modification_func and
91+ sign it again with self.keystore[rolename] signer."""
92+ metadata = Metadata .from_bytes (self .metadata [rolename ])
93+ modification_func (metadata .signed )
94+ metadata .sign (self .keystore [rolename ])
95+ return metadata .to_bytes ()
12296
12397 def test_update (self ):
12498 self .trusted_set .root_update_finished ()
@@ -255,7 +229,10 @@ def test_update_timestamp_new_timestamp_ver_below_trusted_ver(self):
255229 self .trusted_set .update_timestamp (self .metadata ["timestamp" ])
256230
257231 def test_update_timestamp_snapshot_ver_below_trusted_snapshot_ver (self ):
258- modified_timestamp = self ._modify_timestamp_meta (version = 3 )
232+ def version_modifier (timestamp : Timestamp ):
233+ timestamp .version = 3
234+
235+ modified_timestamp = self .modify_metadata ("timestamp" , version_modifier )
259236 self ._root_updated_and_update_timestamp (modified_timestamp )
260237 # new_timestamp.snapshot.version < trusted_timestamp.snapshot.version
261238 with self .assertRaises (exceptions .ReplayedMetadataError ):
@@ -272,16 +249,27 @@ def test_update_timestamp_expired(self):
272249
273250
274251 def test_update_snapshot_cannot_verify_snapshot_with_threshold (self ):
275- modified_timestamp = self ._modify_timestamp_meta ()
276- self ._root_updated_and_update_timestamp (modified_timestamp )
252+ def hashes_length_modifier (timestamp : Timestamp ):
253+ timestamp .meta ["snapshot.json" ].hashes = None
254+ timestamp .meta ["snapshot.json" ].length = None
255+
256+ timestamp = self .modify_metadata ("timestamp" , hashes_length_modifier )
257+ self ._root_updated_and_update_timestamp (timestamp )
277258 snapshot = Metadata .from_bytes (self .metadata ["snapshot" ])
278259 snapshot .signatures .clear ()
279260 with self .assertRaises (exceptions .UnsignedMetadataError ):
280261 self .trusted_set .update_snapshot (snapshot .to_bytes ())
281262
282263 def test_update_snapshot_version_different_timestamp_snapshot_version (self ):
283- modified_timestamp = self ._modify_timestamp_meta (version = 2 )
284- self ._root_updated_and_update_timestamp (modified_timestamp )
264+ def hashes_length_version_modifier (timestamp : Timestamp ):
265+ timestamp .meta ["snapshot.json" ].hashes = None
266+ timestamp .meta ["snapshot.json" ].length = None
267+ timestamp .meta ["snapshot.json" ].version = 2
268+
269+ timestamp = self .modify_metadata (
270+ "timestamp" , hashes_length_version_modifier
271+ )
272+ self ._root_updated_and_update_timestamp (timestamp )
285273 # new_snapshot.version != trusted timestamp.meta["snapshot"].version
286274 snapshot = Metadata .from_bytes (self .metadata ["snapshot" ])
287275 snapshot .signed .version = 3
@@ -290,8 +278,12 @@ def test_update_snapshot_version_different_timestamp_snapshot_version(self):
290278 self .trusted_set .update_snapshot (snapshot .to_bytes ())
291279
292280 def test_update_snapshot_after_successful_update_new_snapshot_no_meta (self ):
293- modified_timestamp = self ._modify_timestamp_meta ()
294- self ._update_all_besides_targets (modified_timestamp )
281+ def hashes_length_modifier (timestamp : Timestamp ):
282+ timestamp .meta ["snapshot.json" ].hashes = None
283+ timestamp .meta ["snapshot.json" ].length = None
284+
285+ timestamp = self .modify_metadata ("timestamp" , hashes_length_modifier )
286+ self ._update_all_besides_targets (timestamp )
295287 # Test removing a meta_file in new_snapshot compared to the old snapshot
296288 snapshot = Metadata .from_bytes (self .metadata ["snapshot" ])
297289 snapshot .signed .meta = {}
@@ -300,8 +292,12 @@ def test_update_snapshot_after_successful_update_new_snapshot_no_meta(self):
300292 self .trusted_set .update_snapshot (snapshot .to_bytes ())
301293
302294 def test_update_snapshot_after_succesfull_update_new_snapshot_meta_version_different (self ):
303- modified_timestamp = self ._modify_timestamp_meta ()
304- self ._root_updated_and_update_timestamp (modified_timestamp )
295+ def hashes_length_modifier (timestamp : Timestamp ):
296+ timestamp .meta ["snapshot.json" ].hashes = None
297+ timestamp .meta ["snapshot.json" ].length = None
298+
299+ timestamp = self .modify_metadata ("timestamp" , hashes_length_modifier )
300+ self ._root_updated_and_update_timestamp (timestamp )
305301 # snapshot.meta["project1"].version != new_snapshot.meta["project1"].version
306302 snapshot = Metadata .from_bytes (self .metadata ["snapshot" ])
307303 for metafile_path in snapshot .signed .meta .keys ():
@@ -312,8 +308,12 @@ def test_update_snapshot_after_succesfull_update_new_snapshot_meta_version_diffe
312308 self .trusted_set .update_snapshot (self .metadata ["snapshot" ])
313309
314310 def test_update_snapshot_expired_new_snapshot (self ):
315- modified_timestamp = self ._modify_timestamp_meta ()
316- self ._root_updated_and_update_timestamp (modified_timestamp )
311+ def hashes_length_modifier (timestamp : Timestamp ):
312+ timestamp .meta ["snapshot.json" ].hashes = None
313+ timestamp .meta ["snapshot.json" ].length = None
314+
315+ timestamp = self .modify_metadata ("timestamp" , hashes_length_modifier )
316+ self ._root_updated_and_update_timestamp (timestamp )
317317 # new_snapshot has expired
318318 snapshot = Metadata .from_bytes (self .metadata ["snapshot" ])
319319 snapshot .signed .expires = datetime (1970 , 1 , 1 )
@@ -323,34 +323,48 @@ def test_update_snapshot_expired_new_snapshot(self):
323323
324324
325325 def test_update_targets_no_meta_in_snapshot (self ):
326- modified_timestamp = self ._modify_timestamp_meta ()
327- modified_snapshot = self ._modify_snapshot_meta (version = None )
328- self ._update_all_besides_targets (
329- timestamp_bytes = modified_timestamp ,
330- snapshot_bytes = modified_snapshot
331- )
326+ def hashes_length_modifier (timestamp : Timestamp ):
327+ timestamp .meta ["snapshot.json" ].hashes = None
328+ timestamp .meta ["snapshot.json" ].length = None
329+
330+ timestamp = self .modify_metadata ("timestamp" , hashes_length_modifier )
331+ def no_meta_modifier (snapshot : Snapshot ):
332+ snapshot .meta = {}
333+
334+ snapshot = self .modify_metadata ("snapshot" , no_meta_modifier )
335+ self ._update_all_besides_targets (timestamp , snapshot )
332336 # remove meta information with information about targets from snapshot
333337 with self .assertRaises (exceptions .RepositoryError ):
334338 self .trusted_set .update_targets (self .metadata ["targets" ])
335339
336340 def test_update_targets_hash_different_than_snapshot_meta_hash (self ):
337- modified_timestamp = self ._modify_timestamp_meta ()
338- modified_snapshot = self ._modify_snapshot_meta (version = 1 , length = 1 )
339- self ._update_all_besides_targets (
340- timestamp_bytes = modified_timestamp ,
341- snapshot_bytes = modified_snapshot
342- )
341+ def hashes_length_modifier (timestamp : Timestamp ):
342+ timestamp .meta ["snapshot.json" ].hashes = None
343+ timestamp .meta ["snapshot.json" ].length = None
344+
345+ timestamp = self .modify_metadata ("timestamp" , hashes_length_modifier )
346+ def meta_length_modifier (snapshot : Snapshot ):
347+ for metafile_path in snapshot .meta :
348+ snapshot .meta [metafile_path ] = MetaFile (version = 1 , length = 1 )
349+
350+ snapshot = self .modify_metadata ("snapshot" , meta_length_modifier )
351+ self ._update_all_besides_targets (timestamp , snapshot )
343352 # observed_hash != stored hash in snapshot meta for targets
344353 with self .assertRaises (exceptions .RepositoryError ):
345354 self .trusted_set .update_targets (self .metadata ["targets" ])
346355
347356 def test_update_targets_version_different_snapshot_meta_version (self ):
348- modified_timestamp = self ._modify_timestamp_meta ()
349- modified_snapshot = self ._modify_snapshot_meta (version = 2 )
350- self ._update_all_besides_targets (
351- timestamp_bytes = modified_timestamp ,
352- snapshot_bytes = modified_snapshot
353- )
357+ def hashes_length_modifier (timestamp : Timestamp ):
358+ timestamp .meta ["snapshot.json" ].hashes = None
359+ timestamp .meta ["snapshot.json" ].length = None
360+
361+ timestamp = self .modify_metadata ("timestamp" , hashes_length_modifier )
362+ def meta_modifier (snapshot : Snapshot ):
363+ for metafile_path in snapshot .meta :
364+ snapshot .meta [metafile_path ] = MetaFile (version = 2 )
365+
366+ snapshot = self .modify_metadata ("snapshot" , meta_modifier )
367+ self ._update_all_besides_targets (timestamp , snapshot )
354368 # new_delegate.signed.version != meta.version stored in snapshot
355369 with self .assertRaises (exceptions .BadVersionNumberError ):
356370 self .trusted_set .update_targets (self .metadata ["targets" ])
0 commit comments