support DER serialization of public keys
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 4c866f6..b7fdc67 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -6,6 +6,12 @@
 
 .. note:: This version is not yet released and is under active development.
 
+* Support DER serialization of public keys using the ``public_bytes`` method of
+  :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKeyWithSerialization`,
+  :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKeyWithSerialization`,
+  and
+  :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKeyWithSerialization`,
+
 0.8 - 2015-03-08
 ~~~~~~~~~~~~~~~~
 
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index f33aba9..25cce6e 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -1184,8 +1184,7 @@
         assert res == 1
         return self._read_mem_bio(bio)
 
-    def _public_key_bytes(self, encoding, format, pkcs1_write_func, evp_pkey,
-                          cdata):
+    def _public_key_bytes(self, encoding, format, evp_pkey, cdata):
         if not isinstance(encoding, serialization.Encoding):
             raise TypeError("encoding must be an item from the Encoding enum")
 
@@ -1194,15 +1193,21 @@
                 "format must be an item from the PublicFormat enum"
             )
 
-        # This is a temporary check until we land DER serialization.
-        if encoding is not serialization.Encoding.PEM:
-            raise ValueError("Only PEM encoding is supported by this backend")
-
         if format is serialization.PublicFormat.SubjectPublicKeyInfo:
-            write_bio = self._lib.PEM_write_bio_PUBKEY
+            if encoding is serialization.Encoding.PEM:
+                write_bio = self._lib.PEM_write_bio_PUBKEY
+            elif encoding is serialization.Encoding.DER:
+                write_bio = self._lib.i2d_PUBKEY_bio
+
             key = evp_pkey
         elif format is serialization.PublicFormat.PKCS1:
-            write_bio = pkcs1_write_func
+            # Only RSA is supported here.
+            assert evp_pkey.type == self._lib.EVP_PKEY_RSA
+            if encoding is serialization.Encoding.PEM:
+                write_bio = self._lib.PEM_write_bio_RSAPublicKey
+            elif encoding is serialization.Encoding.DER:
+                write_bio = self._lib.i2d_RSAPublicKey_bio
+
             key = cdata
 
         bio = self._create_mem_bio()
diff --git a/src/cryptography/hazmat/backends/openssl/dsa.py b/src/cryptography/hazmat/backends/openssl/dsa.py
index 0089f58..4e9ab3d 100644
--- a/src/cryptography/hazmat/backends/openssl/dsa.py
+++ b/src/cryptography/hazmat/backends/openssl/dsa.py
@@ -225,7 +225,6 @@
         return self._backend._public_key_bytes(
             encoding,
             format,
-            None,
             evp_pkey,
             None
         )
diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py
index 39b0a55..76c529d 100644
--- a/src/cryptography/hazmat/backends/openssl/ec.py
+++ b/src/cryptography/hazmat/backends/openssl/ec.py
@@ -279,7 +279,6 @@
         return self._backend._public_key_bytes(
             encoding,
             format,
-            None,
             evp_pkey,
             None
         )
diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py
index 25168c2..8aafa8a 100644
--- a/src/cryptography/hazmat/backends/openssl/rsa.py
+++ b/src/cryptography/hazmat/backends/openssl/rsa.py
@@ -609,7 +609,6 @@
         return self._backend._public_key_bytes(
             encoding,
             format,
-            self._backend._lib.PEM_write_bio_RSAPublicKey,
             self._evp_pkey,
             self._rsa_cdata
         )
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index ba0a2ba..cfdc06b 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -516,11 +516,3 @@
                 serialization.PrivateFormat.PKCS8,
                 serialization.NoEncryption()
             )
-
-    def test_unsupported_public_key_encoding(self):
-        key = RSA_KEY_2048.private_key(backend).public_key()
-        with pytest.raises(ValueError):
-            key.public_bytes(
-                serialization.Encoding.DER,
-                serialization.PublicFormat.SubjectPublicKeyInfo
-            )
diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py
index 112818f..d699b7c 100644
--- a/tests/hazmat/primitives/test_dsa.py
+++ b/tests/hazmat/primitives/test_dsa.py
@@ -944,16 +944,33 @@
 @pytest.mark.requires_backend_interface(interface=DSABackend)
 @pytest.mark.requires_backend_interface(interface=PEMSerializationBackend)
 class TestDSAPEMPublicKeySerialization(object):
-    def test_public_bytes_unencrypted_pem(self, backend):
+    @pytest.mark.parametrize(
+        ("key_path", "loader_func", "encoding"),
+        [
+            (
+                os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.pub.pem"),
+                serialization.load_pem_public_key,
+                serialization.Encoding.PEM,
+            ), (
+                os.path.join(
+                    "asymmetric",
+                    "DER_Serialization",
+                    "unenc-dsa-pkcs8.pub.der"
+                ),
+                serialization.load_der_public_key,
+                serialization.Encoding.DER,
+            )
+        ]
+    )
+    def test_public_bytes_match(self, key_path, loader_func, encoding,
+                                backend):
         key_bytes = load_vectors_from_file(
-            os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.pub.pem"),
-            lambda pemfile: pemfile.read().encode()
+            key_path, lambda pemfile: pemfile.read(), mode="rb"
         )
-        key = serialization.load_pem_public_key(key_bytes, backend)
+        key = loader_func(key_bytes, backend)
         _skip_if_no_serialization(key, backend)
         serialized = key.public_bytes(
-            serialization.Encoding.PEM,
-            serialization.PublicFormat.SubjectPublicKeyInfo,
+            encoding, serialization.PublicFormat.SubjectPublicKeyInfo,
         )
         assert serialized == key_bytes
 
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py
index 40b1741..a0d7861 100644
--- a/tests/hazmat/primitives/test_ec.py
+++ b/tests/hazmat/primitives/test_ec.py
@@ -558,19 +558,34 @@
 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
 @pytest.mark.requires_backend_interface(interface=PEMSerializationBackend)
 class TestEllipticCurvePEMPublicKeySerialization(object):
-    def test_public_bytes_unencrypted_pem(self, backend):
+    @pytest.mark.parametrize(
+        ("key_path", "loader_func", "encoding"),
+        [
+            (
+                os.path.join(
+                    "asymmetric", "PEM_Serialization", "ec_public_key.pem"
+                ),
+                serialization.load_pem_public_key,
+                serialization.Encoding.PEM,
+            ), (
+                os.path.join(
+                    "asymmetric", "DER_Serialization", "ec_public_key.der"
+                ),
+                serialization.load_der_public_key,
+                serialization.Encoding.DER,
+            )
+        ]
+    )
+    def test_public_bytes_match(self, key_path, loader_func, encoding,
+                                backend):
         _skip_curve_unsupported(backend, ec.SECP256R1())
         key_bytes = load_vectors_from_file(
-            os.path.join(
-                "asymmetric", "PEM_Serialization", "ec_public_key.pem"
-            ),
-            lambda pemfile: pemfile.read().encode()
+            key_path, lambda pemfile: pemfile.read(), mode="rb"
         )
-        key = serialization.load_pem_public_key(key_bytes, backend)
+        key = loader_func(key_bytes, backend)
         _skip_if_no_serialization(key, backend)
         serialized = key.public_bytes(
-            serialization.Encoding.PEM,
-            serialization.PublicFormat.SubjectPublicKeyInfo,
+            encoding, serialization.PublicFormat.SubjectPublicKeyInfo,
         )
         assert serialized == key_bytes
 
diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py
index e6d0ac2..78e550d 100644
--- a/tests/hazmat/primitives/test_rsa.py
+++ b/tests/hazmat/primitives/test_rsa.py
@@ -1865,30 +1865,44 @@
 @pytest.mark.requires_backend_interface(interface=RSABackend)
 @pytest.mark.requires_backend_interface(interface=PEMSerializationBackend)
 class TestRSAPEMPublicKeySerialization(object):
-    def test_public_bytes_unencrypted_pem(self, backend):
+    @pytest.mark.parametrize(
+        ("key_path", "loader_func", "encoding", "format"),
+        [
+            (
+                os.path.join("asymmetric", "public", "PKCS1", "rsa.pub.pem"),
+                serialization.load_pem_public_key,
+                serialization.Encoding.PEM,
+                serialization.PublicFormat.PKCS1,
+            ), (
+                os.path.join("asymmetric", "public", "PKCS1", "rsa.pub.der"),
+                serialization.load_der_public_key,
+                serialization.Encoding.DER,
+                serialization.PublicFormat.PKCS1,
+            ), (
+                os.path.join("asymmetric", "PKCS8", "unenc-rsa-pkcs8.pub.pem"),
+                serialization.load_pem_public_key,
+                serialization.Encoding.PEM,
+                serialization.PublicFormat.SubjectPublicKeyInfo,
+            ), (
+                os.path.join(
+                    "asymmetric",
+                    "DER_Serialization",
+                    "unenc-rsa-pkcs8.pub.der"
+                ),
+                serialization.load_der_public_key,
+                serialization.Encoding.DER,
+                serialization.PublicFormat.SubjectPublicKeyInfo,
+            )
+        ]
+    )
+    def test_public_bytes_match(self, key_path, loader_func, encoding, format,
+                                backend):
         key_bytes = load_vectors_from_file(
-            os.path.join("asymmetric", "PKCS8", "unenc-rsa-pkcs8.pub.pem"),
-            lambda pemfile: pemfile.read().encode()
+            key_path, lambda pemfile: pemfile.read(), mode="rb"
         )
-        key = serialization.load_pem_public_key(key_bytes, backend)
+        key = loader_func(key_bytes, backend)
         _skip_if_no_serialization(key, backend)
-        serialized = key.public_bytes(
-            serialization.Encoding.PEM,
-            serialization.PublicFormat.SubjectPublicKeyInfo,
-        )
-        assert serialized == key_bytes
-
-    def test_public_bytes_pkcs1_unencrypted_pem(self, backend):
-        key_bytes = load_vectors_from_file(
-            os.path.join("asymmetric", "public", "PKCS1", "rsa.pub.pem"),
-            lambda pemfile: pemfile.read().encode()
-        )
-        key = serialization.load_pem_public_key(key_bytes, backend)
-        _skip_if_no_serialization(key, backend)
-        serialized = key.public_bytes(
-            serialization.Encoding.PEM,
-            serialization.PublicFormat.PKCS1,
-        )
+        serialized = key.public_bytes(encoding, format)
         assert serialized == key_bytes
 
     def test_public_bytes_invalid_encoding(self, backend):