Merge branch 'master' into pem-loading-backend
diff --git a/.travis/install.sh b/.travis/install.sh
index 3582ea1..fafc4ca 100755
--- a/.travis/install.sh
+++ b/.travis/install.sh
@@ -33,8 +33,6 @@
 fi
 
 if [[ "$DARWIN" = true ]]; then
-    brew update
-    brew install pyenv
     if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi
     case "${TOX_ENV}" in
         py26)
@@ -48,8 +46,8 @@
             sudo pip install virtualenv
             ;;
         pypy)
-            pyenv install pypy-2.3
-            pyenv global pypy-2.3
+            pyenv install pypy-2.3.1
+            pyenv global pypy-2.3.1
             pip install virtualenv
             ;;
         py32)
@@ -63,8 +61,8 @@
             pip install virtualenv
             ;;
         py34)
-            pyenv install 3.4.0
-            pyenv global 3.4.0
+            pyenv install 3.4.1
+            pyenv global 3.4.1
             pip install virtualenv
             ;;
         docs)
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/cryptography/hazmat/bindings/openssl/nid.py b/cryptography/hazmat/bindings/openssl/nid.py
index 7fa0866..133d2ca 100644
--- a/cryptography/hazmat/bindings/openssl/nid.py
+++ b/cryptography/hazmat/bindings/openssl/nid.py
@@ -42,6 +42,7 @@
 static const int NID_crl_reason;
 static const int NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
 static const int NID_subject_alt_name;
+static const int NID_issuer_alt_name;
 static const int NID_X9_62_c2pnb163v1;
 static const int NID_X9_62_c2pnb163v2;
 static const int NID_X9_62_c2pnb163v3;
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])