diff options
| author | Alex Gaynor <alex.gaynor@gmail.com> | 2013-11-13 13:26:24 -0800 | 
|---|---|---|
| committer | Alex Gaynor <alex.gaynor@gmail.com> | 2013-11-13 13:26:24 -0800 | 
| commit | c2cddd2b1f0bd935ed53ee49446e268d9bf874e7 (patch) | |
| tree | 5ab21f260a23d74145662ece1c5c1b3917e28d63 | |
| parent | e0c1fe9991cb1e428d5179994940726baae899a0 (diff) | |
| parent | 00fb12ae9d453e1c6db6a046ebf1f68000b44377 (diff) | |
| download | cryptography-c2cddd2b1f0bd935ed53ee49446e268d9bf874e7.tar.gz cryptography-c2cddd2b1f0bd935ed53ee49446e268d9bf874e7.tar.bz2 cryptography-c2cddd2b1f0bd935ed53ee49446e268d9bf874e7.zip | |
Merge pull request #253 from dreid/hash-raise-after-finalize
raise an exception if you try to use a HashContext after finalize is called.
| -rw-r--r-- | cryptography/exceptions.py | 4 | ||||
| -rw-r--r-- | cryptography/hazmat/primitives/hashes.py | 9 | ||||
| -rw-r--r-- | docs/exceptions.rst | 6 | ||||
| -rw-r--r-- | docs/hazmat/primitives/cryptographic-hashes.rst | 13 | ||||
| -rw-r--r-- | tests/hazmat/primitives/test_hashes.py | 11 | 
5 files changed, 40 insertions, 3 deletions
| diff --git a/cryptography/exceptions.py b/cryptography/exceptions.py index 391bed82..c2e71493 100644 --- a/cryptography/exceptions.py +++ b/cryptography/exceptions.py @@ -14,3 +14,7 @@  class UnsupportedAlgorithm(Exception):      pass + + +class AlreadyFinalized(Exception): +    pass diff --git a/cryptography/hazmat/primitives/hashes.py b/cryptography/hazmat/primitives/hashes.py index 3bd3ad46..b8de6c4b 100644 --- a/cryptography/hazmat/primitives/hashes.py +++ b/cryptography/hazmat/primitives/hashes.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function  import six +from cryptography.exceptions import AlreadyFinalized  from cryptography.hazmat.primitives import interfaces @@ -37,17 +38,23 @@ class Hash(object):              self._ctx = ctx      def update(self, data): +        if self._ctx is None: +            raise AlreadyFinalized()          if isinstance(data, six.text_type):              raise TypeError("Unicode-objects must be encoded before hashing")          self._ctx.update(data)      def copy(self): +        if self._ctx is None: +            raise AlreadyFinalized()          return Hash(              self.algorithm, backend=self._backend, ctx=self._ctx.copy()          )      def finalize(self): -        return self._ctx.finalize() +        digest = self._ctx.finalize() +        self._ctx = None +        return digest  @interfaces.register(interfaces.HashAlgorithm) diff --git a/docs/exceptions.rst b/docs/exceptions.rst index 6ac11b3c..ab1b28fe 100644 --- a/docs/exceptions.rst +++ b/docs/exceptions.rst @@ -3,7 +3,13 @@ Exceptions  .. currentmodule:: cryptography.exceptions +.. class:: AlreadyFinalized + +    This is raised when a context is used after being finalized. + +  .. class:: UnsupportedAlgorithm      This is raised when a backend doesn't support the requested algorithm (or      combination of algorithms). + diff --git a/docs/hazmat/primitives/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst index e7b4f2d6..525fd889 100644 --- a/docs/hazmat/primitives/cryptographic-hashes.rst +++ b/docs/hazmat/primitives/cryptographic-hashes.rst @@ -36,16 +36,25 @@ Message Digests      .. method:: update(data)          :param bytes data: The bytes you wish to hash. +        :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`      .. method:: copy() -        :return: a new instance of this object with a copied internal state. +        Copy this :class:`Hash` instance, usually so that we may call +        :meth:`finalize` and get an intermediate digest value while we continue +        to call :meth:`update` on the original. + +        :return: A new instance of :class:`Hash` which can be updated +            and finalized independently of the original instance. +        :raises cryptography.exceptions.AlreadyFinalized: See :meth:`finalize`      .. method:: finalize()          Finalize the current context and return the message digest as bytes. -        Once ``finalize`` is called this object can no longer be used. +        Once ``finalize`` is called this object can no longer be used and +        :meth:`update` and :meth:`copy` will raise +        :class:`~cryptography.exceptions.AlreadyFinalized`.          :return bytes: The message digest as bytes. diff --git a/tests/hazmat/primitives/test_hashes.py b/tests/hazmat/primitives/test_hashes.py index c022f537..991caf15 100644 --- a/tests/hazmat/primitives/test_hashes.py +++ b/tests/hazmat/primitives/test_hashes.py @@ -19,6 +19,7 @@ import pytest  import six +from cryptography.exceptions import AlreadyFinalized  from cryptography.hazmat.bindings import _default_backend  from cryptography.hazmat.primitives import hashes @@ -51,6 +52,16 @@ class TestHashContext(object):          with pytest.raises(TypeError):              hashes.Hash(hashes.SHA1) +    def test_raises_after_finalize(self): +        h = hashes.Hash(hashes.SHA1()) +        h.finalize() + +        with pytest.raises(AlreadyFinalized): +            h.update(b"foo") + +        with pytest.raises(AlreadyFinalized): +            h.copy() +  class TestSHA1(object):      test_SHA1 = generate_base_hash_test( | 
