aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Krause <julian.krause@gmail.com>2013-12-17 21:26:23 -0800
committerJulian Krause <julian.krause@gmail.com>2013-12-17 21:26:23 -0800
commit2288e30119e2af3e2b448345cf6a9e61f8d06aa0 (patch)
tree9b36ad3394d2d4348c40f40c049815f38378bf0b
parenta4aa420cc6c0203d201a0f418af68d1f11abbcf5 (diff)
downloadcryptography-2288e30119e2af3e2b448345cf6a9e61f8d06aa0.tar.gz
cryptography-2288e30119e2af3e2b448345cf6a9e61f8d06aa0.tar.bz2
cryptography-2288e30119e2af3e2b448345cf6a9e61f8d06aa0.zip
Add verify function to hmac and hashes.
-rw-r--r--cryptography/exceptions.py4
-rw-r--r--cryptography/hazmat/primitives/hashes.py11
-rw-r--r--cryptography/hazmat/primitives/hmac.py11
-rw-r--r--cryptography/hazmat/primitives/interfaces.py6
-rw-r--r--docs/hazmat/primitives/cryptographic-hashes.rst7
-rw-r--r--docs/hazmat/primitives/hmac.rst7
-rw-r--r--tests/hazmat/primitives/test_hashes.py25
-rw-r--r--tests/hazmat/primitives/test_hmac.py25
8 files changed, 90 insertions, 6 deletions
diff --git a/cryptography/exceptions.py b/cryptography/exceptions.py
index e9d88199..44363c24 100644
--- a/cryptography/exceptions.py
+++ b/cryptography/exceptions.py
@@ -30,3 +30,7 @@ class NotYetFinalized(Exception):
class InvalidTag(Exception):
pass
+
+
+class InvalidSignature(Exception):
+ pass
diff --git a/cryptography/hazmat/primitives/hashes.py b/cryptography/hazmat/primitives/hashes.py
index bee188b3..b3c626d4 100644
--- a/cryptography/hazmat/primitives/hashes.py
+++ b/cryptography/hazmat/primitives/hashes.py
@@ -16,8 +16,8 @@ from __future__ import absolute_import, division, print_function
import six
from cryptography import utils
-from cryptography.exceptions import AlreadyFinalized
-from cryptography.hazmat.primitives import interfaces
+from cryptography.exceptions import AlreadyFinalized, InvalidSignature
+from cryptography.hazmat.primitives import constant_time, interfaces
@utils.register_interface(interfaces.HashContext)
@@ -55,6 +55,13 @@ class Hash(object):
self._ctx = None
return digest
+ def verify(self, sig):
+ if isinstance(sig, six.text_type):
+ raise TypeError("Unicode-objects must be encoded before verifying")
+ digest = self.finalize()
+ if not constant_time.bytes_eq(digest, sig):
+ raise InvalidSignature("Signature did not match digest.")
+
@utils.register_interface(interfaces.HashAlgorithm)
class SHA1(object):
diff --git a/cryptography/hazmat/primitives/hmac.py b/cryptography/hazmat/primitives/hmac.py
index 618bccc5..8ade84aa 100644
--- a/cryptography/hazmat/primitives/hmac.py
+++ b/cryptography/hazmat/primitives/hmac.py
@@ -16,8 +16,8 @@ from __future__ import absolute_import, division, print_function
import six
from cryptography import utils
-from cryptography.exceptions import AlreadyFinalized
-from cryptography.hazmat.primitives import interfaces
+from cryptography.exceptions import AlreadyFinalized, InvalidSignature
+from cryptography.hazmat.primitives import constant_time, interfaces
@utils.register_interface(interfaces.HashContext)
@@ -57,3 +57,10 @@ class HMAC(object):
digest = self._ctx.finalize()
self._ctx = None
return digest
+
+ def verify(self, sig):
+ if isinstance(sig, six.text_type):
+ raise TypeError("Unicode-objects must be encoded before verifying")
+ digest = self.finalize()
+ if not constant_time.bytes_eq(digest, sig):
+ raise InvalidSignature("Signature did not match digest.")
diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py
index e3f4f586..76dc9339 100644
--- a/cryptography/hazmat/primitives/interfaces.py
+++ b/cryptography/hazmat/primitives/interfaces.py
@@ -152,3 +152,9 @@ class HashContext(six.with_metaclass(abc.ABCMeta)):
"""
return a HashContext that is a copy of the current context.
"""
+
+ @abc.abstractmethod
+ def verify(self, sig):
+ """
+ compare digest to sig and raise exception if not equal.
+ """
diff --git a/docs/hazmat/primitives/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst
index 90ca198a..02c7b5e1 100644
--- a/docs/hazmat/primitives/cryptographic-hashes.rst
+++ b/docs/hazmat/primitives/cryptographic-hashes.rst
@@ -67,6 +67,13 @@ Message Digests
:return bytes: The message digest as bytes.
+ .. method:: verify(sig)
+
+ Finalize the current context and securely compare digest to sig.
+
+ :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
+ :raises cryptography.exceptions.InvalidSignature: If sig does not match digest
+
.. _cryptographic-hash-algorithms:
diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst
index 0c0d0220..b556bd6a 100644
--- a/docs/hazmat/primitives/hmac.rst
+++ b/docs/hazmat/primitives/hmac.rst
@@ -69,3 +69,10 @@ message.
:return bytes: The message digest as bytes.
:raises cryptography.exceptions.AlreadyFinalized:
+
+ .. method:: verify(sig)
+
+ Finalize the current context and securely compare digest to sig.
+
+ :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
+ :raises cryptography.exceptions.InvalidSignature: If sig does not match digest
diff --git a/tests/hazmat/primitives/test_hashes.py b/tests/hazmat/primitives/test_hashes.py
index ff42e8f4..cd58b065 100644
--- a/tests/hazmat/primitives/test_hashes.py
+++ b/tests/hazmat/primitives/test_hashes.py
@@ -19,7 +19,7 @@ import pytest
import six
-from cryptography.exceptions import AlreadyFinalized
+from cryptography.exceptions import AlreadyFinalized, InvalidSignature
from cryptography.hazmat.primitives import hashes
from .utils import generate_base_hash_test
@@ -57,6 +57,29 @@ class TestHashContext(object):
with pytest.raises(AlreadyFinalized):
h.finalize()
+ def test_verify(self, backend):
+ h = hashes.Hash(hashes.SHA1(), backend=backend)
+ digest = h.finalize()
+
+ h = hashes.Hash(hashes.SHA1(), backend=backend)
+ h.verify(digest)
+
+ with pytest.raises(AlreadyFinalized):
+ h.verify(b'')
+
+ def test_invalid_verify(self, backend):
+ h = hashes.Hash(hashes.SHA1(), backend=backend)
+ with pytest.raises(InvalidSignature):
+ h.verify(b'')
+
+ with pytest.raises(AlreadyFinalized):
+ h.verify(b'')
+
+ def test_verify_reject_unicode(self, backend):
+ h = hashes.Hash(hashes.SHA1(), backend=backend)
+ with pytest.raises(TypeError):
+ h.verify(six.u(''))
+
class TestSHA1(object):
test_SHA1 = generate_base_hash_test(
diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py
index 992bcb1a..48360185 100644
--- a/tests/hazmat/primitives/test_hmac.py
+++ b/tests/hazmat/primitives/test_hmac.py
@@ -19,7 +19,7 @@ import pytest
import six
-from cryptography.exceptions import AlreadyFinalized
+from cryptography.exceptions import AlreadyFinalized, InvalidSignature
from cryptography.hazmat.primitives import hashes, hmac
from .utils import generate_base_hmac_test
@@ -63,3 +63,26 @@ class TestHMAC(object):
with pytest.raises(AlreadyFinalized):
h.finalize()
+
+ def test_verify(self, backend):
+ h = hmac.HMAC(b'', hashes.SHA1(), backend=backend)
+ digest = h.finalize()
+
+ h = hmac.HMAC(b'', hashes.SHA1(), backend=backend)
+ h.verify(digest)
+
+ with pytest.raises(AlreadyFinalized):
+ h.verify(b'')
+
+ def test_invalid_verify(self, backend):
+ h = hmac.HMAC(b'', hashes.SHA1(), backend=backend)
+ with pytest.raises(InvalidSignature):
+ h.verify(b'')
+
+ with pytest.raises(AlreadyFinalized):
+ h.verify(b'')
+
+ def test_verify_reject_unicode(self, backend):
+ h = hmac.HMAC(b'', hashes.SHA1(), backend=backend)
+ with pytest.raises(TypeError):
+ h.verify(six.u(''))