diff options
author | Alex Gaynor <alex.gaynor@gmail.com> | 2013-12-27 08:21:54 -0800 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2013-12-27 08:21:54 -0800 |
commit | 37c88a0dea800b3028f95bf71a8cd6e344254d4e (patch) | |
tree | bcf227588c0a96073336041978880763ce03bc7e | |
parent | b645521e84026633f666aa107816ac2fc5e05cc6 (diff) | |
parent | b808f8cc91e302d4120eefa80c946a7cdcf9a155 (diff) | |
download | cryptography-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.py | 4 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/hmac.py | 11 | ||||
-rw-r--r-- | docs/exceptions.rst | 6 | ||||
-rw-r--r-- | docs/hazmat/primitives/hmac.rst | 8 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_hmac.py | 27 |
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) |