def test_signature_from_to_dict(self): signature_dict = { "sig": "30460221009342e4566528fcecf6a7a5d53ebacdb1df151e242f55f8775883469cb01dbc6602210086b426cc826709acfa2c3f9214610cb0a832db94bbd266fd7c5939a48064a851", "keyid": "11fa391a0ed7a447cbfeb4b2667e286fc248f64d5e6d0eeed2e5e23f97f9f714" } sig_obj = Signature.from_dict(signature_dict) self.assertDictEqual(signature_dict, sig_obj.to_dict())
def from_dict(cls, metadata: Dict[str, Any]) -> "Metadata[T]": """Creates Metadata object from its dict representation. Arguments: metadata: TUF metadata in dict representation. Raises: KeyError: The metadata dict format is invalid. ValueError: The metadata has an unrecognized signed._type field. Side Effect: Destroys the metadata dict passed by reference. Returns: A TUF Metadata object. """ # Dispatch to contained metadata class on metadata _type field. _type = metadata["signed"]["_type"] if _type == "targets": inner_cls: Type[Signed] = Targets elif _type == "snapshot": inner_cls = Snapshot elif _type == "timestamp": inner_cls = Timestamp elif _type == "root": inner_cls = Root else: raise ValueError(f'unrecognized metadata type "{_type}"') # Make sure signatures are unique signatures: "OrderedDict[str, Signature]" = OrderedDict() for sig_dict in metadata.pop("signatures"): sig = Signature.from_dict(sig_dict) if sig.keyid in signatures: raise ValueError( f"Multiple signatures found for keyid {sig.keyid}") signatures[sig.keyid] = sig return cls( # Specific type T is not known at static type check time: use cast signed=cast(T, inner_cls.from_dict(metadata.pop("signed"))), signatures=signatures, )
def from_dict(cls, metadata: Mapping[str, Any]) -> "Metadata": """Creates Metadata object from its dict representation. Arguments: metadata: TUF metadata in dict representation. Raises: KeyError: The metadata dict format is invalid. ValueError: The metadata has an unrecognized signed._type field. Side Effect: Destroys the metadata Mapping passed by reference. Returns: A TUF Metadata object. """ # Dispatch to contained metadata class on metadata _type field. _type = metadata["signed"]["_type"] if _type == "targets": inner_cls = Targets elif _type == "snapshot": inner_cls = Snapshot elif _type == "timestamp": inner_cls = Timestamp elif _type == "root": inner_cls = Root else: raise ValueError(f'unrecognized metadata type "{_type}"') signatures = [] for signature in metadata.pop("signatures"): signature_obj = Signature.from_dict(signature) signatures.append(signature_obj) return cls( signed=inner_cls.from_dict(metadata.pop("signed")), signatures=signatures, )
def test_metadata_verify_delegate(self) -> None: root_path = os.path.join(self.repo_dir, "metadata", "root.json") root = Metadata[Root].from_file(root_path) snapshot_path = os.path.join(self.repo_dir, "metadata", "snapshot.json") snapshot = Metadata[Snapshot].from_file(snapshot_path) targets_path = os.path.join(self.repo_dir, "metadata", "targets.json") targets = Metadata[Targets].from_file(targets_path) role1_path = os.path.join(self.repo_dir, "metadata", "role1.json") role1 = Metadata[Targets].from_file(role1_path) role2_path = os.path.join(self.repo_dir, "metadata", "role2.json") role2 = Metadata[Targets].from_file(role2_path) # test the expected delegation tree root.verify_delegate(Root.type, root) root.verify_delegate(Snapshot.type, snapshot) root.verify_delegate(Targets.type, targets) targets.verify_delegate("role1", role1) role1.verify_delegate("role2", role2) # only root and targets can verify delegates with self.assertRaises(TypeError): snapshot.verify_delegate(Snapshot.type, snapshot) # verify fails for roles that are not delegated by delegator with self.assertRaises(ValueError): root.verify_delegate("role1", role1) with self.assertRaises(ValueError): targets.verify_delegate(Targets.type, targets) # verify fails when delegator has no delegations with self.assertRaises(ValueError): role2.verify_delegate("role1", role1) # verify fails when delegate content is modified expires = snapshot.signed.expires snapshot.signed.expires = expires + timedelta(days=1) with self.assertRaises(exceptions.UnsignedMetadataError): root.verify_delegate(Snapshot.type, snapshot) snapshot.signed.expires = expires # verify fails if roles keys do not sign the metadata with self.assertRaises(exceptions.UnsignedMetadataError): root.verify_delegate(Timestamp.type, snapshot) # Add a key to snapshot role, make sure the new sig fails to verify ts_keyid = next(iter(root.signed.roles[Timestamp.type].keyids)) root.signed.add_key(root.signed.keys[ts_keyid], Snapshot.type) snapshot.signatures[ts_keyid] = Signature(ts_keyid, "ff" * 64) # verify succeeds if threshold is reached even if some signatures # fail to verify root.verify_delegate(Snapshot.type, snapshot) # verify fails if threshold of signatures is not reached root.signed.roles[Snapshot.type].threshold = 2 with self.assertRaises(exceptions.UnsignedMetadataError): root.verify_delegate(Snapshot.type, snapshot) # verify succeeds when we correct the new signature and reach the # threshold of 2 keys snapshot.sign(SSlibSigner(self.keystore[Timestamp.type]), append=True) root.verify_delegate(Snapshot.type, snapshot)
def test_metadata_verify_delegate(self): root_path = os.path.join(self.repo_dir, 'metadata', 'root.json') root = Metadata.from_file(root_path) snapshot_path = os.path.join( self.repo_dir, 'metadata', 'snapshot.json') snapshot = Metadata.from_file(snapshot_path) targets_path = os.path.join( self.repo_dir, 'metadata', 'targets.json') targets = Metadata.from_file(targets_path) role1_path = os.path.join( self.repo_dir, 'metadata', 'role1.json') role1 = Metadata.from_file(role1_path) role2_path = os.path.join( self.repo_dir, 'metadata', 'role2.json') role2 = Metadata.from_file(role2_path) # test the expected delegation tree root.verify_delegate('root', root) root.verify_delegate('snapshot', snapshot) root.verify_delegate('targets', targets) targets.verify_delegate('role1', role1) role1.verify_delegate('role2', role2) # only root and targets can verify delegates with self.assertRaises(TypeError): snapshot.verify_delegate('snapshot', snapshot) # verify fails for roles that are not delegated by delegator with self.assertRaises(ValueError): root.verify_delegate('role1', role1) with self.assertRaises(ValueError): targets.verify_delegate('targets', targets) # verify fails when delegator has no delegations with self.assertRaises(ValueError): role2.verify_delegate('role1', role1) # verify fails when delegate content is modified expires = snapshot.signed.expires snapshot.signed.bump_expiration() with self.assertRaises(exceptions.UnsignedMetadataError): root.verify_delegate('snapshot', snapshot) snapshot.signed.expires = expires # verify fails if roles keys do not sign the metadata with self.assertRaises(exceptions.UnsignedMetadataError): root.verify_delegate('timestamp', snapshot) # Add a key to snapshot role, make sure the new sig fails to verify ts_keyid = next(iter(root.signed.roles["timestamp"].keyids)) root.signed.add_key("snapshot", root.signed.keys[ts_keyid]) snapshot.signatures[ts_keyid] = Signature(ts_keyid, "ff"*64) # verify succeeds if threshold is reached even if some signatures # fail to verify root.verify_delegate('snapshot', snapshot) # verify fails if threshold of signatures is not reached root.signed.roles['snapshot'].threshold = 2 with self.assertRaises(exceptions.UnsignedMetadataError): root.verify_delegate('snapshot', snapshot) # verify succeeds when we correct the new signature and reach the # threshold of 2 keys snapshot.sign(SSlibSigner(self.keystore['timestamp']), append=True) root.verify_delegate('snapshot', snapshot)
def test_signature_serialization(self, test_case_data: str) -> None: case_dict = json.loads(test_case_data) signature = Signature.from_dict(copy.copy(case_dict)) self.assertEqual(case_dict, signature.to_dict())
def test_invalid_signature_serialization(self, test_data: str) -> None: case_dict = json.loads(test_data) with self.assertRaises(KeyError): Signature.from_dict(case_dict)