From 2288e30119e2af3e2b448345cf6a9e61f8d06aa0 Mon Sep 17 00:00:00 2001 From: Julian Krause Date: Tue, 17 Dec 2013 21:26:23 -0800 Subject: Add verify function to hmac and hashes. --- cryptography/exceptions.py | 4 ++++ cryptography/hazmat/primitives/hashes.py | 11 +++++++++-- cryptography/hazmat/primitives/hmac.py | 11 +++++++++-- cryptography/hazmat/primitives/interfaces.py | 6 ++++++ docs/hazmat/primitives/cryptographic-hashes.rst | 7 +++++++ docs/hazmat/primitives/hmac.rst | 7 +++++++ tests/hazmat/primitives/test_hashes.py | 25 ++++++++++++++++++++++++- tests/hazmat/primitives/test_hmac.py | 25 ++++++++++++++++++++++++- 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('')) -- cgit v1.2.3 From c91fe6a21fbae3107de7b2e53b7343cd67ac8c6d Mon Sep 17 00:00:00 2001 From: Julian Krause Date: Wed, 25 Dec 2013 11:00:49 -0800 Subject: Clean up documentation and naming. --- cryptography/hazmat/primitives/hashes.py | 10 +++++----- cryptography/hazmat/primitives/hmac.py | 6 +++--- docs/exceptions.rst | 6 ++++++ docs/hazmat/primitives/cryptographic-hashes.rst | 7 ++++--- docs/hazmat/primitives/hmac.rst | 7 ++++--- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/cryptography/hazmat/primitives/hashes.py b/cryptography/hazmat/primitives/hashes.py index b3c626d4..c71377d7 100644 --- a/cryptography/hazmat/primitives/hashes.py +++ b/cryptography/hazmat/primitives/hashes.py @@ -55,12 +55,12 @@ class Hash(object): self._ctx = None return digest - def verify(self, sig): - if isinstance(sig, six.text_type): + def verify(self, digest): + if isinstance(digest, 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.") + hash_digest = self.finalize() + if not constant_time.bytes_eq(digest, hash_digest): + raise InvalidSignature("Digest did not match hash digest.") @utils.register_interface(interfaces.HashAlgorithm) diff --git a/cryptography/hazmat/primitives/hmac.py b/cryptography/hazmat/primitives/hmac.py index 8ade84aa..76d658aa 100644 --- a/cryptography/hazmat/primitives/hmac.py +++ b/cryptography/hazmat/primitives/hmac.py @@ -58,9 +58,9 @@ class HMAC(object): self._ctx = None return digest - def verify(self, sig): - if isinstance(sig, six.text_type): + 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, sig): + 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..8be2c48c 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 function of a hash function 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/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst index 02c7b5e1..f6a3f7a1 100644 --- a/docs/hazmat/primitives/cryptographic-hashes.rst +++ b/docs/hazmat/primitives/cryptographic-hashes.rst @@ -67,12 +67,13 @@ Message Digests :return bytes: The message digest as bytes. - .. method:: verify(sig) + .. method:: verify(digest) - Finalize the current context and securely compare digest to sig. + Finalize the current context and securely compare that digest to ``digest``. + :param bytes digest: Received hash digest :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize` - :raises cryptography.exceptions.InvalidSignature: If sig does not match digest + :raises cryptography.exceptions.InvalidSignature: If hash digest does not match digest .. _cryptographic-hash-algorithms: diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst index b556bd6a..0c19f20c 100644 --- a/docs/hazmat/primitives/hmac.rst +++ b/docs/hazmat/primitives/hmac.rst @@ -70,9 +70,10 @@ message. :return bytes: The message digest as bytes. :raises cryptography.exceptions.AlreadyFinalized: - .. method:: verify(sig) + .. method:: verify(signature) - Finalize the current context and securely compare digest to sig. + 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 sig does not match digest + :raises cryptography.exceptions.InvalidSignature: If signature does not match digest -- cgit v1.2.3 From 5093d97130ff3ae5328d1e6e83e86f1988f1e277 Mon Sep 17 00:00:00 2001 From: Julian Krause Date: Thu, 26 Dec 2013 21:06:07 -0800 Subject: Update documentation on interface as well. --- cryptography/hazmat/primitives/interfaces.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py index c6377df5..4143d644 100644 --- a/cryptography/hazmat/primitives/interfaces.py +++ b/cryptography/hazmat/primitives/interfaces.py @@ -164,7 +164,8 @@ class HashContext(six.with_metaclass(abc.ABCMeta)): """ @abc.abstractmethod - def verify(self, sig): + def verify(self, signature): """ - compare digest to sig and raise exception if not equal. + Compare hash digest to signature and raises InvalidSignature + they are not equal. """ -- cgit v1.2.3 From 831467cce6c2a2b916e30914635924042b15ed2d Mon Sep 17 00:00:00 2001 From: Julian Krause Date: Thu, 26 Dec 2013 21:12:58 -0800 Subject: Documentation clarity and grammer fixes. --- cryptography/hazmat/primitives/interfaces.py | 2 +- docs/exceptions.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py index 4143d644..371701a4 100644 --- a/cryptography/hazmat/primitives/interfaces.py +++ b/cryptography/hazmat/primitives/interfaces.py @@ -167,5 +167,5 @@ class HashContext(six.with_metaclass(abc.ABCMeta)): def verify(self, signature): """ Compare hash digest to signature and raises InvalidSignature - they are not equal. + if they are not equal. """ diff --git a/docs/exceptions.rst b/docs/exceptions.rst index 8be2c48c..1fbd3267 100644 --- a/docs/exceptions.rst +++ b/docs/exceptions.rst @@ -10,7 +10,7 @@ Exceptions .. class:: InvalidSignature - This is raised when the verify function of a hash function does not + This is raised when the verify method of a hash context does not compare equal. -- cgit v1.2.3 From b808f8cc91e302d4120eefa80c946a7cdcf9a155 Mon Sep 17 00:00:00 2001 From: Julian Krause Date: Thu, 26 Dec 2013 21:47:39 -0800 Subject: Remove verify from Hash. --- cryptography/hazmat/primitives/hashes.py | 11 ++-------- cryptography/hazmat/primitives/interfaces.py | 7 ------- docs/hazmat/primitives/cryptographic-hashes.rst | 8 -------- tests/hazmat/primitives/test_hashes.py | 27 +------------------------ 4 files changed, 3 insertions(+), 50 deletions(-) diff --git a/cryptography/hazmat/primitives/hashes.py b/cryptography/hazmat/primitives/hashes.py index c71377d7..bee188b3 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, InvalidSignature -from cryptography.hazmat.primitives import constant_time, interfaces +from cryptography.exceptions import AlreadyFinalized +from cryptography.hazmat.primitives import interfaces @utils.register_interface(interfaces.HashContext) @@ -55,13 +55,6 @@ class Hash(object): self._ctx = None return digest - def verify(self, digest): - if isinstance(digest, six.text_type): - raise TypeError("Unicode-objects must be encoded before verifying") - hash_digest = self.finalize() - if not constant_time.bytes_eq(digest, hash_digest): - raise InvalidSignature("Digest did not match hash digest.") - @utils.register_interface(interfaces.HashAlgorithm) class SHA1(object): diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py index 371701a4..e87c9ca9 100644 --- a/cryptography/hazmat/primitives/interfaces.py +++ b/cryptography/hazmat/primitives/interfaces.py @@ -162,10 +162,3 @@ class HashContext(six.with_metaclass(abc.ABCMeta)): """ Return a HashContext that is a copy of the current context. """ - - @abc.abstractmethod - def verify(self, signature): - """ - Compare hash digest to signature and raises InvalidSignature - if they are not equal. - """ diff --git a/docs/hazmat/primitives/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst index f00dd3f5..38347378 100644 --- a/docs/hazmat/primitives/cryptographic-hashes.rst +++ b/docs/hazmat/primitives/cryptographic-hashes.rst @@ -70,14 +70,6 @@ Message Digests :return bytes: The message digest as bytes. - .. method:: verify(digest) - - Finalize the current context and securely compare that digest to ``digest``. - - :param bytes digest: Received hash digest - :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize` - :raises cryptography.exceptions.InvalidSignature: If hash digest does not match digest - .. _cryptographic-hash-algorithms: diff --git a/tests/hazmat/primitives/test_hashes.py b/tests/hazmat/primitives/test_hashes.py index 69d0773a..45faaab2 100644 --- a/tests/hazmat/primitives/test_hashes.py +++ b/tests/hazmat/primitives/test_hashes.py @@ -20,9 +20,7 @@ import pytest import six from cryptography import utils -from cryptography.exceptions import ( - AlreadyFinalized, UnsupportedAlgorithm, InvalidSignature -) +from cryptography.exceptions import AlreadyFinalized, UnsupportedAlgorithm from cryptography.hazmat.primitives import hashes, interfaces from .utils import generate_base_hash_test @@ -66,29 +64,6 @@ 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('')) - def test_unsupported_hash(self, backend): with pytest.raises(UnsupportedAlgorithm): hashes.Hash(UnsupportedDummyHash(), backend) -- cgit v1.2.3