88from datetime import datetime
99
1010from tuf import exceptions
11- from tuf .api .metadata import Metadata , MetaFile
11+ from tuf .api .metadata import Metadata
1212from tuf .ngclient ._internal .trusted_metadata_set import (
13- TrustedMetadataSet ,
14- verify_with_threshold
13+ TrustedMetadataSet
1514)
1615from securesystemslib import hash as sslib_hash
1716from 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
2022from 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