diff --git a/securesystemslib/signer.py b/securesystemslib/signer.py index 59ad9999..bfe87d77 100644 --- a/securesystemslib/signer.py +++ b/securesystemslib/signer.py @@ -7,7 +7,7 @@ import abc import securesystemslib.keys as sslib_keys -from typing import Any, Dict +from typing import Any, Dict, Optional, Mapping class Signature: @@ -22,18 +22,30 @@ class Signature: Attributes: keyid: HEX string used as a unique identifier of the key. signature: HEX string representing the signature. + unrecognized_fields: Dictionary of all attributes that are not managed + by securesystemslib. """ - def __init__(self, keyid: str, sig: str): + def __init__( + self, + keyid: str, + sig: str, + unrecognized_fields: Optional[Mapping[str, Any]] = None + ): self.keyid = keyid self.signature = sig + self.unrecognized_fields: Mapping[str, Any] = unrecognized_fields or {} def __eq__(self, other: Any) -> bool: if not isinstance(other, Signature): return False - return self.keyid == other.keyid and self.signature == other.signature + return ( + self.keyid == other.keyid + and self.signature == other.signature + and self.unrecognized_fields == other.unrecognized_fields + ) @classmethod @@ -50,11 +62,19 @@ def from_dict(cls, signature_dict: Dict) -> "Signature": KeyError: If any of the "keyid" and "sig" fields are missing from the signature_dict. + Side Effect: + Destroys the metadata dict passed by reference. + Returns: A "Signature" instance. """ - return cls(signature_dict["keyid"], signature_dict["sig"]) + keyid = signature_dict.pop("keyid") + sig = signature_dict.pop("sig") + # All fields left in the signature_dict are unrecognized. + return cls( + keyid, sig, signature_dict + ) def to_dict(self) -> Dict: @@ -62,7 +82,8 @@ def to_dict(self) -> Dict: return { "keyid": self.keyid, - "sig": self.signature + "sig": self.signature, + **self.unrecognized_fields, } diff --git a/tests/test_signer.py b/tests/test_signer.py index 81006ab6..b4f79bcb 100644 --- a/tests/test_signer.py +++ b/tests/test_signer.py @@ -61,9 +61,13 @@ def test_sslib_sign(self): def test_signature_from_to_dict(self): signature_dict = { "sig": "30460221009342e4566528fcecf6a7a5d53ebacdb1df151e242f55f8775883469cb01dbc6602210086b426cc826709acfa2c3f9214610cb0a832db94bbd266fd7c5939a48064a851", - "keyid": "11fa391a0ed7a447cbfeb4b2667e286fc248f64d5e6d0eeed2e5e23f97f9f714" + "keyid": "11fa391a0ed7a447cbfeb4b2667e286fc248f64d5e6d0eeed2e5e23f97f9f714", + "foo": "bar" # unrecognized_field } - sig_obj = Signature.from_dict(signature_dict) + sig_obj = Signature.from_dict(copy.copy(signature_dict)) + + # Verify that unrecognized fields are stored correctly. + self.assertEqual(sig_obj.unrecognized_fields, {"foo": "bar"}) self.assertDictEqual(signature_dict, sig_obj.to_dict())