1"""Signature container class"""
2
3from __future__ import annotations
4
5import logging
6from typing import Any
7
8logger = logging.getLogger(__name__)
9
10
11class Signature:
12 """A container class containing information about a signature.
13
14 Contains a signature and the keyid uniquely identifying the key used
15 to generate the signature.
16
17 Provides utility methods to easily create an object from a dictionary
18 and return the dictionary representation of the object.
19
20 Args:
21 keyid: HEX string used as a unique identifier of the key.
22 sig: HEX string representing the signature.
23 unrecognized_fields: Dictionary of all attributes that are not managed
24 by securesystemslib.
25
26 Attributes:
27 keyid: HEX string used as a unique identifier of the key.
28 signature: HEX string representing the signature.
29 unrecognized_fields: Dictionary of all attributes that are not managed
30 by securesystemslib.
31
32 """
33
34 def __init__(
35 self,
36 keyid: str,
37 sig: str,
38 unrecognized_fields: dict[str, Any] | None = None,
39 ):
40 self.keyid = keyid
41 self.signature = sig
42
43 if unrecognized_fields is None:
44 unrecognized_fields = {}
45
46 self.unrecognized_fields = unrecognized_fields
47
48 def __eq__(self, other: Any) -> bool:
49 if not isinstance(other, Signature):
50 return False
51
52 return (
53 self.keyid == other.keyid
54 and self.signature == other.signature
55 and self.unrecognized_fields == other.unrecognized_fields
56 )
57
58 def __hash__(self) -> int:
59 return hash((self.keyid, self.signature, self.unrecognized_fields))
60
61 @classmethod
62 def from_dict(cls, signature_dict: dict) -> Signature:
63 """Creates a Signature object from its JSON/dict representation.
64
65 Arguments:
66 signature_dict:
67 A dict containing a valid keyid and a signature.
68 Note that the fields in it should be named "keyid" and "sig"
69 respectively.
70
71 Raises:
72 KeyError: If any of the "keyid" and "sig" fields are missing from
73 the signature_dict.
74
75 Side Effect:
76 Destroys the metadata dict passed by reference.
77
78 Returns:
79 A "Signature" instance.
80 """
81
82 keyid = signature_dict.pop("keyid")
83 sig = signature_dict.pop("sig")
84 # All fields left in the signature_dict are unrecognized.
85 return cls(keyid, sig, signature_dict)
86
87 def to_dict(self) -> dict:
88 """Returns the JSON-serializable dictionary representation of self."""
89
90 return {
91 "keyid": self.keyid,
92 "sig": self.signature,
93 **self.unrecognized_fields,
94 }