aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2013-12-27 08:21:54 -0800
committerAlex Gaynor <alex.gaynor@gmail.com>2013-12-27 08:21:54 -0800
commit37c88a0dea800b3028f95bf71a8cd6e344254d4e (patch)
treebcf227588c0a96073336041978880763ce03bc7e
parentb645521e84026633f666aa107816ac2fc5e05cc6 (diff)
parentb808f8cc91e302d4120eefa80c946a7cdcf9a155 (diff)
downloadcryptography-37c88a0dea800b3028f95bf71a8cd6e344254d4e.tar.gz
cryptography-37c88a0dea800b3028f95bf71a8cd6e344254d4e.tar.bz2
cryptography-37c88a0dea800b3028f95bf71a8cd6e344254d4e.zip
Merge pull request #315 from juliankrause/verify
Add verify function to hmac and hashes.
-rw-r--r--cryptography/exceptions.py4
-rw-r--r--cryptography/hazmat/primitives/hmac.py11
-rw-r--r--docs/exceptions.rst6
-rw-r--r--docs/hazmat/primitives/hmac.rst8
-rw-r--r--tests/hazmat/primitives/test_hmac.py27
5 files changed, 53 insertions, 3 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/hmac.py b/cryptography/hazmat/primitives/hmac.py
index 618bccc5..76d658aa 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, signature):
+ if isinstance(signature, six.text_type):
+ raise TypeError("Unicode-objects must be encoded before verifying")
+ digest = self.finalize()
+ if not constant_time.bytes_eq(digest, signature):
+ raise InvalidSignature("Signature did not match digest.")
diff --git a/docs/exceptions.rst b/docs/exceptions.rst
index 087066b8..1fbd3267 100644
--- a/docs/exceptions.rst
+++ b/docs/exceptions.rst
@@ -8,6 +8,12 @@ Exceptions
This is raised when a context is used after being finalized.
+.. class:: InvalidSignature
+
+ This is raised when the verify method of a hash context does not
+ compare equal.
+
+
.. class:: NotYetFinalized
This is raised when the AEAD tag property is accessed on a context
diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst
index 0547b7d2..b8f94fd2 100644
--- a/docs/hazmat/primitives/hmac.rst
+++ b/docs/hazmat/primitives/hmac.rst
@@ -71,3 +71,11 @@ message.
:return bytes: The message digest as bytes.
:raises cryptography.exceptions.AlreadyFinalized:
+
+ .. method:: verify(signature)
+
+ Finalize the current context and securely compare digest to ``signature``.
+
+ :param bytes signature: The bytes of the HMAC signature recieved.
+ :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`
+ :raises cryptography.exceptions.InvalidSignature: If signature does not match digest
diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py
index 6d8cc27b..7acb78b7 100644
--- a/tests/hazmat/primitives/test_hmac.py
+++ b/tests/hazmat/primitives/test_hmac.py
@@ -20,7 +20,9 @@ import pytest
import six
from cryptography import utils
-from cryptography.exceptions import AlreadyFinalized, UnsupportedAlgorithm
+from cryptography.exceptions import (
+ AlreadyFinalized, UnsupportedAlgorithm, InvalidSignature
+)
from cryptography.hazmat.primitives import hashes, hmac, interfaces
from .utils import generate_base_hmac_test
@@ -71,6 +73,29 @@ 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(''))
+
def test_unsupported_hash(self, backend):
with pytest.raises(UnsupportedAlgorithm):
hmac.HMAC(b"key", UnsupportedDummyHash(), backend)