Skip to content

Commit 1856040

Browse files
committed
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 801c5e3 commit 1856040

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
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: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,9 @@ def test_sign_verify(self):
153153
self.assertTrue(metadata_obj.verify(
154154
self.keystore['targets']['public']))
155155

156+
sslib_signer = SSlibSigner(self.keystore['snapshot']['private'])
156157
# Append a new signature with the unrelated key and assert that ...
157-
metadata_obj.sign(self.keystore['snapshot']['private'], append=True)
158+
metadata_obj.sign(sslib_signer, append=True)
158159
# ... there are now two signatures, and
159160
self.assertTrue(len(metadata_obj.signatures) == 2)
160161
# ... both are valid for the corresponding keys.
@@ -163,16 +164,17 @@ def test_sign_verify(self):
163164
self.assertTrue(metadata_obj.verify(
164165
self.keystore['snapshot']['public']))
165166

167+
sslib_signer.key_dict = self.keystore['timestamp']['private']
166168
# Create and assign (don't append) a new signature and assert that ...
167-
metadata_obj.sign(self.keystore['timestamp']['private'], append=False)
169+
metadata_obj.sign(sslib_signer, append=False)
168170
# ... there now is only one signature,
169171
self.assertTrue(len(metadata_obj.signatures) == 1)
170172
# ... valid for that key.
171173
self.assertTrue(metadata_obj.verify(
172174
self.keystore['timestamp']['public']))
173175

174176
# Assert exception if there are more than one signatures for a key
175-
metadata_obj.sign(self.keystore['timestamp']['private'], append=True)
177+
metadata_obj.sign(sslib_signer, append=True)
176178
with self.assertRaises(tuf.exceptions.Error) as ctx:
177179
metadata_obj.verify(self.keystore['timestamp']['public'])
178180
self.assertTrue(

tuf/api/metadata.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
persist_temp_file
2020
)
2121
from securesystemslib.storage import StorageBackendInterface
22-
from securesystemslib.keys import create_signature, verify_signature
22+
from securesystemslib.keys import verify_signature
23+
from securesystemslib.signer import Signer, Signature
2324

2425
import tuf.formats
2526
import tuf.exceptions
@@ -92,12 +93,17 @@ class also that has a 'from_dict' factory method. (Currently this is
9293
else:
9394
raise ValueError(f'unrecognized metadata type "{_type}"')
9495

96+
signatures = []
97+
for signature in metadata['signatures']:
98+
new_signature = Signature(signature['keyid'], signature['sig'])
99+
signatures.append(new_signature)
100+
95101
# NOTE: If Signature becomes a class, we should iterate over
96102
# metadata['signatures'], call Signature.from_dict for each item, and
97103
# pass a list of Signature objects to the Metadata constructor intead.
98104
return cls(
99105
signed=inner_cls.from_dict(metadata['signed']),
100-
signatures=metadata['signatures'])
106+
signatures=signatures)
101107

102108

103109
@classmethod
@@ -146,8 +152,13 @@ def from_json_file(
146152
# Serialization.
147153
def to_dict(self) -> JsonDict:
148154
"""Returns the JSON-serializable dictionary representation of self. """
155+
156+
signatures = []
157+
for sig in self.signatures:
158+
signatures.append(sig.to_dict())
159+
149160
return {
150-
'signatures': self.signatures,
161+
'signatures': signatures,
151162
'signed': self.signed.to_dict()
152163
}
153164

@@ -184,11 +195,12 @@ def to_json_file(
184195

185196

186197
# Signatures.
187-
def sign(self, key: JsonDict, append: bool = False) -> JsonDict:
198+
def sign(self, signer: Signer, append: bool = False) -> JsonDict:
188199
"""Creates signature over 'signed' and assigns it to 'signatures'.
189200
190201
Arguments:
191-
key: A securesystemslib-style private key object used for signing.
202+
singer: An object implementing the securesystemslib.signer.Signer
203+
interface.
192204
append: A boolean indicating if the signature should be appended to
193205
the list of signatures or replace any existing signatures. The
194206
default behavior is to replace signatures.
@@ -203,7 +215,7 @@ def sign(self, key: JsonDict, append: bool = False) -> JsonDict:
203215
A securesystemslib-style signature object.
204216
205217
"""
206-
signature = create_signature(key, self.signed.to_canonical_bytes())
218+
signature = signer.sign(self.signed.to_canonical_bytes())
207219

208220
if append:
209221
self.signatures.append(signature)
@@ -232,7 +244,7 @@ def verify(self, key: JsonDict) -> bool:
232244
233245
"""
234246
signatures_for_keyid = list(filter(
235-
lambda sig: sig['keyid'] == key['keyid'], self.signatures))
247+
lambda sig: sig.keyid == key['keyid'], self.signatures))
236248

237249
if not signatures_for_keyid:
238250
raise tuf.exceptions.Error(
@@ -244,7 +256,7 @@ def verify(self, key: JsonDict) -> bool:
244256
f'{key["keyid"]}, not sure which one to verify.')
245257

246258
return verify_signature(
247-
key, signatures_for_keyid[0],
259+
key, signatures_for_keyid[0].to_dict(),
248260
self.signed.to_canonical_bytes())
249261

250262

0 commit comments

Comments
 (0)