181 lines
5.5 KiB
Python
181 lines
5.5 KiB
Python
# 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()
|