# Author: Stanislav Zidek # See the LICENSE file for legal information regarding use of this file. """Abstract class for ECDSA.""" from .cryptomath import secureHash class ECDSAKey(object): """This is an abstract base class for ECDSA keys. Particular implementations of ECDSA keys, such as :py:class:`~.python_ecdsakey.Python_ECDSAKey` ... more coming inherit from this. To create or parse an ECDSA key, don't use one of these classes directly. Instead, use the factory functions in :py:class:`~tlslite.utils.keyfactory`. """ def __init__(self, public_key, private_key): """Create a new ECDSA key. If public_key or private_key are passed in, the new key will be initialized. :param public_key: ECDSA public key. :param private_key: ECDSA private key. """ raise NotImplementedError() def __len__(self): """Return the size of the order of the curve of this key, in bits. :rtype: int """ raise NotImplementedError() def hasPrivateKey(self): """Return whether or not this key has a private component. :rtype: bool """ raise NotImplementedError() def _sign(self, data, hash_alg): raise NotImplementedError() def _hashAndSign(self, data, hAlg): raise NotImplementedError() def _verify(self, signature, hash_bytes): raise NotImplementedError() def hashAndSign(self, bytes, rsaScheme=None, hAlg='sha1', sLen=None): """Hash and sign the passed-in bytes. This requires the key to have a private component. It performs a signature on the passed-in data with selected hash algorithm. :type bytes: bytes-like object :param bytes: The value which will be hashed and signed. :type rsaScheme: str :param rsaScheme: Ignored, present for API compatibility with RSA :type hAlg: str :param hAlg: The hash algorithm that will be used to hash data :type sLen: int :param sLen: Ignored, present for API compatibility with RSA :rtype: bytearray :returns: An ECDSA signature on the passed-in data. """ hAlg = hAlg.lower() hashBytes = secureHash(bytearray(bytes), hAlg) return self.sign(hashBytes, padding=rsaScheme, hashAlg=hAlg, saltLen=sLen) def hashAndVerify(self, sigBytes, bytes, rsaScheme=None, hAlg='sha1', sLen=None): """Hash and verify the passed-in bytes with the signature. This verifies an ECDSA signature on the passed-in data with selected hash algorithm. :type sigBytes: bytearray :param sigBytes: An ECDSA signature, DER encoded. :type bytes: str or bytearray :param bytes: The value which will be hashed and verified. :type rsaScheme: str :param rsaScheme: Ignored, present for API compatibility with RSA :type hAlg: str :param hAlg: The hash algorithm that will be used :type sLen: int :param sLen: Ignored, present for API compatibility with RSA :rtype: bool :returns: Whether the signature matches the passed-in data. """ hAlg = hAlg.lower() hashBytes = secureHash(bytearray(bytes), hAlg) return self.verify(sigBytes, hashBytes, rsaScheme, hAlg, sLen) def sign(self, bytes, padding=None, hashAlg="sha1", saltLen=None): """Sign the passed-in bytes. This requires the key to have a private component. It performs an ECDSA signature on the passed-in data. :type bytes: bytearray :param bytes: The value which will be signed (generally a binary encoding of hash output. :type padding: str :param padding: Ignored, present for API compatibility with RSA :type hashAlg: str :param hashAlg: name of hash that was used for calculating the bytes :type saltLen: int :param saltLen: Ignored, present for API compatibility with RSA :rtype: bytearray :returns: An ECDSA signature on the passed-in data. """ sigBytes = self._sign(bytes, hashAlg) return sigBytes def verify(self, sigBytes, bytes, padding=None, hashAlg=None, saltLen=None): """Verify the passed-in bytes with the signature. This verifies a PKCS1 signature on the passed-in data. :type sigBytes: bytearray :param sigBytes: A PKCS1 signature. :type bytes: bytearray :param bytes: The value which will be verified. :type padding: str :param padding: Ignored, present for API compatibility with RSA :rtype: bool :returns: Whether the signature matches the passed-in data. """ return self._verify(sigBytes, bytes) def acceptsPassword(self): """Return True if the write() method accepts a password for use in encrypting the private key. :rtype: bool """ raise NotImplementedError() def write(self, password=None): """Return a string containing the key. :rtype: str :returns: A string describing the key, in whichever format (PEM) is native to the implementation. """ raise NotImplementedError() @staticmethod def generate(bits): """Generate a new key with the specified curve. :rtype: ~tlslite.utils.ECDSAKey.ECDSAKey """ raise NotImplementedError()