aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/hazmat/primitives/asymmetric/rsa.rst76
-rw-r--r--src/cryptography/hazmat/backends/openssl/rsa.py11
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/rsa.py12
-rw-r--r--tests/hazmat/primitives/test_rsa.py22
4 files changed, 118 insertions, 3 deletions
diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst
index c2a6d437..70e1678e 100644
--- a/docs/hazmat/primitives/asymmetric/rsa.rst
+++ b/docs/hazmat/primitives/asymmetric/rsa.rst
@@ -153,6 +153,20 @@ secure hash function and padding:
>>> signer.update(message)
>>> signature = signer.finalize()
+There is a shortcut to sign sufficiently short messages directly:
+
+.. doctest::
+
+ >>> message = b"A message I want to sign"
+ >>> signature = private_key.sign(
+ ... message,
+ ... padding.PSS(
+ ... mgf=padding.MGF1(hashes.SHA256()),
+ ... salt_length=padding.PSS.MAX_LENGTH
+ ... ),
+ ... hashes.SHA256()
+ ... )
+
Valid paddings for signatures are
:class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` and
:class:`~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15`. ``PSS``
@@ -190,6 +204,20 @@ a public key to use in verification using
If the signature does not match, ``verify()`` will raise an
:class:`~cryptography.exceptions.InvalidSignature` exception.
+There is a shortcut to verify sufficiently short messages directly:
+
+.. doctest::
+
+ >>> public_key.verify(
+ ... signature,
+ ... message,
+ ... padding.PSS(
+ ... mgf=padding.MGF1(hashes.SHA256()),
+ ... salt_length=padding.PSS.MAX_LENGTH
+ ... ),
+ ... hashes.SHA256()
+ ... )
+
Encryption
~~~~~~~~~~
@@ -486,7 +514,8 @@ Key interfaces
.. versionadded:: 0.3
- Sign data which can be verified later by others using the public key.
+ Get signer to sign data which can be verified later by others using
+ the public key.
:param padding: An instance of a
:class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`
@@ -525,6 +554,25 @@ Key interfaces
The bit length of the modulus.
+ .. method:: sign(data, padding, algorithm)
+
+ .. versionadded:: 1.4
+
+ 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 padding: An instance of an
+ :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`
+ provider.
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
+ provider.
+
+ :return: bytes: Signature.
+
.. class:: RSAPrivateKeyWithSerialization
@@ -580,8 +628,8 @@ Key interfaces
.. versionadded:: 0.3
- Verify data was signed by the private key associated with this public
- key.
+ Get verifier to verify data was signed by the private key associated
+ with this public key.
:param bytes signature: The signature to verify.
@@ -645,6 +693,28 @@ Key interfaces
:return bytes: Serialized key.
+ .. method:: verify(signature, data, padding, algorithm)
+
+ .. versionadded:: 1.4
+
+ Verify one block of data which can be verified later by others using the
+ public key.
+
+ :param bytes signature: The signature to verify.
+
+ :param bytes data: The message string that was signed.
+
+ :param padding: An instance of an
+ :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`
+ provider.
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
+ provider.
+
+ :raises cryptography.exceptions.InvalidSignature: If the signature does
+ not validate.
+
.. class:: RSAPublicKeyWithSerialization
diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py
index fa23bf89..10c51fee 100644
--- a/src/cryptography/hazmat/backends/openssl/rsa.py
+++ b/src/cryptography/hazmat/backends/openssl/rsa.py
@@ -611,6 +611,12 @@ class _RSAPrivateKey(object):
self._rsa_cdata
)
+ def sign(self, data, padding, algorithm):
+ signer = self.signer(padding, algorithm)
+ signer.update(data)
+ signature = signer.finalize()
+ return signature
+
@utils.register_interface(RSAPublicKeyWithSerialization)
class _RSAPublicKey(object):
@@ -661,3 +667,8 @@ class _RSAPublicKey(object):
self._evp_pkey,
self._rsa_cdata
)
+
+ def verify(self, signature, data, padding, algorithm):
+ verifier = self.verifier(signature, padding, algorithm)
+ verifier.update(data)
+ verifier.verify()
diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
index 41b0089e..2cb89515 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
@@ -40,6 +40,12 @@ class RSAPrivateKey(object):
The RSAPublicKey associated with this private key.
"""
+ @abc.abstractmethod
+ def sign(self, data, padding, algorithm):
+ """
+ Signs the data.
+ """
+
@six.add_metaclass(abc.ABCMeta)
class RSAPrivateKeyWithSerialization(RSAPrivateKey):
@@ -88,6 +94,12 @@ class RSAPublicKey(object):
Returns the key serialized as bytes.
"""
+ @abc.abstractmethod
+ def verify(self, signature, data, padding, algorithm):
+ """
+ Verifies the signature of the data.
+ """
+
RSAPublicKeyWithSerialization = RSAPublicKey
diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py
index c94e0df9..9f3008e3 100644
--- a/tests/hazmat/primitives/test_rsa.py
+++ b/tests/hazmat/primitives/test_rsa.py
@@ -481,6 +481,17 @@ class TestRSASignature(object):
signer.update(b"no failure")
signer.finalize()
+ def test_sign(self, backend):
+ private_key = RSA_KEY_512.private_key(backend)
+ message = b"one little message"
+ pkcs = padding.PKCS1v15()
+ algorithm = hashes.SHA1()
+ signature = private_key.sign(message, pkcs, algorithm)
+ public_key = private_key.public_key()
+ verifier = public_key.verifier(signature, pkcs, algorithm)
+ verifier.update(message)
+ verifier.verify()
+
@pytest.mark.requires_backend_interface(interface=RSABackend)
class TestRSAVerification(object):
@@ -836,6 +847,17 @@ class TestRSAVerification(object):
with pytest.raises(InvalidSignature):
verifier.verify()
+ def test_verify(self, backend):
+ private_key = RSA_KEY_512.private_key(backend)
+ message = b"one little message"
+ pkcs = padding.PKCS1v15()
+ algorithm = hashes.SHA1()
+ signer = private_key.signer(pkcs, algorithm)
+ signer.update(message)
+ signature = signer.finalize()
+ public_key = private_key.public_key()
+ public_key.verify(signature, message, pkcs, algorithm)
+
@pytest.mark.requires_backend_interface(interface=RSABackend)
class TestRSAPSSMGF1Verification(object):