Skip to content

Commit 49aa0fc

Browse files
MVrachevlukpueh
authored andcommitted
Make new API compatible with the Signing interface
In the securesystemslib pr secure-systems-lab/securesystemslib#319 I added a new Signer interface with the purpose of supporting multiple signing implementations. Additionally, I added the SSlibSigner implementation of that interface which implements the signing operation for rsa, ed25519 and ecdsa schemes. With this commit, I integrate the SSlibSigner into the new API in tuf. Signed-off-by: Martin Vrachev <[email protected]>
1 parent 3b33deb commit 49aa0fc

File tree

3 files changed

+30
-16
lines changed

3 files changed

+30
-16
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
python_requires="~=3.6",
114114
install_requires = [
115115
'requests>=2.19.1',
116-
'securesystemslib>=0.18.0',
116+
'securesystemslib>=0.20.0',
117117
'six>=1.11.0'
118118
],
119119
packages = find_packages(exclude=['tests']),

tests/test_api.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
format_keyval_to_metadata
4848
)
4949

50+
from securesystemslib.signer import (
51+
SSlibSigner
52+
)
53+
5054
logger = logging.getLogger(__name__)
5155

5256

@@ -163,8 +167,9 @@ def test_sign_verify(self):
163167
self.assertTrue(metadata_obj.verify(
164168
self.keystore['targets']['public']))
165169

170+
sslib_signer = SSlibSigner(self.keystore['snapshot']['private'])
166171
# Append a new signature with the unrelated key and assert that ...
167-
metadata_obj.sign(self.keystore['snapshot']['private'], append=True)
172+
metadata_obj.sign(sslib_signer, append=True)
168173
# ... there are now two signatures, and
169174
self.assertTrue(len(metadata_obj.signatures) == 2)
170175
# ... both are valid for the corresponding keys.
@@ -173,16 +178,17 @@ def test_sign_verify(self):
173178
self.assertTrue(metadata_obj.verify(
174179
self.keystore['snapshot']['public']))
175180

181+
sslib_signer.key_dict = self.keystore['timestamp']['private']
176182
# Create and assign (don't append) a new signature and assert that ...
177-
metadata_obj.sign(self.keystore['timestamp']['private'], append=False)
183+
metadata_obj.sign(sslib_signer, append=False)
178184
# ... there now is only one signature,
179185
self.assertTrue(len(metadata_obj.signatures) == 1)
180186
# ... valid for that key.
181187
self.assertTrue(metadata_obj.verify(
182188
self.keystore['timestamp']['public']))
183189

184190
# Assert exception if there are more than one signatures for a key
185-
metadata_obj.sign(self.keystore['timestamp']['private'], append=True)
191+
metadata_obj.sign(sslib_signer, append=True)
186192
with self.assertRaises(tuf.exceptions.Error) as ctx:
187193
metadata_obj.verify(self.keystore['timestamp']['public'])
188194
self.assertTrue(

tuf/api/metadata.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020

2121
import tempfile
2222

23+
from securesystemslib.keys import verify_signature
2324
from securesystemslib.util import persist_temp_file
25+
from securesystemslib.signer import Signer, Signature
2426
from securesystemslib.storage import (StorageBackendInterface,
2527
FilesystemBackend)
26-
from securesystemslib.keys import create_signature, verify_signature
2728

2829
from tuf.api.serialization import (MetadataSerializer, MetadataDeserializer,
2930
SignedSerializer)
@@ -90,12 +91,14 @@ def from_dict(cls, metadata: Mapping[str, Any]) -> 'Metadata':
9091
else:
9192
raise ValueError(f'unrecognized metadata type "{_type}"')
9293

93-
# NOTE: If Signature becomes a class, we should iterate over
94-
# metadata['signatures'], call Signature.from_dict for each item, and
95-
# pass a list of Signature objects to the Metadata constructor instead.
94+
signatures = []
95+
for signature in metadata.pop('signatures'):
96+
signature_obj = Signature.from_dict(signature)
97+
signatures.append(signature_obj)
98+
9699
return cls(
97100
signed=inner_cls.from_dict(metadata.pop('signed')),
98-
signatures=metadata.pop('signatures'))
101+
signatures=signatures)
99102

100103
@classmethod
101104
def from_file(
@@ -139,8 +142,13 @@ def from_file(
139142

140143
def to_dict(self) -> Dict[str, Any]:
141144
"""Returns the dict representation of self. """
145+
146+
signatures = []
147+
for sig in self.signatures:
148+
signatures.append(sig.to_dict())
149+
142150
return {
143-
'signatures': self.signatures,
151+
'signatures': signatures,
144152
'signed': self.signed.to_dict()
145153
}
146154

@@ -178,13 +186,14 @@ def to_file(
178186

179187
# Signatures.
180188
def sign(
181-
self, key: Mapping[str, Any], append: bool = False,
189+
self, signer: Signer, append: bool = False,
182190
signed_serializer: Optional[SignedSerializer] = None
183191
) -> Dict[str, Any]:
184192
"""Creates signature over 'signed' and assigns it to 'signatures'.
185193
186194
Arguments:
187-
key: A securesystemslib-style private key object used for signing.
195+
signer: An object implementing the securesystemslib.signer.Signer
196+
interface.
188197
append: A boolean indicating if the signature should be appended to
189198
the list of signatures or replace any existing signatures. The
190199
default behavior is to replace signatures.
@@ -209,8 +218,7 @@ def sign(
209218
from tuf.api.serialization.json import CanonicalJSONSerializer
210219
signed_serializer = CanonicalJSONSerializer()
211220

212-
signature = create_signature(key,
213-
signed_serializer.serialize(self.signed))
221+
signature = signer.sign(signed_serializer.serialize(self.signed))
214222

215223
if append:
216224
self.signatures.append(signature)
@@ -244,7 +252,7 @@ def verify(self, key: Mapping[str, Any],
244252
245253
"""
246254
signatures_for_keyid = list(filter(
247-
lambda sig: sig['keyid'] == key['keyid'], self.signatures))
255+
lambda sig: sig.keyid == key['keyid'], self.signatures))
248256

249257
if not signatures_for_keyid:
250258
raise tuf.exceptions.Error(
@@ -262,7 +270,7 @@ def verify(self, key: Mapping[str, Any],
262270
signed_serializer = CanonicalJSONSerializer()
263271

264272
return verify_signature(
265-
key, signatures_for_keyid[0],
273+
key, signatures_for_keyid[0].to_dict(),
266274
signed_serializer.serialize(self.signed))
267275

268276

0 commit comments

Comments
 (0)