aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAviv Palivoda <palaviv@gmail.com>2016-07-02 19:43:06 +0300
committerAlex Gaynor <alex.gaynor@gmail.com>2016-07-02 12:43:06 -0400
commit2120a8e090ff8974d727f76aae5f2f9eac56656c (patch)
treec79d3eaac5584d05bead50f516e5f5dac0cd4bea
parent14a9ad4c35a625088339e2e142907243adfffa99 (diff)
downloadcryptography-2120a8e090ff8974d727f76aae5f2f9eac56656c.tar.gz
cryptography-2120a8e090ff8974d727f76aae5f2f9eac56656c.tar.bz2
cryptography-2120a8e090ff8974d727f76aae5f2f9eac56656c.zip
One shot sign/verification ECDSA (#3029)
* Add sign and verify methods to ECDSA * Documented ECDSA sign/verify methods * Added CHANGELOG entry * Skipping test verify and sign if curve is not supported * Fixed typo in documentation return type * Removed provider language from EllipticCurvePrivateKey and EllipticCurvePublicKey
-rw-r--r--CHANGELOG.rst5
-rw-r--r--docs/hazmat/primitives/asymmetric/dsa.rst2
-rw-r--r--docs/hazmat/primitives/asymmetric/ec.rst49
-rw-r--r--src/cryptography/hazmat/backends/openssl/ec.py10
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/ec.py12
-rw-r--r--tests/hazmat/primitives/test_ec.py22
6 files changed, 95 insertions, 5 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index f044c7e7..518f57ec 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -13,6 +13,11 @@ Changelog
and
:meth:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey.verify`
methods to DSA keys.
+* Added "one shot"
+ :meth:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey.sign`
+ and
+ :meth:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey.verify`
+ methods to ECDSA keys.
1.4 - 2016-06-04
diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst
index 7ab79f8c..f77af2a2 100644
--- a/docs/hazmat/primitives/asymmetric/dsa.rst
+++ b/docs/hazmat/primitives/asymmetric/dsa.rst
@@ -322,7 +322,7 @@ Key interfaces
:class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
provider.
- :return: bytes: Signature.
+ :return bytes: Signature.
.. class:: DSAPrivateKeyWithSerialization
diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst
index 2c59374a..979d3e4b 100644
--- a/docs/hazmat/primitives/asymmetric/ec.rst
+++ b/docs/hazmat/primitives/asymmetric/ec.rst
@@ -48,6 +48,16 @@ Elliptic Curve Signature Algorithms
>>> signer.update(b" to sign")
>>> signature = signer.finalize()
+ There is a shortcut to sign sufficiently short messages directly:
+
+ .. doctest::
+
+ >>> data = b"this is some data I'd like to sign"
+ >>> signature = private_key.sign(
+ ... data,
+ ... ec.ECDSA(hashes.SHA256())
+ ... )
+
The ``signature`` is a ``bytes`` object, whose contents is DER encoded as
described in :rfc:`3279`. This can be decoded using
:func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_dss_signature`.
@@ -371,8 +381,8 @@ Key Interfaces
The signature is formatted as DER-encoded bytes, as specified in
:rfc:`3279`.
- :param signature_algorithm: An instance of a
- :class:`EllipticCurveSignatureAlgorithm` provider.
+ :param signature_algorithm: An instance of
+ :class:`EllipticCurveSignatureAlgorithm`.
:returns:
:class:`~cryptography.hazmat.primitives.asymmetric.AsymmetricSignatureContext`
@@ -401,6 +411,20 @@ Key Interfaces
The EllipticCurvePublicKey object for this private key.
+ .. method:: sign(data, signature_algorithm)
+
+ .. versionadded:: 1.5
+
+ Sign one block of data which can be verified later by others using the
+ public key.
+
+ :param bytes data: The message string to sign.
+
+ :param signature_algorithm: An instance of
+ :class:`EllipticCurveSignatureAlgorithm`.
+
+ :return bytes: Signature.
+
.. class:: EllipticCurvePrivateKeyWithSerialization
@@ -455,8 +479,8 @@ Key Interfaces
:param bytes signature: The signature to verify. DER encoded as
specified in :rfc:`3279`.
- :param signature_algorithm: An instance of a
- :class:`EllipticCurveSignatureAlgorithm` provider.
+ :param signature_algorithm: An instance of
+ :class:`EllipticCurveSignatureAlgorithm`.
:returns:
:class:`~cryptography.hazmat.primitives.asymmetric.AsymmetricVerificationContext`
@@ -490,6 +514,23 @@ Key Interfaces
:return bytes: Serialized key.
+ .. method:: verify(signature, data, signature_algorithm)
+
+ .. versionadded:: 1.5
+
+ Verify one block of data was signed by the private key associated
+ with this public key.
+
+ :param bytes signature: The signature to verify.
+
+ :param bytes data: The message string that was signed.
+
+ :param signature_algorithm: An instance of
+ :class:`EllipticCurveSignatureAlgorithm`.
+
+ :raises cryptography.exceptions.InvalidSignature: If the signature does
+ not validate.
+
.. class:: EllipticCurvePublicKeyWithSerialization
diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py
index 2f476031..1e45e402 100644
--- a/src/cryptography/hazmat/backends/openssl/ec.py
+++ b/src/cryptography/hazmat/backends/openssl/ec.py
@@ -240,6 +240,11 @@ class _EllipticCurvePrivateKey(object):
self._ec_key
)
+ def sign(self, data, signature_algorithm):
+ signer = self.signer(signature_algorithm)
+ signer.update(data)
+ return signer.finalize()
+
@utils.register_interface(ec.EllipticCurvePublicKeyWithSerialization)
class _EllipticCurvePublicKey(object):
@@ -303,3 +308,8 @@ class _EllipticCurvePublicKey(object):
self._evp_pkey,
None
)
+
+ def verify(self, signature, data, signature_algorithm):
+ verifier = self.verifier(signature, signature_algorithm)
+ verifier.update(data)
+ verifier.verify()
diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py
index 907a6358..1c576c6d 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -62,6 +62,12 @@ class EllipticCurvePrivateKey(object):
The EllipticCurve that this key is on.
"""
+ @abc.abstractproperty
+ def sign(self, data, signature_algorithm):
+ """
+ Signs the data
+ """
+
@six.add_metaclass(abc.ABCMeta)
class EllipticCurvePrivateKeyWithSerialization(EllipticCurvePrivateKey):
@@ -104,6 +110,12 @@ class EllipticCurvePublicKey(object):
Returns the key serialized as bytes.
"""
+ @abc.abstractmethod
+ def verify(self, signature, data, signature_algorithm):
+ """
+ Verifies the signature of the data.
+ """
+
EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py
index 8705f79c..dff2f3e1 100644
--- a/tests/hazmat/primitives/test_ec.py
+++ b/tests/hazmat/primitives/test_ec.py
@@ -503,6 +503,28 @@ class TestECDSAVectors(object):
else:
verifier.verify()
+ def test_sign(self, backend):
+ _skip_curve_unsupported(backend, ec.SECP256R1())
+ message = b"one little message"
+ algorithm = ec.ECDSA(hashes.SHA1())
+ private_key = ec.generate_private_key(ec.SECP256R1(), backend)
+ signature = private_key.sign(message, algorithm)
+ public_key = private_key.public_key()
+ verifier = public_key.verifier(signature, algorithm)
+ verifier.update(message)
+ verifier.verify()
+
+ def test_verify(self, backend):
+ _skip_curve_unsupported(backend, ec.SECP256R1())
+ message = b"one little message"
+ algorithm = ec.ECDSA(hashes.SHA1())
+ private_key = ec.generate_private_key(ec.SECP256R1(), backend)
+ signer = private_key.signer(algorithm)
+ signer.update(message)
+ signature = signer.finalize()
+ public_key = private_key.public_key()
+ public_key.verify(signature, message, algorithm)
+
class TestECNumbersEquality(object):
def test_public_numbers_eq(self):