Merge pull request #1708 from reaperhulk/serialize-shared-private-bytes

move private_bytes to a shared method so we can reuse it
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index eb23ef0..ce11f6c 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -36,7 +36,7 @@
 )
 from cryptography.hazmat.backends.openssl.x509 import _Certificate
 from cryptography.hazmat.bindings.openssl.binding import Binding
-from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives import hashes, serialization
 from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
 from cryptography.hazmat.primitives.asymmetric.padding import (
     MGF1, OAEP, PKCS1v15, PSS
@@ -1093,6 +1093,65 @@
 
         return ctx
 
+    def _private_key_bytes(self, encoding, format, encryption_algorithm,
+                           traditional_write_func, evp_pkey, cdata):
+        if not isinstance(encoding, serialization.Encoding):
+            raise TypeError("encoding must be an item from the Encoding enum")
+
+        if not isinstance(format, serialization.Format):
+            raise TypeError("format must be an item from the Format 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.Format.PKCS8:
+            write_bio = self._lib.PEM_write_bio_PKCS8PrivateKey
+            key = evp_pkey
+        elif format is serialization.Format.TraditionalOpenSSL:
+            write_bio = traditional_write_func
+            key = cdata
+
+        if not isinstance(encryption_algorithm,
+                          serialization.KeySerializationEncryption):
+            raise TypeError(
+                "Encryption algorithm must be a KeySerializationEncryption "
+                "instance"
+            )
+
+        if isinstance(encryption_algorithm, serialization.NoEncryption):
+            password = b""
+            passlen = 0
+            evp_cipher = self._ffi.NULL
+        elif isinstance(encryption_algorithm,
+                        serialization.BestAvailableEncryption):
+            # This is a curated value that we will update over time.
+            evp_cipher = self._lib.EVP_get_cipherbyname(
+                b"aes-256-cbc"
+            )
+            password = encryption_algorithm.password
+            passlen = len(password)
+            if passlen > 1023:
+                raise ValueError(
+                    "Passwords longer than 1023 bytes are not supported by "
+                    "this backend"
+                )
+        else:
+            raise ValueError("Unsupported encryption type")
+
+        bio = self._create_mem_bio()
+        res = write_bio(
+            bio,
+            key,
+            evp_cipher,
+            password,
+            passlen,
+            self._ffi.NULL,
+            self._ffi.NULL
+        )
+        assert res == 1
+        return self._read_mem_bio(bio)
+
 
 class GetCipherByName(object):
     def __init__(self, fmt):
diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py
index e7365c1..0470c3f 100644
--- a/src/cryptography/hazmat/backends/openssl/rsa.py
+++ b/src/cryptography/hazmat/backends/openssl/rsa.py
@@ -21,10 +21,6 @@
     RSAPrivateKeyWithNumbers, RSAPrivateKeyWithSerialization,
     RSAPublicKeyWithNumbers
 )
-from cryptography.hazmat.primitives.serialization import (
-    BestAvailableEncryption, Encoding, Format, KeySerializationEncryption,
-    NoEncryption
-)
 
 
 def _get_rsa_pss_salt_length(pss, key_size, digest_size):
@@ -566,60 +562,14 @@
         )
 
     def private_bytes(self, encoding, format, encryption_algorithm):
-        if not isinstance(encoding, Encoding):
-            raise TypeError("encoding must be an item from the Encoding enum")
-
-        if not isinstance(format, Format):
-            raise TypeError("format must be an item from the Format enum")
-
-        # This is a temporary check until we land DER serialization.
-        if encoding is not Encoding.PEM:
-            raise ValueError("Only PEM encoding is supported by this backend")
-
-        if format is Format.PKCS8:
-            write_bio = self._backend._lib.PEM_write_bio_PKCS8PrivateKey
-            key = self._evp_pkey
-        elif format is Format.TraditionalOpenSSL:
-            write_bio = self._backend._lib.PEM_write_bio_RSAPrivateKey
-            key = self._rsa_cdata
-
-        if not isinstance(encryption_algorithm, KeySerializationEncryption):
-            raise TypeError(
-                "Encryption algorithm must be a KeySerializationEncryption "
-                "instance"
-            )
-
-        if isinstance(encryption_algorithm, NoEncryption):
-            password = b""
-            passlen = 0
-            evp_cipher = self._backend._ffi.NULL
-        elif isinstance(encryption_algorithm, BestAvailableEncryption):
-            # This is a curated value that we will update over time.
-            evp_cipher = self._backend._lib.EVP_get_cipherbyname(
-                b"aes-256-cbc"
-            )
-            password = encryption_algorithm.password
-            passlen = len(password)
-            if passlen > 1023:
-                raise ValueError(
-                    "Passwords longer than 1023 bytes are not supported by "
-                    "this backend"
-                )
-        else:
-            raise ValueError("Unsupported encryption type")
-
-        bio = self._backend._create_mem_bio()
-        res = write_bio(
-            bio,
-            key,
-            evp_cipher,
-            password,
-            passlen,
-            self._backend._ffi.NULL,
-            self._backend._ffi.NULL
+        return self._backend._private_key_bytes(
+            encoding,
+            format,
+            encryption_algorithm,
+            self._backend._lib.PEM_write_bio_RSAPrivateKey,
+            self._evp_pkey,
+            self._rsa_cdata
         )
-        assert res == 1
-        return self._backend._read_mem_bio(bio)
 
 
 @utils.register_interface(RSAPublicKeyWithNumbers)