1515
1616from tests import utils
1717from tuf .api import exceptions
18+ from tuf .api .dsse import SimpleEnvelope
1819from tuf .api .metadata import (
1920 Metadata ,
2021 MetaFile ,
2122 Root ,
23+ Signed ,
2224 Snapshot ,
2325 Targets ,
2426 Timestamp ,
2527)
2628from tuf .api .serialization .json import JSONSerializer
27- from tuf .ngclient ._internal .trusted_metadata_set import TrustedMetadataSet
29+ from tuf .ngclient ._internal .trusted_metadata_set import (
30+ TrustedMetadataSet ,
31+ _load_from_simple_envelope ,
32+ )
33+ from tuf .ngclient .config import EnvelopeType
2834
2935logger = logging .getLogger (__name__ )
3036
@@ -93,7 +99,9 @@ def hashes_length_modifier(timestamp: Timestamp) -> None:
9399 )
94100
95101 def setUp (self ) -> None :
96- self .trusted_set = TrustedMetadataSet (self .metadata [Root .type ])
102+ self .trusted_set = TrustedMetadataSet (
103+ self .metadata [Root .type ], EnvelopeType .METADATA
104+ )
97105
98106 def _update_all_besides_targets (
99107 self ,
@@ -132,7 +140,7 @@ def test_update(self) -> None:
132140
133141 count = 0
134142 for md in self .trusted_set :
135- self .assertIsInstance (md , Metadata )
143+ self .assertIsInstance (md , Signed )
136144 count += 1
137145
138146 self .assertTrue (count , 6 )
@@ -149,11 +157,11 @@ def test_update_metadata_output(self) -> None:
149157 delegeted_targets_2 = self .trusted_set .update_delegated_targets (
150158 self .metadata ["role2" ], "role2" , "role1"
151159 )
152- self .assertIsInstance (timestamp . signed , Timestamp )
153- self .assertIsInstance (snapshot . signed , Snapshot )
154- self .assertIsInstance (targets . signed , Targets )
155- self .assertIsInstance (delegeted_targets_1 . signed , Targets )
156- self .assertIsInstance (delegeted_targets_2 . signed , Targets )
160+ self .assertIsInstance (timestamp , Timestamp )
161+ self .assertIsInstance (snapshot , Snapshot )
162+ self .assertIsInstance (targets , Targets )
163+ self .assertIsInstance (delegeted_targets_1 , Targets )
164+ self .assertIsInstance (delegeted_targets_2 , Targets )
157165
158166 def test_out_of_order_ops (self ) -> None :
159167 # Update snapshot before timestamp
@@ -192,25 +200,40 @@ def test_out_of_order_ops(self) -> None:
192200 self .metadata ["role1" ], "role1" , Targets .type
193201 )
194202
195- def test_root_with_invalid_json (self ) -> None :
196- # Test loading initial root and root update
197- for test_func in [TrustedMetadataSet , self .trusted_set .update_root ]:
198- # root is not json
199- with self .assertRaises (exceptions .RepositoryError ):
200- test_func (b"" )
203+ def test_bad_initial_root (self ) -> None :
204+ # root is not json
205+ with self .assertRaises (exceptions .RepositoryError ):
206+ TrustedMetadataSet (b"" , EnvelopeType .METADATA )
201207
202- # root is invalid
203- root = Metadata .from_bytes (self .metadata [Root .type ])
204- root .signed .version += 1
205- with self .assertRaises (exceptions .UnsignedMetadataError ):
206- test_func (root .to_bytes ())
208+ # root is invalid
209+ root = Metadata .from_bytes (self .metadata [Root .type ])
210+ root .signed .version += 1
211+ with self .assertRaises (exceptions .UnsignedMetadataError ):
212+ TrustedMetadataSet (root .to_bytes (), EnvelopeType . METADATA )
207213
208- # metadata is of wrong type
209- with self .assertRaises (exceptions .RepositoryError ):
210- test_func (self .metadata [Snapshot .type ])
214+ # metadata is of wrong type
215+ with self .assertRaises (exceptions .RepositoryError ):
216+ TrustedMetadataSet (
217+ self .metadata [Snapshot .type ], EnvelopeType .METADATA
218+ )
219+
220+ def test_bad_root_update (self ) -> None :
221+ # root is not json
222+ with self .assertRaises (exceptions .RepositoryError ):
223+ self .trusted_set .update_root (b"" )
224+
225+ # root is invalid
226+ root = Metadata .from_bytes (self .metadata [Root .type ])
227+ root .signed .version += 1
228+ with self .assertRaises (exceptions .UnsignedMetadataError ):
229+ self .trusted_set .update_root (root .to_bytes ())
230+
231+ # metadata is of wrong type
232+ with self .assertRaises (exceptions .RepositoryError ):
233+ self .trusted_set .update_root (self .metadata [Snapshot .type ])
211234
212235 def test_top_level_md_with_invalid_json (self ) -> None :
213- top_level_md : List [Tuple [bytes , Callable [[bytes ], Metadata ]]] = [
236+ top_level_md : List [Tuple [bytes , Callable [[bytes ], Signed ]]] = [
214237 (self .metadata [Timestamp .type ], self .trusted_set .update_timestamp ),
215238 (self .metadata [Snapshot .type ], self .trusted_set .update_snapshot ),
216239 (self .metadata [Targets .type ], self .trusted_set .update_targets ),
@@ -260,7 +283,7 @@ def root_expired_modifier(root: Root) -> None:
260283
261284 # intermediate root can be expired
262285 root = self .modify_metadata (Root .type , root_expired_modifier )
263- tmp_trusted_set = TrustedMetadataSet (root )
286+ tmp_trusted_set = TrustedMetadataSet (root , EnvelopeType . METADATA )
264287 # update timestamp to trigger final root expiry check
265288 with self .assertRaises (exceptions .ExpiredMetadataError ):
266289 tmp_trusted_set .update_timestamp (self .metadata [Timestamp .type ])
@@ -471,6 +494,52 @@ def target_expired_modifier(target: Targets) -> None:
471494
472495 # TODO test updating over initial metadata (new keys, newer timestamp, etc)
473496
497+ def test_load_from_simple_envelope (self ) -> None :
498+ """Basic unit test for ``_load_from_simple_envelope`` helper.
499+
500+ TODO: Test via trusted metadata set tests like for traditional metadata
501+ """
502+ metadata = Metadata .from_bytes (self .metadata [Root .type ])
503+ root = metadata .signed
504+ envelope = SimpleEnvelope .from_signed (root )
505+
506+ # Unwrap unsigned envelope without verification
507+ envelope_bytes = envelope .to_bytes ()
508+ payload_obj , signed_bytes , signatures = _load_from_simple_envelope (
509+ Root , envelope_bytes
510+ )
511+
512+ self .assertEqual (payload_obj , root )
513+ self .assertEqual (signed_bytes , envelope .pae ())
514+ self .assertDictEqual (signatures , {})
515+
516+ # Unwrap correctly signed envelope (use default role name)
517+ sig = envelope .sign (self .keystore [Root .type ])
518+ envelope_bytes = envelope .to_bytes ()
519+ _ , _ , signatures = _load_from_simple_envelope (
520+ Root , envelope_bytes , root
521+ )
522+ self .assertDictEqual (signatures , {sig .keyid : sig })
523+
524+ # Load correctly signed envelope (with explicit role name)
525+ _ , _ , signatures = _load_from_simple_envelope (
526+ Root , envelope .to_bytes (), root , Root .type
527+ )
528+ self .assertDictEqual (signatures , {sig .keyid : sig })
529+
530+ # Fail load envelope with unexpected 'payload_type'
531+ envelope_bad_type = SimpleEnvelope .from_signed (root )
532+ envelope_bad_type .payload_type = "foo"
533+ envelope_bad_type_bytes = envelope_bad_type .to_bytes ()
534+ with self .assertRaises (exceptions .RepositoryError ):
535+ _load_from_simple_envelope (Root , envelope_bad_type_bytes )
536+
537+ # Fail load envelope with unexpected payload type
538+ envelope_bad_signed = SimpleEnvelope .from_signed (root )
539+ envelope_bad_signed_bytes = envelope_bad_signed .to_bytes ()
540+ with self .assertRaises (exceptions .RepositoryError ):
541+ _load_from_simple_envelope (Targets , envelope_bad_signed_bytes )
542+
474543
475544if __name__ == "__main__" :
476545 utils .configure_test_logging (sys .argv )
0 commit comments