Merge pull request #1423 from alex/pr/1396

Add MACContext and switch HMAC and CMAC to use it
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 70e30e6..c8cec58 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -8,6 +8,9 @@
 
 * More bit-lengths are now support for ``p`` and ``q`` when loading DSA keys
   from numbers.
+* Added :class:`~cryptography.hazmat.primitives.interfaces.MACContext` as a
+  common interface for CMAC and HMAC and deprecated
+  :class:`~cryptography.hazmat.primitives.interfaces.CMACContext`.
 
 0.6.1 - 2014-10-15
 ~~~~~~~~~~~~~~~~~~
diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py
index 69d776f..ecb5bf4 100644
--- a/cryptography/hazmat/backends/interfaces.py
+++ b/cryptography/hazmat/backends/interfaces.py
@@ -66,7 +66,7 @@
     @abc.abstractmethod
     def create_hmac_ctx(self, key, algorithm):
         """
-        Create a HashContext for calculating a message authentication code.
+        Create a MACContext for calculating a message authentication code.
         """
 
 
@@ -81,7 +81,7 @@
     @abc.abstractmethod
     def create_cmac_ctx(self, algorithm):
         """
-        Create a CMACContext for calculating a message authentication code.
+        Create a MACContext for calculating a message authentication code.
         """
 
 
diff --git a/cryptography/hazmat/backends/openssl/cmac.py b/cryptography/hazmat/backends/openssl/cmac.py
index 7acf439..da7b748 100644
--- a/cryptography/hazmat/backends/openssl/cmac.py
+++ b/cryptography/hazmat/backends/openssl/cmac.py
@@ -20,7 +20,7 @@
 from cryptography.hazmat.primitives.ciphers.modes import CBC
 
 
-@utils.register_interface(interfaces.CMACContext)
+@utils.register_interface(interfaces.MACContext)
 class _CMACContext(object):
     def __init__(self, backend, algorithm, ctx=None):
         if not backend.cmac_algorithm_supported(algorithm):
diff --git a/cryptography/hazmat/primitives/cmac.py b/cryptography/hazmat/primitives/cmac.py
index fa463ae..7ae5c11 100644
--- a/cryptography/hazmat/primitives/cmac.py
+++ b/cryptography/hazmat/primitives/cmac.py
@@ -21,7 +21,7 @@
 from cryptography.hazmat.primitives import constant_time, interfaces
 
 
-@utils.register_interface(interfaces.CMACContext)
+@utils.register_interface(interfaces.MACContext)
 class CMAC(object):
     def __init__(self, algorithm, backend, ctx=None):
         if not isinstance(backend, CMACBackend):
diff --git a/cryptography/hazmat/primitives/hmac.py b/cryptography/hazmat/primitives/hmac.py
index 026ad3b..2329243 100644
--- a/cryptography/hazmat/primitives/hmac.py
+++ b/cryptography/hazmat/primitives/hmac.py
@@ -21,6 +21,7 @@
 from cryptography.hazmat.primitives import constant_time, interfaces
 
 
+@utils.register_interface(interfaces.MACContext)
 @utils.register_interface(interfaces.HashContext)
 class HMAC(object):
     def __init__(self, key, algorithm, backend, ctx=None):
diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py
index 6ae0a4c..370fd68 100644
--- a/cryptography/hazmat/primitives/interfaces.py
+++ b/cryptography/hazmat/primitives/interfaces.py
@@ -391,26 +391,6 @@
 
 
 @six.add_metaclass(abc.ABCMeta)
-class CMACContext(object):
-    @abc.abstractmethod
-    def update(self, data):
-        """
-        Processes the provided bytes.
-        """
-
-    def finalize(self):
-        """
-        Returns the message authentication code as bytes.
-        """
-
-    @abc.abstractmethod
-    def copy(self):
-        """
-        Return a CMACContext that is a copy of the current context.
-        """
-
-
-@six.add_metaclass(abc.ABCMeta)
 class EllipticCurve(object):
     @abc.abstractproperty
     def name(self):
@@ -486,3 +466,34 @@
         """
         Returns an EllipticCurvePublicNumbers.
         """
+
+
+@six.add_metaclass(abc.ABCMeta)
+class MACContext(object):
+    @abc.abstractmethod
+    def update(self, data):
+        """
+        Processes the provided bytes.
+        """
+
+    @abc.abstractmethod
+    def finalize(self):
+        """
+        Returns the message authentication code as bytes.
+        """
+
+    @abc.abstractmethod
+    def copy(self):
+        """
+        Return a MACContext that is a copy of the current context.
+        """
+
+    @abc.abstractmethod
+    def verify(self, signature):
+        """
+        Checks if the generated message authentication code matches the
+        signature.
+        """
+
+# DeprecatedIn07
+CMACContext = MACContext
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index 2d594c8..4cb64c8 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -643,11 +643,13 @@
         stored derived key.
 
 
-`CMAC`_
--------
+`Message Authentication Code`_
+------------------------------
 
 .. class:: CMACContext
 
+    :class:`CMACContext` has been deprecated in favor of :class:`MACContext`.
+
     .. versionadded:: 0.4
 
     .. method:: update(data)
@@ -663,6 +665,30 @@
         :return: A :class:`~cryptography.hazmat.primitives.interfaces.CMACContext`
             that is a copy of the current context.
 
+.. class:: MACContext
+
+    .. versionadded:: 0.7
+
+    .. method:: update(data)
+
+        :param data bytes: The data you want to authenticate.
+
+    .. method:: finalize()
+
+        :return: The message authentication code.
+
+    .. method:: copy()
+
+        :return: A
+            :class:`~cryptography.hazmat.primitives.interfaces.MACContext` that
+            is a copy of the current context.
+
+    .. method:: verify(signature)
+
+        :param signature bytes: The signature to verify.
+
+        :raises cryptography.exceptions.InvalidSignature: This is raised when
+            the provided signature does not match the expected signature.
 
 .. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)
 .. _`Chinese remainder theorem`: https://en.wikipedia.org/wiki/Chinese_remainder_theorem