Skip to content

Commit

Permalink
Merge pull request #743 from NicholasTanz/ChangeSignaturestoDictUpstream
Browse files Browse the repository at this point in the history
Change securesystemslib.dsse.Envelope.signatures to dict upstream
  • Loading branch information
lukpueh authored Apr 3, 2024
2 parents 185aa9c + fa7c92d commit e73758b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
22 changes: 15 additions & 7 deletions securesystemslib/dsse.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ class Envelope:
Attributes:
payload: Arbitrary byte sequence of serialized body.
payload_type: string that identifies how to interpret payload.
signatures: list of Signature.
signatures: dict of Signature key id and Signatures.
"""

def __init__(
self, payload: bytes, payload_type: str, signatures: List[Signature]
self,
payload: bytes,
payload_type: str,
signatures: Dict[str, Signature],
):
self.payload = payload
self.payload_type = payload_type
Expand Down Expand Up @@ -58,18 +61,23 @@ def from_dict(cls, data: dict) -> "Envelope":
payload = b64dec(data["payload"])
payload_type = data["payloadType"]

signatures = []
signatures = {}
for signature in data["signatures"]:
signature["sig"] = b64dec(signature["sig"]).hex()
signatures.append(Signature.from_dict(signature))
signature = Signature.from_dict(signature)
if signature.keyid in signatures:
raise ValueError(
f"Multiple signatures found for keyid {signature.keyid}"
)
signatures[signature.keyid] = signature

return cls(payload, payload_type, signatures)

def to_dict(self) -> dict:
"""Returns the JSON-serializable dictionary representation of self."""

signatures = []
for signature in self.signatures:
for signature in self.signatures.values():
sig_dict = signature.to_dict()
sig_dict["sig"] = b64enc(bytes.fromhex(sig_dict["sig"]))
signatures.append(sig_dict)
Expand Down Expand Up @@ -101,7 +109,7 @@ def sign(self, signer: Signer) -> Signature:
"""

signature = signer.sign(self.pae())
self.signatures.append(signature)
self.signatures[signature.keyid] = signature

return signature

Expand Down Expand Up @@ -140,7 +148,7 @@ def verify(self, keys: List[Key], threshold: int) -> Dict[str, Key]:
if len(keys) < threshold:
raise ValueError("Number of keys can't be less than threshold")

for signature in self.signatures:
for signature in self.signatures.values():
for key in keys:
# If Signature keyid doesn't match with Key, skip.
if not key.keyid == signature.keyid:
Expand Down
18 changes: 16 additions & 2 deletions tests/test_dsse.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,28 @@ def setUpClass(cls):
}
cls.pae = b"DSSEv1 29 http://example.com/HelloWorld 11 hello world"

def test_envelope_from_dict_with_duplicate_signatures(self):
"""Test envelope from_dict generates error with duplicate signature keyids"""
envelope_dict = copy.deepcopy(self.envelope_dict)

# add duplicate keyid.
envelope_dict["signatures"].append(copy.deepcopy(self.signature_dict))

# assert that calling from_dict will raise an error.
expected_error_message = f"Multiple signatures found for keyid {self.signature_dict['keyid']}"
with self.assertRaises(ValueError) as context:
Envelope.from_dict(envelope_dict)

self.assertEqual(str(context.exception), expected_error_message)

def test_envelope_from_to_dict(self):
"""Test envelope to_dict and from_dict methods."""

envelope_dict = copy.deepcopy(self.envelope_dict)

# create envelope object from its dict.
envelope_obj = Envelope.from_dict(envelope_dict)
for signature in envelope_obj.signatures:
for signature in envelope_obj.signatures.values():
self.assertIsInstance(signature, Signature)

# Assert envelope dict created by to_dict will be equal.
Expand Down Expand Up @@ -105,7 +119,7 @@ def test_sign_and_verify(self):

# Check for signatures of Envelope.
self.assertEqual(len(self.key_dicts), len(envelope_obj.signatures))
for signature in envelope_obj.signatures:
for signature in envelope_obj.signatures.values():
self.assertIsInstance(signature, Signature)

# Test for invalid threshold value for keys_list.
Expand Down

0 comments on commit e73758b

Please sign in to comment.