Merge pull request #1275 from crc32a/master

Adding binding for NID_issuer_alt_name cause we may need it in pyopenssl
diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py
index 35e2a09..6893cad 100644
--- a/cryptography/hazmat/backends/multibackend.py
+++ b/cryptography/hazmat/backends/multibackend.py
@@ -239,6 +239,18 @@
         raise UnsupportedAlgorithm("DSA is not supported by the backend.",
                                    _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
 
+    def load_dsa_public_numbers(self, numbers):
+        for b in self._filtered_backends(DSABackend):
+            return b.load_dsa_public_numbers(numbers)
+        raise UnsupportedAlgorithm("DSA is not supported by the backend.",
+                                   _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+
+    def load_dsa_private_numbers(self, numbers):
+        for b in self._filtered_backends(DSABackend):
+            return b.load_dsa_private_numbers(numbers)
+        raise UnsupportedAlgorithm("DSA is not supported by the backend.",
+                                   _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+
     def cmac_algorithm_supported(self, algorithm):
         return any(
             b.cmac_algorithm_supported(algorithm)
diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst
index 8622912..63f8406 100644
--- a/docs/hazmat/backends/interfaces.rst
+++ b/docs/hazmat/backends/interfaces.rst
@@ -148,6 +148,33 @@
             :class:`~cryptography.hazmat.primitives.interfaces.HashContext`
 
 
+.. class:: CMACBackend
+
+    .. versionadded:: 0.4
+
+    A backend with methods for using CMAC
+
+    .. method:: cmac_algorithm_supported(algorithm)
+
+        :param algorithm: An instance of a
+            :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm`
+            provider.
+        :return: Returns True if the block cipher is supported for CMAC by this backend
+
+    .. method:: create_cmac_ctx(algorithm)
+
+        Create a
+        :class:`~cryptography.hazmat.primitives.interfaces.CMACContext` that
+        uses the specified ``algorithm`` to calculate a message authentication code.
+
+        :param algorithm: An instance of a
+            :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm`
+            provider.
+
+        :returns:
+            :class:`~cryptography.hazmat.primitives.interfaces.CMACContext`
+
+
 .. class:: PBKDF2HMACBackend
 
     .. versionadded:: 0.2
@@ -364,29 +391,6 @@
             any backend specific criteria are not met.
 
 
-.. class:: TraditionalOpenSSLSerializationBackend
-
-    .. versionadded:: 0.3
-
-    A backend with methods for working with OpenSSL's "traditional" PKCS #1
-    style key serialization.
-
-    .. method:: load_openssl_pem_private_key(data, password)
-
-        :param bytes data: PEM data to deserialize.
-
-        :param bytes password: The password to use if this data is encrypted.
-            Should be None if the data is not encrypted.
-
-        :return: A new instance of the appropriate private key or public key
-            that the serialized data contains.
-
-        :raises ValueError: If the data could not be deserialized correctly.
-
-        :raises cryptography.exceptions.UnsupportedAlgorithm: If the data is
-            encrypted with an unsupported algorithm.
-
-
 .. class:: DSABackend
 
     .. versionadded:: 0.4
@@ -524,56 +528,6 @@
             any backend specific criteria are not met.
 
 
-
-.. class:: CMACBackend
-
-    .. versionadded:: 0.4
-
-    A backend with methods for using CMAC
-
-    .. method:: cmac_algorithm_supported(algorithm)
-
-        :param algorithm: An instance of a
-            :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm`
-            provider.
-        :return: Returns True if the block cipher is supported for CMAC by this backend
-
-    .. method:: create_cmac_ctx(algorithm)
-
-        Create a
-        :class:`~cryptography.hazmat.primitives.interfaces.CMACContext` that
-        uses the specified ``algorithm`` to calculate a message authentication code.
-
-        :param algorithm: An instance of a
-            :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm`
-            provider.
-
-        :returns:
-            :class:`~cryptography.hazmat.primitives.interfaces.CMACContext`
-
-
-.. class:: PKCS8SerializationBackend
-
-    .. versionadded:: 0.5
-
-    A backend with methods for working with PKCS #8 key serialization.
-
-    .. method:: load_pkcs8_pem_private_key(data, password)
-
-        :param bytes data: PEM data to deserialize.
-
-        :param bytes password: The password to use if this data is encrypted.
-            Should be None if the data is not encrypted.
-
-        :return: A new instance of the appropriate private key or public key
-            that the serialized data contains.
-
-        :raises ValueError: If the data could not be deserialized correctly.
-
-        :raises cryptography.exceptions.UnsupportedAlgorithm: If the data is
-            encrypted with an unsupported algorithm.
-
-
 .. class:: EllipticCurveBackend
 
     .. versionadded:: 0.5
@@ -623,3 +577,48 @@
         :returns: An instance of a
             :class:`~cryptography.hazmat.primitives.interfaces.EllipticCurvePublicKey`
             provider.
+
+.. class:: TraditionalOpenSSLSerializationBackend
+
+    .. versionadded:: 0.3
+
+    A backend with methods for working with OpenSSL's "traditional" PKCS #1
+    style key serialization.
+
+    .. method:: load_openssl_pem_private_key(data, password)
+
+        :param bytes data: PEM data to deserialize.
+
+        :param bytes password: The password to use if this data is encrypted.
+            Should be None if the data is not encrypted.
+
+        :return: A new instance of the appropriate private key or public key
+            that the serialized data contains.
+
+        :raises ValueError: If the data could not be deserialized correctly.
+
+        :raises cryptography.exceptions.UnsupportedAlgorithm: If the data is
+            encrypted with an unsupported algorithm.
+
+
+.. class:: PKCS8SerializationBackend
+
+    .. versionadded:: 0.5
+
+    A backend with methods for working with PKCS #8 key serialization.
+
+    .. method:: load_pkcs8_pem_private_key(data, password)
+
+        :param bytes data: PEM data to deserialize.
+
+        :param bytes password: The password to use if this data is encrypted.
+            Should be None if the data is not encrypted.
+
+        :return: A new instance of the appropriate private key or public key
+            that the serialized data contains.
+
+        :raises ValueError: If the data could not be deserialized correctly.
+
+        :raises cryptography.exceptions.UnsupportedAlgorithm: If the data is
+            encrypted with an unsupported algorithm.
+
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index de5f1fd..168ed68 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -144,6 +144,12 @@
     def dsa_parameters_supported(self, p, q, g):
         pass
 
+    def load_dsa_private_numbers(self, numbers):
+        pass
+
+    def load_dsa_public_numbers(self, numbers):
+        pass
+
 
 @utils.register_interface(CMACBackend)
 class DummyCMACBackend(object):
@@ -365,6 +371,8 @@
         backend.create_dsa_signature_ctx("private_key", hashes.SHA1())
         backend.dsa_hash_supported(hashes.SHA1())
         backend.dsa_parameters_supported(1, 2, 3)
+        backend.load_dsa_private_numbers("numbers")
+        backend.load_dsa_public_numbers("numbers")
 
         backend = MultiBackend([])
         with raises_unsupported_algorithm(
@@ -404,6 +412,16 @@
         ):
             backend.dsa_parameters_supported('p', 'q', 'g')
 
+        with raises_unsupported_algorithm(
+            _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
+        ):
+            backend.load_dsa_private_numbers("numbers")
+
+        with raises_unsupported_algorithm(
+            _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
+        ):
+            backend.load_dsa_public_numbers("numbers")
+
     def test_cmac(self):
         backend = MultiBackend([
             DummyCMACBackend([algorithms.AES])