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 @classmethod
59 def from_dict(cls, signature_dict: dict) -> Signature:
60 """Creates a Signature object from its JSON/dict representation.
61
62 Arguments:
63 signature_dict:
64 A dict containing a valid keyid and a signature.
65 Note that the fields in it should be named "keyid" and "sig"
66 respectively.
67
68 Raises:
69 KeyError: If any of the "keyid" and "sig" fields are missing from
70 the signature_dict.
71
72 Side Effect:
73 Destroys the metadata dict passed by reference.
74
75 Returns:
76 A "Signature" instance.
77 """
78
79 keyid = signature_dict.pop("keyid")
80 sig = signature_dict.pop("sig")
81 # All fields left in the signature_dict are unrecognized.
82 return cls(keyid, sig, signature_dict)
83
84 def to_dict(self) -> dict:
85 """Returns the JSON-serializable dictionary representation of self."""
86
87 return {
88 "keyid": self.keyid,
89 "sig": self.signature,
90 **self.unrecognized_fields,
91 }