# Path: securesystemslib/exceptions.py
# class FormatError(Error):
#   """Indicate an error while validating an object's format."""
#   pass
# 
# class UnsupportedAlgorithmError(Error):
#   """Indicate an error while trying to identify a user-specified algorithm."""
#   pass
# 
# Path: securesystemslib/signer.py
# 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.
#         unrecognized_fields: Dictionary of all attributes that are not managed
#             by securesystemslib.
# 
#     """
#     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
#             and self.unrecognized_fields == other.unrecognized_fields
#         )
# 
# 
#     @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.
# 
#         Side Effect:
#             Destroys the metadata dict passed by reference.
# 
#         Returns:
#             A "Signature" instance.
#         """
# 
#         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:
#         """Returns the JSON-serializable dictionary representation of self."""
# 
#         return {
#             "keyid": self.keyid,
#             "sig": self.signature,
#             **self.unrecognized_fields,
#         }
# 
# 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)


import copy
import sys
import unittest
import unittest
import securesystemslib.formats
import securesystemslib.keys as KEYS
from securesystemslib.exceptions import FormatError, UnsupportedAlgorithmError
from securesystemslib.signer import Signature, SSlibSigner

class TestSSlibSigner(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.rsakey_dict = KEYS.generate_rsa_key()
        cls.ed25519key_dict = KEYS.generate_ed25519_key()
        cls.ecdsakey_dict = KEYS.generate_ecdsa_key()
        cls.DATA_STR = "SOME DATA REQUIRING AUTHENTICITY."
        cls.DATA = securesystemslib.formats.encode_canonical(
                cls.DATA_STR).encode("utf-8")


    def test_sslib_sign(self):
        dicts = [self.rsakey_dict, self.ecdsakey_dict, self.ed25519key_dict]
        for scheme_dict in dicts:
            # Test generation of signatures.
            sslib_signer = SSlibSigner(scheme_dict)
            sig_obj = sslib_signer.sign(self.DATA)

            # Verify signature
            verified = KEYS.verify_signature(scheme_dict, sig_obj.to_dict(),
                    self.DATA)
            self.assertTrue(verified, "Incorrect signature.")

            # Removing private key from "scheme_dict".
            private = scheme_dict["keyval"]["private"]
            scheme_dict["keyval"]["private"] = ""
            sslib_signer.key_dict = scheme_dict


# Path: securesystemslib/exceptions.py
# class FormatError(Error):
#   """Indicate an error while validating an object's format."""
#   pass
# 
# class UnsupportedAlgorithmError(Error):
#   """Indicate an error while trying to identify a user-specified algorithm."""
#   pass
# 
# Path: securesystemslib/signer.py
# 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.
#         unrecognized_fields: Dictionary of all attributes that are not managed
#             by securesystemslib.
# 
#     """
#     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
#             and self.unrecognized_fields == other.unrecognized_fields
#         )
# 
# 
#     @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.
# 
#         Side Effect:
#             Destroys the metadata dict passed by reference.
# 
#         Returns:
#             A "Signature" instance.
#         """
# 
#         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:
#         """Returns the JSON-serializable dictionary representation of self."""
# 
#         return {
#             "keyid": self.keyid,
#             "sig": self.signature,
#             **self.unrecognized_fields,
#         }
# 
# 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)


# Path: tests/test_signer.py
import copy
import sys
import unittest
import unittest
import securesystemslib.formats
import securesystemslib.keys as KEYS
from securesystemslib.exceptions import FormatError, UnsupportedAlgorithmError
from securesystemslib.signer import Signature, SSlibSigner


class TestSSlibSigner(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.rsakey_dict = KEYS.generate_rsa_key()
        cls.ed25519key_dict = KEYS.generate_ed25519_key()
        cls.ecdsakey_dict = KEYS.generate_ecdsa_key()
        cls.DATA_STR = "SOME DATA REQUIRING AUTHENTICITY."
        cls.DATA = securesystemslib.formats.encode_canonical(
                cls.DATA_STR).encode("utf-8")


    def test_sslib_sign(self):
        dicts = [self.rsakey_dict, self.ecdsakey_dict, self.ed25519key_dict]
        for scheme_dict in dicts:
            # Test generation of signatures.
            sslib_signer = SSlibSigner(scheme_dict)
            sig_obj = sslib_signer.sign(self.DATA)

            # Verify signature
            verified = KEYS.verify_signature(scheme_dict, sig_obj.to_dict(),
                    self.DATA)
            self.assertTrue(verified, "Incorrect signature.")

            # Removing private key from "scheme_dict".
            private = scheme_dict["keyval"]["private"]
            scheme_dict["keyval"]["private"] = ""
            sslib_signer.key_dict = scheme_dict


            with self.assertRaises((ValueError, FormatError)):