Skip to content

Commit

Permalink
Add the Signer interface and the SSlibSigner
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Vrachev <[email protected]>
  • Loading branch information
MVrachev committed Feb 19, 2021
1 parent 6924059 commit a04e0b3
Showing 1 changed file with 130 additions and 0 deletions.
130 changes: 130 additions & 0 deletions securesystemslib/signer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"""The goal of this module is to provide a signing interface supporting multiple
signing implementations and a couple of example implementations.
"""

import abc
import securesystemslib.keys as sslib_keys
from typing import Dict


class Signature:
"""A container class containing information about a signature.
Contains a signature and the keyid
uniquely identifying the key used to generate the signature.
Provides utility methods to easily create an object from a dictionary
and return the dictionary representation of the object.
Attributes:
keyid: HEX string used as a unique identifier of the key.
signature: HEX string representing the signature.
"""
def __init__(self, keyid: str, sig: str):
self.keyid = keyid
self.signature = sig


@classmethod
def from_dict(cls, signature_dict: Dict) -> 'Signature':
"""Creates a Signature object from its JSON/dict representation.
Arguments:
signature_dict:
A dict containing a valid keyid and a signature.
Note that the fields in it should be named "keyid" and "sig"
respectively.
Raises:
KeyError: If any of the "keyid" and "sig" fields are missing from
the signature_dict.
Returns:
A "Signature" instance.
"""

return cls(signature_dict["keyid"], signature_dict["sig"])


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

return {
"keyid": self.keyid,
"sig": self.signature
}



class Signer:
"""Signer interface created to support multiple signing implementations."""

__metaclass__ = abc.ABCMeta

@abc.abstractmethod
def sign(payload: bytes) -> 'Signature':
"""Signs a given payload by the key assigned to the Signer instance.
Arguments:
payload: The bytes to be signed.
Returns:
Returns a "Signature" class instance.
"""
raise NotImplementedError # pragma: no cover



class SSlibSigner(Signer):
"""A securesystemslib signer implementation.
Provides a sign method to generate a cryptographic signature with a
securesystemslib-style rsa, ed25519 or ecdsa private key on the instance.
The signature scheme is determined by the key and must be one of:
- rsa(ssa-pss|pkcs1v15)-(md5|sha1|sha224|sha256|sha384|sha512) (12 schemes)
- ed25519
- ecdsa-sha2-nistp256
See 'securesystemslib.interface' for functions to generate and load keys.
Attributes:
key_dict:
A securesystemslib-style key dictionary, which includes a keyid,
key type, signature scheme, and the public and private key values,
e.g.::
{
"keytype": "rsa",
"scheme": "rsassa-pss-sha256",
"keyid": "f30a0870d026980100c0573bd557394f8c1bbd6...",
"keyval": {
"public": "-----BEGIN RSA PUBLIC KEY----- ...",
"private": "-----BEGIN RSA PRIVATE KEY----- ..."
}
}
The public and private keys are strings in PEM format.
"""
def __init__(self, key_dict: Dict):
self.key_dict = key_dict


def sign(self, payload: bytes) -> 'Signature':
"""Signs a given payload by the key assigned to the SSlibSigner instance.
Arguments:
payload: The bytes to be signed.
Raises:
securesystemslib.exceptions.FormatError: Key argument is malformed.
securesystemslib.exceptions.CryptoError, \
securesystemslib.exceptions.UnsupportedAlgorithmError:
Signing errors.
Returns:
Returns a "Signature" class instance.
"""

sig_dict = sslib_keys.create_signature(self.key_dict, payload)
return Signature(**sig_dict)

0 comments on commit a04e0b3

Please sign in to comment.