Fix set_cipher_list on modern OpenSSL

Also port forward a few changes from #422.
diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
index 0dbabc1..5dbe52b 100644
--- a/src/OpenSSL/SSL.py
+++ b/src/OpenSSL/SSL.py
@@ -5,7 +5,6 @@
 from weakref import WeakValueDictionary
 from errno import errorcode
 
-from six import text_type as _text_type
 from six import binary_type as _binary_type
 from six import integer_types as integer_types
 from six import int2byte, indexbytes
@@ -15,6 +14,7 @@
     lib as _lib,
     exception_from_error_queue as _exception_from_error_queue,
     native as _native,
+    make_assert as _make_assert,
     text_to_bytes_and_warn as _text_to_bytes_and_warn,
     path_string as _path_string,
     UNSPECIFIED as _UNSPECIFIED,
@@ -148,6 +148,7 @@
 
 
 _raise_current_error = partial(_exception_from_error_queue, Error)
+_openssl_assert = _make_assert(Error)
 
 
 class WantReadError(Error):
@@ -441,7 +442,7 @@
 
 class Context(object):
     """
-    :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting
+    :class:`OpenSSL.SSL.Context` instances define the parameters for setting
     up new SSL connections.
     """
     _methods = {
@@ -808,20 +809,22 @@
 
     def set_cipher_list(self, cipher_list):
         """
-        Change the cipher list
+        Set the list of ciphers to be used in this context.
 
-        :param cipher_list: A cipher list, see ciphers(1)
+        See the OpenSSL manual for more information (e.g.
+        :manpage:`ciphers(1)`).
+
+        :param bytes cipher_list: An OpenSSL cipher string.
         :return: None
         """
-        if isinstance(cipher_list, _text_type):
-            cipher_list = cipher_list.encode("ascii")
+        cipher_list = _text_to_bytes_and_warn("cipher_list", cipher_list)
 
         if not isinstance(cipher_list, bytes):
-            raise TypeError("cipher_list must be bytes or unicode")
+            raise TypeError("cipher_list must be a bytes string.")
 
-        result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
-        if not result:
-            _raise_current_error()
+        _openssl_assert(
+            _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
+        )
 
     def set_client_ca_list(self, certificate_authorities):
         """
@@ -1498,9 +1501,9 @@
 
     def get_cipher_list(self):
         """
-        Get the session cipher list
+        Retrieve the list of ciphers used by the Connection object.
 
-        :return: A list of cipher strings
+        :return: A list of native cipher strings.
         """
         ciphers = []
         for i in count():
diff --git a/src/OpenSSL/_util.py b/src/OpenSSL/_util.py
index 074ef3d..cba72ad 100644
--- a/src/OpenSSL/_util.py
+++ b/src/OpenSSL/_util.py
@@ -1,9 +1,11 @@
-from warnings import warn
 import sys
+import warnings
 
 from six import PY3, binary_type, text_type
 
 from cryptography.hazmat.bindings.openssl.binding import Binding
+
+
 binding = Binding()
 binding.init_static_locks()
 ffi = binding.ffi
@@ -47,6 +49,21 @@
     raise exception_type(errors)
 
 
+def make_assert(error):
+    """
+    Create an assert function that uses :func:`exception_from_error_queue` to
+    raise an exception wrapped by *error*.
+    """
+    def openssl_assert(ok):
+        """
+        If ok is not true-ish, retrieve the error from OpenSSL and raise it.
+        """
+        if not ok:
+            exception_from_error_queue(error)
+
+    return openssl_assert
+
+
 def native(s):
     """
     Convert :py:class:`bytes` or :py:class:`unicode` to the native
@@ -116,7 +133,7 @@
         returned.
     """
     if isinstance(obj, text_type):
-        warn(
+        warnings.warn(
             _TEXT_WARNING.format(label),
             category=DeprecationWarning,
             stacklevel=3