Merge pull request #253 from dreid/hash-raise-after-finalize

raise an exception if you try to use a HashContext after finalize is called.
diff --git a/cryptography/exceptions.py b/cryptography/exceptions.py
index 391bed8..c2e7149 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 3bd3ad4..b8de6c4 100644
--- a/cryptography/hazmat/primitives/hashes.py
+++ b/cryptography/hazmat/primitives/hashes.py
@@ -15,6 +15,7 @@
 
 import six
 
+from cryptography.exceptions import AlreadyFinalized
 from cryptography.hazmat.primitives import interfaces
 
 
@@ -37,17 +38,23 @@
             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 6ac11b3..ab1b28f 100644
--- a/docs/exceptions.rst
+++ b/docs/exceptions.rst
@@ -3,7 +3,13 @@
 
 .. 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 e7b4f2d..525fd88 100644
--- a/docs/hazmat/primitives/cryptographic-hashes.rst
+++ b/docs/hazmat/primitives/cryptographic-hashes.rst
@@ -36,16 +36,25 @@
     .. 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 c022f53..991caf1 100644
--- a/tests/hazmat/primitives/test_hashes.py
+++ b/tests/hazmat/primitives/test_hashes.py
@@ -19,6 +19,7 @@
 
 import six
 
+from cryptography.exceptions import AlreadyFinalized
 from cryptography.hazmat.bindings import _default_backend
 from cryptography.hazmat.primitives import hashes
 
@@ -51,6 +52,16 @@
         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(