@@ -395,56 +395,16 @@ def verify_delegate(
395395 """Verify that ``delegated_metadata`` is signed with the required
396396 threshold of keys for the delegated role ``delegated_role``.
397397
398- Args:
399- delegated_role: Name of the delegated role to verify
400- delegated_metadata: ``Metadata`` object for the delegated role
401- signed_serializer: Serializer used for delegate
402- serialization. Default is ``CanonicalJSONSerializer``.
403-
404- Raises:
405- UnsignedMetadataError: ``delegated_role`` was not signed with
406- required threshold of keys for ``role_name``.
407- ValueError: no delegation was found for ``delegated_role``.
408- TypeError: called this function on non-delegating metadata class.
398+ .. deprecated:: 2.2.0
399+ Please use ``Root.verify_delegate()`` or ``Targets.verify_delegate()``.
409400 """
410401
411402 if self .signed .type not in ["root" , "targets" ]:
412403 raise TypeError ("Call is valid only on delegator metadata" )
413404
414- if signed_serializer is None :
415- # pylint: disable=import-outside-toplevel
416- from tuf .api .serialization .json import CanonicalJSONSerializer
417-
418- signed_serializer = CanonicalJSONSerializer ()
419-
420- data = signed_serializer .serialize (delegated_metadata .signed )
421- role = self .signed .get_delegated_role (delegated_role )
422-
423- # verify that delegated_metadata is signed by threshold of unique keys
424- signing_keys = set ()
425- for keyid in role .keyids :
426- try :
427- key = self .signed .get_key (keyid )
428- except ValueError :
429- logger .info ("No key for keyid %s" , keyid )
430- continue
431-
432- if keyid not in delegated_metadata .signatures :
433- logger .info ("No signature for keyid %s" , keyid )
434- continue
435-
436- sig = delegated_metadata .signatures [keyid ]
437- try :
438- key .verify_signature (sig , data )
439- signing_keys .add (keyid )
440- except sslib_exceptions .UnverifiedSignatureError :
441- logger .info ("Key %s failed to verify %s" , keyid , delegated_role )
442-
443- if len (signing_keys ) < role .threshold :
444- raise UnsignedMetadataError (
445- f"{ delegated_role } was signed by { len (signing_keys )} /"
446- f"{ role .threshold } keys" ,
447- )
405+ self .signed .verify_delegate (
406+ delegated_role , delegated_metadata , signed_serializer
407+ )
448408
449409
450410class Signed (metaclass = abc .ABCMeta ):
@@ -674,7 +634,83 @@ def to_dict(self) -> Dict[str, Any]:
674634 }
675635
676636
677- class Root (Signed ):
637+ class _Delegator (metaclass = abc .ABCMeta ):
638+ """Class that implements verify_delegate() for Root and Targets"""
639+
640+ @abc .abstractmethod
641+ def get_delegated_role (self , delegated_role : str ) -> Role :
642+ """Return the role object for the given delegated role.
643+
644+ Raises ValueError if delegated_role is not actually delegated.
645+ """
646+ raise NotImplementedError
647+
648+ @abc .abstractmethod
649+ def get_key (self , keyid : str ) -> Key :
650+ """Return the key object for the given keyid.
651+
652+ Raises ValueError if key is not found.
653+ """
654+ raise NotImplementedError
655+
656+ def verify_delegate (
657+ self ,
658+ delegated_role : str ,
659+ delegated_metadata : "Metadata" ,
660+ signed_serializer : Optional [SignedSerializer ] = None ,
661+ ) -> None :
662+ """Verify that ``delegated_metadata`` is signed with the required
663+ threshold of keys for the delegated role ``delegated_role``.
664+
665+ Args:
666+ delegated_role: Name of the delegated role to verify
667+ delegated_metadata: ``Metadata`` object for the delegated role
668+ signed_serializer: Serializer used for delegate
669+ serialization. Default is ``CanonicalJSONSerializer``.
670+
671+ Raises:
672+ UnsignedMetadataError: ``delegated_role`` was not signed with
673+ required threshold of keys for ``role_name``.
674+ ValueError: no delegation was found for ``delegated_role``.
675+ """
676+
677+ if signed_serializer is None :
678+ # pylint: disable=import-outside-toplevel
679+ from tuf .api .serialization .json import CanonicalJSONSerializer
680+
681+ signed_serializer = CanonicalJSONSerializer ()
682+
683+ data = signed_serializer .serialize (delegated_metadata .signed )
684+ role = self .get_delegated_role (delegated_role )
685+
686+ # verify that delegated_metadata is signed by threshold of unique keys
687+ signing_keys = set ()
688+ for keyid in role .keyids :
689+ try :
690+ key = self .get_key (keyid )
691+ except ValueError :
692+ logger .info ("No key for keyid %s" , keyid )
693+ continue
694+
695+ if keyid not in delegated_metadata .signatures :
696+ logger .info ("No signature for keyid %s" , keyid )
697+ continue
698+
699+ sig = delegated_metadata .signatures [keyid ]
700+ try :
701+ key .verify_signature (sig , data )
702+ signing_keys .add (keyid )
703+ except sslib_exceptions .UnverifiedSignatureError :
704+ logger .info ("Key %s failed to verify %s" , keyid , delegated_role )
705+
706+ if len (signing_keys ) < role .threshold :
707+ raise UnsignedMetadataError (
708+ f"{ delegated_role } was signed by { len (signing_keys )} /"
709+ f"{ role .threshold } keys" ,
710+ )
711+
712+
713+ class Root (Signed , _Delegator ):
678714 """A container for the signed part of root metadata.
679715
680716 Parameters listed below are also instance attributes.
@@ -1748,7 +1784,7 @@ def get_prefixed_paths(self) -> List[str]:
17481784 return paths
17491785
17501786
1751- class Targets (Signed ):
1787+ class Targets (Signed , _Delegator ):
17521788 """A container for the signed part of targets metadata.
17531789
17541790 Targets contains verifying information about target files and also
@@ -1925,7 +1961,7 @@ def get_delegated_role(self, delegated_role: str) -> Role:
19251961 def get_key (self , keyid : str ) -> Key :
19261962 """Return the key object for the given keyid.
19271963
1928- Raises ValueError if keyid is not found.
1964+ Raises ValueError if key is not found.
19291965 """
19301966 if self .delegations is None :
19311967 raise ValueError ("No delegations found" )
0 commit comments