Upgrade python/pyopenssl to 20.0.1 am: 85a0e4a2f1 am: a8bfc97dba

Original change: https://android-review.googlesource.com/c/platform/external/python/pyopenssl/+/1531280

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: If3eeb5f43ea6e9adf9e1d9d1d7e199c01ec4f1b5
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..1230149
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+  - package-ecosystem: "github-actions"
+    directory: "/"
+    schedule:
+      interval: "daily"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..b65b728
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,79 @@
+name: CI
+on:
+  pull_request: {}
+  push: {}
+
+jobs:
+  linux:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        PYTHON:
+          # Base builds
+          - {VERSION: "2.7", TOXENV: "py27"}
+          - {VERSION: "3.5", TOXENV: "py35"}
+          - {VERSION: "3.6", TOXENV: "py36"}
+          - {VERSION: "3.7", TOXENV: "py37"}
+          - {VERSION: "3.8", TOXENV: "py38"}
+          - {VERSION: "3.9", TOXENV: "py39"}
+          - {VERSION: "pypy2", TOXENV: "pypy"}
+          - {VERSION: "pypy3", TOXENV: "pypy3"}
+          # -cryptographyMaster
+          - {VERSION: "3.6", TOXENV: "py36-cryptographyMaster"}
+          - {VERSION: "3.7", TOXENV: "py37-cryptographyMaster"}
+          - {VERSION: "3.8", TOXENV: "py38-cryptographyMaster"}
+          - {VERSION: "3.9", TOXENV: "py39-cryptographyMaster"}
+          - {VERSION: "pypy3", TOXENV: "pypy3-cryptographyMaster"}
+          # -cryptographyMinimum
+          - {VERSION: "2.7", TOXENV: "py27-cryptographyMinimum"}
+          - {VERSION: "3.5", TOXENV: "py35-cryptographyMinimum"}
+          - {VERSION: "3.6", TOXENV: "py36-cryptographyMinimum"}
+          - {VERSION: "3.7", TOXENV: "py37-cryptographyMinimum"}
+          - {VERSION: "3.8", TOXENV: "py38-cryptographyMinimum"}
+          - {VERSION: "3.9", TOXENV: "py39-cryptographyMinimum"}
+          - {VERSION: "pypy2", TOXENV: "pypy-cryptographyMinimum"}
+          - {VERSION: "pypy3", TOXENV: "pypy3-cryptographyMinimum"}
+          # Random order
+          - {VERSION: "2.7", TOXENV: "py27-randomorder"}
+          - {VERSION: "3.9", TOXENV: "py39-randomorder"}
+          # Downstreams
+          - {VERSION: "3.7", TOXENV: "py37-twistedMaster"}
+          # Meta
+          - {VERSION: "2.7", TOXENV: "check-manifest"}
+          - {VERSION: "2.7", TOXENV: "pypi-readme"}
+          - {VERSION: "3.9", TOXENV: "flake8"}
+          - {VERSION: "2.7", TOXENV: "docs"}
+    name: "${{ matrix.PYTHON.TOXENV }}"
+    steps:
+      - uses: actions/checkout@v2
+      - name: Setup python
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.PYTHON.VERSION }}
+      - run: python -m pip install tox coverage
+      - run: tox -v
+        env:
+          TOXENV: ${{ matrix.PYTHON.TOXENV }}
+      - name: Upload coverage
+        run: |
+          curl -o codecov.sh -f https://codecov.io/bash || curl -o codecov.sh -f https://codecov.io/bash || curl -o codecov.sh -f https://codecov.io/bash
+          bash codecov.sh -n "tox -e ${{ matrix.PYTHON.TOXENV }}"
+
+  linux-docker:
+    runs-on: ubuntu-latest
+    container: ghcr.io/pyca/cryptography-runner-${{ matrix.TEST.CONTAINER }}
+    strategy:
+      matrix:
+        TEST:
+          - {CONTAINER: "stretch", TOXENV: "py27"}
+          - {CONTAINER: "stretch", TOXENV: "py35"}
+    name: "${{ matrix.TEST.TOXENV }} on ${{ matrix.TEST.CONTAINER }}"
+    steps:
+      - uses: actions/checkout@v2
+      - run: tox -v
+        env:
+          TOXENV: ${{ matrix.TEST.TOXENV }}
+      - name: Upload coverage
+        run: |
+          curl -o codecov.sh -f https://codecov.io/bash || curl -o codecov.sh -f https://codecov.io/bash || curl -o codecov.sh -f https://codecov.io/bash
+          bash codecov.sh -n "tox -e ${{ matrix.TEST.TOXENV }} on ${{ matrix.TEST.CONTAINER }}"
diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml
new file mode 100644
index 0000000..7356bd4
--- /dev/null
+++ b/.github/workflows/lock.yml
@@ -0,0 +1,14 @@
+name: Lock Issues
+on:
+  schedule:
+    - cron: '0 0 * * *'
+
+jobs:
+  lock:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: dessant/lock-threads@v2
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          issue-lock-inactive-days: 90
+          pr-lock-inactive-days: 90
diff --git a/.gitignore b/.gitignore
index 2040b80..e3057ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@
 examples/simple/*.cert
 examples/simple/*.pkey
 .cache
+.mypy_cache
\ No newline at end of file
diff --git a/.mention-bot b/.mention-bot
deleted file mode 100644
index 9a20eb3..0000000
--- a/.mention-bot
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "userBlacklist": ["exarkun"]
-}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 52131e8..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,148 +0,0 @@
-dist: trusty
-sudo: false
-language: python
-
-cache:
-  directories:
-    - $HOME/.cache/pip
-
-env:
-  global:
-    - LC_ALL=en_US.UTF-8
-
-matrix:
-  include:
-  - language: generic
-    os: osx
-    osx_image: xcode10.1
-    env: TOXENV=py27
-  - language: generic
-    os: osx
-    osx_image: xcode10.1
-    env: TOXENV=py27 OPENSSL=1.1.0
-  - python: "2.7" # these are just to make travis's UI a bit prettier
-    env: TOXENV=py27
-  - python: "3.4"
-    env: TOXENV=py34
-  - python: "3.5"
-    env: TOXENV=py35
-  - python: "3.6"
-    env: TOXENV=py36
-  - python: "3.7"
-    env: TOXENV=py37
-    dist: xenial
-    sudo: true
-  - python: "pypy"
-    env: TOXENV=pypy
-  - python: "pypy3"
-    env: TOXENV=pypy3
-
-  # Also run the tests against cryptography master.
-  - python: "2.7"
-    env: TOXENV=py27-cryptographyMaster
-  - python: "3.4"
-    env: TOXENV=py34-cryptographyMaster
-  - python: "3.5"
-    env: TOXENV=py35-cryptographyMaster
-  - python: "3.6"
-    env: TOXENV=py36-cryptographyMaster
-  - python: "3.7"
-    env: TOXENV=py37-cryptographyMaster
-    dist: xenial
-    sudo: true
-  - python: "pypy"
-    env: TOXENV=pypy-cryptographyMaster
-  - python: "pypy3"
-    env: TOXENV=pypy3-cryptographyMaster
-
-  # And current minimum cryptography version.
-  - python: "2.7"
-    env: TOXENV=py27-cryptographyMinimum
-  - python: "3.4"
-    env: TOXENV=py34-cryptographyMinimum
-  - python: "3.5"
-    env: TOXENV=py35-cryptographyMinimum
-  - python: "3.6"
-    env: TOXENV=py36-cryptographyMinimum
-  - python: "3.7"
-    env: TOXENV=py37-cryptographyMinimum
-    dist: xenial
-    sudo: true
-  - python: "pypy"
-    env: TOXENV=pypy-cryptographyMinimum
-  - python: "pypy3"
-    env: TOXENV=pypy3-cryptographyMinimum
-
-
-  # Make sure we don't break Twisted or urllib3
-  - python: "2.7"
-    env: TOXENV=py27-twistedMaster
-  - python: "3.5"
-    env: TOXENV=py35-urllib3Master
-
-
-  # Meta
-  - python: "2.7"
-    env: TOXENV=check-manifest
-
-  - python: "2.7"
-    env: TOXENV=pypi-readme
-
-  - python: "2.7"
-    env: TOXENV=flake8
-
-  - python: "2.7"
-    env: TOXENV=docs
-
-  # Let the cryptography master builds fail because they might be caused by
-  # cryptography changes that are beyond our control.
-  allow_failures:
-  - env: TOXENV=py27-cryptographyMaster
-  - env: TOXENV=py34-cryptographyMaster
-  - env: TOXENV=py35-cryptographyMaster
-  - env: TOXENV=py36-cryptographyMaster
-  - env: TOXENV=py37-cryptographyMaster
-  - env: TOXENV=pypy-cryptographyMaster
-  - env: TOXENV=pypy3-cryptographyMaster
-
-
-install:
-  - |
-    if [[ "$(uname -s)" == 'Darwin' ]]; then
-      brew update
-      if [[ "${OPENSSL}" == "1.1.0" ]]; then
-        brew upgrade [email protected]
-      else
-        brew upgrade openssl
-      fi
-      curl -O https://bootstrap.pypa.io/get-pip.py
-      python get-pip.py --user
-      python -m pip install --user virtualenv
-    else
-      pip install virtualenv
-    fi
-    python -m virtualenv ~/.venv
-    ~/.venv/bin/pip install tox coverage
-
-script:
-  - |
-    if [[ "$(uname -s)" == 'Darwin' ]]; then
-      # set our flags to use homebrew openssl
-      if [[ "${OPENSSL}"  == "1.1.0" ]]; then
-        export LDFLAGS="-L/usr/local/opt/[email protected]/lib"
-        export CFLAGS="-I/usr/local/opt/[email protected]/include"
-        export PATH="/usr/local/opt/[email protected]/bin:$PATH"
-      else
-        export LDFLAGS="-L/usr/local/opt/openssl/lib"
-        export CFLAGS="-I/usr/local/opt/openssl/include"
-        export PATH="/usr/local/opt/openssl/bin:$PATH"
-      fi
-    fi
-    openssl version
-    ~/.venv/bin/tox -v
-
-after_script:
-  - ./.travis/upload_coverage.sh
-
-notifications:
-  email: false
diff --git a/.travis/install_urllib3.sh b/.travis/install_urllib3.sh
deleted file mode 100755
index 1324ded..0000000
--- a/.travis/install_urllib3.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-set -e
-set -x
-
-git clone --depth 1 https://github.com/shazow/urllib3.git
-pip install -r ./urllib3/dev-requirements.txt
-pip install ./urllib3[socks]
diff --git a/.travis/upload_coverage.sh b/.travis/upload_coverage.sh
deleted file mode 100755
index 02ea5f4..0000000
--- a/.travis/upload_coverage.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-set -e
-set -x
-
-NO_COVERAGE_TOXENVS=(pypy docs check-manifest pypi-readme flake8)
-if ! [[ "${NO_COVERAGE_TOXENVS[*]}" =~ "${TOXENV}" ]]; then
-    source ~/.venv/bin/activate
-    coverage combine
-    bash <(curl -s https://codecov.io/bash) -e TRAVIS_OS_NAME,TOXENV,OPENSSL
-fi
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 2dda0d2..63e74cb 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -4,6 +4,92 @@
 Versions are year-based with a strict backward-compatibility policy.
 The third digit is only for regressions.
 
+20.0.1 (2020-12-15)
+-------------------
+
+Backward-incompatible changes:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Deprecations:
+^^^^^^^^^^^^^
+
+Changes:
+^^^^^^^^
+
+- Fixed compatibility with OpenSSL 1.1.0.
+
+20.0.0 (2020-11-27)
+-------------------
+
+
+Backward-incompatible changes:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- The minimum ``cryptography`` version is now 3.2.
+- Remove deprecated ``OpenSSL.tsafe`` module.
+- Removed deprecated ``OpenSSL.SSL.Context.set_npn_advertise_callback``, ``OpenSSL.SSL.Context.set_npn_select_callback``, and ``OpenSSL.SSL.Connection.get_next_proto_negotiated``.
+- Drop support for Python 3.4
+- Drop support for OpenSSL 1.0.1 and 1.0.2
+
+Deprecations:
+^^^^^^^^^^^^^
+
+- Deprecated ``OpenSSL.crypto.loads_pkcs7`` and ``OpenSSL.crypto.loads_pkcs12``.
+
+Changes:
+^^^^^^^^
+
+- Added a new optional ``chain`` parameter to ``OpenSSL.crypto.X509StoreContext()``
+  where additional untrusted certificates can be specified to help chain building.
+  `#948 <https://github.com/pyca/pyopenssl/pull/948>`_
+- Added ``OpenSSL.crypto.X509Store.load_locations`` to set trusted
+  certificate file bundles and/or directories for verification.
+  `#943 <https://github.com/pyca/pyopenssl/pull/943>`_
+- Added ``Context.set_keylog_callback`` to log key material.
+  `#910 <https://github.com/pyca/pyopenssl/pull/910>`_
+- Added ``OpenSSL.SSL.Connection.get_verified_chain`` to retrieve the
+  verified certificate chain of the peer.
+  `#894 <https://github.com/pyca/pyopenssl/pull/894>`_.
+- Make verification callback optional in ``Context.set_verify``.
+  If omitted, OpenSSL's default verification is used.
+  `#933 <https://github.com/pyca/pyopenssl/pull/933>`_
+- Fixed a bug that could truncate or cause a zero-length key error due to a
+  null byte in private key passphrase in ``OpenSSL.crypto.load_privatekey``
+  and ``OpenSSL.crypto.dump_privatekey``.
+  `#947 <https://github.com/pyca/pyopenssl/pull/947>`_
+
+19.1.0 (2019-11-18)
+-------------------
+
+
+Backward-incompatible changes:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Removed deprecated ``ContextType``, ``ConnectionType``, ``PKeyType``, ``X509NameType``, ``X509ReqType``, ``X509Type``, ``X509StoreType``, ``CRLType``, ``PKCS7Type``, ``PKCS12Type``, and ``NetscapeSPKIType`` aliases.
+  Use the classes without the ``Type`` suffix instead.
+  `#814 <https://github.com/pyca/pyopenssl/pull/814>`_
+- The minimum ``cryptography`` version is now 2.8 due to issues on macOS with a transitive dependency.
+  `#875 <https://github.com/pyca/pyopenssl/pull/875>`_
+
+Deprecations:
+^^^^^^^^^^^^^
+
+- Deprecated ``OpenSSL.SSL.Context.set_npn_advertise_callback``, ``OpenSSL.SSL.Context.set_npn_select_callback``, and ``OpenSSL.SSL.Connection.get_next_proto_negotiated``.
+  ALPN should be used instead.
+  `#820 <https://github.com/pyca/pyopenssl/pull/820>`_
+
+
+Changes:
+^^^^^^^^
+
+- Support ``bytearray`` in ``SSL.Connection.send()`` by using cffi's from_buffer.
+  `#852 <https://github.com/pyca/pyopenssl/pull/852>`_
+- The ``OpenSSL.SSL.Context.set_alpn_select_callback`` can return a new ``NO_OVERLAPPING_PROTOCOLS`` sentinel value
+  to allow a TLS handshake to complete without an application protocol.
+
+
+----
+
 19.0.0 (2019-01-21)
 -------------------
 
diff --git a/INSTALL.rst b/INSTALL.rst
index 71fe1ed..75540d5 100644
--- a/INSTALL.rst
+++ b/INSTALL.rst
@@ -25,14 +25,9 @@
 pyOpenSSL supports the same platforms and releases as the upstream cryptography project `does <https://cryptography.io/en/latest/installation/#supported-platforms>`_.
 Currently that means:
 
-- 1.0.1
 - 1.0.2
 - 1.1.0
-
-If you need support for older releases, the following pinned versions will work:
-
-- **OpenSSL 0.9.8**: ``'pyOpenSSL<17.0' 'cryptography<1.4'``
-- **OpenSSL 1.0.0**: ``'pyOpenSSL<17.1' 'cryptography<1.7'``
+- 1.1.1
 
 You can always find out the versions of pyOpenSSL, cryptography, and the linked OpenSSL by running ``python -m OpenSSL.debug``.
 
diff --git a/MANIFEST.in b/MANIFEST.in
index 036bcdb..65b7dc3 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,11 +1,6 @@
 include             LICENSE MANIFEST.in *.rst tox.ini .coveragerc
-exclude             leakcheck codecov.yml
+exclude             codecov.yml
 recursive-include   tests           *.py
 recursive-include   doc             *
-recursive-include   examples        *
-recursive-include   rpm             *
-recursive-exclude   leakcheck       *.py *.pem
-recursive-exclude   examples/simple *.cert *.pkey
 prune               doc/_build
 prune               .travis
-prune               .mention-bot
diff --git a/METADATA b/METADATA
index 45585c0..d9be77a 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/pyca/pyopenssl"
   }
-  version: "19.0.0"
+  version: "20.0.1"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2019
-    month: 5
-    day: 13
+    year: 2020
+    month: 12
+    day: 15
   }
 }
diff --git a/README.rst b/README.rst
index ed078d4..1366384 100644
--- a/README.rst
+++ b/README.rst
@@ -6,8 +6,8 @@
    :target: https://pyopenssl.org/en/stable/
    :alt: Stable Docs
 
-.. image:: https://travis-ci.org/pyca/pyopenssl.svg?branch=master
-   :target: https://travis-ci.org/pyca/pyopenssl
+.. image:: https://travis-ci.com/pyca/pyopenssl.svg?branch=master
+   :target: https://travis-ci.com/pyca/pyopenssl
    :alt: Build status
 
 .. image:: https://codecov.io/github/pyca/pyopenssl/branch/master/graph/badge.svg
diff --git a/doc/api/ssl.rst b/doc/api/ssl.rst
index c678b28..ead1452 100644
--- a/doc/api/ssl.rst
+++ b/doc/api/ssl.rst
@@ -74,6 +74,7 @@
              OP_NO_TLSv1
              OP_NO_TLSv1_1
              OP_NO_TLSv1_2
+             OP_NO_TLSv1_3
 
     Constants used with :py:meth:`set_options` of Context objects.
 
@@ -118,6 +119,15 @@
     for details.
 
 
+.. py:data:: NO_OVERLAPPING_PROTOCOLS
+
+    A sentinel value that can be returned by the callback passed to
+    :py:meth:`Context.set_alpn_select_callback` to indicate that
+    the handshake can continue without a specific application protocol.
+
+    .. versionadded:: 19.1
+
+
 .. autofunction:: SSLeay_version
 
 
diff --git a/doc/conf.py b/doc/conf.py
index 3940dd2..dd8d011 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -3,7 +3,7 @@
 # pyOpenSSL documentation build configuration file, created by
 # sphinx-quickstart on Sat Jul 16 07:12:22 2011.
 #
-# This file is execfile()d with the current directory set to its containing dir.
+# This file is execfile()d with the current directory set to its parent dir.
 #
 # Note that not all possible configuration values are present in this
 # autogenerated file.
@@ -11,7 +11,6 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import datetime
 import codecs
 import os
 import re
@@ -32,8 +31,9 @@
 
 def find_version(*file_paths):
     version_file = read_file(*file_paths)
-    version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
-                              version_file, re.M)
+    version_match = re.search(
+        r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M
+    )
     if version_match:
         return version_match.group(1)
     raise RuntimeError("Unable to find version string.")
@@ -45,34 +45,34 @@
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
+# sys.path.insert(0, os.path.abspath('.'))
 
-# -- General configuration -----------------------------------------------------
+# -- General configuration ----------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
-needs_sphinx = '1.0'
+needs_sphinx = "1.0"
 
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
 extensions = [
     "sphinx.ext.autodoc",
-    'sphinx.ext.intersphinx',
+    "sphinx.ext.intersphinx",
 ]
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
 
 # The suffix of source filenames.
-source_suffix = '.rst'
+source_suffix = ".rst"
 
 # The encoding of source files.
-#source_encoding = 'utf-8-sig'
+# source_encoding = 'utf-8-sig'
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = "index"
 
 # General information about the project.
-project = u'pyOpenSSL'
+project = u"pyOpenSSL"
 authors = u"The pyOpenSSL developers"
 copyright = u"2001 " + authors
 
@@ -87,73 +87,74 @@
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
-#language = None
+# language = None
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
-#today = ''
+# today = ''
 # Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
+# today_fmt = '%B %d, %Y'
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
-exclude_patterns = ['_build']
+exclude_patterns = ["_build"]
 
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
+# The reST default role (used for this markup `text`) to use for all documents.
+# default_role = None
 
 # If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
+# add_function_parentheses = True
 
 # If true, the current module name will be prepended to all description
 # unit titles (such as .. function::).
-#add_module_names = True
+# add_module_names = True
 
 # If true, sectionauthor and moduleauthor directives will be shown in the
 # output. They are ignored by default.
-#show_authors = False
+# show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
 
 # A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+# modindex_common_prefix = []
 
 
-# -- Options for HTML output ---------------------------------------------------
+# -- Options for HTML output --------------------------------------------------
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
-on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+on_rtd = os.environ.get("READTHEDOCS", None) == "True"
 
 if not on_rtd:  # only import and set the theme if we're building docs locally
     import sphinx_rtd_theme
-    html_theme = 'sphinx_rtd_theme'
+
+    html_theme = "sphinx_rtd_theme"
     html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
 # documentation.
-#html_theme_options = {}
+# html_theme_options = {}
 
 # Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
+# html_theme_path = []
 
 # The name for this set of Sphinx documents.  If None, it defaults to
 # "<project> v<release> documentation".
-#html_title = None
+# html_title = None
 
 # A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
+# html_short_title = None
 
 # The name of an image file (relative to this directory) to place at the top
 # of the sidebar.
-#html_logo = None
+# html_logo = None
 
 # The name of an image file (within the static path) to use as favicon of the
 # docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
 # pixels large.
-#html_favicon = None
+# html_favicon = None
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
@@ -162,96 +163,92 @@
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
+# html_last_updated_fmt = '%b %d, %Y'
 
 # If true, SmartyPants will be used to convert quotes and dashes to
 # typographically correct entities.
-#html_use_smartypants = True
+# html_use_smartypants = True
 
 # Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
+# html_sidebars = {}
 
 # Additional templates that should be rendered to pages, maps page names to
 # template names.
-#html_additional_pages = {}
+# html_additional_pages = {}
 
 # If false, no module index is generated.
-#html_domain_indices = True
+# html_domain_indices = True
 
 # If false, no index is generated.
-#html_use_index = True
+# html_use_index = True
 
 # If true, the index is split into individual pages for each letter.
-#html_split_index = False
+# html_split_index = False
 
 # If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
+# html_show_sourcelink = True
 
 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
+# html_show_sphinx = True
 
 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
+# html_show_copyright = True
 
 # If true, an OpenSearch description file will be output, and all pages will
 # contain a <link> tag referring to it.  The value of this option must be the
 # base URL from which the finished HTML is served.
-#html_use_opensearch = ''
+# html_use_opensearch = ''
 
 # This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
+# html_file_suffix = None
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'pyOpenSSLdoc'
+htmlhelp_basename = "pyOpenSSLdoc"
 
 
-# -- Options for LaTeX output --------------------------------------------------
+# -- Options for LaTeX output -------------------------------------------------
 
 # The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
+# latex_paper_size = 'letter'
 
 # The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
+# latex_font_size = '10pt'
 
 # Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
+# (source start file, target name, title, author, documentclass [howto/manual])
 latex_documents = [
-  ('index', 'pyOpenSSL.tex', u'pyOpenSSL Documentation',
-   authors, 'manual'),
+    ("index", "pyOpenSSL.tex", u"pyOpenSSL Documentation", authors, "manual"),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
 # the title page.
-#latex_logo = None
+# latex_logo = None
 
 # For "manual" documents, if this is true, then toplevel headings are parts,
 # not chapters.
-#latex_use_parts = False
+# latex_use_parts = False
 
 # If true, show page references after internal links.
-#latex_show_pagerefs = False
+# latex_show_pagerefs = False
 
 # If true, show URL addresses after external links.
-#latex_show_urls = False
+# latex_show_urls = False
 
 # Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
+# latex_preamble = ''
 
 # Documents to append as an appendix to all manuals.
-#latex_appendices = []
+# latex_appendices = []
 
 # If false, no module index is generated.
-#latex_domain_indices = True
+# latex_domain_indices = True
 
 
-# -- Options for manual page output --------------------------------------------
+# -- Options for manual page output -------------------------------------------
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
-man_pages = [
-    ('index', 'pyopenssl', u'pyOpenSSL Documentation',
-     [authors], 1)
-]
+man_pages = [("index", "pyopenssl", u"pyOpenSSL Documentation", [authors], 1)]
 
 intersphinx_mapping = {
     "https://docs.python.org/3": None,
diff --git a/doc/index.rst b/doc/index.rst
index d4c5e2e..2d64d3b 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -20,7 +20,6 @@
    api
    internals
 
-There are also `examples in the pyOpenSSL repository <https://github.com/pyca/pyopenssl/tree/master/examples>`_ that may help you getting started.
 
 
 Meta
diff --git a/examples/README.rst b/examples/README.rst
deleted file mode 100644
index 1e9116b..0000000
--- a/examples/README.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-========
-Examples
-========
-
-
-certgen.py -- Certificate generation module
-===========================================
-
-Example module with three functions:
-
-createKeyPair
-   Create a public/private key pair.
-
-createCertRequest
-   Create a certificate request.
-
-createCertificate
-   Create a certificate given a cert request.
-
-In fact, I created the certificates and keys in the 'simple' directory with the script ``mk_simple_certs.py``.
-
-
-simple -- Simple client/server example
-======================================
-
-Start the server with::
-
-    python server.py PORT
-
-and start clients with::
-
-    python client.py HOST PORT
-
-The server is a simple echo server, anything a client sends, it sends back.
-
-
-proxy.py -- Example of an SSL-enabled proxy
-===========================================
-
-The proxy example demonstrate how to use set_connect_state to start talking SSL over an already connected socket.
-
-Usage::
-
-  python proxy.py server[:port] proxy[:port]
-
-Contributed by Mihai Ibanescu
-
-
-SecureXMLRPCServer.py -- SSL-enabled version of SimpleXMLRPCServer
-==================================================================
-
-Acts exactly like `SimpleXMLRPCServer <https://docs.python.org/3/library/xmlrpc.server.html>`_ from the Python standard library, but uses secure connections.
-The technique and classes should work for any SocketServer style server.
-However, the code has not been extensively tested.
-
-Contributed by Michal Wallace
diff --git a/examples/SecureXMLRPCServer.py b/examples/SecureXMLRPCServer.py
deleted file mode 100644
index 56bfaea..0000000
--- a/examples/SecureXMLRPCServer.py
+++ /dev/null
@@ -1,115 +0,0 @@
-"""
-SecureXMLRPCServer module using pyOpenSSL 0.5
-Written 0907.2002
-by Michal Wallace
-http://www.sabren.net/
-
-This acts exactly like SimpleXMLRPCServer
-from the standard python library, but
-uses secure connections. The technique
-and classes should work for any SocketServer
-style server. However, the code has not
-been extensively tested.
-
-This code is in the public domain.
-It is provided AS-IS WITH NO WARRANTY WHATSOEVER.
-"""
-
-import SimpleXMLRPCServer
-import SocketServer
-import os
-import socket
-
-from OpenSSL import SSL
-
-
-class SSLWrapper:
-    """
-    This whole class exists just to filter out a parameter
-    passed in to the shutdown() method in SimpleXMLRPC.doPOST()
-    """
-    def __init__(self, conn):
-        """
-        Connection is not yet a new-style class,
-        so I'm making a proxy instead of subclassing.
-        """
-        self.__dict__["conn"] = conn
-
-    def __getattr__(self, name):
-        return getattr(self.__dict__["conn"], name)
-
-    def __setattr__(self, name, value):
-        setattr(self.__dict__["conn"], name, value)
-
-    def shutdown(self, how=1):
-        """
-        SimpleXMLRpcServer.doPOST calls shutdown(1),
-        and Connection.shutdown() doesn't take
-        an argument. So we just discard the argument.
-        """
-        self.__dict__["conn"].shutdown()
-
-    def accept(self):
-        """
-        This is the other part of the shutdown() workaround.
-        Since servers create new sockets, we have to infect
-        them with our magic. :)
-        """
-        c, a = self.__dict__["conn"].accept()
-        return (SSLWrapper(c), a)
-
-
-class SecureTCPServer(SocketServer.TCPServer):
-    """
-    Just like TCPServer, but use a socket.
-    This really ought to let you specify the key and certificate files.
-    """
-    def __init__(self, server_address, RequestHandlerClass):
-        SocketServer.BaseServer.__init__(
-            self, server_address, RequestHandlerClass
-        )
-
-        # Same as normal, but make it secure:
-        ctx = SSL.Context(SSL.SSLv23_METHOD)
-        ctx.set_options(SSL.OP_NO_SSLv2)
-
-        dir = os.curdir
-        ctx.use_privatekey_file(os.path.join(dir, 'server.pkey'))
-        ctx.use_certificate_file(os.path.join(dir, 'server.cert'))
-
-        self.socket = SSLWrapper(
-            SSL.Connection(
-                ctx, socket.socket(self.address_family, self.socket_type)
-            )
-        )
-        self.server_bind()
-        self.server_activate()
-
-
-class SecureXMLRPCRequestHandler(
-        SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
-    def setup(self):
-        """
-        We need to use socket._fileobject Because SSL.Connection
-        doesn't have a 'dup'. Not exactly sure WHY this is, but
-        this is backed up by comments in socket.py and SSL/connection.c
-        """
-        self.connection = self.request  # for doPOST
-        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
-        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
-
-
-class SecureXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer,
-                         SecureTCPServer):
-    def __init__(self, addr,
-                 requestHandler=SecureXMLRPCRequestHandler,
-                 logRequests=1):
-        """
-        This is the exact same code as SimpleXMLRPCServer.__init__
-        except it calls SecureTCPServer.__init__ instead of plain
-        old TCPServer.__init__
-        """
-        self.funcs = {}
-        self.logRequests = logRequests
-        self.instance = None
-        SecureTCPServer.__init__(self, addr, requestHandler)
diff --git a/examples/certgen.py b/examples/certgen.py
deleted file mode 100644
index 7b70e98..0000000
--- a/examples/certgen.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# -*- coding: latin-1 -*-
-#
-# Copyright (C) AB Strakt
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-
-"""
-Certificate generation module.
-"""
-
-from OpenSSL import crypto
-
-TYPE_RSA = crypto.TYPE_RSA
-TYPE_DSA = crypto.TYPE_DSA
-
-
-def createKeyPair(type, bits):
-    """
-    Create a public/private key pair.
-
-    Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA
-               bits - Number of bits to use in the key
-    Returns:   The public/private key pair in a PKey object
-    """
-    pkey = crypto.PKey()
-    pkey.generate_key(type, bits)
-    return pkey
-
-
-def createCertRequest(pkey, digest="sha256", **name):
-    """
-    Create a certificate request.
-
-    Arguments: pkey   - The key to associate with the request
-               digest - Digestion method to use for signing, default is sha256
-               **name - The name of the subject of the request, possible
-                        arguments are:
-                          C     - Country name
-                          ST    - State or province name
-                          L     - Locality name
-                          O     - Organization name
-                          OU    - Organizational unit name
-                          CN    - Common name
-                          emailAddress - E-mail address
-    Returns:   The certificate request in an X509Req object
-    """
-    req = crypto.X509Req()
-    subj = req.get_subject()
-
-    for key, value in name.items():
-        setattr(subj, key, value)
-
-    req.set_pubkey(pkey)
-    req.sign(pkey, digest)
-    return req
-
-
-def createCertificate(req, issuerCertKey, serial, validityPeriod,
-                      digest="sha256"):
-    """
-    Generate a certificate given a certificate request.
-
-    Arguments: req        - Certificate request to use
-               issuerCert - The certificate of the issuer
-               issuerKey  - The private key of the issuer
-               serial     - Serial number for the certificate
-               notBefore  - Timestamp (relative to now) when the certificate
-                            starts being valid
-               notAfter   - Timestamp (relative to now) when the certificate
-                            stops being valid
-               digest     - Digest method to use for signing, default is sha256
-    Returns:   The signed certificate in an X509 object
-    """
-    issuerCert, issuerKey = issuerCertKey
-    notBefore, notAfter = validityPeriod
-    cert = crypto.X509()
-    cert.set_serial_number(serial)
-    cert.gmtime_adj_notBefore(notBefore)
-    cert.gmtime_adj_notAfter(notAfter)
-    cert.set_issuer(issuerCert.get_subject())
-    cert.set_subject(req.get_subject())
-    cert.set_pubkey(req.get_pubkey())
-    cert.sign(issuerKey, digest)
-    return cert
diff --git a/examples/mk_simple_certs.py b/examples/mk_simple_certs.py
deleted file mode 100644
index f0416cd..0000000
--- a/examples/mk_simple_certs.py
+++ /dev/null
@@ -1,50 +0,0 @@
-"""
-Create certificates and private keys for the 'simple' example.
-"""
-
-from __future__ import print_function
-
-from OpenSSL import crypto
-from certgen import (
-    createKeyPair,
-    createCertRequest,
-    createCertificate,
-)
-
-cakey = createKeyPair(crypto.TYPE_RSA, 2048)
-careq = createCertRequest(cakey, CN='Certificate Authority')
-# CA certificate is valid for five years.
-cacert = createCertificate(careq, (careq, cakey), 0, (0, 60*60*24*365*5))
-
-print('Creating Certificate Authority private key in "simple/CA.pkey"')
-with open('simple/CA.pkey', 'w') as capkey:
-    capkey.write(
-        crypto.dump_privatekey(crypto.FILETYPE_PEM, cakey).decode('utf-8')
-    )
-
-print('Creating Certificate Authority certificate in "simple/CA.cert"')
-with open('simple/CA.cert', 'w') as ca:
-    ca.write(
-        crypto.dump_certificate(crypto.FILETYPE_PEM, cacert).decode('utf-8')
-    )
-
-for (fname, cname) in [('client', 'Simple Client'),
-                       ('server', 'Simple Server')]:
-    pkey = createKeyPair(crypto.TYPE_RSA, 2048)
-    req = createCertRequest(pkey, CN=cname)
-    # Certificates are valid for five years.
-    cert = createCertificate(req, (cacert, cakey), 1, (0, 60*60*24*365*5))
-
-    print('Creating Certificate %s private key in "simple/%s.pkey"'
-          % (fname, fname))
-    with open('simple/%s.pkey' % (fname,), 'w') as leafpkey:
-        leafpkey.write(
-            crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey).decode('utf-8')
-        )
-
-    print('Creating Certificate %s certificate in "simple/%s.cert"'
-          % (fname, fname))
-    with open('simple/%s.cert' % (fname,), 'w') as leafcert:
-        leafcert.write(
-            crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode('utf-8')
-        )
diff --git a/examples/proxy.py b/examples/proxy.py
deleted file mode 100644
index 3be26f9..0000000
--- a/examples/proxy.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-#
-# This script demonstrates how one can use pyOpenSSL to speak SSL over an HTTP
-# proxy
-# The challenge here is to start talking SSL over an already connected socket
-#
-# Author: Mihai Ibanescu <[email protected]>
-#
-# $Id: proxy.py,v 1.2 2004/07/22 12:01:25 martin Exp $
-
-import sys
-import socket
-import string
-
-from OpenSSL import SSL
-
-
-def usage(exit_code=0):
-    print "Usage: %s server[:port] proxy[:port]" % sys.argv[0]
-    print "  Connects SSL to the specified server (port 443 by default)"
-    print "    using the specified proxy (port 8080 by default)"
-    sys.exit(exit_code)
-
-
-def main():
-    # Command-line processing
-    if len(sys.argv) != 3:
-        usage(-1)
-
-    server, proxy = sys.argv[1:3]
-
-    run(split_host(server, 443), split_host(proxy, 8080))
-
-
-def split_host(hostname, default_port=80):
-    a = string.split(hostname, ':', 1)
-    if len(a) == 1:
-        a.append(default_port)
-    return a[0], int(a[1])
-
-
-# Connects to the server, through the proxy
-def run(server, proxy):
-    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    try:
-        s.connect(proxy)
-    except socket.error, e:
-        print "Unable to connect to %s:%s %s" % (proxy[0], proxy[1], str(e))
-        sys.exit(-1)
-
-    # Use the CONNECT method to get a connection to the actual server
-    s.send("CONNECT %s:%s HTTP/1.0\n\n" % (server[0], server[1]))
-    print "Proxy response: %s" % string.strip(s.recv(1024))
-
-    ctx = SSL.Context(SSL.SSLv23_METHOD)
-    conn = SSL.Connection(ctx, s)
-
-    # Go to client mode
-    conn.set_connect_state()
-
-    # start using HTTP
-
-    conn.send("HEAD / HTTP/1.0\n\n")
-    print "Sever response:"
-    print "-" * 40
-    while 1:
-        try:
-            buff = conn.recv(4096)
-        except SSL.ZeroReturnError:
-            # we're done
-            break
-
-        print buff,
-
-
-if __name__ == '__main__':
-    main()
diff --git a/examples/simple/README b/examples/simple/README
deleted file mode 100644
index a072998..0000000
--- a/examples/simple/README
+++ /dev/null
@@ -1,3 +0,0 @@
-To use this example, first generate keys and certificates for both the
-client and the server.  You can do this with the script in the directory
-above this one, mk_simple_certs.py.
diff --git a/examples/simple/client.py b/examples/simple/client.py
deleted file mode 100644
index 5662122..0000000
--- a/examples/simple/client.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- coding: latin-1 -*-
-#
-# Copyright (C) AB Strakt
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-
-"""
-Simple SSL client, using blocking I/O
-"""
-
-import os
-import socket
-import sys
-
-from OpenSSL import SSL, crypto
-
-
-def verify_cb(conn, cert, errnum, depth, ok):
-    certsubject = crypto.X509Name(cert.get_subject())
-    commonname = certsubject.commonName
-    print('Got certificate: ' + commonname)
-    return ok
-
-
-if len(sys.argv) < 3:
-    print('Usage: python client.py HOST PORT')
-    sys.exit(1)
-
-
-dir = os.path.dirname(sys.argv[0])
-if dir == '':
-    dir = os.curdir
-
-
-# Initialize context
-ctx = SSL.Context(SSL.SSLv23_METHOD)
-ctx.set_options(SSL.OP_NO_SSLv2)
-ctx.set_options(SSL.OP_NO_SSLv3)
-ctx.set_verify(SSL.VERIFY_PEER, verify_cb)  # Demand a certificate
-ctx.use_privatekey_file(os.path.join(dir, 'client.pkey'))
-ctx.use_certificate_file(os.path.join(dir, 'client.cert'))
-ctx.load_verify_locations(os.path.join(dir, 'CA.cert'))
-
-# Set up client
-sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
-sock.connect((sys.argv[1], int(sys.argv[2])))
-
-while 1:
-    line = sys.stdin.readline()
-    if line == '':
-        break
-    try:
-        sock.send(line)
-        sys.stdout.write(sock.recv(1024).decode('utf-8'))
-        sys.stdout.flush()
-    except SSL.Error:
-        print('Connection died unexpectedly')
-        break
-
-
-sock.shutdown()
-sock.close()
diff --git a/examples/simple/server.py b/examples/simple/server.py
deleted file mode 100644
index d25feb1..0000000
--- a/examples/simple/server.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# -*- coding: latin-1 -*-
-#
-# Copyright (C) AB Strakt
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-
-"""
-Simple echo server, using nonblocking I/O
-"""
-
-from __future__ import print_function
-
-import os
-import select
-import socket
-import sys
-
-from OpenSSL import SSL, crypto
-
-
-def verify_cb(conn, cert, errnum, depth, ok):
-    certsubject = crypto.X509Name(cert.get_subject())
-    commonname = certsubject.commonName
-    print('Got certificate: ' + commonname)
-    return ok
-
-
-if len(sys.argv) < 2:
-    print('Usage: python server.py PORT')
-    sys.exit(1)
-
-dir = os.path.dirname(sys.argv[0])
-if dir == '':
-    dir = os.curdir
-
-# Initialize context
-ctx = SSL.Context(SSL.SSLv23_METHOD)
-ctx.set_options(SSL.OP_NO_SSLv2)
-ctx.set_options(SSL.OP_NO_SSLv3)
-ctx.set_verify(
-    SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb
-)  # Demand a certificate
-ctx.use_privatekey_file(os.path.join(dir, 'server.pkey'))
-ctx.use_certificate_file(os.path.join(dir, 'server.cert'))
-ctx.load_verify_locations(os.path.join(dir, 'CA.cert'))
-
-# Set up server
-server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
-server.bind(('', int(sys.argv[1])))
-server.listen(3)
-server.setblocking(0)
-
-clients = {}
-writers = {}
-
-
-def dropClient(cli, errors=None):
-    if errors:
-        print('Client %s left unexpectedly:' % (clients[cli],))
-        print('  ', errors)
-    else:
-        print('Client %s left politely' % (clients[cli],))
-    del clients[cli]
-    if cli in writers:
-        del writers[cli]
-    if not errors:
-        cli.shutdown()
-    cli.close()
-
-
-while 1:
-    try:
-        r, w, _ = select.select(
-            [server] + list(clients.keys()), list(writers.keys()), []
-        )
-    except Exception:
-        break
-
-    for cli in r:
-        if cli == server:
-            cli, addr = server.accept()
-            print('Connection from %s' % (addr,))
-            clients[cli] = addr
-
-        else:
-            try:
-                ret = cli.recv(1024).decode('utf-8')
-            except (SSL.WantReadError,
-                    SSL.WantWriteError,
-                    SSL.WantX509LookupError):
-                pass
-            except SSL.ZeroReturnError:
-                dropClient(cli)
-            except SSL.Error as errors:
-                dropClient(cli, errors)
-            else:
-                if cli not in writers:
-                    writers[cli] = ''
-                writers[cli] = writers[cli] + ret
-
-    for cli in w:
-        try:
-            ret = cli.send(writers[cli])
-        except (SSL.WantReadError,
-                SSL.WantWriteError,
-                SSL.WantX509LookupError):
-            pass
-        except SSL.ZeroReturnError:
-            dropClient(cli)
-        except SSL.Error as errors:
-            dropClient(cli, errors)
-        else:
-            writers[cli] = writers[cli][ret:]
-            if writers[cli] == '':
-                del writers[cli]
-
-for cli in clients.keys():
-    cli.close()
-server.close()
diff --git a/examples/sni/README b/examples/sni/README
deleted file mode 100644
index 4c74eb5..0000000
--- a/examples/sni/README
+++ /dev/null
@@ -1,19 +0,0 @@
-This directory contains client and server examples for the "Server Name
-Indication" (SNI) feature.
-
-Run server.py with no arguments.  It will accept one client connection and
-then exit.  It has two certificates it can use, one for "example.invalid"
-and another for "another.invalid".  If a client indicates one of these names
-to it, it will use the corresponding certificate for that connection (if a
-client doesn't indicate a name or indicates another name, it won't try to
-use any certificate).
-
-Run client.py with one argument, the server name to indicate.  For example:
-
-  $ python client.py example.invalid
-  Connecting... connected ('127.0.0.1', 8443)
-  Server subject is <X509Name object '/OU=Security/O=pyOpenSSL/CN=example.invalid/ST=New York/C=US/[email protected]/L=New York'>
-  $
-
-Depending on what hostname is supplied, the server will select a different
-certificate to use and the client output will be different.
diff --git a/examples/sni/another.invalid.crt b/examples/sni/another.invalid.crt
deleted file mode 100644
index 995e14c..0000000
--- a/examples/sni/another.invalid.crt
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICqTCCAhICAQEwDQYJKoZIhvcNAQEEBQAwgZwxETAPBgNVBAsTCFNlY3VyaXR5
-MRIwEAYDVQQKEwlweU9wZW5TU0wxGDAWBgNVBAMTD2Fub3RoZXIuaW52YWxpZDER
-MA8GA1UECBMITmV3IFlvcmsxCzAJBgNVBAYTAlVTMSYwJAYJKoZIhvcNAQkBFhdp
-bnZhbGlkQGFub3RoZXIuaW52YWxpZDERMA8GA1UEBxMITmV3IFlvcmswHhcNMTEw
-NjA2MTIyMTQyWhcNMTIwNjA1MTIyMTQyWjCBnDERMA8GA1UECxMIU2VjdXJpdHkx
-EjAQBgNVBAoTCXB5T3BlblNTTDEYMBYGA1UEAxMPYW5vdGhlci5pbnZhbGlkMREw
-DwYDVQQIEwhOZXcgWW9yazELMAkGA1UEBhMCVVMxJjAkBgkqhkiG9w0BCQEWF2lu
-dmFsaWRAYW5vdGhlci5pbnZhbGlkMREwDwYDVQQHEwhOZXcgWW9yazCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEA7jUOM0EnH0/bvqyQfrGlZ5ROc29JWEq3wp7/
-n96cxQ/oSf5G6rlQ5ZYnDlp44csQOY3DIq5/7cRju/Qf5cZ03YMOjzYSi4ElS0+o
-3Av/VgL/ssC6Z0PfQO4+NyXIQTn+cS6P6T65AVBdqn6Z5t0eY0wkU6QznpdJ/1c2
-a7gIYnUCAwEAATANBgkqhkiG9w0BAQQFAAOBgQBqyrP1wmpTmfeZnoB7piJd+qIj
-VHpCDRAZcdsxKUl/8PahjtWPMB0G5VaMwOoIGIlMxZ/LPKf44cA+QNEIXq8rohr2
-XFaA4t4X4aP7OmwQ4pa8mh4r86mP+vQU2iRJOqRYP+/gKaAqI2+ZbORZXJ7bewb5
-DTvvQRw2PRBf270h8g==
------END CERTIFICATE-----
diff --git a/examples/sni/another.invalid.key b/examples/sni/another.invalid.key
deleted file mode 100644
index 8d955f6..0000000
--- a/examples/sni/another.invalid.key
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDuNQ4zQScfT9u+rJB+saVnlE5zb0lYSrfCnv+f3pzFD+hJ/kbq
-uVDllicOWnjhyxA5jcMirn/txGO79B/lxnTdgw6PNhKLgSVLT6jcC/9WAv+ywLpn
-Q99A7j43JchBOf5xLo/pPrkBUF2qfpnm3R5jTCRTpDOel0n/VzZruAhidQIDAQAB
-AoGBAOGaJBHM8fWI17DVlKA5NVNNNaPEUW2qjjFoDuflmQpWD4UMqzOhQYm/VMwW
-SYhnnr0zkw1kwUp6Bo87HX6sH37b1GeqIyp+b0Hqc+vLyiXPo0suqV23B9K8jjZ0
-6ap8h6hxpa5D1HtYKKDzWLhLJVtmtslxsvimR/CS+rmpUgBBAkEA+lJ2dXMDsUzB
-xOpX8MLfQsl8XB5tx4ejmXGyNp/hmRFqFi38FFemJXX1YC3wL5jbQ2Ltz9rnbdnG
-Xb/IWrn25QJBAPOcPua6xiNTWW5519JGaNgWdYnUgbj/ib8waLoElHp5Hl5DLuYX
-y8U96Xl/wAE4aQnp5R/PS75tYrKZo79z9FECQQDALk1J8IpWNbLSRoRLkKEtulji
-tG3d8VH1/WcwLuFZzhfffWB6Eay6N+yx8bLkJ/u2qZ4gpVRmbvqvgQ0GMp3NAkBE
-FFczzeCPgLyOdjiNSCYGtYgVg7DZDXjmWFX8HkmMTIrjFu1lWiMVNS8pSD1VWflo
-zte8Ywcs6Y7akLtFRtdxAkEA346J1/Zqtibez2TcjzCK+s9Ihwta23ZN2YTjo60o
-sDZ5AVJwyLa7VFEzO/e9v2ytD7k9fCJjHcxIWIe8zj0dYA==
------END RSA PRIVATE KEY-----
diff --git a/examples/sni/client.py b/examples/sni/client.py
deleted file mode 100644
index 428525b..0000000
--- a/examples/sni/client.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-
-from sys import argv, stdout
-from socket import socket
-
-from OpenSSL.SSL import TLSv1_METHOD, Context, Connection
-
-
-def main():
-    """
-    Connect to an SNI-enabled server and request a specific hostname, specified
-    by argv[1], of it.
-    """
-    if len(argv) < 2:
-        print 'Usage: %s <hostname>' % (argv[0],)
-        return 1
-
-    client = socket()
-
-    print 'Connecting...',
-    stdout.flush()
-    client.connect(('127.0.0.1', 8443))
-    print 'connected', client.getpeername()
-
-    client_ssl = Connection(Context(TLSv1_METHOD), client)
-    client_ssl.set_connect_state()
-    client_ssl.set_tlsext_host_name(argv[1])
-    client_ssl.do_handshake()
-    print 'Server subject is', client_ssl.get_peer_certificate().get_subject()
-    client_ssl.close()
-
-
-if __name__ == '__main__':
-    import client
-    raise SystemExit(client.main())
diff --git a/examples/sni/example.invalid.crt b/examples/sni/example.invalid.crt
deleted file mode 100644
index b0cabac..0000000
--- a/examples/sni/example.invalid.crt
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICqTCCAhICAQEwDQYJKoZIhvcNAQEEBQAwgZwxETAPBgNVBAsTCFNlY3VyaXR5
-MRIwEAYDVQQKEwlweU9wZW5TU0wxGDAWBgNVBAMTD2V4YW1wbGUuaW52YWxpZDER
-MA8GA1UECBMITmV3IFlvcmsxCzAJBgNVBAYTAlVTMSYwJAYJKoZIhvcNAQkBFhdp
-bnZhbGlkQGV4YW1wbGUuaW52YWxpZDERMA8GA1UEBxMITmV3IFlvcmswHhcNMTEw
-NjA2MTIyMTMzWhcNMTIwNjA1MTIyMTMzWjCBnDERMA8GA1UECxMIU2VjdXJpdHkx
-EjAQBgNVBAoTCXB5T3BlblNTTDEYMBYGA1UEAxMPZXhhbXBsZS5pbnZhbGlkMREw
-DwYDVQQIEwhOZXcgWW9yazELMAkGA1UEBhMCVVMxJjAkBgkqhkiG9w0BCQEWF2lu
-dmFsaWRAZXhhbXBsZS5pbnZhbGlkMREwDwYDVQQHEwhOZXcgWW9yazCBnzANBgkq
-hkiG9w0BAQEFAAOBjQAwgYkCgYEAwmLucR0IXvoGTOfzb2WJlHis2s/FFJfmYAKd
-hq9bs+XzPeAPG0VQqAsy+om1gBOb8KPGtSet2SeNc25FU+QuwAza8uws7EaxD9b9
-CcarIh2X5LMcmiI/p34FuVGUSVsfc4QCTYFWGA0Mrw4jz9sGGeSEmTjVRnc3uAix
-31orKScCAwEAATANBgkqhkiG9w0BAQQFAAOBgQBxm8Qta5wYFmQ3l3EAne9+HaQ5
-gPStgox6STmyOGfRkybSePgOeKftOasaXpKboiNg6PJEkaFEnl9epNwS+8PIjQqv
-mPiZdlrNIfw+YVWpqgcTAIzkhYFH0K4v6d5Wn2adNgd5KbrxYOjsr2w0ixQEtdW/
-+z1x/ngjc08EPqOIPQ==
------END CERTIFICATE-----
diff --git a/examples/sni/example.invalid.key b/examples/sni/example.invalid.key
deleted file mode 100644
index 192e346..0000000
--- a/examples/sni/example.invalid.key
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDCYu5xHQhe+gZM5/NvZYmUeKzaz8UUl+ZgAp2Gr1uz5fM94A8b
-RVCoCzL6ibWAE5vwo8a1J63ZJ41zbkVT5C7ADNry7CzsRrEP1v0JxqsiHZfksxya
-Ij+nfgW5UZRJWx9zhAJNgVYYDQyvDiPP2wYZ5ISZONVGdze4CLHfWispJwIDAQAB
-AoGBAL8L8qNTUHXgL68ITRZP6g71J5YKm/zoafA0wdOsp2lA+Hb4roAz+Nif4SOh
-krPlEd9JZ7OF4vRJTlmDqDmSS2qY7hJuZpdrdvhdxaPGeX4uftC43thEzxLxPQHd
-gCCxugbGJOHChjMPk06oC0w1q70ex3gWmki82Jt/5INV6Z6RAkEA4km0s0RvbVmW
-AT12PROplCRE86eJNlLCVp2TJNl0LPZe5uWqaZZ8wBvfFd1PXEk/Qcpj4IotMZ5M
-1Ai4zw2+6QJBANvo6R5yLRrY8/7YKw9Y/1bbSRLhGYok2Ur4fFz64G28wA1VI3yS
-uXrJ7NjTVykfrBq59WEfh3a15P9g/TMAPY8CQQDdW3Z9iqtpj6IScnowgwR22wfs
-RW4PCuP6cMhY2rMvrI3nVrDd+wzrrBgNPmF8iFZt2Drdkq1lBVJodGO8f9jJAj9O
-K3yyVeOyp2wUKsMjsX8SYOCY1Ws+r9qNy8ZpRsSAPZgHJTx4C6/i9eQ7LuTMuXV0
-CqYu4AZHLGE6Zj+a4XsCQQC8Ken471EXuahfPcKTzsphuZnYZkoVUsFUxJFfqG+S
-8k2Jo/4c+2NyyvVXhXu2at8kmu45c92BrCTXIvLEwtnn
------END RSA PRIVATE KEY-----
diff --git a/examples/sni/server.py b/examples/sni/server.py
deleted file mode 100644
index e0c159a..0000000
--- a/examples/sni/server.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-
-from sys import stdout
-from socket import SOL_SOCKET, SO_REUSEADDR, socket
-
-from OpenSSL.crypto import FILETYPE_PEM, load_privatekey, load_certificate
-from OpenSSL.SSL import TLSv1_METHOD, Context, Connection
-
-
-def load(domain):
-    crt = open(domain + ".crt")
-    key = open(domain + ".key")
-    result = (
-        load_privatekey(FILETYPE_PEM, key.read()),
-        load_certificate(FILETYPE_PEM, crt.read()))
-    crt.close()
-    key.close()
-    return result
-
-
-def main():
-    """
-    Run an SNI-enabled server which selects between a few certificates in a
-    C{dict} based on the handshake request it receives from a client.
-    """
-    port = socket()
-    port.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
-    port.bind(('', 8443))
-    port.listen(3)
-
-    print 'Accepting...',
-    stdout.flush()
-    server, addr = port.accept()
-    print 'accepted', addr
-
-    server_context = Context(TLSv1_METHOD)
-    server_context.set_tlsext_servername_callback(pick_certificate)
-
-    server_ssl = Connection(server_context, server)
-    server_ssl.set_accept_state()
-    server_ssl.do_handshake()
-    server.close()
-
-
-certificates = {
-    "example.invalid": load("example.invalid"),
-    "another.invalid": load("another.invalid"),
-}
-
-
-def pick_certificate(connection):
-    try:
-        key, cert = certificates[connection.get_servername()]
-    except KeyError:
-        pass
-    else:
-        new_context = Context(TLSv1_METHOD)
-        new_context.use_privatekey(key)
-        new_context.use_certificate(cert)
-        connection.set_context(new_context)
-
-
-if __name__ == '__main__':
-    raise SystemExit(main())
diff --git a/leakcheck/context-info-callback.py b/leakcheck/context-info-callback.py
deleted file mode 100644
index 6a3925c..0000000
--- a/leakcheck/context-info-callback.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-#
-# Stress tester for thread-related bugs in global_info_callback in
-# src/ssl/context.c.  In 0.7 and earlier, this will somewhat reliably
-# segfault or abort after a few dozen to a few thousand iterations on an SMP
-# machine (generally not on a UP machine) due to uses of Python/C API
-# without holding the GIL.
-
-from itertools import count
-from threading import Thread
-from socket import socket
-
-from OpenSSL.SSL import Context, TLSv1_METHOD, Connection, WantReadError
-from OpenSSL.crypto import FILETYPE_PEM, load_certificate, load_privatekey
-
-cleartextPrivateKeyPEM = (
-    "-----BEGIN RSA PRIVATE KEY-----\n"
-    "MIICXAIBAAKBgQDaemNe1syksAbFFpF3aoOrZ18vB/IQNZrAjFqXPv9iieJm7+Tc\n"
-    "g+lA/v0qmoEKrpT2xfwxXmvZwBNM4ZhyRC3DPIFEyJV7/3IA1p5iuMY/GJI1VIgn\n"
-    "aikQCnrsyxtaRpsMBeZRniaVzcUJ+XnEdFGEjlo+k0xlwfVclDEMwgpXAQIDAQAB\n"
-    "AoGBALi0a7pMQqqgnriVAdpBVJveQtxSDVWi2/gZMKVZfzNheuSnv4amhtaKPKJ+\n"
-    "CMZtHkcazsE2IFvxRN/kgato9H3gJqq8nq2CkdpdLNVKBoxiCtkLfutdY4SQLtoY\n"
-    "USN7exk131pchsAJXYlR6mCW+ZP+E523cNwpPgsyKxVbmXSBAkEA9470fy2W0jFM\n"
-    "taZFslpntKSzbvn6JmdtjtvWrM1bBaeeqFiGBuQFYg46VaCUaeRWYw02jmYAsDYh\n"
-    "ZQavmXThaQJBAOHtlAQ0IJJEiMZr6vtVPH32fmbthSv1AUSYPzKqdlQrUnOXPQXu\n"
-    "z70cFoLG1TvPF5rBxbOkbQ/s8/ka5ZjPfdkCQCeC7YsO36+UpsWnUCBzRXITh4AC\n"
-    "7eYLQ/U1KUJTVF/GrQ/5cQrQgftwgecAxi9Qfmk4xqhbp2h4e0QAmS5I9WECQH02\n"
-    "0QwrX8nxFeTytr8pFGezj4a4KVCdb2B3CL+p3f70K7RIo9d/7b6frJI6ZL/LHQf2\n"
-    "UP4pKRDkgKsVDx7MELECQGm072/Z7vmb03h/uE95IYJOgY4nfmYs0QKA9Is18wUz\n"
-    "DpjfE33p0Ha6GO1VZRIQoqE24F8o5oimy3BEjryFuw4=\n"
-    "-----END RSA PRIVATE KEY-----\n")
-
-
-cleartextCertificatePEM = (
-    "-----BEGIN CERTIFICATE-----\n"
-    "MIICfTCCAeYCAQEwDQYJKoZIhvcNAQEEBQAwgYYxCzAJBgNVBAYTAlVTMRkwFwYD\n"
-    "VQQDExBweW9wZW5zc2wuc2YubmV0MREwDwYDVQQHEwhOZXcgWW9yazESMBAGA1UE\n"
-    "ChMJUHlPcGVuU1NMMREwDwYDVQQIEwhOZXcgWW9yazEQMA4GCSqGSIb3DQEJARYB\n"
-    "IDEQMA4GA1UECxMHVGVzdGluZzAeFw0wODAzMjUxOTA0MTNaFw0wOTAzMjUxOTA0\n"
-    "MTNaMIGGMQswCQYDVQQGEwJVUzEZMBcGA1UEAxMQcHlvcGVuc3NsLnNmLm5ldDER\n"
-    "MA8GA1UEBxMITmV3IFlvcmsxEjAQBgNVBAoTCVB5T3BlblNTTDERMA8GA1UECBMI\n"
-    "TmV3IFlvcmsxEDAOBgkqhkiG9w0BCQEWASAxEDAOBgNVBAsTB1Rlc3RpbmcwgZ8w\n"
-    "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSwBsUWkXdqg6tnXy8H8hA1\n"
-    "msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nAE0zhmHJELcM8gUTIlXv/\n"
-    "cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXNxQn5ecR0UYSOWj6TTGXB\n"
-    "9VyUMQzCClcBAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAmm0Vzvv1O91WLl2LnF2P\n"
-    "q55LJdOnJbCCXIgxLdoVmvYAz1ZJq1eGKgKWI5QLgxiSzJLEU7KK//aVfiZzoCd5\n"
-    "RipBiEEMEV4eAY317bHPwPP+4Bj9t0l8AsDLseC5vLRHgxrLEu3bn08DYx6imB5Q\n"
-    "UBj849/xpszEM7BhwKE0GiQ=\n"
-    "-----END CERTIFICATE-----\n")
-
-count = count()
-def go():
-    port = socket()
-    port.bind(('', 0))
-    port.listen(1)
-
-    called = []
-    def info(conn, where, ret):
-        print count.next()
-        called.append(None)
-    context = Context(TLSv1_METHOD)
-    context.set_info_callback(info)
-    context.use_certificate(
-        load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
-    context.use_privatekey(
-        load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
-
-    while 1:
-        client = socket()
-        client.setblocking(False)
-        client.connect_ex(port.getsockname())
-
-        clientSSL = Connection(Context(TLSv1_METHOD), client)
-        clientSSL.set_connect_state()
-
-        server, ignored = port.accept()
-        server.setblocking(False)
-
-        serverSSL = Connection(context, server)
-        serverSSL.set_accept_state()
-
-        del called[:]
-        while not called:
-            for ssl in clientSSL, serverSSL:
-                try:
-                    ssl.do_handshake()
-                except WantReadError:
-                    pass
-
-
-threads = [Thread(target=go, args=()) for i in xrange(2)]
-for th in threads:
-    th.start()
-for th in threads:
-    th.join()
diff --git a/leakcheck/context-passphrase-callback.py b/leakcheck/context-passphrase-callback.py
deleted file mode 100644
index ba71655..0000000
--- a/leakcheck/context-passphrase-callback.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-#
-# Stress tester for thread-related bugs in global_passphrase_callback in
-# src/ssl/context.c.  In 0.7 and earlier, this will somewhat reliably
-# segfault or abort after a few dozen to a few thousand iterations on an SMP
-# machine (generally not on a UP machine) due to uses of Python/C API
-# without holding the GIL.
-
-from itertools import count
-from threading import Thread
-
-from OpenSSL.SSL import Context, TLSv1_METHOD
-from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM, PKey, dump_privatekey
-
-k = PKey()
-k.generate_key(TYPE_RSA, 128)
-file('pkey.pem', 'w').write(dump_privatekey(FILETYPE_PEM, k, "blowfish", "foobar"))
-
-count = count()
-def go():
-    def cb(a, b, c):
-        print count.next()
-        return "foobar"
-    c = Context(TLSv1_METHOD)
-    c.set_passwd_cb(cb)
-    while 1:
-        c.use_privatekey_file('pkey.pem')
-
-threads = [Thread(target=go, args=()) for i in xrange(2)]
-for th in threads:
-    th.start()
-for th in threads:
-    th.join()
diff --git a/leakcheck/context-verify-callback.py b/leakcheck/context-verify-callback.py
deleted file mode 100644
index 0ae586b..0000000
--- a/leakcheck/context-verify-callback.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-#
-# Stress tester for thread-related bugs in global_verify_callback in
-# src/ssl/context.c.  This will reliably segfault if context.c isn't a
-# PyThreadState management technique which is compatible with the approach used
-# by ssl.c.
-
-
-from itertools import count
-from threading import Thread
-from socket import socket
-
-from OpenSSL.SSL import Context, TLSv1_METHOD, VERIFY_PEER, Connection, WantReadError
-from OpenSSL.crypto import FILETYPE_PEM, load_certificate, load_privatekey
-
-cleartextPrivateKeyPEM = (
-    "-----BEGIN RSA PRIVATE KEY-----\n"
-    "MIICXAIBAAKBgQDaemNe1syksAbFFpF3aoOrZ18vB/IQNZrAjFqXPv9iieJm7+Tc\n"
-    "g+lA/v0qmoEKrpT2xfwxXmvZwBNM4ZhyRC3DPIFEyJV7/3IA1p5iuMY/GJI1VIgn\n"
-    "aikQCnrsyxtaRpsMBeZRniaVzcUJ+XnEdFGEjlo+k0xlwfVclDEMwgpXAQIDAQAB\n"
-    "AoGBALi0a7pMQqqgnriVAdpBVJveQtxSDVWi2/gZMKVZfzNheuSnv4amhtaKPKJ+\n"
-    "CMZtHkcazsE2IFvxRN/kgato9H3gJqq8nq2CkdpdLNVKBoxiCtkLfutdY4SQLtoY\n"
-    "USN7exk131pchsAJXYlR6mCW+ZP+E523cNwpPgsyKxVbmXSBAkEA9470fy2W0jFM\n"
-    "taZFslpntKSzbvn6JmdtjtvWrM1bBaeeqFiGBuQFYg46VaCUaeRWYw02jmYAsDYh\n"
-    "ZQavmXThaQJBAOHtlAQ0IJJEiMZr6vtVPH32fmbthSv1AUSYPzKqdlQrUnOXPQXu\n"
-    "z70cFoLG1TvPF5rBxbOkbQ/s8/ka5ZjPfdkCQCeC7YsO36+UpsWnUCBzRXITh4AC\n"
-    "7eYLQ/U1KUJTVF/GrQ/5cQrQgftwgecAxi9Qfmk4xqhbp2h4e0QAmS5I9WECQH02\n"
-    "0QwrX8nxFeTytr8pFGezj4a4KVCdb2B3CL+p3f70K7RIo9d/7b6frJI6ZL/LHQf2\n"
-    "UP4pKRDkgKsVDx7MELECQGm072/Z7vmb03h/uE95IYJOgY4nfmYs0QKA9Is18wUz\n"
-    "DpjfE33p0Ha6GO1VZRIQoqE24F8o5oimy3BEjryFuw4=\n"
-    "-----END RSA PRIVATE KEY-----\n")
-
-
-cleartextCertificatePEM = (
-    "-----BEGIN CERTIFICATE-----\n"
-    "MIICfTCCAeYCAQEwDQYJKoZIhvcNAQEEBQAwgYYxCzAJBgNVBAYTAlVTMRkwFwYD\n"
-    "VQQDExBweW9wZW5zc2wuc2YubmV0MREwDwYDVQQHEwhOZXcgWW9yazESMBAGA1UE\n"
-    "ChMJUHlPcGVuU1NMMREwDwYDVQQIEwhOZXcgWW9yazEQMA4GCSqGSIb3DQEJARYB\n"
-    "IDEQMA4GA1UECxMHVGVzdGluZzAeFw0wODAzMjUxOTA0MTNaFw0wOTAzMjUxOTA0\n"
-    "MTNaMIGGMQswCQYDVQQGEwJVUzEZMBcGA1UEAxMQcHlvcGVuc3NsLnNmLm5ldDER\n"
-    "MA8GA1UEBxMITmV3IFlvcmsxEjAQBgNVBAoTCVB5T3BlblNTTDERMA8GA1UECBMI\n"
-    "TmV3IFlvcmsxEDAOBgkqhkiG9w0BCQEWASAxEDAOBgNVBAsTB1Rlc3RpbmcwgZ8w\n"
-    "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSwBsUWkXdqg6tnXy8H8hA1\n"
-    "msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nAE0zhmHJELcM8gUTIlXv/\n"
-    "cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXNxQn5ecR0UYSOWj6TTGXB\n"
-    "9VyUMQzCClcBAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAmm0Vzvv1O91WLl2LnF2P\n"
-    "q55LJdOnJbCCXIgxLdoVmvYAz1ZJq1eGKgKWI5QLgxiSzJLEU7KK//aVfiZzoCd5\n"
-    "RipBiEEMEV4eAY317bHPwPP+4Bj9t0l8AsDLseC5vLRHgxrLEu3bn08DYx6imB5Q\n"
-    "UBj849/xpszEM7BhwKE0GiQ=\n"
-    "-----END CERTIFICATE-----\n")
-
-count = count()
-def go():
-    port = socket()
-    port.bind(('', 0))
-    port.listen(1)
-
-    called = []
-    def info(*args):
-        print count.next()
-        called.append(None)
-        return 1
-    context = Context(TLSv1_METHOD)
-    context.set_verify(VERIFY_PEER, info)
-    context.use_certificate(
-        load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
-    context.use_privatekey(
-        load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
-
-    while 1:
-        client = socket()
-        client.setblocking(False)
-        client.connect_ex(port.getsockname())
-
-        clientSSL = Connection(context, client)
-        clientSSL.set_connect_state()
-
-        server, ignored = port.accept()
-        server.setblocking(False)
-
-        serverSSL = Connection(context, server)
-        serverSSL.set_accept_state()
-
-        del called[:]
-        while not called:
-            for ssl in clientSSL, serverSSL:
-                try:
-                    ssl.send('foo')
-                except WantReadError, e:
-                    pass
-
-
-threads = [Thread(target=go, args=()) for i in xrange(2)]
-for th in threads:
-    th.start()
-for th in threads:
-    th.join()
-
diff --git a/leakcheck/crypto.py b/leakcheck/crypto.py
deleted file mode 100644
index ca79b7c..0000000
--- a/leakcheck/crypto.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-
-import sys
-
-from OpenSSL.crypto import (
-    FILETYPE_PEM, TYPE_DSA, Error, PKey, X509, load_privatekey, CRL, Revoked,
-    get_elliptic_curves, _X509_REVOKED_dup)
-
-from OpenSSL._util import lib as _lib
-
-
-
-class BaseChecker(object):
-    def __init__(self, iterations):
-        self.iterations = iterations
-
-
-
-class Checker_X509_get_pubkey(BaseChecker):
-    """
-    Leak checks for L{X509.get_pubkey}.
-    """
-    def check_exception(self):
-        """
-        Call the method repeatedly such that it will raise an exception.
-        """
-        for i in xrange(self.iterations):
-            cert = X509()
-            try:
-                cert.get_pubkey()
-            except Error:
-                pass
-
-
-    def check_success(self):
-        """
-        Call the method repeatedly such that it will return a PKey object.
-        """
-        small = xrange(3)
-        for i in xrange(self.iterations):
-            key = PKey()
-            key.generate_key(TYPE_DSA, 256)
-            for i in small:
-                cert = X509()
-                cert.set_pubkey(key)
-                for i in small:
-                    cert.get_pubkey()
-
-
-
-class Checker_load_privatekey(BaseChecker):
-    """
-    Leak checks for :py:obj:`load_privatekey`.
-    """
-    ENCRYPTED_PEM = """\
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: BF-CBC,3763C340F9B5A1D0
-
-a/DO10mLjHLCAOG8/Hc5Lbuh3pfjvcTZiCexShP+tupkp0VxW2YbZjML8uoXrpA6
-fSPUo7cEC+r96GjV03ZIVhjmsxxesdWMpfkzXRpG8rUbWEW2KcCJWdSX8bEkuNW3
-uvAXdXZwiOrm56ANDo/48gj27GcLwnlA8ld39+ylAzkUJ1tcMVzzTjfcyd6BMFpR
-Yjg23ikseug6iWEsZQormdl0ITdYzmFpM+YYsG7kmmmi4UjCEYfb9zFaqJn+WZT2
-qXxmo2ZPFzmEVkuB46mf5GCqMwLRN2QTbIZX2+Dljj1Hfo5erf5jROewE/yzcTwO
-FCB5K3c2kkTv2KjcCAimjxkE+SBKfHg35W0wB0AWkXpVFO5W/TbHg4tqtkpt/KMn
-/MPnSxvYr/vEqYMfW4Y83c45iqK0Cyr2pwY60lcn8Kk=
------END RSA PRIVATE KEY-----
-"""
-    def check_load_privatekey_callback(self):
-        """
-        Call the function with an encrypted PEM and a passphrase callback.
-        """
-        for i in xrange(self.iterations * 10):
-            load_privatekey(
-                FILETYPE_PEM, self.ENCRYPTED_PEM, lambda *args: "hello, secret")
-
-
-    def check_load_privatekey_callback_incorrect(self):
-        """
-        Call the function with an encrypted PEM and a passphrase callback which
-        returns the wrong passphrase.
-        """
-        for i in xrange(self.iterations * 10):
-            try:
-                load_privatekey(
-                    FILETYPE_PEM, self.ENCRYPTED_PEM,
-                    lambda *args: "hello, public")
-            except Error:
-                pass
-
-
-    def check_load_privatekey_callback_wrong_type(self):
-        """
-        Call the function with an encrypted PEM and a passphrase callback which
-        returns a non-string.
-        """
-        for i in xrange(self.iterations * 10):
-            try:
-                load_privatekey(
-                    FILETYPE_PEM, self.ENCRYPTED_PEM,
-                    lambda *args: {})
-            except ValueError:
-                pass
-
-
-
-class Checker_CRL(BaseChecker):
-    """
-    Leak checks for L{CRL.add_revoked} and L{CRL.get_revoked}.
-    """
-    def check_add_revoked(self):
-        """
-        Call the add_revoked method repeatedly on an empty CRL.
-        """
-        for i in xrange(self.iterations * 200):
-            CRL().add_revoked(Revoked())
-
-
-    def check_get_revoked(self):
-        """
-        Create a CRL object with 100 Revoked objects, then call the
-        get_revoked method repeatedly.
-        """
-        crl = CRL()
-        for i in xrange(100):
-            crl.add_revoked(Revoked())
-        for i in xrange(self.iterations):
-            crl.get_revoked()
-
-
-
-class Checker_X509_REVOKED_dup(BaseChecker):
-    """
-    Leak checks for :py:obj:`_X509_REVOKED_dup`.
-    """
-    def check_X509_REVOKED_dup(self):
-        """
-        Copy an empty Revoked object repeatedly. The copy is not garbage
-        collected, therefore it needs to be manually freed.
-        """
-        for i in xrange(self.iterations * 100):
-            revoked_copy = _X509_REVOKED_dup(Revoked()._revoked)
-            _lib.X509_REVOKED_free(revoked_copy)
-
-
-
-class Checker_EllipticCurve(BaseChecker):
-    """
-    Leak checks for :py:obj:`_EllipticCurve`.
-    """
-    def check_to_EC_KEY(self):
-        """
-        Repeatedly create an EC_KEY* from an :py:obj:`_EllipticCurve`.  The
-        structure should be automatically garbage collected.
-        """
-        curves = get_elliptic_curves()
-        if curves:
-            curve = next(iter(curves))
-            for i in xrange(self.iterations * 1000):
-                curve._to_EC_KEY()
-
-
-def vmsize():
-    return [x for x in file('/proc/self/status').readlines() if 'VmSize' in x]
-
-
-def main(iterations='1000'):
-    iterations = int(iterations)
-    for klass in globals():
-        if klass.startswith('Checker_'):
-            klass = globals()[klass]
-            print klass
-            checker = klass(iterations)
-            for meth in dir(checker):
-                if meth.startswith('check_'):
-                    print '\t', meth, vmsize(), '...',
-                    getattr(checker, meth)()
-                    print vmsize()
-
-
-if __name__ == '__main__':
-    main(*sys.argv[1:])
diff --git a/leakcheck/dhparam.pem b/leakcheck/dhparam.pem
deleted file mode 100644
index 9d33a4a..0000000
--- a/leakcheck/dhparam.pem
+++ /dev/null
@@ -1,4 +0,0 @@
------BEGIN DH PARAMETERS-----
-MEYCQQDM2LbvAjF5ahXHOUdDR09Vw/7kxjF/euWhNKBqUQQYT7FDSAMCCMq+Jhno
-BKxWEDhlxR1Q1VZ4H/NVTAGtWai7AgEC
------END DH PARAMETERS-----
diff --git a/leakcheck/thread-crash.py b/leakcheck/thread-crash.py
deleted file mode 100644
index a1ebbdd..0000000
--- a/leakcheck/thread-crash.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-#
-# Stress tester for thread-related bugs in ssl_Connection_send and
-# ssl_Connection_recv in src/ssl/connection.c for usage of a single
-# Connection object simultaneously in multiple threads.  In 0.7 and earlier,
-# this will somewhat reliably cause Python to abort with a "tstate mix-up"
-# almost immediately, due to the incorrect sharing between threads of the
-# `tstate` field of the connection object.
-
-
-from socket import socket
-from threading import Thread
-
-from OpenSSL.SSL import Connection, Context, TLSv1_METHOD
-
-def send(conn):
-    while 1:
-        for i in xrange(1024 * 32):
-            conn.send('x')
-        print 'Sent 32KB on', hex(id(conn))
-
-
-def recv(conn):
-    while 1:
-        for i in xrange(1024 * 64):
-            conn.recv(1)
-        print 'Received 64KB on', hex(id(conn))
-
-
-def main():
-    port = socket()
-    port.bind(('', 0))
-    port.listen(5)
-
-    client = socket()
-    client.setblocking(False)
-    client.connect_ex(port.getsockname())
-    client.setblocking(True)
-
-    server = port.accept()[0]
-
-    clientCtx = Context(TLSv1_METHOD)
-    clientCtx.set_cipher_list('ALL:ADH')
-    clientCtx.load_tmp_dh('dhparam.pem')
-
-    sslClient = Connection(clientCtx, client)
-    sslClient.set_connect_state()
-
-    serverCtx = Context(TLSv1_METHOD)
-    serverCtx.set_cipher_list('ALL:ADH')
-    serverCtx.load_tmp_dh('dhparam.pem')
-
-    sslServer = Connection(serverCtx, server)
-    sslServer.set_accept_state()
-
-    t1 = Thread(target=send, args=(sslClient,))
-    t2 = Thread(target=send, args=(sslServer,))
-    t3 = Thread(target=recv, args=(sslClient,))
-    t4 = Thread(target=recv, args=(sslServer,))
-
-    t1.start()
-    t2.start()
-    t3.start()
-    t4.start()
-    t1.join()
-    t2.join()
-    t3.join()
-    t4.join()
-
-main()
diff --git a/leakcheck/thread-key-gen.py b/leakcheck/thread-key-gen.py
deleted file mode 100644
index 62e1a58..0000000
--- a/leakcheck/thread-key-gen.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-#
-# Stress tester for thread-related bugs in RSA and DSA key generation.  0.12 and
-# older held the GIL during these operations.  Subsequent versions release it
-# during them.
-
-from threading import Thread
-
-from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, PKey
-
-def generate_rsa():
-    keys = []
-    for i in range(100):
-        key = PKey()
-        key.generate_key(TYPE_RSA, 1024)
-        keys.append(key)
-
-def generate_dsa():
-    keys = []
-    for i in range(100):
-        key = PKey()
-        key.generate_key(TYPE_DSA, 512)
-        keys.append(key)
-
-
-def main():
-    threads = []
-    for i in range(3):
-        t = Thread(target=generate_rsa, args=())
-        threads.append(t)
-        t = Thread(target=generate_dsa, args=())
-        threads.append(t)
-
-    for t in threads:
-        t.start()
-
-main()
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..ff6e2bb
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,4 @@
+[tool.black]
+line-length = 79
+target-version = ["py27"]
+
diff --git a/rpm/build_script b/rpm/build_script
deleted file mode 100644
index 1b0276b..0000000
--- a/rpm/build_script
+++ /dev/null
@@ -1 +0,0 @@
-make -C doc text html
diff --git a/setup.py b/setup.py
index 5387d2a..fbd6571 100755
--- a/setup.py
+++ b/setup.py
@@ -36,8 +36,7 @@
     Extract __*meta*__ from META_FILE.
     """
     meta_match = re.search(
-        r"^__{meta}__ = ['\"]([^'\"]*)['\"]".format(meta=meta),
-        META_FILE, re.M
+        r"^__{meta}__ = ['\"]([^'\"]*)['\"]".format(meta=meta), META_FILE, re.M
     )
     if meta_match:
         return meta_match.group(1)
@@ -46,13 +45,17 @@
 
 URI = find_meta("uri")
 LONG = (
-    read_file("README.rst") + "\n\n" +
-    "Release Information\n" +
-    "===================\n\n" +
-    re.search(r"(\d{2}.\d.\d \(.*?\)\n.*?)\n\n\n----\n",
-              read_file("CHANGELOG.rst"), re.S).group(1) +
-    "\n\n`Full changelog " +
-    "<{uri}en/stable/changelog.html>`_.\n\n"
+    read_file("README.rst")
+    + "\n\n"
+    + "Release Information\n"
+    + "===================\n\n"
+    + re.search(
+        r"(\d{2}.\d.\d \(.*?\)\n.*?)\n\n\n----\n",
+        read_file("CHANGELOG.rst"),
+        re.S,
+    ).group(1)
+    + "\n\n`Full changelog "
+    + "<{uri}en/stable/changelog.html>`_.\n\n"
 ).format(uri=URI)
 
 
@@ -64,49 +67,39 @@
         long_description=LONG,
         author=find_meta("author"),
         author_email=find_meta("email"),
-        maintainer="Hynek Schlawack",
-        maintainer_email="[email protected]",
         url=URI,
         license=find_meta("license"),
         classifiers=[
-            'Development Status :: 6 - Mature',
-            'Intended Audience :: Developers',
-            'License :: OSI Approved :: Apache Software License',
-            'Operating System :: MacOS :: MacOS X',
-            'Operating System :: Microsoft :: Windows',
-            'Operating System :: POSIX',
-
-            'Programming Language :: Python :: 2',
-            'Programming Language :: Python :: 2.7',
-            'Programming Language :: Python :: 3',
-            'Programming Language :: Python :: 3.4',
-            'Programming Language :: Python :: 3.5',
-            'Programming Language :: Python :: 3.6',
-            'Programming Language :: Python :: 3.7',
-
-            'Programming Language :: Python :: Implementation :: CPython',
-            'Programming Language :: Python :: Implementation :: PyPy',
-            'Topic :: Security :: Cryptography',
-            'Topic :: Software Development :: Libraries :: Python Modules',
-            'Topic :: System :: Networking',
+            "Development Status :: 6 - Mature",
+            "Intended Audience :: Developers",
+            "License :: OSI Approved :: Apache Software License",
+            "Operating System :: MacOS :: MacOS X",
+            "Operating System :: Microsoft :: Windows",
+            "Operating System :: POSIX",
+            "Programming Language :: Python :: 2",
+            "Programming Language :: Python :: 2.7",
+            "Programming Language :: Python :: 3",
+            "Programming Language :: Python :: 3.5",
+            "Programming Language :: Python :: 3.6",
+            "Programming Language :: Python :: 3.7",
+            "Programming Language :: Python :: 3.8",
+            "Programming Language :: Python :: 3.9",
+            "Programming Language :: Python :: Implementation :: CPython",
+            "Programming Language :: Python :: Implementation :: PyPy",
+            "Topic :: Security :: Cryptography",
+            "Topic :: Software Development :: Libraries :: Python Modules",
+            "Topic :: System :: Networking",
         ],
-
+        python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*",
         packages=find_packages(where="src"),
         package_dir={"": "src"},
         install_requires=[
             # Fix cryptographyMinimum in tox.ini when changing this!
-            "cryptography>=2.3",
-            "six>=1.5.2"
+            "cryptography>=3.2",
+            "six>=1.5.2",
         ],
         extras_require={
-            "test": [
-                "flaky",
-                "pretend",
-                "pytest>=3.0.1",
-            ],
-            "docs": [
-                "sphinx",
-                "sphinx_rtd_theme",
-            ]
+            "test": ["flaky", "pretend", "pytest>=3.0.1"],
+            "docs": ["sphinx", "sphinx_rtd_theme"],
         },
     )
diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
index 0687fc3..e5fea1e 100644
--- a/src/OpenSSL/SSL.py
+++ b/src/OpenSSL/SSL.py
@@ -6,16 +6,13 @@
 from weakref import WeakValueDictionary
 from errno import errorcode
 
-from cryptography.utils import deprecated
-
-from six import (
-    binary_type as _binary_type, integer_types as integer_types, int2byte,
-    indexbytes)
+from six import integer_types, int2byte, indexbytes
 
 from OpenSSL._util import (
     UNSPECIFIED as _UNSPECIFIED,
     exception_from_error_queue as _exception_from_error_queue,
     ffi as _ffi,
+    from_buffer as _from_buffer,
     lib as _lib,
     make_assert as _make_assert,
     native as _native,
@@ -25,99 +22,108 @@
 )
 
 from OpenSSL.crypto import (
-    FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
+    FILETYPE_PEM,
+    _PassphraseHelper,
+    PKey,
+    X509Name,
+    X509,
+    X509Store,
+)
 
 __all__ = [
-    'OPENSSL_VERSION_NUMBER',
-    'SSLEAY_VERSION',
-    'SSLEAY_CFLAGS',
-    'SSLEAY_PLATFORM',
-    'SSLEAY_DIR',
-    'SSLEAY_BUILT_ON',
-    'SENT_SHUTDOWN',
-    'RECEIVED_SHUTDOWN',
-    'SSLv2_METHOD',
-    'SSLv3_METHOD',
-    'SSLv23_METHOD',
-    'TLSv1_METHOD',
-    'TLSv1_1_METHOD',
-    'TLSv1_2_METHOD',
-    'OP_NO_SSLv2',
-    'OP_NO_SSLv3',
-    'OP_NO_TLSv1',
-    'OP_NO_TLSv1_1',
-    'OP_NO_TLSv1_2',
-    'MODE_RELEASE_BUFFERS',
-    'OP_SINGLE_DH_USE',
-    'OP_SINGLE_ECDH_USE',
-    'OP_EPHEMERAL_RSA',
-    'OP_MICROSOFT_SESS_ID_BUG',
-    'OP_NETSCAPE_CHALLENGE_BUG',
-    'OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG',
-    'OP_SSLREF2_REUSE_CERT_TYPE_BUG',
-    'OP_MICROSOFT_BIG_SSLV3_BUFFER',
-    'OP_MSIE_SSLV2_RSA_PADDING',
-    'OP_SSLEAY_080_CLIENT_DH_BUG',
-    'OP_TLS_D5_BUG',
-    'OP_TLS_BLOCK_PADDING_BUG',
-    'OP_DONT_INSERT_EMPTY_FRAGMENTS',
-    'OP_CIPHER_SERVER_PREFERENCE',
-    'OP_TLS_ROLLBACK_BUG',
-    'OP_PKCS1_CHECK_1',
-    'OP_PKCS1_CHECK_2',
-    'OP_NETSCAPE_CA_DN_BUG',
-    'OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG',
-    'OP_NO_COMPRESSION',
-    'OP_NO_QUERY_MTU',
-    'OP_COOKIE_EXCHANGE',
-    'OP_NO_TICKET',
-    'OP_ALL',
-    'VERIFY_PEER',
-    'VERIFY_FAIL_IF_NO_PEER_CERT',
-    'VERIFY_CLIENT_ONCE',
-    'VERIFY_NONE',
-    'SESS_CACHE_OFF',
-    'SESS_CACHE_CLIENT',
-    'SESS_CACHE_SERVER',
-    'SESS_CACHE_BOTH',
-    'SESS_CACHE_NO_AUTO_CLEAR',
-    'SESS_CACHE_NO_INTERNAL_LOOKUP',
-    'SESS_CACHE_NO_INTERNAL_STORE',
-    'SESS_CACHE_NO_INTERNAL',
-    'SSL_ST_CONNECT',
-    'SSL_ST_ACCEPT',
-    'SSL_ST_MASK',
-    'SSL_CB_LOOP',
-    'SSL_CB_EXIT',
-    'SSL_CB_READ',
-    'SSL_CB_WRITE',
-    'SSL_CB_ALERT',
-    'SSL_CB_READ_ALERT',
-    'SSL_CB_WRITE_ALERT',
-    'SSL_CB_ACCEPT_LOOP',
-    'SSL_CB_ACCEPT_EXIT',
-    'SSL_CB_CONNECT_LOOP',
-    'SSL_CB_CONNECT_EXIT',
-    'SSL_CB_HANDSHAKE_START',
-    'SSL_CB_HANDSHAKE_DONE',
-    'Error',
-    'WantReadError',
-    'WantWriteError',
-    'WantX509LookupError',
-    'ZeroReturnError',
-    'SysCallError',
-    'SSLeay_version',
-    'Session',
-    'Context',
-    'Connection'
+    "OPENSSL_VERSION_NUMBER",
+    "SSLEAY_VERSION",
+    "SSLEAY_CFLAGS",
+    "SSLEAY_PLATFORM",
+    "SSLEAY_DIR",
+    "SSLEAY_BUILT_ON",
+    "SENT_SHUTDOWN",
+    "RECEIVED_SHUTDOWN",
+    "SSLv2_METHOD",
+    "SSLv3_METHOD",
+    "SSLv23_METHOD",
+    "TLSv1_METHOD",
+    "TLSv1_1_METHOD",
+    "TLSv1_2_METHOD",
+    "OP_NO_SSLv2",
+    "OP_NO_SSLv3",
+    "OP_NO_TLSv1",
+    "OP_NO_TLSv1_1",
+    "OP_NO_TLSv1_2",
+    "OP_NO_TLSv1_3",
+    "MODE_RELEASE_BUFFERS",
+    "OP_SINGLE_DH_USE",
+    "OP_SINGLE_ECDH_USE",
+    "OP_EPHEMERAL_RSA",
+    "OP_MICROSOFT_SESS_ID_BUG",
+    "OP_NETSCAPE_CHALLENGE_BUG",
+    "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG",
+    "OP_SSLREF2_REUSE_CERT_TYPE_BUG",
+    "OP_MICROSOFT_BIG_SSLV3_BUFFER",
+    "OP_MSIE_SSLV2_RSA_PADDING",
+    "OP_SSLEAY_080_CLIENT_DH_BUG",
+    "OP_TLS_D5_BUG",
+    "OP_TLS_BLOCK_PADDING_BUG",
+    "OP_DONT_INSERT_EMPTY_FRAGMENTS",
+    "OP_CIPHER_SERVER_PREFERENCE",
+    "OP_TLS_ROLLBACK_BUG",
+    "OP_PKCS1_CHECK_1",
+    "OP_PKCS1_CHECK_2",
+    "OP_NETSCAPE_CA_DN_BUG",
+    "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG",
+    "OP_NO_COMPRESSION",
+    "OP_NO_QUERY_MTU",
+    "OP_COOKIE_EXCHANGE",
+    "OP_NO_TICKET",
+    "OP_ALL",
+    "VERIFY_PEER",
+    "VERIFY_FAIL_IF_NO_PEER_CERT",
+    "VERIFY_CLIENT_ONCE",
+    "VERIFY_NONE",
+    "SESS_CACHE_OFF",
+    "SESS_CACHE_CLIENT",
+    "SESS_CACHE_SERVER",
+    "SESS_CACHE_BOTH",
+    "SESS_CACHE_NO_AUTO_CLEAR",
+    "SESS_CACHE_NO_INTERNAL_LOOKUP",
+    "SESS_CACHE_NO_INTERNAL_STORE",
+    "SESS_CACHE_NO_INTERNAL",
+    "SSL_ST_CONNECT",
+    "SSL_ST_ACCEPT",
+    "SSL_ST_MASK",
+    "SSL_CB_LOOP",
+    "SSL_CB_EXIT",
+    "SSL_CB_READ",
+    "SSL_CB_WRITE",
+    "SSL_CB_ALERT",
+    "SSL_CB_READ_ALERT",
+    "SSL_CB_WRITE_ALERT",
+    "SSL_CB_ACCEPT_LOOP",
+    "SSL_CB_ACCEPT_EXIT",
+    "SSL_CB_CONNECT_LOOP",
+    "SSL_CB_CONNECT_EXIT",
+    "SSL_CB_HANDSHAKE_START",
+    "SSL_CB_HANDSHAKE_DONE",
+    "Error",
+    "WantReadError",
+    "WantWriteError",
+    "WantX509LookupError",
+    "ZeroReturnError",
+    "SysCallError",
+    "SSLeay_version",
+    "Session",
+    "Context",
+    "Connection",
 ]
 
 try:
     _buffer = buffer
 except NameError:
+
     class _buffer(object):
         pass
 
+
 OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
 SSLEAY_VERSION = _lib.SSLEAY_VERSION
 SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
@@ -140,6 +146,10 @@
 OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
 OP_NO_TLSv1_1 = _lib.SSL_OP_NO_TLSv1_1
 OP_NO_TLSv1_2 = _lib.SSL_OP_NO_TLSv1_2
+try:
+    OP_NO_TLSv1_3 = _lib.SSL_OP_NO_TLSv1_3
+except AttributeError:
+    pass
 
 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
 
@@ -191,17 +201,6 @@
 SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
 SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
 SSL_ST_MASK = _lib.SSL_ST_MASK
-if _lib.Cryptography_HAS_SSL_ST:
-    SSL_ST_INIT = _lib.SSL_ST_INIT
-    SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
-    SSL_ST_OK = _lib.SSL_ST_OK
-    SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
-    __all__.extend([
-        'SSL_ST_INIT',
-        'SSL_ST_BEFORE',
-        'SSL_ST_OK',
-        'SSL_ST_RENEGOTIATE',
-    ])
 
 SSL_CB_LOOP = _lib.SSL_CB_LOOP
 SSL_CB_EXIT = _lib.SSL_CB_EXIT
@@ -330,97 +329,11 @@
                     return 0
 
         self.callback = _ffi.callback(
-            "int (*)(int, X509_STORE_CTX *)", wrapper)
-
-
-class _NpnAdvertiseHelper(_CallbackExceptionHelper):
-    """
-    Wrap a callback such that it can be used as an NPN advertisement callback.
-    """
-
-    def __init__(self, callback):
-        _CallbackExceptionHelper.__init__(self)
-
-        @wraps(callback)
-        def wrapper(ssl, out, outlen, arg):
-            try:
-                conn = Connection._reverse_mapping[ssl]
-                protos = callback(conn)
-
-                # Join the protocols into a Python bytestring, length-prefixing
-                # each element.
-                protostr = b''.join(
-                    chain.from_iterable((int2byte(len(p)), p) for p in protos)
-                )
-
-                # Save our callback arguments on the connection object. This is
-                # done to make sure that they don't get freed before OpenSSL
-                # uses them. Then, return them appropriately in the output
-                # parameters.
-                conn._npn_advertise_callback_args = [
-                    _ffi.new("unsigned int *", len(protostr)),
-                    _ffi.new("unsigned char[]", protostr),
-                ]
-                outlen[0] = conn._npn_advertise_callback_args[0][0]
-                out[0] = conn._npn_advertise_callback_args[1]
-                return 0
-            except Exception as e:
-                self._problems.append(e)
-                return 2  # SSL_TLSEXT_ERR_ALERT_FATAL
-
-        self.callback = _ffi.callback(
-            "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
-            wrapper
+            "int (*)(int, X509_STORE_CTX *)", wrapper
         )
 
 
-class _NpnSelectHelper(_CallbackExceptionHelper):
-    """
-    Wrap a callback such that it can be used as an NPN selection callback.
-    """
-
-    def __init__(self, callback):
-        _CallbackExceptionHelper.__init__(self)
-
-        @wraps(callback)
-        def wrapper(ssl, out, outlen, in_, inlen, arg):
-            try:
-                conn = Connection._reverse_mapping[ssl]
-
-                # The string passed to us is actually made up of multiple
-                # length-prefixed bytestrings. We need to split that into a
-                # list.
-                instr = _ffi.buffer(in_, inlen)[:]
-                protolist = []
-                while instr:
-                    length = indexbytes(instr, 0)
-                    proto = instr[1:length + 1]
-                    protolist.append(proto)
-                    instr = instr[length + 1:]
-
-                # Call the callback
-                outstr = callback(conn, protolist)
-
-                # Save our callback arguments on the connection object. This is
-                # done to make sure that they don't get freed before OpenSSL
-                # uses them. Then, return them appropriately in the output
-                # parameters.
-                conn._npn_select_callback_args = [
-                    _ffi.new("unsigned char *", len(outstr)),
-                    _ffi.new("unsigned char[]", outstr),
-                ]
-                outlen[0] = conn._npn_select_callback_args[0][0]
-                out[0] = conn._npn_select_callback_args[1]
-                return 0
-            except Exception as e:
-                self._problems.append(e)
-                return 2  # SSL_TLSEXT_ERR_ALERT_FATAL
-
-        self.callback = _ffi.callback(
-            ("int (*)(SSL *, unsigned char **, unsigned char *, "
-                "const unsigned char *, unsigned int, void *)"),
-            wrapper
-        )
+NO_OVERLAPPING_PROTOCOLS = object()
 
 
 class _ALPNSelectHelper(_CallbackExceptionHelper):
@@ -443,34 +356,44 @@
                 protolist = []
                 while instr:
                     encoded_len = indexbytes(instr, 0)
-                    proto = instr[1:encoded_len + 1]
+                    proto = instr[1 : encoded_len + 1]
                     protolist.append(proto)
-                    instr = instr[encoded_len + 1:]
+                    instr = instr[encoded_len + 1 :]
 
                 # Call the callback
-                outstr = callback(conn, protolist)
-
-                if not isinstance(outstr, _binary_type):
-                    raise TypeError("ALPN callback must return a bytestring.")
+                outbytes = callback(conn, protolist)
+                any_accepted = True
+                if outbytes is NO_OVERLAPPING_PROTOCOLS:
+                    outbytes = b""
+                    any_accepted = False
+                elif not isinstance(outbytes, bytes):
+                    raise TypeError(
+                        "ALPN callback must return a bytestring or the "
+                        "special NO_OVERLAPPING_PROTOCOLS sentinel value."
+                    )
 
                 # Save our callback arguments on the connection object to make
                 # sure that they don't get freed before OpenSSL can use them.
                 # Then, return them in the appropriate output parameters.
                 conn._alpn_select_callback_args = [
-                    _ffi.new("unsigned char *", len(outstr)),
-                    _ffi.new("unsigned char[]", outstr),
+                    _ffi.new("unsigned char *", len(outbytes)),
+                    _ffi.new("unsigned char[]", outbytes),
                 ]
                 outlen[0] = conn._alpn_select_callback_args[0][0]
                 out[0] = conn._alpn_select_callback_args[1]
-                return 0
+                if not any_accepted:
+                    return _lib.SSL_TLSEXT_ERR_NOACK
+                return _lib.SSL_TLSEXT_ERR_OK
             except Exception as e:
                 self._problems.append(e)
-                return 2  # SSL_TLSEXT_ERR_ALERT_FATAL
+                return _lib.SSL_TLSEXT_ERR_ALERT_FATAL
 
         self.callback = _ffi.callback(
-            ("int (*)(SSL *, unsigned char **, unsigned char *, "
-                "const unsigned char *, unsigned int, void *)"),
-            wrapper
+            (
+                "int (*)(SSL *, unsigned char **, unsigned char *, "
+                "const unsigned char *, unsigned int, void *)"
+            ),
+            wrapper,
         )
 
 
@@ -513,7 +436,7 @@
                 # Call the callback.
                 ocsp_data = callback(conn, data)
 
-                if not isinstance(ocsp_data, _binary_type):
+                if not isinstance(ocsp_data, bytes):
                     raise TypeError("OCSP callback must return a bytestring.")
 
                 # If the OCSP data was provided, we will pass it to OpenSSL.
@@ -582,7 +505,7 @@
                 ocsp_len = _lib.SSL_get_tlsext_status_ocsp_resp(ssl, ocsp_ptr)
                 if ocsp_len < 0:
                     # No OCSP data.
-                    ocsp_data = b''
+                    ocsp_data = b""
                 else:
                     # Copy the OCSP data, then pass it to the callback.
                     ocsp_data = _ffi.buffer(ocsp_ptr[0], ocsp_len)[:]
@@ -614,7 +537,8 @@
         raise TypeError("argument must be an int, or have a fileno() method.")
     elif fd < 0:
         raise ValueError(
-            "file descriptor cannot be a negative integer (%i)" % (fd,))
+            "file descriptor cannot be a negative integer (%i)" % (fd,)
+        )
 
     return fd
 
@@ -638,11 +562,14 @@
         ``Cryptography_HAS_NEXTPROTONEG``.
     :param error: The string to be used in the exception if the flag is false.
     """
+
     def _requires_decorator(func):
         if not flag:
+
             @wraps(func)
             def explode(*args, **kwargs):
                 raise NotImplementedError(error)
+
             return explode
         else:
             return func
@@ -650,18 +577,13 @@
     return _requires_decorator
 
 
-_requires_npn = _make_requires(
-    _lib.Cryptography_HAS_NEXTPROTONEG, "NPN not available"
-)
-
-
 _requires_alpn = _make_requires(
     _lib.Cryptography_HAS_ALPN, "ALPN not available"
 )
 
 
-_requires_sni = _make_requires(
-    _lib.Cryptography_HAS_TLSEXT_HOSTNAME, "SNI not available"
+_requires_keylog = _make_requires(
+    getattr(_lib, "Cryptography_HAS_KEYLOG", None), "Key logging not available"
 )
 
 
@@ -673,6 +595,7 @@
 
     .. versionadded:: 0.14
     """
+
     pass
 
 
@@ -684,6 +607,7 @@
     :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
         TLSv1_METHOD.
     """
+
     _methods = {
         SSLv2_METHOD: "SSLv2_method",
         SSLv3_METHOD: "SSLv3_method",
@@ -695,7 +619,8 @@
     _methods = dict(
         (identifier, getattr(_lib, name))
         for (identifier, name) in _methods.items()
-        if getattr(_lib, name, None) is not None)
+        if getattr(_lib, name, None) is not None
+    )
 
     def __init__(self, method):
         if not isinstance(method, integer_types):
@@ -713,14 +638,11 @@
         _openssl_assert(context != _ffi.NULL)
         context = _ffi.gc(context, _lib.SSL_CTX_free)
 
-        # If SSL_CTX_set_ecdh_auto is available then set it so the ECDH curve
-        # will be auto-selected. This function was added in 1.0.2 and made a
-        # noop in 1.1.0+ (where it is set automatically).
-        try:
-            res = _lib.SSL_CTX_set_ecdh_auto(context, 1)
-            _openssl_assert(res == 1)
-        except AttributeError:
-            pass
+        # Set SSL_CTX_set_ecdh_auto so that the ECDH curve will be
+        # auto-selected. This function was added in 1.0.2 and made a noop in
+        # 1.1.0+ (where it is set automatically).
+        res = _lib.SSL_CTX_set_ecdh_auto(context, 1)
+        _openssl_assert(res == 1)
 
         self._context = context
         self._passphrase_helper = None
@@ -729,12 +651,9 @@
         self._verify_helper = None
         self._verify_callback = None
         self._info_callback = None
+        self._keylog_callback = None
         self._tlsext_servername_callback = None
         self._app_data = None
-        self._npn_advertise_helper = None
-        self._npn_advertise_callback = None
-        self._npn_select_helper = None
-        self._npn_select_callback = None
         self._alpn_select_helper = None
         self._alpn_select_callback = None
         self._ocsp_helper = None
@@ -779,8 +698,10 @@
         @wraps(callback)
         def wrapper(size, verify, userdata):
             return callback(size, verify, self._passphrase_userdata)
+
         return _PassphraseHelper(
-            FILETYPE_PEM, wrapper, more_args=True, truncate=True)
+            FILETYPE_PEM, wrapper, more_args=True, truncate=True
+        )
 
     def set_passwd_cb(self, callback, userdata=None):
         """
@@ -807,7 +728,8 @@
         self._passphrase_helper = self._wrap_callback(callback)
         self._passphrase_callback = self._passphrase_helper.callback
         _lib.SSL_CTX_set_default_passwd_cb(
-            self._context, self._passphrase_callback)
+            self._context, self._passphrase_callback
+        )
         self._passphrase_userdata = userdata
 
     def set_default_verify_paths(self):
@@ -837,9 +759,9 @@
         # First we'll check to see if any env vars have been set. If so,
         # we won't try to do anything else because the user has set the path
         # themselves.
-        dir_env_var = _ffi.string(
-            _lib.X509_get_default_cert_dir_env()
-        ).decode("ascii")
+        dir_env_var = _ffi.string(_lib.X509_get_default_cert_dir_env()).decode(
+            "ascii"
+        )
         file_env_var = _ffi.string(
             _lib.X509_get_default_cert_file_env()
         ).decode("ascii")
@@ -850,13 +772,12 @@
             # to the exact values we use in our manylinux1 builds. If they are
             # then we know to load the fallbacks
             if (
-                default_dir == _CRYPTOGRAPHY_MANYLINUX1_CA_DIR and
-                default_file == _CRYPTOGRAPHY_MANYLINUX1_CA_FILE
+                default_dir == _CRYPTOGRAPHY_MANYLINUX1_CA_DIR
+                and default_file == _CRYPTOGRAPHY_MANYLINUX1_CA_FILE
             ):
                 # This is manylinux1, let's load our fallback paths
                 self._fallback_default_verify_paths(
-                    _CERTIFICATE_FILE_LOCATIONS,
-                    _CERTIFICATE_PATH_LOCATIONS
+                    _CERTIFICATE_FILE_LOCATIONS, _CERTIFICATE_PATH_LOCATIONS
                 )
 
     def _check_env_vars_set(self, dir_env_var, file_env_var):
@@ -866,8 +787,8 @@
         :return: bool
         """
         return (
-            os.environ.get(file_env_var) is not None or
-            os.environ.get(dir_env_var) is not None
+            os.environ.get(file_env_var) is not None
+            or os.environ.get(dir_env_var) is not None
         )
 
     def _fallback_default_verify_paths(self, file_path, dir_path):
@@ -985,7 +906,8 @@
             raise TypeError("filetype must be an integer")
 
         use_result = _lib.SSL_CTX_use_PrivateKey_file(
-            self._context, keyfile, filetype)
+            self._context, keyfile, filetype
+        )
         if not use_result:
             self._raise_passphrase_exception()
 
@@ -1041,11 +963,8 @@
         """
         buf = _text_to_bytes_and_warn("buf", buf)
         _openssl_assert(
-            _lib.SSL_CTX_set_session_id_context(
-                self._context,
-                buf,
-                len(buf),
-            ) == 1
+            _lib.SSL_CTX_set_session_id_context(self._context, buf, len(buf))
+            == 1
         )
 
     def set_session_cache_mode(self, mode):
@@ -1075,21 +994,22 @@
         """
         return _lib.SSL_CTX_get_session_cache_mode(self._context)
 
-    def set_verify(self, mode, callback):
+    def set_verify(self, mode, callback=None):
         """
-        et the verification flags for this Context object to *mode* and specify
-        that *callback* should be used for verification callbacks.
+        Set the verification flags for this Context object to *mode* and
+        specify that *callback* should be used for verification callbacks.
 
         :param mode: The verify mode, this should be one of
             :const:`VERIFY_NONE` and :const:`VERIFY_PEER`. If
             :const:`VERIFY_PEER` is used, *mode* can be OR:ed with
             :const:`VERIFY_FAIL_IF_NO_PEER_CERT` and
             :const:`VERIFY_CLIENT_ONCE` to further control the behaviour.
-        :param callback: The Python callback to use.  This should take five
-            arguments: A Connection object, an X509 object, and three integer
-            variables, which are in turn potential error number, error depth
-            and return code. *callback* should return True if verification
-            passes and False otherwise.
+        :param callback: The optional Python verification callback to use.
+            This should take five arguments: A Connection object, an X509
+            object, and three integer variables, which are in turn potential
+            error number, error depth and return code. *callback* should
+            return True if verification passes and False otherwise.
+            If omitted, OpenSSL's default verification is used.
         :return: None
 
         See SSL_CTX_set_verify(3SSL) for further details.
@@ -1097,12 +1017,17 @@
         if not isinstance(mode, integer_types):
             raise TypeError("mode must be an integer")
 
-        if not callable(callback):
-            raise TypeError("callback must be callable")
+        if callback is None:
+            self._verify_helper = None
+            self._verify_callback = None
+            _lib.SSL_CTX_set_verify(self._context, mode, _ffi.NULL)
+        else:
+            if not callable(callback):
+                raise TypeError("callback must be callable")
 
-        self._verify_helper = _VerifyHelper(callback)
-        self._verify_callback = self._verify_helper.callback
-        _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
+            self._verify_helper = _VerifyHelper(callback)
+            self._verify_callback = self._verify_helper.callback
+            _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
 
     def set_verify_depth(self, depth):
         """
@@ -1153,7 +1078,8 @@
 
         dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
         dh = _ffi.gc(dh, _lib.DH_free)
-        _lib.SSL_CTX_set_tmp_dh(self._context, dh)
+        res = _lib.SSL_CTX_set_tmp_dh(self._context, dh)
+        _openssl_assert(res == 1)
 
     def set_tmp_ecdh(self, curve):
         """
@@ -1191,13 +1117,20 @@
         # invalid cipher string is passed, but without the following check
         # for the TLS 1.3 specific cipher suites it would never error.
         tmpconn = Connection(self, None)
-        _openssl_assert(
-            tmpconn.get_cipher_list() != [
-                'TLS_AES_256_GCM_SHA384',
-                'TLS_CHACHA20_POLY1305_SHA256',
-                'TLS_AES_128_GCM_SHA256'
-            ]
-        )
+        if tmpconn.get_cipher_list() == [
+            "TLS_AES_256_GCM_SHA384",
+            "TLS_CHACHA20_POLY1305_SHA256",
+            "TLS_AES_128_GCM_SHA256",
+        ]:
+            raise Error(
+                [
+                    (
+                        "SSL routines",
+                        "SSL_CTX_set_cipher_list",
+                        "no cipher match",
+                    ),
+                ],
+            )
 
     def set_client_ca_list(self, certificate_authorities):
         """
@@ -1220,9 +1153,7 @@
                 if not isinstance(ca_name, X509Name):
                     raise TypeError(
                         "client CAs must be X509Name objects, not %s "
-                        "objects" % (
-                            type(ca_name).__name__,
-                        )
+                        "objects" % (type(ca_name).__name__,)
                     )
                 copy = _lib.X509_NAME_dup(ca_name._name)
                 _openssl_assert(copy != _ffi.NULL)
@@ -1253,7 +1184,8 @@
             raise TypeError("certificate_authority must be an X509 instance")
 
         add_result = _lib.SSL_CTX_add_client_CA(
-            self._context, certificate_authority._x509)
+            self._context, certificate_authority._x509
+        )
         _openssl_assert(add_result == 1)
 
     def set_timeout(self, timeout):
@@ -1291,13 +1223,41 @@
             function call.
         :return: None
         """
+
         @wraps(callback)
         def wrapper(ssl, where, return_code):
             callback(Connection._reverse_mapping[ssl], where, return_code)
+
         self._info_callback = _ffi.callback(
-            "void (*)(const SSL *, int, int)", wrapper)
+            "void (*)(const SSL *, int, int)", wrapper
+        )
         _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
 
+    @_requires_keylog
+    def set_keylog_callback(self, callback):
+        """
+        Set the TLS key logging callback to *callback*. This function will be
+        called whenever TLS key material is generated or received, in order
+        to allow applications to store this keying material for debugging
+        purposes.
+
+        :param callback: The Python callback to use.  This should take two
+            arguments: a Connection object and a bytestring that contains
+            the key material in the format used by NSS for its SSLKEYLOGFILE
+            debugging output.
+        :return: None
+        """
+
+        @wraps(callback)
+        def wrapper(ssl, line):
+            line = _ffi.string(line)
+            callback(Connection._reverse_mapping[ssl], line)
+
+        self._keylog_callback = _ffi.callback(
+            "void (*)(const SSL *, const char *)", wrapper
+        )
+        _lib.SSL_CTX_set_keylog_callback(self._context, self._keylog_callback)
+
     def get_app_data(self):
         """
         Get the application data (supplied via :meth:`set_app_data()`)
@@ -1358,7 +1318,6 @@
 
         return _lib.SSL_CTX_set_mode(self._context, mode)
 
-    @_requires_sni
     def set_tlsext_servername_callback(self, callback):
         """
         Specify a callback function to be called when clients specify a server
@@ -1369,15 +1328,18 @@
 
         .. versionadded:: 0.13
         """
+
         @wraps(callback)
         def wrapper(ssl, alert, arg):
             callback(Connection._reverse_mapping[ssl])
             return 0
 
         self._tlsext_servername_callback = _ffi.callback(
-            "int (*)(SSL *, int *, void *)", wrapper)
+            "int (*)(SSL *, int *, void *)", wrapper
+        )
         _lib.SSL_CTX_set_tlsext_servername_callback(
-            self._context, self._tlsext_servername_callback)
+            self._context, self._tlsext_servername_callback
+        )
 
     def set_tlsext_use_srtp(self, profiles):
         """
@@ -1394,43 +1356,6 @@
             _lib.SSL_CTX_set_tlsext_use_srtp(self._context, profiles) == 0
         )
 
-    @_requires_npn
-    def set_npn_advertise_callback(self, callback):
-        """
-        Specify a callback function that will be called when offering `Next
-        Protocol Negotiation
-        <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
-
-        :param callback: The callback function.  It will be invoked with one
-            argument, the :class:`Connection` instance.  It should return a
-            list of bytestrings representing the advertised protocols, like
-            ``[b'http/1.1', b'spdy/2']``.
-
-        .. versionadded:: 0.15
-        """
-        self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
-        self._npn_advertise_callback = self._npn_advertise_helper.callback
-        _lib.SSL_CTX_set_next_protos_advertised_cb(
-            self._context, self._npn_advertise_callback, _ffi.NULL)
-
-    @_requires_npn
-    def set_npn_select_callback(self, callback):
-        """
-        Specify a callback function that will be called when a server offers
-        Next Protocol Negotiation options.
-
-        :param callback: The callback function.  It will be invoked with two
-            arguments: the Connection, and a list of offered protocols as
-            bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``.  It should return
-            one of those bytestrings, the chosen protocol.
-
-        .. versionadded:: 0.15
-        """
-        self._npn_select_helper = _NpnSelectHelper(callback)
-        self._npn_select_callback = self._npn_select_helper.callback
-        _lib.SSL_CTX_set_next_proto_select_cb(
-            self._context, self._npn_select_callback, _ffi.NULL)
-
     @_requires_alpn
     def set_alpn_protos(self, protos):
         """
@@ -1444,7 +1369,7 @@
         """
         # Take the list of protocols and join them together, prefixing them
         # with their lengths.
-        protostr = b''.join(
+        protostr = b"".join(
             chain.from_iterable((int2byte(len(p)), p) for p in protos)
         )
 
@@ -1461,13 +1386,18 @@
 
         :param callback: The callback function.  It will be invoked with two
             arguments: the Connection, and a list of offered protocols as
-            bytestrings, e.g ``[b'http/1.1', b'spdy/2']``.  It should return
-            one of those bytestrings, the chosen protocol.
+            bytestrings, e.g ``[b'http/1.1', b'spdy/2']``.  It can return
+            one of those bytestrings to indicate the chosen protocol, the
+            empty bytestring to terminate the TLS connection, or the
+            :py:obj:`NO_OVERLAPPING_PROTOCOLS` to indicate that no offered
+            protocol was selected, but that the connection should not be
+            aborted.
         """
         self._alpn_select_helper = _ALPNSelectHelper(callback)
         self._alpn_select_callback = self._alpn_select_helper.callback
         _lib.SSL_CTX_set_alpn_select_cb(
-            self._context, self._alpn_select_callback, _ffi.NULL)
+            self._context, self._alpn_select_callback, _ffi.NULL
+        )
 
     def _set_ocsp_callback(self, helper, data):
         """
@@ -1528,15 +1458,7 @@
         self._set_ocsp_callback(helper, data)
 
 
-ContextType = deprecated(
-    Context, __name__,
-    "ContextType has been deprecated, use Context instead", DeprecationWarning
-)
-
-
 class Connection(object):
-    """
-    """
     _reverse_mapping = WeakValueDictionary()
 
     def __init__(self, context, socket=None):
@@ -1560,19 +1482,18 @@
         self._context = context
         self._app_data = None
 
-        # References to strings used for Next Protocol Negotiation. OpenSSL's
-        # header files suggest that these might get copied at some point, but
-        # doesn't specify when, so we store them here to make sure they don't
-        # get freed before OpenSSL uses them.
-        self._npn_advertise_callback_args = None
-        self._npn_select_callback_args = None
-
         # References to strings used for Application Layer Protocol
         # Negotiation. These strings get copied at some point but it's well
         # after the callback returns, so we have to hang them somewhere to
         # avoid them getting freed.
         self._alpn_select_callback_args = None
 
+        # Reference the verify_callback of the Context. This ensures that if
+        # set_verify is called again after the SSL object has been created we
+        # do not point to a dangling reference
+        self._verify_helper = context._verify_helper
+        self._verify_callback = context._verify_callback
+
         self._reverse_mapping[self._ssl] = self
 
         if socket is None:
@@ -1590,7 +1511,8 @@
             self._from_ssl = None
             self._socket = socket
             set_result = _lib.SSL_set_fd(
-                self._ssl, _asFileDescriptor(self._socket))
+                self._ssl, _asFileDescriptor(self._socket)
+            )
             _openssl_assert(set_result == 1)
 
     def __getattr__(self, name):
@@ -1599,19 +1521,16 @@
         on the Connection object.
         """
         if self._socket is None:
-            raise AttributeError("'%s' object has no attribute '%s'" % (
-                self.__class__.__name__, name
-            ))
+            raise AttributeError(
+                "'%s' object has no attribute '%s'"
+                % (self.__class__.__name__, name)
+            )
         else:
             return getattr(self._socket, name)
 
     def _raise_ssl_error(self, ssl, result):
         if self._context._verify_helper is not None:
             self._context._verify_helper.raise_if_problem()
-        if self._context._npn_advertise_helper is not None:
-            self._context._npn_advertise_helper.raise_if_problem()
-        if self._context._npn_select_helper is not None:
-            self._context._npn_select_helper.raise_if_problem()
         if self._context._alpn_select_helper is not None:
             self._context._alpn_select_helper.raise_if_problem()
         if self._context._ocsp_helper is not None:
@@ -1666,7 +1585,6 @@
         _lib.SSL_set_SSL_CTX(self._ssl, context._context)
         self._context = context
 
-    @_requires_sni
     def get_servername(self):
         """
         Retrieve the servername extension value if provided in the client hello
@@ -1684,7 +1602,6 @@
 
         return _ffi.string(name)
 
-    @_requires_sni
     def set_tlsext_host_name(self, name):
         """
         Set the value of the servername extension to send in the client hello.
@@ -1724,18 +1641,18 @@
         # Backward compatibility
         buf = _text_to_bytes_and_warn("buf", buf)
 
-        if isinstance(buf, memoryview):
-            buf = buf.tobytes()
-        if isinstance(buf, _buffer):
-            buf = str(buf)
-        if not isinstance(buf, bytes):
-            raise TypeError("data must be a memoryview, buffer or byte string")
-        if len(buf) > 2147483647:
-            raise ValueError("Cannot send more than 2**31-1 bytes at once.")
+        with _from_buffer(buf) as data:
+            # check len(buf) instead of len(data) for testability
+            if len(buf) > 2147483647:
+                raise ValueError(
+                    "Cannot send more than 2**31-1 bytes at once."
+                )
 
-        result = _lib.SSL_write(self._ssl, buf, len(buf))
-        self._raise_ssl_error(self._ssl, result)
-        return result
+            result = _lib.SSL_write(self._ssl, data, len(data))
+            self._raise_ssl_error(self._ssl, result)
+
+            return result
+
     write = send
 
     def sendall(self, buf, flags=0):
@@ -1751,28 +1668,22 @@
         """
         buf = _text_to_bytes_and_warn("buf", buf)
 
-        if isinstance(buf, memoryview):
-            buf = buf.tobytes()
-        if isinstance(buf, _buffer):
-            buf = str(buf)
-        if not isinstance(buf, bytes):
-            raise TypeError("buf must be a memoryview, buffer or byte string")
+        with _from_buffer(buf) as data:
 
-        left_to_send = len(buf)
-        total_sent = 0
-        data = _ffi.new("char[]", buf)
+            left_to_send = len(buf)
+            total_sent = 0
 
-        while left_to_send:
-            # SSL_write's num arg is an int,
-            # so we cannot send more than 2**31-1 bytes at once.
-            result = _lib.SSL_write(
-                self._ssl,
-                data + total_sent,
-                min(left_to_send, 2147483647)
-            )
-            self._raise_ssl_error(self._ssl, result)
-            total_sent += result
-            left_to_send -= result
+            while left_to_send:
+                # SSL_write's num arg is an int,
+                # so we cannot send more than 2**31-1 bytes at once.
+                result = _lib.SSL_write(
+                    self._ssl, data + total_sent, min(left_to_send, 2147483647)
+                )
+                self._raise_ssl_error(self._ssl, result)
+                total_sent += result
+                left_to_send -= result
+
+            return total_sent
 
     def recv(self, bufsiz, flags=None):
         """
@@ -1790,6 +1701,7 @@
             result = _lib.SSL_read(self._ssl, buf, bufsiz)
         self._raise_ssl_error(self._ssl, result)
         return _ffi.buffer(buf, result)[:]
+
     read = recv
 
     def recv_into(self, buffer, nbytes=None, flags=None):
@@ -1886,10 +1798,11 @@
         if self._into_ssl is None:
             raise TypeError("Connection sock was not None")
 
-        result = _lib.BIO_write(self._into_ssl, buf, len(buf))
-        if result <= 0:
-            self._handle_bio_errors(self._into_ssl, result)
-        return result
+        with _from_buffer(buf) as data:
+            result = _lib.BIO_write(self._into_ssl, data, len(data))
+            if result <= 0:
+                self._handle_bio_errors(self._into_ssl, result)
+            return result
 
     def renegotiate(self):
         """
@@ -1906,7 +1819,7 @@
     def do_handshake(self):
         """
         Perform an SSL handshake (usually called after :meth:`renegotiate` or
-        one of :meth:`set_accept_state` or :meth:`set_accept_state`). This can
+        one of :meth:`set_accept_state` or :meth:`set_connect_state`). This can
         raise the same exceptions as :meth:`send` and :meth:`recv`.
 
         :return: None.
@@ -2055,7 +1968,8 @@
         :raise: NotImplementedError
         """
         raise NotImplementedError(
-            "Cannot make file object of OpenSSL.SSL.Connection")
+            "Cannot make file object of OpenSSL.SSL.Connection"
+        )
 
     def get_app_data(self):
         """
@@ -2114,7 +2028,7 @@
         if session == _ffi.NULL:
             return None
         length = _lib.SSL_get_server_random(self._ssl, _ffi.NULL, 0)
-        assert length > 0
+        _openssl_assert(length > 0)
         outp = _no_zero_allocator("unsigned char[]", length)
         _lib.SSL_get_server_random(self._ssl, outp, length)
         return _ffi.buffer(outp, length)[:]
@@ -2130,7 +2044,7 @@
             return None
 
         length = _lib.SSL_get_client_random(self._ssl, _ffi.NULL, 0)
-        assert length > 0
+        _openssl_assert(length > 0)
         outp = _no_zero_allocator("unsigned char[]", length)
         _lib.SSL_get_client_random(self._ssl, outp, length)
         return _ffi.buffer(outp, length)[:]
@@ -2146,7 +2060,7 @@
             return None
 
         length = _lib.SSL_SESSION_get_master_key(session, _ffi.NULL, 0)
-        assert length > 0
+        _openssl_assert(length > 0)
         outp = _no_zero_allocator("unsigned char[]", length)
         _lib.SSL_SESSION_get_master_key(session, outp, length)
         return _ffi.buffer(outp, length)[:]
@@ -2168,10 +2082,16 @@
             context_buf = context
             context_len = len(context)
             use_context = 1
-        success = _lib.SSL_export_keying_material(self._ssl, outp, olen,
-                                                  label, len(label),
-                                                  context_buf, context_len,
-                                                  use_context)
+        success = _lib.SSL_export_keying_material(
+            self._ssl,
+            outp,
+            olen,
+            label,
+            len(label),
+            context_buf,
+            context_len,
+            use_context,
+        )
         _openssl_assert(success == 1)
         return _ffi.buffer(outp, olen)[:]
 
@@ -2207,6 +2127,22 @@
             return X509._from_raw_x509_ptr(cert)
         return None
 
+    @staticmethod
+    def _cert_stack_to_list(cert_stack):
+        """
+        Internal helper to convert a STACK_OF(X509) to a list of X509
+        instances.
+        """
+        result = []
+        for i in range(_lib.sk_X509_num(cert_stack)):
+            cert = _lib.sk_X509_value(cert_stack, i)
+            _openssl_assert(cert != _ffi.NULL)
+            res = _lib.X509_up_ref(cert)
+            _openssl_assert(res >= 1)
+            pycert = X509._from_raw_x509_ptr(cert)
+            result.append(pycert)
+        return result
+
     def get_peer_cert_chain(self):
         """
         Retrieve the other side's certificate (if any)
@@ -2218,13 +2154,26 @@
         if cert_stack == _ffi.NULL:
             return None
 
-        result = []
-        for i in range(_lib.sk_X509_num(cert_stack)):
-            # TODO could incref instead of dup here
-            cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
-            pycert = X509._from_raw_x509_ptr(cert)
-            result.append(pycert)
-        return result
+        return self._cert_stack_to_list(cert_stack)
+
+    def get_verified_chain(self):
+        """
+        Retrieve the verified certificate chain of the peer including the
+        peer's end entity certificate. It must be called after a session has
+        been successfully established. If peer verification was not successful
+        the chain may be incomplete, invalid, or None.
+
+        :return: A list of X509 instances giving the peer's verified
+                 certificate chain, or None if it does not have one.
+
+        .. versionadded:: 20.0
+        """
+        # OpenSSL 1.1+
+        cert_stack = _lib.SSL_get0_verified_chain(self._ssl)
+        if cert_stack == _ffi.NULL:
+            return None
+
+        return self._cert_stack_to_list(cert_stack)
 
     def want_read(self):
         """
@@ -2292,8 +2241,7 @@
             raise TypeError("session must be a Session instance")
 
         result = _lib.SSL_set_session(self._ssl, session._session)
-        if not result:
-            _raise_current_error()
+        _openssl_assert(result == 1)
 
     def _get_finished_message(self, function):
         """
@@ -2426,23 +2374,6 @@
         version = _lib.SSL_version(self._ssl)
         return version
 
-    @_requires_npn
-    def get_next_proto_negotiated(self):
-        """
-        Get the protocol that was negotiated by NPN.
-
-        :returns: A bytestring of the protocol name.  If no protocol has been
-            negotiated yet, returns an empty string.
-
-        .. versionadded:: 0.15
-        """
-        data = _ffi.new("unsigned char **")
-        data_len = _ffi.new("unsigned int *")
-
-        _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
-
-        return _ffi.buffer(data[0], data_len[0])[:]
-
     @_requires_alpn
     def set_alpn_protos(self, protos):
         """
@@ -2456,7 +2387,7 @@
         """
         # Take the list of protocols and join them together, prefixing them
         # with their lengths.
-        protostr = b''.join(
+        protostr = b"".join(
             chain.from_iterable((int2byte(len(p)), p) for p in protos)
         )
 
@@ -2479,7 +2410,7 @@
         _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
 
         if not data_len:
-            return b''
+            return b""
 
         return _ffi.buffer(data[0], data_len[0])[:]
 
@@ -2496,12 +2427,6 @@
         _openssl_assert(rc == 1)
 
 
-ConnectionType = deprecated(
-    Connection, __name__,
-    "ConnectionType has been deprecated, use Connection instead",
-    DeprecationWarning
-)
-
 # This is similar to the initialization calls at the end of OpenSSL/crypto.py
 # but is exercised mostly by the Context initializer.
 _lib.SSL_library_init()
diff --git a/src/OpenSSL/__init__.py b/src/OpenSSL/__init__.py
index 810d00d..11e896a 100644
--- a/src/OpenSSL/__init__.py
+++ b/src/OpenSSL/__init__.py
@@ -7,14 +7,26 @@
 
 from OpenSSL import crypto, SSL
 from OpenSSL.version import (
-    __author__, __copyright__, __email__, __license__, __summary__, __title__,
-    __uri__, __version__,
+    __author__,
+    __copyright__,
+    __email__,
+    __license__,
+    __summary__,
+    __title__,
+    __uri__,
+    __version__,
 )
 
 
 __all__ = [
-    "SSL", "crypto",
-
-    "__author__", "__copyright__", "__email__", "__license__", "__summary__",
-    "__title__", "__uri__", "__version__",
+    "SSL",
+    "crypto",
+    "__author__",
+    "__copyright__",
+    "__email__",
+    "__license__",
+    "__summary__",
+    "__title__",
+    "__uri__",
+    "__version__",
 ]
diff --git a/src/OpenSSL/_util.py b/src/OpenSSL/_util.py
index cf8b888..d04244c 100644
--- a/src/OpenSSL/_util.py
+++ b/src/OpenSSL/_util.py
@@ -1,7 +1,7 @@
 import sys
 import warnings
 
-from six import PY3, binary_type, text_type
+from six import PY2, text_type
 
 from cryptography.hazmat.bindings.openssl.binding import Binding
 
@@ -46,10 +46,13 @@
         error = lib.ERR_get_error()
         if error == 0:
             break
-        errors.append((
-            text(lib.ERR_lib_error_string(error)),
-            text(lib.ERR_func_error_string(error)),
-            text(lib.ERR_reason_error_string(error))))
+        errors.append(
+            (
+                text(lib.ERR_lib_error_string(error)),
+                text(lib.ERR_func_error_string(error)),
+                text(lib.ERR_reason_error_string(error)),
+            )
+        )
 
     raise exception_type(errors)
 
@@ -59,6 +62,7 @@
     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, retrieve the error from OpenSSL and raise it.
@@ -79,14 +83,14 @@
     :raise TypeError: The input is neither :py:class:`bytes` nor
         :py:class:`unicode`.
     """
-    if not isinstance(s, (binary_type, text_type)):
+    if not isinstance(s, (bytes, text_type)):
         raise TypeError("%r is neither bytes nor unicode" % s)
-    if PY3:
-        if isinstance(s, binary_type):
-            return s.decode("utf-8")
-    else:
+    if PY2:
         if isinstance(s, text_type):
             return s.encode("utf-8")
+    else:
+        if isinstance(s, bytes):
+            return s.decode("utf-8")
     return s
 
 
@@ -99,7 +103,7 @@
 
     :return: An instance of :py:class:`bytes`.
     """
-    if isinstance(s, binary_type):
+    if isinstance(s, bytes):
         return s
     elif isinstance(s, text_type):
         return s.encode(sys.getfilesystemencoding())
@@ -107,14 +111,18 @@
         raise TypeError("Path must be represented as bytes or unicode string")
 
 
-if PY3:
-    def byte_string(s):
-        return s.encode("charmap")
-else:
+if PY2:
+
     def byte_string(s):
         return s
 
 
+else:
+
+    def byte_string(s):
+        return s.encode("charmap")
+
+
 # A marker object to observe whether some optional arguments are passed any
 # value or not.
 UNSPECIFIED = object()
@@ -141,7 +149,10 @@
         warnings.warn(
             _TEXT_WARNING.format(label),
             category=DeprecationWarning,
-            stacklevel=3
+            stacklevel=3,
         )
-        return obj.encode('utf-8')
+        return obj.encode("utf-8")
     return obj
+
+
+from_buffer = ffi.from_buffer
diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py
index 12e92df..4265525 100644
--- a/src/OpenSSL/crypto.py
+++ b/src/OpenSSL/crypto.py
@@ -1,3 +1,4 @@
+import calendar
 import datetime
 
 from base64 import b16encode
@@ -7,11 +8,11 @@
 from six import (
     integer_types as _integer_types,
     text_type as _text_type,
-    PY3 as _PY3)
+    PY2 as _PY2,
+)
 
-from cryptography import x509
+from cryptography import utils, x509
 from cryptography.hazmat.primitives.asymmetric import dsa, rsa
-from cryptography.utils import deprecated
 
 from OpenSSL._util import (
     ffi as _ffi,
@@ -19,48 +20,49 @@
     exception_from_error_queue as _exception_from_error_queue,
     byte_string as _byte_string,
     native as _native,
+    path_string as _path_string,
     UNSPECIFIED as _UNSPECIFIED,
     text_to_bytes_and_warn as _text_to_bytes_and_warn,
     make_assert as _make_assert,
 )
 
 __all__ = [
-    'FILETYPE_PEM',
-    'FILETYPE_ASN1',
-    'FILETYPE_TEXT',
-    'TYPE_RSA',
-    'TYPE_DSA',
-    'Error',
-    'PKey',
-    'get_elliptic_curves',
-    'get_elliptic_curve',
-    'X509Name',
-    'X509Extension',
-    'X509Req',
-    'X509',
-    'X509StoreFlags',
-    'X509Store',
-    'X509StoreContextError',
-    'X509StoreContext',
-    'load_certificate',
-    'dump_certificate',
-    'dump_publickey',
-    'dump_privatekey',
-    'Revoked',
-    'CRL',
-    'PKCS7',
-    'PKCS12',
-    'NetscapeSPKI',
-    'load_publickey',
-    'load_privatekey',
-    'dump_certificate_request',
-    'load_certificate_request',
-    'sign',
-    'verify',
-    'dump_crl',
-    'load_crl',
-    'load_pkcs7_data',
-    'load_pkcs12'
+    "FILETYPE_PEM",
+    "FILETYPE_ASN1",
+    "FILETYPE_TEXT",
+    "TYPE_RSA",
+    "TYPE_DSA",
+    "Error",
+    "PKey",
+    "get_elliptic_curves",
+    "get_elliptic_curve",
+    "X509Name",
+    "X509Extension",
+    "X509Req",
+    "X509",
+    "X509StoreFlags",
+    "X509Store",
+    "X509StoreContextError",
+    "X509StoreContext",
+    "load_certificate",
+    "dump_certificate",
+    "dump_publickey",
+    "dump_privatekey",
+    "Revoked",
+    "CRL",
+    "PKCS7",
+    "PKCS12",
+    "NetscapeSPKI",
+    "load_publickey",
+    "load_privatekey",
+    "dump_certificate_request",
+    "load_certificate_request",
+    "sign",
+    "verify",
+    "dump_crl",
+    "load_crl",
+    "load_pkcs7_data",
+    "load_pkcs12",
 ]
 
 FILETYPE_PEM = _lib.SSL_FILETYPE_PEM
@@ -94,6 +96,7 @@
     triggering this side effect unless _get_backend is called.
     """
     from cryptography.hazmat.backends.openssl.backend import backend
+
     return backend
 
 
@@ -136,7 +139,7 @@
     """
     Copy the contents of an OpenSSL BIO object into a Python byte string.
     """
-    result_buffer = _ffi.new('char**')
+    result_buffer = _ffi.new("char**")
     buffer_length = _lib.BIO_get_mem_data(bio, result_buffer)
     return _ffi.buffer(result_buffer[0], buffer_length)[:]
 
@@ -173,7 +176,7 @@
     @return: The time value from C{timestamp} as a L{bytes} string in a certain
         format.  Or C{None} if the object contains no time value.
     """
-    string_timestamp = _ffi.cast('ASN1_STRING*', timestamp)
+    string_timestamp = _ffi.cast("ASN1_STRING*", timestamp)
     if _lib.ASN1_STRING_length(string_timestamp) == 0:
         return None
     elif (
@@ -196,7 +199,8 @@
             _untested_error("ASN1_TIME_to_generalizedtime")
         else:
             string_timestamp = _ffi.cast(
-                "ASN1_STRING*", generalized_timestamp[0])
+                "ASN1_STRING*", generalized_timestamp[0]
+            )
             string_data = _lib.ASN1_STRING_data(string_timestamp)
             string_result = _ffi.string(string_data)
             _lib.ASN1_GENERALIZEDTIME_free(generalized_timestamp[0])
@@ -220,6 +224,7 @@
     """
     A class representing an DSA or RSA public key or key pair.
     """
+
     _only_public = False
     _initialized = True
 
@@ -258,8 +263,15 @@
         .. versionadded:: 16.1.0
         """
         pkey = cls()
-        if not isinstance(crypto_key, (rsa.RSAPublicKey, rsa.RSAPrivateKey,
-                                       dsa.DSAPublicKey, dsa.DSAPrivateKey)):
+        if not isinstance(
+            crypto_key,
+            (
+                rsa.RSAPublicKey,
+                rsa.RSAPrivateKey,
+                dsa.DSAPublicKey,
+                dsa.DSAPrivateKey,
+            ),
+        ):
             raise TypeError("Unsupported key type")
 
         pkey._pkey = crypto_key._evp_pkey
@@ -346,7 +358,7 @@
         rsa = _lib.EVP_PKEY_get1_RSA(self._pkey)
         rsa = _ffi.gc(rsa, _lib.RSA_free)
         result = _lib.RSA_check_key(rsa)
-        if result:
+        if result == 1:
             return True
         _raise_current_error()
 
@@ -367,13 +379,6 @@
         return _lib.EVP_PKEY_bits(self._pkey)
 
 
-PKeyType = deprecated(
-    PKey, __name__,
-    "PKeyType has been deprecated, use PKey instead",
-    DeprecationWarning
-)
-
-
 class _EllipticCurve(object):
     """
     A representation of a supported elliptic curve.
@@ -383,10 +388,11 @@
         instances each of which represents one curve supported by the system.
     @type _curves: :py:type:`NoneType` or :py:type:`set`
     """
+
     _curves = None
 
-    if _PY3:
-        # This only necessary on Python 3.  Morever, it is broken on Python 2.
+    if not _PY2:
+        # This only necessary on Python 3.  Moreover, it is broken on Python 2.
         def __ne__(self, other):
             """
             Implement cooperation with the right-hand side argument of ``!=``.
@@ -409,14 +415,12 @@
             elliptic curves the underlying library supports.
         """
         num_curves = lib.EC_get_builtin_curves(_ffi.NULL, 0)
-        builtin_curves = _ffi.new('EC_builtin_curve[]', num_curves)
+        builtin_curves = _ffi.new("EC_builtin_curve[]", num_curves)
         # The return value on this call should be num_curves again.  We
         # could check it to make sure but if it *isn't* then.. what could
         # we do? Abort the whole process, I suppose...?  -exarkun
         lib.EC_get_builtin_curves(builtin_curves, num_curves)
-        return set(
-            cls.from_nid(lib, c.nid)
-            for c in builtin_curves)
+        return set(cls.from_nid(lib, c.nid) for c in builtin_curves)
 
     @classmethod
     def _get_elliptic_curves(cls, lib):
@@ -549,14 +553,16 @@
         self._name = _ffi.gc(name, _lib.X509_NAME_free)
 
     def __setattr__(self, name, value):
-        if name.startswith('_'):
+        if name.startswith("_"):
             return super(X509Name, self).__setattr__(name, value)
 
         # Note: we really do not want str subclasses here, so we do not use
         # isinstance.
         if type(name) is not str:
-            raise TypeError("attribute name must be string, not '%.200s'" % (
-                type(value).__name__,))
+            raise TypeError(
+                "attribute name must be string, not '%.200s'"
+                % (type(value).__name__,)
+            )
 
         nid = _lib.OBJ_txt2nid(_byte_string(name))
         if nid == _lib.NID_undef:
@@ -577,10 +583,11 @@
                 break
 
         if isinstance(value, _text_type):
-            value = value.encode('utf-8')
+            value = value.encode("utf-8")
 
         add_result = _lib.X509_NAME_add_entry_by_NID(
-            self._name, nid, _lib.MBSTRING_UTF8, value, -1, -1, 0)
+            self._name, nid, _lib.MBSTRING_UTF8, value, -1, -1, 0
+        )
         if not add_result:
             _raise_current_error()
 
@@ -616,9 +623,9 @@
         _openssl_assert(data_length >= 0)
 
         try:
-            result = _ffi.buffer(
-                result_buffer[0], data_length
-            )[:].decode('utf-8')
+            result = _ffi.buffer(result_buffer[0], data_length)[:].decode(
+                "utf-8"
+            )
         finally:
             # XXX untested
             _lib.OPENSSL_free(result_buffer[0])
@@ -630,6 +637,7 @@
                 return NotImplemented
             result = _lib.X509_NAME_cmp(self._name, other._name)
             return op(result, 0)
+
         return f
 
     __eq__ = _cmp(__eq__)
@@ -647,11 +655,13 @@
         """
         result_buffer = _ffi.new("char[]", 512)
         format_result = _lib.X509_NAME_oneline(
-            self._name, result_buffer, len(result_buffer))
+            self._name, result_buffer, len(result_buffer)
+        )
         _openssl_assert(format_result != _ffi.NULL)
 
         return "<X509Name object '%s'>" % (
-            _native(_ffi.string(result_buffer)),)
+            _native(_ffi.string(result_buffer)),
+        )
 
     def hash(self):
         """
@@ -672,7 +682,7 @@
         :return: The DER encoded form of this name.
         :rtype: :py:class:`bytes`
         """
-        result_buffer = _ffi.new('unsigned char**')
+        result_buffer = _ffi.new("unsigned char**")
         encode_result = _lib.i2d_X509_NAME(self._name, result_buffer)
         _openssl_assert(encode_result >= 0)
 
@@ -699,20 +709,14 @@
 
             # ffi.string does not handle strings containing NULL bytes
             # (which may have been generated by old, broken software)
-            value = _ffi.buffer(_lib.ASN1_STRING_data(fval),
-                                _lib.ASN1_STRING_length(fval))[:]
+            value = _ffi.buffer(
+                _lib.ASN1_STRING_data(fval), _lib.ASN1_STRING_length(fval)
+            )[:]
             result.append((_ffi.string(name), value))
 
         return result
 
 
-X509NameType = deprecated(
-    X509Name, __name__,
-    "X509NameType has been deprecated, use X509Name instead",
-    DeprecationWarning
-)
-
-
 class X509Extension(object):
     """
     An X.509 v3 certificate extension.
@@ -808,7 +812,8 @@
                 parts.append(_native(_bio_to_string(bio)))
             else:
                 value = _native(
-                    _ffi.buffer(name.d.ia5.data, name.d.ia5.length)[:])
+                    _ffi.buffer(name.d.ia5.data, name.d.ia5.length)[:]
+                )
                 parts.append(label + ":" + value)
         return ", ".join(parts)
 
@@ -858,19 +863,12 @@
         .. versionadded:: 0.12
         """
         octet_result = _lib.X509_EXTENSION_get_data(self._extension)
-        string_result = _ffi.cast('ASN1_STRING*', octet_result)
+        string_result = _ffi.cast("ASN1_STRING*", octet_result)
         char_result = _lib.ASN1_STRING_data(string_result)
         result_length = _lib.ASN1_STRING_length(string_result)
         return _ffi.buffer(char_result, result_length)[:]
 
 
-X509ExtensionType = deprecated(
-    X509Extension, __name__,
-    "X509ExtensionType has been deprecated, use X509Extension instead",
-    DeprecationWarning
-)
-
-
 class X509Req(object):
     """
     An X.509 certificate signing requests.
@@ -891,8 +889,9 @@
         .. versionadded:: 17.1.0
         """
         from cryptography.hazmat.backends.openssl.x509 import (
-            _CertificateSigningRequest
+            _CertificateSigningRequest,
         )
+
         backend = _get_backend()
         return _CertificateSigningRequest(backend, self._req)
 
@@ -1018,9 +1017,20 @@
         """
         exts = []
         native_exts_obj = _lib.X509_REQ_get_extensions(self._req)
+        native_exts_obj = _ffi.gc(
+            native_exts_obj,
+            lambda x: _lib.sk_X509_EXTENSION_pop_free(
+                x,
+                _ffi.addressof(_lib._original_lib, "X509_EXTENSION_free"),
+            ),
+        )
+
         for i in range(_lib.sk_X509_EXTENSION_num(native_exts_obj)):
             ext = X509Extension.__new__(X509Extension)
-            ext._extension = _lib.sk_X509_EXTENSION_value(native_exts_obj, i)
+            extension = _lib.X509_EXTENSION_dup(
+                _lib.sk_X509_EXTENSION_value(native_exts_obj, i)
+            )
+            ext._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free)
             exts.append(ext)
         return exts
 
@@ -1070,17 +1080,11 @@
         return result
 
 
-X509ReqType = deprecated(
-    X509Req, __name__,
-    "X509ReqType has been deprecated, use X509Req instead",
-    DeprecationWarning
-)
-
-
 class X509(object):
     """
     An X.509 certificate.
     """
+
     def __init__(self):
         x509 = _lib.X509_new()
         _openssl_assert(x509 != _ffi.NULL)
@@ -1106,6 +1110,7 @@
         .. versionadded:: 17.1.0
         """
         from cryptography.hazmat.backends.openssl.x509 import _Certificate
+
         backend = _get_backend()
         return _Certificate(backend, self._x509)
 
@@ -1247,12 +1252,16 @@
         result_length[0] = len(result_buffer)
 
         digest_result = _lib.X509_digest(
-            self._x509, digest, result_buffer, result_length)
+            self._x509, digest, result_buffer, result_length
+        )
         _openssl_assert(digest_result == 1)
 
-        return b":".join([
-            b16encode(ch).upper() for ch
-            in _ffi.buffer(result_buffer, result_length[0])])
+        return b":".join(
+            [
+                b16encode(ch).upper()
+                for ch in _ffi.buffer(result_buffer, result_length[0])
+            ]
+        )
 
     def subject_name_hash(self):
         """
@@ -1277,7 +1286,7 @@
 
         hex_serial = hex(serial)[2:]
         if not isinstance(hex_serial, bytes):
-            hex_serial = hex_serial.encode('ascii')
+            hex_serial = hex_serial.encode("ascii")
 
         bignum_serial = _ffi.new("BIGNUM**")
 
@@ -1288,7 +1297,8 @@
 
         if bignum_serial[0] == _ffi.NULL:
             set_result = _lib.ASN1_INTEGER_set(
-                _lib.X509_get_serialNumber(self._x509), small_serial)
+                _lib.X509_get_serialNumber(self._x509), small_serial
+            )
             if set_result:
                 # TODO Not tested
                 _raise_current_error()
@@ -1333,7 +1343,7 @@
         if not isinstance(amount, int):
             raise TypeError("amount must be an integer")
 
-        notAfter = _lib.X509_get_notAfter(self._x509)
+        notAfter = _lib.X509_getm_notAfter(self._x509)
         _lib.X509_gmtime_adj(notAfter, amount)
 
     def gmtime_adj_notBefore(self, amount):
@@ -1346,7 +1356,7 @@
         if not isinstance(amount, int):
             raise TypeError("amount must be an integer")
 
-        notBefore = _lib.X509_get_notBefore(self._x509)
+        notBefore = _lib.X509_getm_notBefore(self._x509)
         _lib.X509_gmtime_adj(notBefore, amount)
 
     def has_expired(self):
@@ -1375,7 +1385,7 @@
         :return: A timestamp string, or ``None`` if there is none.
         :rtype: bytes or NoneType
         """
-        return self._get_boundary_time(_lib.X509_get_notBefore)
+        return self._get_boundary_time(_lib.X509_getm_notBefore)
 
     def _set_boundary_time(self, which, when):
         return _set_asn1_time(which(self._x509), when)
@@ -1391,7 +1401,7 @@
         :param bytes when: A timestamp string.
         :return: ``None``
         """
-        return self._set_boundary_time(_lib.X509_get_notBefore, when)
+        return self._set_boundary_time(_lib.X509_getm_notBefore, when)
 
     def get_notAfter(self):
         """
@@ -1404,7 +1414,7 @@
         :return: A timestamp string, or ``None`` if there is none.
         :rtype: bytes or NoneType
         """
-        return self._get_boundary_time(_lib.X509_get_notAfter)
+        return self._get_boundary_time(_lib.X509_getm_notAfter)
 
     def set_notAfter(self, when):
         """
@@ -1417,7 +1427,7 @@
         :param bytes when: A timestamp string.
         :return: ``None``
         """
-        return self._set_boundary_time(_lib.X509_get_notAfter, when)
+        return self._set_boundary_time(_lib.X509_getm_notAfter, when)
 
     def _get_name(self, which):
         name = X509Name.__new__(X509Name)
@@ -1543,13 +1553,6 @@
         return ext
 
 
-X509Type = deprecated(
-    X509, __name__,
-    "X509Type has been deprecated, use X509 instead",
-    DeprecationWarning
-)
-
-
 class X509StoreFlags(object):
     """
     Flags for X509 verification, used to change the behavior of
@@ -1560,6 +1563,7 @@
     .. _OpenSSL Verification Flags:
         https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_flags.html
     """
+
     CRL_CHECK = _lib.X509_V_FLAG_CRL_CHECK
     CRL_CHECK_ALL = _lib.X509_V_FLAG_CRL_CHECK_ALL
     IGNORE_CRITICAL = _lib.X509_V_FLAG_IGNORE_CRITICAL
@@ -1610,16 +1614,8 @@
         if not isinstance(cert, X509):
             raise TypeError()
 
-        # As of OpenSSL 1.1.0i adding the same cert to the store more than
-        # once doesn't cause an error. Accordingly, this code now silences
-        # the error for OpenSSL < 1.1.0i as well.
-        if _lib.X509_STORE_add_cert(self._store, cert._x509) == 0:
-            code = _lib.ERR_peek_error()
-            err_reason = _lib.ERR_GET_REASON(code)
-            _openssl_assert(
-                err_reason == _lib.X509_R_CERT_ALREADY_IN_HASH_TABLE
-            )
-            _lib.ERR_clear_error()
+        res = _lib.X509_STORE_add_cert(self._store, cert._x509)
+        _openssl_assert(res == 1)
 
     def add_crl(self, crl):
         """
@@ -1680,15 +1676,57 @@
         param = _lib.X509_VERIFY_PARAM_new()
         param = _ffi.gc(param, _lib.X509_VERIFY_PARAM_free)
 
-        _lib.X509_VERIFY_PARAM_set_time(param, int(vfy_time.strftime('%s')))
+        _lib.X509_VERIFY_PARAM_set_time(
+            param, calendar.timegm(vfy_time.timetuple())
+        )
         _openssl_assert(_lib.X509_STORE_set1_param(self._store, param) != 0)
 
+    def load_locations(self, cafile, capath=None):
+        """
+        Let X509Store know where we can find trusted certificates for the
+        certificate chain.  Note that the certificates have to be in PEM
+        format.
 
-X509StoreType = deprecated(
-    X509Store, __name__,
-    "X509StoreType has been deprecated, use X509Store instead",
-    DeprecationWarning
-)
+        If *capath* is passed, it must be a directory prepared using the
+        ``c_rehash`` tool included with OpenSSL.  Either, but not both, of
+        *cafile* or *capath* may be ``None``.
+
+        .. note::
+
+          Both *cafile* and *capath* may be set simultaneously.
+
+          Call this method multiple times to add more than one location.
+          For example, CA certificates, and certificate revocation list bundles
+          may be passed in *cafile* in subsequent calls to this method.
+
+        .. versionadded:: 20.0
+
+        :param cafile: In which file we can find the certificates (``bytes`` or
+                       ``unicode``).
+        :param capath: In which directory we can find the certificates
+                       (``bytes`` or ``unicode``).
+
+        :return: ``None`` if the locations were set successfully.
+
+        :raises OpenSSL.crypto.Error: If both *cafile* and *capath* is ``None``
+            or the locations could not be set for any reason.
+
+        """
+        if cafile is None:
+            cafile = _ffi.NULL
+        else:
+            cafile = _path_string(cafile)
+
+        if capath is None:
+            capath = _ffi.NULL
+        else:
+            capath = _path_string(capath)
+
+        load_result = _lib.X509_STORE_load_locations(
+            self._store, cafile, capath
+        )
+        if not load_result:
+            _raise_current_error()
 
 
 class X509StoreContextError(Exception):
@@ -1718,21 +1756,54 @@
         collected.
     :ivar _store: See the ``store`` ``__init__`` parameter.
     :ivar _cert: See the ``certificate`` ``__init__`` parameter.
+    :ivar _chain: See the ``chain`` ``__init__`` parameter.
     :param X509Store store: The certificates which will be trusted for the
         purposes of any verifications.
     :param X509 certificate: The certificate to be verified.
+    :param chain: List of untrusted certificates that may be used for building
+        the certificate chain. May be ``None``.
+    :type chain: :class:`list` of :class:`X509`
     """
 
-    def __init__(self, store, certificate):
+    def __init__(self, store, certificate, chain=None):
         store_ctx = _lib.X509_STORE_CTX_new()
         self._store_ctx = _ffi.gc(store_ctx, _lib.X509_STORE_CTX_free)
         self._store = store
         self._cert = certificate
+        self._chain = self._build_certificate_stack(chain)
         # Make the store context available for use after instantiating this
         # class by initializing it now. Per testing, subsequent calls to
         # :meth:`_init` have no adverse affect.
         self._init()
 
+    @staticmethod
+    def _build_certificate_stack(certificates):
+        def cleanup(s):
+            # Equivalent to sk_X509_pop_free, but we don't
+            # currently have a CFFI binding for that available
+            for i in range(_lib.sk_X509_num(s)):
+                x = _lib.sk_X509_value(s, i)
+                _lib.X509_free(x)
+            _lib.sk_X509_free(s)
+
+        if certificates is None or len(certificates) == 0:
+            return _ffi.NULL
+
+        stack = _lib.sk_X509_new_null()
+        _openssl_assert(stack != _ffi.NULL)
+        stack = _ffi.gc(stack, cleanup)
+
+        for cert in certificates:
+            if not isinstance(cert, X509):
+                raise TypeError("One of the elements is not an X509 instance")
+
+            _openssl_assert(_lib.X509_up_ref(cert._x509) > 0)
+            if _lib.sk_X509_push(stack, cert._x509) <= 0:
+                _lib.X509_free(cert._x509)
+                _raise_current_error()
+
+        return stack
+
     def _init(self):
         """
         Set up the store context for a subsequent verification operation.
@@ -1741,7 +1812,7 @@
         :meth:`_cleanup` will leak memory.
         """
         ret = _lib.X509_STORE_CTX_init(
-            self._store_ctx, self._store._store, self._cert._x509, _ffi.NULL
+            self._store_ctx, self._store._store, self._cert._x509, self._chain
         )
         if ret <= 0:
             _raise_current_error()
@@ -1765,8 +1836,13 @@
         errors = [
             _lib.X509_STORE_CTX_get_error(self._store_ctx),
             _lib.X509_STORE_CTX_get_error_depth(self._store_ctx),
-            _native(_ffi.string(_lib.X509_verify_cert_error_string(
-                _lib.X509_STORE_CTX_get_error(self._store_ctx)))),
+            _native(
+                _ffi.string(
+                    _lib.X509_verify_cert_error_string(
+                        _lib.X509_STORE_CTX_get_error(self._store_ctx)
+                    )
+                )
+            ),
         ]
         # A context error should always be associated with a certificate, so we
         # expect this call to never return :class:`None`.
@@ -1808,6 +1884,45 @@
         if ret <= 0:
             raise self._exception_from_context()
 
+    def get_verified_chain(self):
+        """
+        Verify a certificate in a context and return the complete validated
+        chain.
+
+        :raises X509StoreContextError: If an error occurred when validating a
+          certificate in the context. Sets ``certificate`` attribute to
+          indicate which certificate caused the error.
+
+        .. versionadded:: 20.0
+        """
+        # Always re-initialize the store context in case
+        # :meth:`verify_certificate` is called multiple times.
+        #
+        # :meth:`_init` is called in :meth:`__init__` so _cleanup is called
+        # before _init to ensure memory is not leaked.
+        self._cleanup()
+        self._init()
+        ret = _lib.X509_verify_cert(self._store_ctx)
+        if ret <= 0:
+            self._cleanup()
+            raise self._exception_from_context()
+
+        # Note: X509_STORE_CTX_get1_chain returns a deep copy of the chain.
+        cert_stack = _lib.X509_STORE_CTX_get1_chain(self._store_ctx)
+        _openssl_assert(cert_stack != _ffi.NULL)
+
+        result = []
+        for i in range(_lib.sk_X509_num(cert_stack)):
+            cert = _lib.sk_X509_value(cert_stack, i)
+            _openssl_assert(cert != _ffi.NULL)
+            pycert = X509._from_raw_x509_ptr(cert)
+            result.append(pycert)
+
+        # Free the stack but not the members which are freed by the X509 class.
+        _lib.sk_X509_free(cert_stack)
+        self._cleanup()
+        return result
+
 
 def load_certificate(type, buffer):
     """
@@ -1830,8 +1945,7 @@
     elif type == FILETYPE_ASN1:
         x509 = _lib.d2i_X509_bio(bio, _ffi.NULL)
     else:
-        raise ValueError(
-            "type argument must be FILETYPE_PEM or FILETYPE_ASN1")
+        raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")
 
     if x509 == _ffi.NULL:
         _raise_current_error()
@@ -1860,9 +1974,10 @@
     else:
         raise ValueError(
             "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or "
-            "FILETYPE_TEXT")
+            "FILETYPE_TEXT"
+        )
 
-    assert result_code == 1
+    _openssl_assert(result_code == 1)
     return _bio_to_string(bio)
 
 
@@ -1916,7 +2031,8 @@
         if passphrase is None:
             raise TypeError(
                 "if a value is given for cipher "
-                "one must also be given for passphrase")
+                "one must also be given for passphrase"
+            )
         cipher_obj = _lib.EVP_get_cipherbyname(_byte_string(cipher))
         if cipher_obj == _ffi.NULL:
             raise ValueError("Invalid cipher name")
@@ -1926,8 +2042,14 @@
     helper = _PassphraseHelper(type, passphrase)
     if type == FILETYPE_PEM:
         result_code = _lib.PEM_write_bio_PrivateKey(
-            bio, pkey._pkey, cipher_obj, _ffi.NULL, 0,
-            helper.callback, helper.callback_args)
+            bio,
+            pkey._pkey,
+            cipher_obj,
+            _ffi.NULL,
+            0,
+            helper.callback,
+            helper.callback_args,
+        )
         helper.raise_if_problem()
     elif type == FILETYPE_ASN1:
         result_code = _lib.i2d_PrivateKey_bio(bio, pkey._pkey)
@@ -1935,15 +2057,13 @@
         if _lib.EVP_PKEY_id(pkey._pkey) != _lib.EVP_PKEY_RSA:
             raise TypeError("Only RSA keys are supported for FILETYPE_TEXT")
 
-        rsa = _ffi.gc(
-            _lib.EVP_PKEY_get1_RSA(pkey._pkey),
-            _lib.RSA_free
-        )
+        rsa = _ffi.gc(_lib.EVP_PKEY_get1_RSA(pkey._pkey), _lib.RSA_free)
         result_code = _lib.RSA_print(bio, rsa, 0)
     else:
         raise ValueError(
             "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or "
-            "FILETYPE_TEXT")
+            "FILETYPE_TEXT"
+        )
 
     _openssl_assert(result_code != 0)
 
@@ -1954,6 +2074,7 @@
     """
     A certificate revocation.
     """
+
     # https://www.openssl.org/docs/manmaster/man5/x509v3_config.html#CRL-distribution-points
     # which differs from crl_reasons of crypto/x509v3/v3_enum.c that matches
     # OCSP_crl_reason_str.  We use the latter, just like the command line
@@ -1993,7 +2114,8 @@
 
         asn1_serial = _ffi.gc(
             _lib.BN_to_ASN1_INTEGER(bignum_serial, _ffi.NULL),
-            _lib.ASN1_INTEGER_free)
+            _lib.ASN1_INTEGER_free,
+        )
         _lib.X509_REVOKED_set_serialNumber(self._revoked, asn1_serial)
 
     def get_serial(self):
@@ -2044,7 +2166,7 @@
         elif not isinstance(reason, bytes):
             raise TypeError("reason must be None or a byte string")
         else:
-            reason = reason.lower().replace(b' ', b'')
+            reason = reason.lower().replace(b" ", b"")
             reason_code = [r.lower() for r in self._crl_reasons].index(reason)
 
             new_reason_ext = _lib.ASN1_ENUMERATED_new()
@@ -2056,7 +2178,8 @@
 
             self._delete_reason()
             add_result = _lib.X509_REVOKED_add1_ext_i2d(
-                self._revoked, _lib.NID_crl_reason, new_reason_ext, 0, 0)
+                self._revoked, _lib.NID_crl_reason, new_reason_ext, 0, 0
+            )
             _openssl_assert(add_result == 1)
 
     def get_reason(self):
@@ -2138,8 +2261,9 @@
         .. versionadded:: 17.1.0
         """
         from cryptography.hazmat.backends.openssl.x509 import (
-            _CertificateRevocationList
+            _CertificateRevocationList,
         )
+
         backend = _get_backend()
         return _CertificateRevocationList(backend, self._crl)
 
@@ -2246,7 +2370,7 @@
 
     def set_nextUpdate(self, when):
         """
-        Set when the CRL will next be udpated.
+        Set when the CRL will next be updated.
 
         The timestamp is formatted as an ASN.1 TIME::
 
@@ -2279,13 +2403,15 @@
         digest_obj = _lib.EVP_get_digestbyname(digest)
         _openssl_assert(digest_obj != _ffi.NULL)
         _lib.X509_CRL_set_issuer_name(
-            self._crl, _lib.X509_get_subject_name(issuer_cert._x509))
+            self._crl, _lib.X509_get_subject_name(issuer_cert._x509)
+        )
         _lib.X509_CRL_sort(self._crl)
         result = _lib.X509_CRL_sign(self._crl, issuer_key._pkey, digest_obj)
         _openssl_assert(result != 0)
 
-    def export(self, cert, key, type=FILETYPE_PEM, days=100,
-               digest=_UNSPECIFIED):
+    def export(
+        self, cert, key, type=FILETYPE_PEM, days=100, digest=_UNSPECIFIED
+    ):
         """
         Export the CRL as a string.
 
@@ -2295,7 +2421,7 @@
             :data:`FILETYPE_ASN1`, or :data:`FILETYPE_TEXT`.
         :param int days: The number of days until the next update of this CRL.
         :param bytes digest: The name of the message digest to use (eg
-            ``b"sha2566"``).
+            ``b"sha256"``).
         :rtype: bytes
         """
 
@@ -2338,13 +2464,6 @@
         return dump_crl(type, self)
 
 
-CRLType = deprecated(
-    CRL, __name__,
-    "CRLType has been deprecated, use CRL instead",
-    DeprecationWarning
-)
-
-
 class PKCS7(object):
     def type_is_signed(self):
         """
@@ -2389,13 +2508,6 @@
         return _ffi.string(string_type)
 
 
-PKCS7Type = deprecated(
-    PKCS7, __name__,
-    "PKCS7Type has been deprecated, use PKCS7 instead",
-    DeprecationWarning
-)
-
-
 class PKCS12(object):
     """
     A PKCS #12 archive.
@@ -2557,10 +2669,17 @@
             cert = self._cert._x509
 
         pkcs12 = _lib.PKCS12_create(
-            passphrase, friendlyname, pkey, cert, cacerts,
+            passphrase,
+            friendlyname,
+            pkey,
+            cert,
+            cacerts,
             _lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
             _lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
-            iter, maciter, 0)
+            iter,
+            maciter,
+            0,
+        )
         if pkcs12 == _ffi.NULL:
             _raise_current_error()
         pkcs12 = _ffi.gc(pkcs12, _lib.PKCS12_free)
@@ -2570,13 +2689,6 @@
         return _bio_to_string(bio)
 
 
-PKCS12Type = deprecated(
-    PKCS12, __name__,
-    "PKCS12Type has been deprecated, use PKCS12 instead",
-    DeprecationWarning
-)
-
-
 class NetscapeSPKI(object):
     """
     A Netscape SPKI object.
@@ -2667,13 +2779,6 @@
         _openssl_assert(set_result == 1)
 
 
-NetscapeSPKIType = deprecated(
-    NetscapeSPKI, __name__,
-    "NetscapeSPKIType has been deprecated, use NetscapeSPKI instead",
-    DeprecationWarning
-)
-
-
 class _PassphraseHelper(object):
     def __init__(self, type, passphrase, more_args=False, truncate=False):
         if type != FILETYPE_PEM and passphrase is not None:
@@ -2689,9 +2794,7 @@
     def callback(self):
         if self._passphrase is None:
             return _ffi.NULL
-        elif isinstance(self._passphrase, bytes):
-            return _ffi.NULL
-        elif callable(self._passphrase):
+        elif isinstance(self._passphrase, bytes) or callable(self._passphrase):
             return _ffi.callback("pem_password_cb", self._read_passphrase)
         else:
             raise TypeError(
@@ -2702,9 +2805,7 @@
     def callback_args(self):
         if self._passphrase is None:
             return _ffi.NULL
-        elif isinstance(self._passphrase, bytes):
-            return self._passphrase
-        elif callable(self._passphrase):
+        elif isinstance(self._passphrase, bytes) or callable(self._passphrase):
             return _ffi.NULL
         else:
             raise TypeError(
@@ -2724,12 +2825,15 @@
 
     def _read_passphrase(self, buf, size, rwflag, userdata):
         try:
-            if self._more_args:
-                result = self._passphrase(size, rwflag, userdata)
+            if callable(self._passphrase):
+                if self._more_args:
+                    result = self._passphrase(size, rwflag, userdata)
+                else:
+                    result = self._passphrase(rwflag)
             else:
-                result = self._passphrase(rwflag)
+                result = self._passphrase
             if not isinstance(result, bytes):
-                raise ValueError("String expected")
+                raise ValueError("Bytes expected")
             if len(result) > size:
                 if self._truncate:
                     result = result[:size]
@@ -2738,7 +2842,7 @@
                         "passphrase returned by callback is too long"
                     )
             for i in range(len(result)):
-                buf[i] = result[i:i + 1]
+                buf[i] = result[i : i + 1]
             return len(result)
         except Exception as e:
             self._problems.append(e)
@@ -2763,7 +2867,8 @@
 
     if type == FILETYPE_PEM:
         evp_pkey = _lib.PEM_read_bio_PUBKEY(
-            bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
+            bio, _ffi.NULL, _ffi.NULL, _ffi.NULL
+        )
     elif type == FILETYPE_ASN1:
         evp_pkey = _lib.d2i_PUBKEY_bio(bio, _ffi.NULL)
     else:
@@ -2799,7 +2904,8 @@
     helper = _PassphraseHelper(type, passphrase)
     if type == FILETYPE_PEM:
         evp_pkey = _lib.PEM_read_bio_PrivateKey(
-            bio, _ffi.NULL, helper.callback, helper.callback_args)
+            bio, _ffi.NULL, helper.callback, helper.callback_args
+        )
         helper.raise_if_problem()
     elif type == FILETYPE_ASN1:
         evp_pkey = _lib.d2i_PrivateKey_bio(bio, _ffi.NULL)
@@ -2898,7 +3004,8 @@
     signature_buffer = _ffi.new("unsigned char[]", length)
     signature_length = _ffi.new("unsigned int *")
     final_result = _lib.EVP_SignFinal(
-        md_ctx, signature_buffer, signature_length, pkey._pkey)
+        md_ctx, signature_buffer, signature_length, pkey._pkey
+    )
     _openssl_assert(final_result == 1)
 
     return _ffi.buffer(signature_buffer, signature_length[0])[:]
@@ -2962,9 +3069,10 @@
     else:
         raise ValueError(
             "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or "
-            "FILETYPE_TEXT")
+            "FILETYPE_TEXT"
+        )
 
-    assert ret == 1
+    _openssl_assert(ret == 1)
     return _bio_to_string(bio)
 
 
@@ -3027,6 +3135,17 @@
     return pypkcs7
 
 
+load_pkcs7_data = utils.deprecated(
+    load_pkcs7_data,
+    __name__,
+    (
+        "PKCS#7 support in pyOpenSSL is deprecated. You should use the APIs "
+        "in cryptography."
+    ),
+    DeprecationWarning,
+)
+
+
 def load_pkcs12(buffer, passphrase=None):
     """
     Load pkcs12 data from the string *buffer*. If the pkcs12 structure is
@@ -3114,6 +3233,17 @@
     return pkcs12
 
 
+load_pkcs12 = utils.deprecated(
+    load_pkcs12,
+    __name__,
+    (
+        "PKCS#12 support in pyOpenSSL is deprecated. You should use the APIs "
+        "in cryptography."
+    ),
+    DeprecationWarning,
+)
+
+
 # There are no direct unit tests for this initialization.  It is tested
 # indirectly since it is necessary for functions like dump_privatekey when
 # using encryption.
@@ -3132,4 +3262,4 @@
 
 # Set the default string mask to match OpenSSL upstream (since 2005) and
 # RFC5280 recommendations.
-_lib.ASN1_STRING_set_default_mask_asc(b'utf8only')
+_lib.ASN1_STRING_set_default_mask_asc(b"utf8only")
diff --git a/src/OpenSSL/debug.py b/src/OpenSSL/debug.py
index 0d37bf5..04521d5 100644
--- a/src/OpenSSL/debug.py
+++ b/src/OpenSSL/debug.py
@@ -16,7 +16,7 @@
 cffi: {cffi}
 cryptography's compiled against OpenSSL: {crypto_openssl_compile}
 cryptography's linked OpenSSL: {crypto_openssl_link}
-Pythons's OpenSSL: {python_openssl}
+Python's OpenSSL: {python_openssl}
 Python executable: {python}
 Python version: {python_version}
 Platform: {platform}
diff --git a/src/OpenSSL/tsafe.py b/src/OpenSSL/tsafe.py
deleted file mode 100644
index f1c6f67..0000000
--- a/src/OpenSSL/tsafe.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import warnings
-from threading import RLock as _RLock
-
-from OpenSSL import SSL as _ssl
-
-
-warnings.warn(
-    "OpenSSL.tsafe is deprecated and will be removed",
-    DeprecationWarning, stacklevel=3
-)
-
-
-class Connection:
-    def __init__(self, *args):
-        self._ssl_conn = _ssl.Connection(*args)
-        self._lock = _RLock()
-
-    for f in ('get_context', 'pending', 'send', 'write', 'recv', 'read',
-              'renegotiate', 'bind', 'listen', 'connect', 'accept',
-              'setblocking', 'fileno', 'shutdown', 'close', 'get_cipher_list',
-              'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
-              'makefile', 'get_app_data', 'set_app_data', 'state_string',
-              'sock_shutdown', 'get_peer_certificate', 'get_peer_cert_chain',
-              'want_read', 'want_write', 'set_connect_state',
-              'set_accept_state', 'connect_ex', 'sendall'):
-        exec("""def %s(self, *args):
-            self._lock.acquire()
-            try:
-                return self._ssl_conn.%s(*args)
-            finally:
-                self._lock.release()\n""" % (f, f))
diff --git a/src/OpenSSL/version.py b/src/OpenSSL/version.py
index 40f31c3..9348867 100644
--- a/src/OpenSSL/version.py
+++ b/src/OpenSSL/version.py
@@ -7,11 +7,17 @@
 """
 
 __all__ = [
-    "__author__", "__copyright__", "__email__", "__license__", "__summary__",
-    "__title__", "__uri__", "__version__",
+    "__author__",
+    "__copyright__",
+    "__email__",
+    "__license__",
+    "__summary__",
+    "__title__",
+    "__uri__",
+    "__version__",
 ]
 
-__version__ = "19.0.0"
+__version__ = "20.0.1"
 
 __title__ = "pyOpenSSL"
 __uri__ = "https://pyopenssl.org/"
@@ -19,4 +25,4 @@
 __author__ = "The pyOpenSSL developers"
 __email__ = "[email protected]"
 __license__ = "Apache License, Version 2.0"
-__copyright__ = "Copyright 2001-2017 {0}".format(__author__)
+__copyright__ = "Copyright 2001-2020 {0}".format(__author__)
diff --git a/tests/conftest.py b/tests/conftest.py
index 366624e..5bae6b8 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -12,7 +12,7 @@
 
     return "OpenSSL: {openssl}\ncryptography: {cryptography}".format(
         openssl=OpenSSL.SSL.SSLeay_version(OpenSSL.SSL.SSLEAY_VERSION),
-        cryptography=cryptography.__version__
+        cryptography=cryptography.__version__,
     )
 
 
diff --git a/tests/memdbg.py b/tests/memdbg.py
index 6e608a7..590b72d 100644
--- a/tests/memdbg.py
+++ b/tests/memdbg.py
@@ -5,8 +5,8 @@
 from cffi import api as _api
 
 
-sys.modules['ssl'] = None
-sys.modules['_hashlib'] = None
+sys.modules["ssl"] = None
+sys.modules["_hashlib"] = None
 
 
 _ffi = _api.FFI()
@@ -16,18 +16,22 @@
     void free(void *ptr);
     void *realloc(void *ptr, size_t size);
 
-    int  CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
+    int  CRYPTO_set_mem_functions(
+        void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
 
     int backtrace(void **buffer, int size);
     char **backtrace_symbols(void *const *buffer, int size);
     void backtrace_symbols_fd(void *const *buffer, int size, int fd);
-    """)  # noqa
+    """
+)  # noqa
 _api = _ffi.verify(
     """
     #include <openssl/crypto.h>
     #include <stdlib.h>
     #include <execinfo.h>
-    """, libraries=["crypto"])
+    """,
+    libraries=["crypto"],
+)
 C = _ffi.dlopen(None)
 
 verbose = False
@@ -80,8 +84,8 @@
 
 
 if _api.CRYPTO_set_mem_functions(malloc, realloc, free):
-    log('Enabled memory debugging')
+    log("Enabled memory debugging")
     heap = {}
 else:
-    log('Failed to enable memory debugging')
+    log("Failed to enable memory debugging")
     heap = None
diff --git a/tests/test_crypto.py b/tests/test_crypto.py
index c938021..265d31e 100644
--- a/tests/test_crypto.py
+++ b/tests/test_crypto.py
@@ -10,11 +10,10 @@
 import base64
 from subprocess import PIPE, Popen
 from datetime import datetime, timedelta
+import sys
 
 import pytest
 
-from six import binary_type
-
 from cryptography import x509
 from cryptography.hazmat.backends.openssl.backend import backend
 from cryptography.hazmat.primitives import serialization
@@ -22,30 +21,40 @@
 
 import flaky
 
-from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
-from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
+from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey
+from OpenSSL.crypto import X509, X509Name
 from OpenSSL.crypto import (
     X509Store,
     X509StoreFlags,
-    X509StoreType,
     X509StoreContext,
-    X509StoreContextError
+    X509StoreContextError,
 )
-from OpenSSL.crypto import X509Req, X509ReqType
-from OpenSSL.crypto import X509Extension, X509ExtensionType
+from OpenSSL.crypto import X509Req
+from OpenSSL.crypto import X509Extension
 from OpenSSL.crypto import load_certificate, load_privatekey
 from OpenSSL.crypto import load_publickey, dump_publickey
 from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
 from OpenSSL.crypto import dump_certificate, load_certificate_request
 from OpenSSL.crypto import dump_certificate_request, dump_privatekey
-from OpenSSL.crypto import PKCS7, PKCS7Type, load_pkcs7_data
-from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
+from OpenSSL.crypto import PKCS7, load_pkcs7_data
+from OpenSSL.crypto import PKCS12, load_pkcs12
 from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
-from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
+from OpenSSL.crypto import NetscapeSPKI
 from OpenSSL.crypto import (
-    sign, verify, get_elliptic_curve, get_elliptic_curves)
+    sign,
+    verify,
+    get_elliptic_curve,
+    get_elliptic_curves,
+)
 
-from .util import EqualityTestsMixin, is_consistent_type, WARNING_TYPE_EXPECTED
+from OpenSSL._util import ffi as _ffi, lib as _lib
+
+from .util import (
+    EqualityTestsMixin,
+    is_consistent_type,
+    WARNING_TYPE_EXPECTED,
+    NON_ASCII,
+)
 
 
 def normalize_privatekey_pem(pem):
@@ -79,213 +88,398 @@
 """
 
 root_cert_pem = b"""-----BEGIN CERTIFICATE-----
-MIIC6TCCAlKgAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
+MIIE7jCCA1agAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQELBQAwWDELMAkGA1UE
 BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
-ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTcwNjExMjIzMjU5
-WhcNMzcwNjA2MjIzMjU5WjBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMCSUwxEDAO
+ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMjAwODAyMTcxMTE5
+WhcNNDcxMjIwMTcxMTE5WjBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMCSUwxEDAO
 BgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMTD1Rlc3Rp
-bmcgUm9vdCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA+ZpC6Yu6ukTn
-bu5IQd0vWmpwNGZbO773xjpgfNP8nspYRqbIwI1np9FbUkJHvzZRDxrTt/LbFewr
-LhZ0prHIbwJxq3CZe+m9FDjh1IA0yKEcQukA1N3JWnoMLKwQPrCRAW6seUXV2yER
-onDxv/KkOGZtUijoKLXG8ImqK9ssWdsCAwEAAaOBuzCBuDAdBgNVHQ4EFgQUg1V3
-LV4h8UkMCSTnVAkSjch+BK4wgYgGA1UdIwSBgDB+gBSDVXctXiHxSQwJJOdUCRKN
-yH4ErqFcpFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdD
-aGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3Qg
-Q0GCCD0MxODG3rn0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEANFYQ
-R+T70VcZ+SnvURnwviFgCXeedBzCr21meo+DNHbkp2gudB9W8Xrned/wtUBVymy9
-gjB5jINfU7Lci0H57Evsw96UJJVfhXdUMHpqt1RGCoEd9FWnrDyrSy0NysnBT2bH
-lEqxh3aFEUx9IOQ4sgnx1/NOFXBpkRtivl6O0Ec=
+bmcgUm9vdCBDQTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALpY5jb+
+S7AUbx9gzN06wkqUeb+eNLTjCOKofiMTn8Y0TqCA2ZyY3XMcNBMaIS7hdFTgmmqt
+fFntYobxLAl/twfbz9AnRaVDh2HyUvHvMBxKn1HSDLALLtqdF0pcXIjP04S7NKPQ
+Umgkv2H0KwcUpYlgjTFtXRiP+7wDSiQeP1YVSriEoE0TXK14F8np6ZKK0oQ+u16d
+Wn3MGQwFzS+Ipgoz0jbi5D2KzmK2dzHdxY8M2Dktkz/W3DUfUwaTohYed2DG39LP
+NUFOxekgXdIZ3vQbDfsEQt27TUzOztbo/BqK7YkRLzzOQFz+dKAxH6Hy6Bu9op7e
+DWS9TfD/+UmDxr3IeoLMpmUBKxmzTC4qpej+W1UuCE12dMo4LoadlkG+/l1oABqd
+Ucf45WgaFk3xpyEuGnDxjs6rqYPoEapIichxN2fgN+jkgH9ed44r0yOoVeG2pmwD
+YFCCxzkmiuzLADlfM1LUzqUNKVFcOakD3iujHEalnDIJsc/znYsqaRvCkQIDAQAB
+o4G7MIG4MB0GA1UdDgQWBBSDVXctXiHxSQwJJOdUCRKNyH4ErjCBiAYDVR0jBIGA
+MH6AFINVdy1eIfFJDAkk51QJEo3IfgSuoVykWjBYMQswCQYDVQQGEwJVUzELMAkG
+A1UECBMCSUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAW
+BgNVBAMTD1Rlc3RpbmcgUm9vdCBDQYIIPQzE4MbeufQwDAYDVR0TBAUwAwEB/zAN
+BgkqhkiG9w0BAQsFAAOCAYEAFIMFxLHaVDY/nsbYzI7+zxe4GJeUqRIj2g4XK/nF
+6lHLRFL2YP5yJ+Jm4JDkoZqKq/tcEQLIssQS++s6tBSdvFwdY6imfpEZgFPuodrZ
+KbYm4Xuouw09EQCEjPxBOQ1NEcPuwuDtvD6/BOfm3SRFRTq/gQwxKlZ7C/4l8b1+
+OQPIUryqdlFBpyE/M95GzaNdmkQx41PevEih2nqWnbTsXLeiSXLGoubMTxKEK4T+
+J7Ci2KTRJ3SYMgTNU6MNcl7b9Tpw9/KVG80IbpzNQ1LDh3ZtkOfqoou1lmBTeNPu
+g2C/oiW6lVAmZx1TL9gbUtkJ0Q2iW4D9TF+zuYi2qpbVU3RvoqK25x3AuIWf4JOL
+3cTNjJ/3zmGSORRJvcGyvVnL30R+vwpaxvyuqMjz3kBjkK2Z2pvElZMJiZhbGG7k
+MHZQ5A26v0/iQVno6FRv3cQb9EeAZtNHcIEgsNhPZ53XVnwZ58ByvATMLKNN8dWF
+Q+8Bbr7QFxeWvQfHYX2yaQZ/
 -----END CERTIFICATE-----
 """
 
 root_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
-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
+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
 -----END RSA PRIVATE KEY-----
 """
 
+root_key_der = base64.b64decode(
+    """
+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'
+"""
+)
+
+normalized_root_key_pem = normalize_privatekey_pem(root_key_pem)
+
 intermediate_cert_pem = b"""-----BEGIN CERTIFICATE-----
-MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
+MIIEXDCCAsSgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQELBQAw
 WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
-DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
-ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
+DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMjAw
+ODAyMTcxMTIwWhcNNDcxMjIwMTcxMTIwWjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
 dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
-MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
-AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
-FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
-21H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
-AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
-QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
-9n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
-9mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
+MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIIBojANBgkqhkiG9w0B
+AQEFAAOCAY8AMIIBigKCAYEAo3rOxOVrdLdRsR1o0+JG7MRpCtMoafA63TM/DczL
+Q4jURv5MzyTE7FFdXq4xNJRYgD16vUavZluQGj30+5Lkt07CuO/BK3itl8UW+dsH
+p95gzBvgnj5AVZGkNOQ0Y4CbXO087Ywep7tpBfZ5fzURLeH+OHQGseEFZ5e0w8Az
+AarWu+Ez5RGpkaZ61iiJa53mAgkrjw+o83UrpDT2nrXiyR6Fx4K4eb1rarodWqGv
+jSkdT5MA4i0gDhsIBnTarPB+0KM8M7od8DkLsTHBt4rYYCHgCX1bWavzGlqPEw9h
+ksK+LAbQKD9J2AxYDkL0PAeUuvWMhxEmN6hXePiw63sJzukRunAvut5A2+42JMkW
+guDyqIvAjlCYcIyBvUbphP3qSFqww/hpZ2wh5UZOc1mzYJKR9MgI8/UhRJEJ7NyY
+pF24EJbisjNE30ot8aM2/5cI5KevclcuPJWH8PjT/i1VnNpM4S8MqoPw6F+d75d/
+CtfI+LLfns4k3G9I+Qgxmpa5AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQELBQADggGBAFVQ3Dmljrnbjys9ZIqcTs/B5ktKUAU2KNMO9TmoFymE
+YhHKbCb5u/CnWq3jtBW6jgkQHrhfY9leUlH87BkB2o16BcSKjHknHZ2MCdEvQvOM
+/nkkMDkOEoRn8mfCCxxgt8Kxf07wHDcnKoeJ3h9BXIl6nyJqJAcVWEJm1d75ayDG
+0Kr0z+LcqMtQqYI0csK/XDQkunlE95qti1HzxW+JeAf6nRkr7RNZLtGmUGAMfyBK
+9A0Db8QLR7O92YEmwoXtp+euN6uDdjw4A7KHjNXMdvqZoRfbZEA9c6XJTBj22h87
+gYUFRVpkNDrC/c9u6WgA943yMgFCwjrlTsmi+uoweT9U5r4TA+dVCDAv943aWCNm
+A+TiuIXlJAHl2PlH7Umu/oMQKDEt+0n4QcQLBZyK3CYU5kg+ms9vOvE19Lhp8HeS
+xqm6dwKpdm7/8EfGNW3s8Gm4KM26mb7dtSdHJFuR/BQ5y/cn4qIMyeGfHvsVew+2
+neyFR2Oc/nUlZMKfyHI+pA==
 -----END CERTIFICATE-----
 """
 
 intermediate_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
-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
+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
 -----END RSA PRIVATE KEY-----
 """
 
 server_cert_pem = b"""-----BEGIN CERTIFICATE-----
-MIICJDCCAY2gAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
+MIIEKTCCApGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
 BAYTAlVTMQswCQYDVQQIDAJJTDEQMA4GA1UEBwwHQ2hpY2FnbzEQMA4GA1UECgwH
-VGVzdGluZzEYMBYGA1UEAwwPVGVzdGluZyBSb290IENBMB4XDTE3MDYxMjAwMTA1
-N1oXDTM3MDYwNzAwMTA1N1owGDEWMBQGA1UEAwwNbG92ZWx5IHNlcnZlcjCBnzAN
-BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvqb4brndXS2kEL84qXbZXE6LYK+UrhNi
-70sdIM/24NVN7tXkPlOXqrMWhFHHml+aeSpPkH5b1vKnY1TcULmEubnNICtvjmZ5
-SGMQn+J+RmBs1SMd0EgY/0wBBQdlrlYp2QYgm8YC+zxTNSqWvhMFZAgHbj6Un5SS
-T8JGBqytjB0CAwEAAaM2MDQwHQYDVR0OBBYEFINVdy1eIfFJDAkk51QJEo3IfgSu
-MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4GBAGki1K6WgHHJ
-qC6aY2EowjaWOXLO6jUZIhGk7BA7vMRfNug429AOZ4m5F6OQhzmJmlw67Jyu2FeI
-h0VtBuQoHPtjqZXF59oX6hMMmGLMs9pV0UA3fJs5MYA4/V5ZcQy0Ie0QoJNejLzE
-6V1Qz1rRTYLUyEcpI7ZCmBg2KQQI8YZI
+VGVzdGluZzEYMBYGA1UEAwwPVGVzdGluZyBSb290IENBMB4XDTIwMDgwMjE3MTEy
+MFoXDTQ3MTIyMDE3MTEyMFowGDEWMBQGA1UEAwwNbG92ZWx5IHNlcnZlcjCCAaIw
+DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKU9txhKg6Nc0dVK9Vv4MYuYP6Hs
+oR483+wC53V8axkfy2TynrBSug8HapeSFW5jwdwcsjaDwEIAugZfRoz0N1vR/Q6T
+OFAYn2hRwlAgUXVk3NXpDNV/QRliGvxhLAVpvu1a4ExfVZoOQyPa8pogDgrUdB3e
+tYmmFHNa09Lv1nyMZWi6t7zH2weq6/Dxpm0BWf+THFcunv9TNfAqmDV5qbxvaUPh
+uvRpN+X2N3tejB8WKt+UmzAXUi3P3OgYimWXwq8Rmorc1rk5j+ksl6qYwZvi7rRV
+g1ZAH7bGhXC9eEU/1Z9q26OhAPdTyJD0pc+G9vMz6VijLRXcgHBUP09lSeqxnNxc
+pWoX6nRdGn6PkDhewHM05iqAE3ZHnc8kSBcRX85SoW5dGOhvvUTs4ePVNTo3vHdQ
+vftTDD+I3rbFnYTKUAzHTPSWGE7LVEiWJ94RKSADXgve0qq8o377UMnY7W3UygSY
+odyUZ29B5EfZ88EpIs/h5NomDv5VcQEoCWN1owIDAQABozYwNDAdBgNVHQ4EFgQU
+g1V3LV4h8UkMCSTnVAkSjch+BK4wEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZI
+hvcNAQELBQADggGBACn0LsqO94tk8i+RbG5hryNduem9n8b8doYD97iaux6QLvY/
+A8DFduJtUevZ3OCsRYQSGa3V/ysMzN7/DIUkpRLevZmdw+1L6PGR7peR2xIQ+yEW
+bL88vLjezaYIzMKHJRmN8oP3DQtGJm6U2fMMiEHWqRtULIVpnFppzPI2z7+tDeyg
+PFD2YeiFWoq5lmXStrK+KYPJbhTn0gz4QlGBs7PLY2JMDRSVj6ctkvrpXbC3Rb3m
+qo2FY/y51ACg77Txc6NAmNE6tCknwaUjRQP2MuoYFm5/Z6O9/g49AEVIE101zHqV
+N6SkcTUaXAuQIyZaqwdndfOB4rrFyAkoxTM5OamIQl80hZKf4R5rM7D7Sz8kAWJi
+BPIcewN0XnI6lm+zPAVUAE8dZfgJmJR5ifZHYCuv96EX0RpYsddeik8UmjkZ2/ch
+vRzvRSNNxVC6Zoe6vKNUb89XMtJZqY80WxfWG3Z2Hwf9KvS+2KAH/6MiSMj0RI5F
+SCB2PMQm6DYXwM1EyA==
 -----END CERTIFICATE-----
 """
 
-server_key_pem = normalize_privatekey_pem(b"""-----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
-U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
-SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
-AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
-j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
-j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
-Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
-msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
-FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
-4e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
-1sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
-NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
-r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
+server_key_pem = normalize_privatekey_pem(
+    b"""-----BEGIN RSA PRIVATE KEY-----
+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
 -----END RSA PRIVATE KEY-----
-""")
+"""
+)
 
 intermediate_server_cert_pem = b"""-----BEGIN CERTIFICATE-----
-MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
+MIIEXTCCAsWgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQELBQAw
 ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
 CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
-biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
+biBEaWVnbzAeFw0yMDA4MDIxNzExMjBaFw00NzEyMjAxNzExMjBaMG4xHTAbBgNV
 BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
 CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
-biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
-iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
-+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
-biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
-UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
-3bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
-x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
+biBEaWVnbzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAL3UcTxwCsMZ
+qIE+7lolm8t6lT0IYZkE4L7u2qI64m9CvztudqqKYZcrprZobZxqPhqc8IO3CFR2
+nVzwZWxrHCcm6nAzJjVXUFrc4TLsVYYJL1QvKXxr97VIiySU7x6xWrQQsqDtlrb0
+jH59EYFbM2eMk2fBT2X4h6YMXlqyrDjZF6apClXtkdxGJGqR5PCTs4cvrYW7TpIm
+cuJq0S+MRBguZpriM+wOK7cXrqfRPFRzZtPXskpQPSAMDDAOGKl8OZfoVFYzG8KG
+omOa0hcHtgYX2GCDs1g1maY6Haw9bgs041BoApH9aQxehy5dfU39DcFoKSE3dCjR
+FaR6ryCA+f8L1F3xVaHsvX443CYF0/holfsptTjNd1T1z8WR5h1jtY0gJ/ERgcJZ
+UgDRE3lEkTLExS/nuGVfdwnlkxny9jbtYp2YcjYjUkChLtTgz4ommeIdBdDvSu8M
+wWHMtQNxECs5qA5J384cLh11Nd9exWUjiQ9yAZ0qTOzTkdH7VPHfxQIDAQABMA0G
+CSqGSIb3DQEBCwUAA4IBgQA2jC5hJ/+46RLBuaZiJhBawiY+HqybEAZWM/IBGZO4
+UKcRotovU+sb1jg+vpXwePSBPEtQoZce0jN0TKiCdlLM4/9lybAvc6qBLJ0d4VS5
+BU5QsCs9IKyvswAFVipQZi0szYwHk8T145SH/fPao8oznf5ae4a6rK9PyZqT7Ix1
+nnKGffbJs0dY+jlxmx/BPlbsGfTwPL6LexghjvbpbXWUdVLP3gAW6DPCtRd6lhWj
+JvgCkF2SnbQ7GgnPEYi8h09j0c6/sK6jLoNAatJyIlRGE1cdGYZVUlVW/xP6lYM0
+Mi1KKl0ZXOne4vPTtnTBBqrpjdLydH3WM1IxdwSRbmF15OD6BWzzKV4IYUJ21GDh
+YrVrcIeN49pUoKVTTn0Sql8f8mXxJhJ54wo9TKdIGZeuwTZrfWjcjWghXgghXGoP
+RI/I5fk/OMu0Oc06/+xdwCBHCSge0/vxK6fhTu7PxmJhQcZF0sDZyb6LXm2feVkG
+6FsxnsvstVNO3oJdpa8daLs=
 -----END CERTIFICATE-----
 """
 
 intermediate_server_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
-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
+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
 -----END RSA PRIVATE KEY-----
 """
 
 client_cert_pem = b"""-----BEGIN CERTIFICATE-----
-MIICIjCCAYugAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
+MIIEJzCCAo+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
 BAYTAlVTMQswCQYDVQQIDAJJTDEQMA4GA1UEBwwHQ2hpY2FnbzEQMA4GA1UECgwH
-VGVzdGluZzEYMBYGA1UEAwwPVGVzdGluZyBSb290IENBMB4XDTE3MDYxMjAwMDQx
-M1oXDTM3MDYwNzAwMDQxM1owFjEUMBIGA1UEAwwLdWdseSBjbGllbnQwgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBAMBmH9JG02bme0xPipvpjMSlOugyWrauf4at
-EdGJn7GQLD8IY2Fu0+Kvv9DFpSPboFKZCsfDVsYoRs+xaJbtt1dJ6ymX7EqKS7gb
-8q+eeZZ14keqyJd5Rm2q6swQtw9ADD3E8cS6GqpQm+8SgxOycISoYz7sO1ugJFqN
-jId+W4BFAgMBAAGjNjA0MB0GA1UdDgQWBBSDVXctXiHxSQwJJOdUCRKNyH4ErjAT
-BgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQUFAAOBgQAMqcHyweaCOZNN
-dWQQOsBKQlL5wqVVZwucHPWqobjxpULKy9gS2ha2zbgkXcB/BnBOSwe0Fm+MJV0T
-NbnTghcGJNpEH7VKn4xSLvIGZmnZZWgxeIB16z4GhpkK2fShBJ+6GKZjsgjT0lSH
-JRgjHbWutZfZvbSHXr9n7PIphG1Ojg==
+VGVzdGluZzEYMBYGA1UEAwwPVGVzdGluZyBSb290IENBMB4XDTIwMDgwMjE3MTEy
+MVoXDTQ3MTIyMDE3MTEyMVowFjEUMBIGA1UEAwwLdWdseSBjbGllbnQwggGiMA0G
+CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDGChdOMY164FScJqfiJ5LEtjYOKEg4
+nmMAMGuHIT8wZZEfzaaHhBbypzKq2cPP1qtyHgvtUMM6KOFEj4y9AonqzzdlVxbM
+i6+AvYLWlPoB5r/G1GdslUvXbc7F02B/6sB/+iFXmcdjOjAQcLWxVgUL+1CoeoY1
+awNYmzQueK/T82a/6AYTdrx7XRX4wfxjYb1o3bnnRD/jGSakIylXeUGFsiSNkBs/
+dJMkUONxizAdAE2tW6NhPuE2O0UipzUhdgFnH6WPfJ0J1S7jZ3eQTUrLkFpWSp/Z
+hx/l/Ql9vO0wagHaT2wOiZdKVT8S6V6OPzJ7/H1evCoM6EuSPBC5DDP1nPetCK1v
+uC9kb7Dg6yFPt1CKrVFt0Y6W5Y5/GzisUtvYV/OGtX4DOwL9It68D04Qrvun1t/a
+Dh/c5gKqfqIGHUvUucFmOi6DrRpadfraLZMRGN2ysPjoVwhMgwwSmSWhziQIUfxK
+oyz1CUsyr5Gh5gdifbe1AOYwu6YdtlmhqCsCAwEAAaM2MDQwHQYDVR0OBBYEFINV
+dy1eIfFJDAkk51QJEo3IfgSuMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3
+DQEBCwUAA4IBgQAhAEACc1j6EYoSfVJD8N/FlYfHRizdfVJyrmMnC8ID1vtfrU2z
+S2q+49ja2NyM4Sq+Cf+i+sFfzFG92LayZt9Mc1BnHZMdNzQL7Ynr2nDLxHsHzuYa
+N21/ucTpHEFGLmvQ/eWBMxQQ9TbiNXn+tnnqg46dRzN3vHJp+g5+ijtMcuh007z2
+niiO8F07wlb960XviejWejMC8hBLWlA7i3EjAkDO8RFQnG2Py5cQX9GgmWH1sDy3
+rIsWlU+e46ysSWK/bnudnAlzZMB9KJATVZu5+xmCumH2hLJv5vz+jnKcgU9MBZMO
+cKgNdFUbtRlU/gfTaohmLIuSquunCCrXLsLD8ygbKKXfSPGVo2XkvX3oxqUo6dmA
+LvU4N4sCQGiSzW+a13HBtk3TBZFsJSWUGSW/H7TVFiAonumJKRqRxMOkkB9JxX+V
+9LZBYuBLpOeK4wZ8BUSNlHKnGpDzl0DzdYrGlzWz0jXlLGZ8KMfXAn9h0mOZ+IyK
+eUlgMBYyAspCQzM=
 -----END CERTIFICATE-----
 """
 
-client_key_pem = normalize_privatekey_pem(b"""-----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
-btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
-eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
-AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
-zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
-h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
-V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
-TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
-dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
-D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
-si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
-JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
-f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
+client_key_pem = normalize_privatekey_pem(
+    b"""-----BEGIN RSA PRIVATE KEY-----
+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
 -----END RSA PRIVATE KEY-----
-""")
-
-cleartextCertificatePEM = b"""-----BEGIN CERTIFICATE-----
-MIIC6TCCAlKgAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
-BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
-ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTcwNjExMjIzMjU5
-WhcNMzcwNjA2MjIzMjU5WjBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMCSUwxEDAO
-BgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMTD1Rlc3Rp
-bmcgUm9vdCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA+ZpC6Yu6ukTn
-bu5IQd0vWmpwNGZbO773xjpgfNP8nspYRqbIwI1np9FbUkJHvzZRDxrTt/LbFewr
-LhZ0prHIbwJxq3CZe+m9FDjh1IA0yKEcQukA1N3JWnoMLKwQPrCRAW6seUXV2yER
-onDxv/KkOGZtUijoKLXG8ImqK9ssWdsCAwEAAaOBuzCBuDAdBgNVHQ4EFgQUg1V3
-LV4h8UkMCSTnVAkSjch+BK4wgYgGA1UdIwSBgDB+gBSDVXctXiHxSQwJJOdUCRKN
-yH4ErqFcpFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdD
-aGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3Qg
-Q0GCCD0MxODG3rn0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEANFYQ
-R+T70VcZ+SnvURnwviFgCXeedBzCr21meo+DNHbkp2gudB9W8Xrned/wtUBVymy9
-gjB5jINfU7Lci0H57Evsw96UJJVfhXdUMHpqt1RGCoEd9FWnrDyrSy0NysnBT2bH
-lEqxh3aFEUx9IOQ4sgnx1/NOFXBpkRtivl6O0Ec=
------END CERTIFICATE-----
 """
-
-cleartextPrivateKeyPEM = normalize_privatekey_pem(b"""\
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
-jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
-3claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
-AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
-yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
-6JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
-BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
-u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
-PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
-I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
-ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
-6AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
-cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
------END RSA PRIVATE KEY-----
-""")
+)
 
 cleartextCertificateRequestPEM = b"""-----BEGIN CERTIFICATE REQUEST-----
 MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
@@ -322,6 +516,23 @@
 
 encryptedPrivateKeyPEMPassphrase = b"foobar"
 
+cleartextPrivateKeyPEM = """-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMcRMugJ4kvkOEuT
+AvMFr9+3A6+HAB6nKYcXXZz93ube8rJpBZQEfWn73H10dQiQR/a+rhxYEeLy8dPc
+UkFcGR9miVkukJ59zex7iySJY76bdBD8gyx1LTKrkCstP2XHKEYqgbj+tm7VzJnY
+sQLqoaa5NeyWJnUC3MJympkAS7p3AgMBAAECgYAoBAcNqd75jnjaiETRgVUnTWzK
+PgMCJmwsob/JrSa/lhWHU6Exbe2f/mcGOQDFpesxaIcrX3DJBDkkc2d9h/vsfo5v
+JLk/rbHoItWxwuY5n5raAPeQPToKpTDxDrL6Ejhgcxd19wNht7/XSrYZ+dq3iU6G
+mOEvU2hrnfIW3kwVYQJBAP62G6R0gucNfaKGtHzfR3TN9G/DnCItchF+TxGTtpdh
+Cz32MG+7pirT/0xunekmUIp15QHdRy496sVxWTCooLkCQQDIEwXTAwhLNRGFEs5S
+jSkxNfTVeNiOzlG8jPBJJDAdlLt1gUqjZWnk9yU+itMSGi/6eeuH2n04FFk+SV/T
+7ryvAkB0y0ZDk5VOozX/p2rtc2iNm77A3N4kIdiTQuq4sZXhNgN0pwWwxke8jbcb
+8gEAnqwBwWt//locTxHu9TmjgT8pAkEAlbF16B0atXptM02QxT8MlN8z4gxaqu4/
+RX2FwpOq1FcVsqMbvwj/o+ouGY8wwRiK0TMrQCf/DFhdNTcc1aqHzQJBAKWtq4LI
+uVZjCAuyrqEnt7R1bOiLrar+/ezJPY2z+f2rb1TGr31ztPeFvO3edLw+QdhzwJGp
+QKImYzqMe+zkIOQ=
+-----END PRIVATE KEY-----
+"""
 
 cleartextPublicKeyPEM = b"""-----BEGIN PUBLIC KEY-----
 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
@@ -362,7 +573,8 @@
 -----END PKCS7-----
 """
 
-pkcs7DataASN1 = base64.b64decode(b"""
+pkcs7DataASN1 = base64.b64decode(
+    b"""
 MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
 BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
 A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
@@ -381,7 +593,8 @@
 VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
 /g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
 Ho4EzbYCOaEAMQA=
-""")
+"""
+)
 
 crlData = b"""\
 -----BEGIN X509 CRL-----
@@ -564,6 +777,12 @@
 Td8GMrwKz0557OxxtKN6uVVy4ACFMqEw0zN/KJI1vxc9
 -----END CERTIFICATE-----"""
 
+rsa_p_not_prime_pem = """
+-----BEGIN RSA PRIVATE KEY-----
+MBsCAQACAS0CAQcCAQACAQ8CAQMCAQACAQACAQA=
+-----END RSA PRIVATE KEY-----
+"""
+
 
 @pytest.fixture
 def x509_data():
@@ -603,42 +822,50 @@
         # This isn't necessarily the best string representation.  Perhaps it
         # will be changed/improved in the future.
         assert (
-            str(X509Extension(b'basicConstraints', True, b'CA:false')) ==
-            'CA:FALSE'
+            str(X509Extension(b"basicConstraints", True, b"CA:false"))
+            == "CA:FALSE"
         )
 
     def test_type(self):
         """
-        `X509Extension` and `X509ExtensionType` refer to the same type object
-        and can be used to create instances of that type.
+        `X509Extension` can be used to create instances of that type.
         """
-        assert X509Extension is X509ExtensionType
         assert is_consistent_type(
             X509Extension,
-            'X509Extension', b'basicConstraints', True, b'CA:true')
+            "X509Extension",
+            b"basicConstraints",
+            True,
+            b"CA:true",
+        )
 
     def test_construction(self):
         """
         `X509Extension` accepts an extension type name, a critical flag,
-        and an extension value and returns an `X509ExtensionType` instance.
+        and an extension value and returns an `X509Extension` instance.
         """
-        basic = X509Extension(b'basicConstraints', True, b'CA:true')
-        assert isinstance(basic, X509ExtensionType)
+        basic = X509Extension(b"basicConstraints", True, b"CA:true")
+        assert isinstance(basic, X509Extension)
 
-        comment = X509Extension(b'nsComment', False, b'pyOpenSSL unit test')
-        assert isinstance(comment, X509ExtensionType)
+        comment = X509Extension(b"nsComment", False, b"pyOpenSSL unit test")
+        assert isinstance(comment, X509Extension)
 
-    @pytest.mark.parametrize('type_name, critical, value', [
-        (b'thisIsMadeUp', False, b'hi'),
-        (b'basicConstraints', False, b'blah blah'),
-
-        # Exercise a weird one (an extension which uses the r2i method).  This
-        # exercises the codepath that requires a non-NULL ctx to be passed to
-        # X509V3_EXT_nconf.  It can't work now because we provide no
-        # configuration database.  It might be made to work in the future.
-        (b'proxyCertInfo', True,
-         b'language:id-ppl-anyLanguage,pathlen:1,policy:text:AB')
-    ])
+    @pytest.mark.parametrize(
+        "type_name, critical, value",
+        [
+            (b"thisIsMadeUp", False, b"hi"),
+            (b"basicConstraints", False, b"blah blah"),
+            # Exercise a weird one (an extension which uses the r2i method).
+            # This exercises the codepath that requires a non-NULL ctx to be
+            # passed to X509V3_EXT_nconf. It can't work now because we provide
+            # no configuration database. It might be made to work in the
+            # future.
+            (
+                b"proxyCertInfo",
+                True,
+                b"language:id-ppl-anyLanguage,pathlen:1,policy:text:AB",
+            ),
+        ],
+    )
     def test_invalid_extension(self, type_name, critical, value):
         """
         `X509Extension` raises something if it is passed a bad
@@ -647,19 +874,19 @@
         with pytest.raises(Error):
             X509Extension(type_name, critical, value)
 
-    @pytest.mark.parametrize('critical_flag', [True, False])
+    @pytest.mark.parametrize("critical_flag", [True, False])
     def test_get_critical(self, critical_flag):
         """
         `X509ExtensionType.get_critical` returns the value of the
         extension's critical flag.
         """
-        ext = X509Extension(b'basicConstraints', critical_flag, b'CA:true')
+        ext = X509Extension(b"basicConstraints", critical_flag, b"CA:true")
         assert ext.get_critical() == critical_flag
 
-    @pytest.mark.parametrize('short_name, value', [
-        (b'basicConstraints', b'CA:true'),
-        (b'nsComment', b'foo bar'),
-    ])
+    @pytest.mark.parametrize(
+        "short_name, value",
+        [(b"basicConstraints", b"CA:true"), (b"nsComment", b"foo bar")],
+    )
     def test_get_short_name(self, short_name, value):
         """
         `X509ExtensionType.get_short_name` returns a string giving the
@@ -673,9 +900,9 @@
         `X509Extension.get_data` returns a string giving the data of
         the extension.
         """
-        ext = X509Extension(b'basicConstraints', True, b'CA:true')
+        ext = X509Extension(b"basicConstraints", True, b"CA:true")
         # Expect to get back the DER encoded form of CA:true.
-        assert ext.get_data() == b'0\x03\x01\x01\xff'
+        assert ext.get_data() == b"0\x03\x01\x01\xff"
 
     def test_unused_subject(self, x509_data):
         """
@@ -684,13 +911,14 @@
         """
         pkey, x509 = x509_data
         ext1 = X509Extension(
-            b'basicConstraints', False, b'CA:TRUE', subject=x509)
+            b"basicConstraints", False, b"CA:TRUE", subject=x509
+        )
         x509.add_extensions([ext1])
-        x509.sign(pkey, 'sha1')
+        x509.sign(pkey, "sha1")
         # This is a little lame.  Can we think of a better way?
         text = dump_certificate(FILETYPE_TEXT, x509)
-        assert b'X509v3 Basic Constraints:' in text
-        assert b'CA:TRUE' in text
+        assert b"X509v3 Basic Constraints:" in text
+        assert b"CA:TRUE" in text
 
     def test_subject(self, x509_data):
         """
@@ -699,11 +927,12 @@
         """
         pkey, x509 = x509_data
         ext3 = X509Extension(
-            b'subjectKeyIdentifier', False, b'hash', subject=x509)
+            b"subjectKeyIdentifier", False, b"hash", subject=x509
+        )
         x509.add_extensions([ext3])
-        x509.sign(pkey, 'sha1')
+        x509.sign(pkey, "sha1")
         text = dump_certificate(FILETYPE_TEXT, x509)
-        assert b'X509v3 Subject Key Identifier:' in text
+        assert b"X509v3 Subject Key Identifier:" in text
 
     def test_missing_subject(self):
         """
@@ -711,14 +940,9 @@
         is given no value, something happens.
         """
         with pytest.raises(Error):
-            X509Extension(b'subjectKeyIdentifier', False, b'hash')
+            X509Extension(b"subjectKeyIdentifier", False, b"hash")
 
-    @pytest.mark.parametrize('bad_obj', [
-        True,
-        object(),
-        "hello",
-        [],
-    ])
+    @pytest.mark.parametrize("bad_obj", [True, object(), "hello", []])
     def test_invalid_subject(self, bad_obj):
         """
         If the `subject` parameter is given a value which is not an
@@ -726,7 +950,8 @@
         """
         with pytest.raises(TypeError):
             X509Extension(
-                'basicConstraints', False, 'CA:TRUE', subject=bad_obj)
+                "basicConstraints", False, "CA:TRUE", subject=bad_obj
+            )
 
     def test_unused_issuer(self, x509_data):
         """
@@ -735,12 +960,13 @@
         """
         pkey, x509 = x509_data
         ext1 = X509Extension(
-            b'basicConstraints', False, b'CA:TRUE', issuer=x509)
+            b"basicConstraints", False, b"CA:TRUE", issuer=x509
+        )
         x509.add_extensions([ext1])
-        x509.sign(pkey, 'sha1')
+        x509.sign(pkey, "sha1")
         text = dump_certificate(FILETYPE_TEXT, x509)
-        assert b'X509v3 Basic Constraints:' in text
-        assert b'CA:TRUE' in text
+        assert b"X509v3 Basic Constraints:" in text
+        assert b"CA:TRUE" in text
 
     def test_issuer(self, x509_data):
         """
@@ -749,13 +975,13 @@
         """
         pkey, x509 = x509_data
         ext2 = X509Extension(
-            b'authorityKeyIdentifier', False, b'issuer:always',
-            issuer=x509)
+            b"authorityKeyIdentifier", False, b"issuer:always", issuer=x509
+        )
         x509.add_extensions([ext2])
-        x509.sign(pkey, 'sha1')
+        x509.sign(pkey, "sha1")
         text = dump_certificate(FILETYPE_TEXT, x509)
-        assert b'X509v3 Authority Key Identifier:' in text
-        assert b'DirName:/CN=Yoda root CA' in text
+        assert b"X509v3 Authority Key Identifier:" in text
+        assert b"DirName:/CN=Yoda root CA" in text
 
     def test_missing_issuer(self):
         """
@@ -764,15 +990,10 @@
         """
         with pytest.raises(Error):
             X509Extension(
-                b'authorityKeyIdentifier',
-                False, b'keyid:always,issuer:always')
+                b"authorityKeyIdentifier", False, b"keyid:always,issuer:always"
+            )
 
-    @pytest.mark.parametrize('bad_obj', [
-        True,
-        object(),
-        "hello",
-        [],
-    ])
+    @pytest.mark.parametrize("bad_obj", [True, object(), "hello", []])
     def test_invalid_issuer(self, bad_obj):
         """
         If the `issuer` parameter is given a value which is not an
@@ -780,8 +1001,11 @@
         """
         with pytest.raises(TypeError):
             X509Extension(
-                'basicConstraints', False, 'keyid:always,issuer:always',
-                issuer=bad_obj)
+                "basicConstraints",
+                False,
+                "keyid:always,issuer:always",
+                issuer=bad_obj,
+            )
 
 
 class TestPKey(object):
@@ -839,7 +1063,7 @@
         """
         PKey.to_cryptography_key creates a proper cryptography private key.
         """
-        pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
         key = pkey.to_cryptography_key()
 
         assert isinstance(key, rsa.RSAPrivateKey)
@@ -847,11 +1071,9 @@
 
     def test_type(self):
         """
-        `PKey` and `PKeyType` refer to the same type object and can be used to
-        create instances of that type.
+        `PKey` can be used to create instances of that type.
         """
-        assert PKey is PKeyType
-        assert is_consistent_type(PKey, 'PKey')
+        assert is_consistent_type(PKey, "PKey")
 
     def test_construction(self):
         """
@@ -973,6 +1195,14 @@
         with pytest.raises(TypeError):
             pub.check()
 
+    def test_check_pr_897(self):
+        """
+        `PKey.check` raises `OpenSSL.crypto.Error` if provided with broken key
+        """
+        pkey = load_privatekey(FILETYPE_PEM, rsa_p_not_prime_pem)
+        with pytest.raises(Error):
+            pkey.check()
+
 
 def x509_name(**attrs):
     """
@@ -985,6 +1215,7 @@
     # Make the order stable - order matters!
     def key(attr):
         return attr[1]
+
     attrs.sort(key=key)
     for k, v in attrs:
         setattr(name, k, v)
@@ -998,14 +1229,10 @@
 
     def test_type(self):
         """
-        The type of X509Name objects is `X509NameType`.
+        The type of X509Name objects is `X509Name`.
         """
-        assert X509Name is X509NameType
-        assert X509NameType.__name__ == 'X509Name'
-        assert isinstance(X509NameType, type)
-
         name = x509_name()
-        assert isinstance(name, X509NameType)
+        assert isinstance(name, X509Name)
 
     def test_only_string_attributes(self):
         """
@@ -1096,6 +1323,7 @@
         """
         `X509Name` instances should compare based on their NIDs.
         """
+
         def _equality(a, b, assert_true, assert_false):
             assert_true(a == b)
             assert_false(a != b)
@@ -1119,30 +1347,28 @@
         assert_equal(x509_name(), x509_name())
 
         # Instances with equal NIDs should compare equal to each other.
-        assert_equal(x509_name(commonName="foo"),
-                     x509_name(commonName="foo"))
+        assert_equal(x509_name(commonName="foo"), x509_name(commonName="foo"))
 
         # Instance with equal NIDs set using different aliases should compare
         # equal to each other.
-        assert_equal(x509_name(commonName="foo"),
-                     x509_name(CN="foo"))
+        assert_equal(x509_name(commonName="foo"), x509_name(CN="foo"))
 
         # Instances with more than one NID with the same values should compare
         # equal to each other.
-        assert_equal(x509_name(CN="foo", organizationalUnitName="bar"),
-                     x509_name(commonName="foo", OU="bar"))
+        assert_equal(
+            x509_name(CN="foo", organizationalUnitName="bar"),
+            x509_name(commonName="foo", OU="bar"),
+        )
 
         def assert_not_equal(a, b):
             _equality(a, b, assert_false, assert_true)
 
         # Instances with different values for the same NID should not compare
         # equal to each other.
-        assert_not_equal(x509_name(CN="foo"),
-                         x509_name(CN="bar"))
+        assert_not_equal(x509_name(CN="foo"), x509_name(CN="bar"))
 
         # Instances with different NIDs should not compare equal to each other.
-        assert_not_equal(x509_name(CN="foo"),
-                         x509_name(OU="foo"))
+        assert_not_equal(x509_name(CN="foo"), x509_name(OU="foo"))
 
         assert_not_equal(x509_name(), object())
 
@@ -1162,8 +1388,7 @@
         # An X509Name with a NID with a value which sorts less than the value
         # of the same NID on another X509Name compares less than the other
         # X509Name.
-        assert_less_than(x509_name(CN="abc"),
-                         x509_name(CN="def"))
+        assert_less_than(x509_name(CN="abc"), x509_name(CN="def"))
 
         def assert_greater_than(a, b):
             _inequality(a, b, assert_false, assert_true)
@@ -1171,8 +1396,7 @@
         # An X509Name with a NID with a value which sorts greater than the
         # value of the same NID on another X509Name compares greater than the
         # other X509Name.
-        assert_greater_than(x509_name(CN="def"),
-                            x509_name(CN="abc"))
+        assert_greater_than(x509_name(CN="def"), x509_name(CN="abc"))
 
     def test_hash(self):
         """
@@ -1189,9 +1413,10 @@
         `X509Name.der` returns the DER encoded form of the name.
         """
         a = x509_name(CN="foo", C="US")
-        assert (a.der() ==
-                b'0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
-                b'1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo')
+        assert (
+            a.der() == b"0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US"
+            b"1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo"
+        )
 
     def test_get_components(self):
         """
@@ -1222,8 +1447,8 @@
         cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
         subject = cert.get_subject()
         components = subject.get_components()
-        ccn = [value for name, value in components if name == b'CN']
-        assert ccn[0] == b'null.python.org\x00example.org'
+        ccn = [value for name, value in components if name == b"CN"]
+        assert ccn[0] == b"null.python.org\x00example.org"
 
     def test_set_attribute_failure(self):
         """
@@ -1292,7 +1517,7 @@
         request.set_pubkey(key)
         request.sign(key, GOOD_DIGEST)
         # If the type has a verify method, cover that too.
-        if getattr(request, 'verify', None) is not None:
+        if getattr(request, "verify", None) is not None:
             pub = request.get_pubkey()
             assert request.verify(pub)
             # Make another key that won't verify.
@@ -1315,18 +1540,16 @@
 
     def test_type(self):
         """
-        `X509Req` and `X509ReqType` refer to the same type object and can be
-        used to create instances of that type.
+        `X509Req` can be used to create instances of that type.
         """
-        assert X509Req is X509ReqType
-        assert is_consistent_type(X509Req, 'X509Req')
+        assert is_consistent_type(X509Req, "X509Req")
 
     def test_construction(self):
         """
-        `X509Req` takes no arguments and returns an `X509ReqType` instance.
+        `X509Req` takes no arguments and returns an `X509Req` instance.
         """
         request = X509Req()
-        assert isinstance(request, X509ReqType)
+        assert isinstance(request, X509Req)
 
     def test_version(self):
         """
@@ -1358,7 +1581,7 @@
         """
         request = X509Req()
         subject = request.get_subject()
-        assert isinstance(subject, X509NameType)
+        assert isinstance(subject, X509Name)
         subject.commonName = "foo"
         assert request.get_subject().commonName == "foo"
         del request
@@ -1371,13 +1594,14 @@
         and adds them to the X509 request.
         """
         request = X509Req()
-        request.add_extensions([
-            X509Extension(b'basicConstraints', True, b'CA:false')])
+        request.add_extensions(
+            [X509Extension(b"basicConstraints", True, b"CA:false")]
+        )
         exts = request.get_extensions()
         assert len(exts) == 1
-        assert exts[0].get_short_name() == b'basicConstraints'
+        assert exts[0].get_short_name() == b"basicConstraints"
         assert exts[0].get_critical() == 1
-        assert exts[0].get_data() == b'0\x00'
+        assert exts[0].get_data() == b"0\x00"
 
     def test_get_extensions(self):
         """
@@ -1387,17 +1611,23 @@
         request = X509Req()
         exts = request.get_extensions()
         assert exts == []
-        request.add_extensions([
-            X509Extension(b'basicConstraints', True, b'CA:true'),
-            X509Extension(b'keyUsage', False, b'digitalSignature')])
+        request.add_extensions(
+            [
+                X509Extension(b"basicConstraints", True, b"CA:true"),
+                X509Extension(b"keyUsage", False, b"digitalSignature"),
+            ]
+        )
         exts = request.get_extensions()
         assert len(exts) == 2
-        assert exts[0].get_short_name() == b'basicConstraints'
+        assert exts[0].get_short_name() == b"basicConstraints"
         assert exts[0].get_critical() == 1
-        assert exts[0].get_data() == b'0\x03\x01\x01\xff'
-        assert exts[1].get_short_name() == b'keyUsage'
+        assert exts[0].get_data() == b"0\x03\x01\x01\xff"
+        assert exts[1].get_short_name() == b"keyUsage"
         assert exts[1].get_critical() == 0
-        assert exts[1].get_data() == b'\x03\x02\x07\x80'
+        assert exts[1].get_data() == b"\x03\x02\x07\x80"
+        # Requesting it a second time should return the same list
+        exts = request.get_extensions()
+        assert len(exts) == 2
 
     def test_add_extensions_wrong_args(self):
         """
@@ -1437,7 +1667,7 @@
         key which signed the request.
         """
         request = X509Req()
-        pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
         request.sign(pkey, GOOD_DIGEST)
         another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
         with pytest.raises(Error):
@@ -1449,7 +1679,7 @@
         which represents the public part of the key which signed the request.
         """
         request = X509Req()
-        pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
         request.sign(pkey, GOOD_DIGEST)
         assert request.verify(pkey)
 
@@ -1476,28 +1706,8 @@
     """
     Tests for `OpenSSL.crypto.X509`.
     """
-    pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
 
-    extpem = """
------BEGIN CERTIFICATE-----
-MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
-BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
-eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
-MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
-aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
-hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
-Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
-zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
-hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
-TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
-03HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
-MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
-b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
-MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
-uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
-WpOdIpB8KksUTCzV591Nr1wd
------END CERTIFICATE-----
-    """
+    pemData = root_cert_pem + root_key_pem
 
     def signable(self):
         """
@@ -1507,21 +1717,17 @@
 
     def test_type(self):
         """
-        `X509` and `X509Type` refer to the same type object and can be used to
-        create instances of that type.
+        `X509` can be used to create instances of that type.
         """
-        assert X509 is X509Type
-        assert is_consistent_type(X509, 'X509')
+        assert is_consistent_type(X509, "X509")
 
     def test_construction(self):
         """
-        `X509` takes no arguments and returns an instance of `X509Type`.
+        `X509` takes no arguments and returns an instance of `X509`.
         """
         certificate = X509()
-        assert isinstance(certificate, X509Type)
-        assert type(X509Type).__name__ == 'type'
-        assert type(certificate).__name__ == 'X509'
-        assert type(certificate) == X509Type
+        assert isinstance(certificate, X509)
+        assert type(certificate).__name__ == "X509"
         assert type(certificate) == X509
 
     def test_set_version_wrong_args(self):
@@ -1568,8 +1774,8 @@
         validity period to it.
         """
         certificate = X509()
-        set = getattr(certificate, 'set_not' + which)
-        get = getattr(certificate, 'get_not' + which)
+        set = getattr(certificate, "set_not" + which)
+        get = getattr(certificate, "get_not" + which)
 
         # Starts with no value.
         assert get() is None
@@ -1653,8 +1859,8 @@
         current time plus the number of seconds passed in.
         """
         cert = load_certificate(FILETYPE_PEM, self.pemData)
-        not_before_min = (
-            datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
+        not_before_min = datetime.utcnow().replace(microsecond=0) + timedelta(
+            seconds=100
         )
         cert.gmtime_adj_notBefore(100)
         not_before = datetime.strptime(
@@ -1679,8 +1885,8 @@
         to be the current time plus the number of seconds passed in.
         """
         cert = load_certificate(FILETYPE_PEM, self.pemData)
-        not_after_min = (
-            datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
+        not_after_min = datetime.utcnow().replace(microsecond=0) + timedelta(
+            seconds=100
         )
         cert.gmtime_adj_notAfter(100)
         not_after = datetime.strptime(
@@ -1727,11 +1933,15 @@
             # digest will not product the same digest).
             # Digest verified with the command:
             # openssl x509 -in root_cert.pem -noout -fingerprint -md5
-            cert.digest("MD5") ==
-            b"19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75")
+            cert.digest("MD5")
+            == b"19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"
+        )
 
     def _extcert(self, pkey, extensions):
         cert = X509()
+        # Certificates with extensions must be X.509v3, which is encoded with a
+        # version of two.
+        cert.set_version(2)
         cert.set_pubkey(pkey)
         cert.get_subject().commonName = "Unit Tests"
         cert.get_issuer().commonName = "Unit Tests"
@@ -1740,9 +1950,10 @@
         cert.set_notAfter(when)
 
         cert.add_extensions(extensions)
-        cert.sign(pkey, 'sha1')
+        cert.sign(pkey, "sha1")
         return load_certificate(
-            FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
+            FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert)
+        )
 
     def test_extension_count(self):
         """
@@ -1750,10 +1961,11 @@
         that are present in the certificate.
         """
         pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
-        ca = X509Extension(b'basicConstraints', True, b'CA:FALSE')
-        key = X509Extension(b'keyUsage', True, b'digitalSignature')
+        ca = X509Extension(b"basicConstraints", True, b"CA:FALSE")
+        key = X509Extension(b"keyUsage", True, b"digitalSignature")
         subjectAltName = X509Extension(
-            b'subjectAltName', True, b'DNS:example.com')
+            b"subjectAltName", True, b"DNS:example.com"
+        )
 
         # Try a certificate with no extensions at all.
         c = self._extcert(pkey, [])
@@ -1773,27 +1985,28 @@
         `X509Extension` corresponding to the extension at that index.
         """
         pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
-        ca = X509Extension(b'basicConstraints', True, b'CA:FALSE')
-        key = X509Extension(b'keyUsage', True, b'digitalSignature')
+        ca = X509Extension(b"basicConstraints", True, b"CA:FALSE")
+        key = X509Extension(b"keyUsage", True, b"digitalSignature")
         subjectAltName = X509Extension(
-            b'subjectAltName', False, b'DNS:example.com')
+            b"subjectAltName", False, b"DNS:example.com"
+        )
 
         cert = self._extcert(pkey, [ca, key, subjectAltName])
 
         ext = cert.get_extension(0)
         assert isinstance(ext, X509Extension)
         assert ext.get_critical()
-        assert ext.get_short_name() == b'basicConstraints'
+        assert ext.get_short_name() == b"basicConstraints"
 
         ext = cert.get_extension(1)
         assert isinstance(ext, X509Extension)
         assert ext.get_critical()
-        assert ext.get_short_name() == b'keyUsage'
+        assert ext.get_short_name() == b"keyUsage"
 
         ext = cert.get_extension(2)
         assert isinstance(ext, X509Extension)
         assert not ext.get_critical()
-        assert ext.get_short_name() == b'subjectAltName'
+        assert ext.get_short_name() == b"subjectAltName"
 
         with pytest.raises(IndexError):
             cert.get_extension(-1)
@@ -1811,13 +2024,14 @@
         cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
 
         ext = cert.get_extension(3)
-        assert ext.get_short_name() == b'subjectAltName'
+        assert ext.get_short_name() == b"subjectAltName"
         assert (
             b"DNS:altnull.python.org\x00example.com, "
             b"email:[email protected]\[email protected], "
             b"URI:http://null.python.org\x00http://example.org, "
-            b"IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n" ==
-            str(ext).encode("ascii"))
+            b"IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"
+            == str(ext).encode("ascii")
+        )
 
     def test_invalid_digest_algorithm(self):
         """
@@ -1835,10 +2049,13 @@
         cert = load_certificate(FILETYPE_PEM, self.pemData)
         subj = cert.get_subject()
         assert isinstance(subj, X509Name)
-        assert (
-            subj.get_components() ==
-            [(b'C', b'US'), (b'ST', b'IL'), (b'L', b'Chicago'),
-             (b'O', b'Testing'), (b'CN', b'Testing Root CA')])
+        assert subj.get_components() == [
+            (b"C", b"US"),
+            (b"ST", b"IL"),
+            (b"L", b"Chicago"),
+            (b"O", b"Testing"),
+            (b"CN", b"Testing Root CA"),
+        ]
 
     def test_set_subject_wrong_args(self):
         """
@@ -1856,12 +2073,13 @@
         """
         cert = X509()
         name = cert.get_subject()
-        name.C = 'AU'
-        name.OU = 'Unit Tests'
+        name.C = "AU"
+        name.OU = "Unit Tests"
         cert.set_subject(name)
-        assert (
-            cert.get_subject().get_components() ==
-            [(b'C', b'AU'), (b'OU', b'Unit Tests')])
+        assert cert.get_subject().get_components() == [
+            (b"C", b"AU"),
+            (b"OU", b"Unit Tests"),
+        ]
 
     def test_get_issuer(self):
         """
@@ -1871,10 +2089,13 @@
         subj = cert.get_issuer()
         assert isinstance(subj, X509Name)
         comp = subj.get_components()
-        assert (
-            comp ==
-            [(b'C', b'US'), (b'ST', b'IL'), (b'L', b'Chicago'),
-             (b'O', b'Testing'), (b'CN', b'Testing Root CA')])
+        assert comp == [
+            (b"C", b"US"),
+            (b"ST", b"IL"),
+            (b"L", b"Chicago"),
+            (b"O", b"Testing"),
+            (b"CN", b"Testing Root CA"),
+        ]
 
     def test_set_issuer_wrong_args(self):
         """
@@ -1892,12 +2113,13 @@
         """
         cert = X509()
         name = cert.get_issuer()
-        name.C = 'AU'
-        name.OU = 'Unit Tests'
+        name.C = "AU"
+        name.OU = "Unit Tests"
         cert.set_issuer(name)
-        assert (
-            cert.get_issuer().get_components() ==
-            [(b'C', b'AU'), (b'OU', b'Unit Tests')])
+        assert cert.get_issuer().get_components() == [
+            (b"C", b"AU"),
+            (b"OU", b"Unit Tests"),
+        ]
 
     def test_get_pubkey_uninitialized(self):
         """
@@ -1923,10 +2145,8 @@
         subject name.
         """
         cert = load_certificate(FILETYPE_PEM, self.pemData)
-        assert cert.subject_name_hash() in [
-            3350047874,  # OpenSSL 0.9.8, MD5
-            3278919224,  # OpenSSL 1.0.0, SHA1
-        ]
+        # SHA1
+        assert cert.subject_name_hash() == 3278919224
 
     def test_get_signature_algorithm(self):
         """
@@ -1934,7 +2154,7 @@
         the algorithm used to sign the certificate.
         """
         cert = load_certificate(FILETYPE_PEM, self.pemData)
-        assert b"sha1WithRSAEncryption" == cert.get_signature_algorithm()
+        assert b"sha256WithRSAEncryption" == cert.get_signature_algorithm()
 
     def test_get_undefined_signature_algorithm(self):
         """
@@ -2006,18 +2226,17 @@
         """
         `X509Store` is a type object.
         """
-        assert X509Store is X509StoreType
-        assert is_consistent_type(X509Store, 'X509Store')
+        assert is_consistent_type(X509Store, "X509Store")
 
     def test_add_cert(self):
         """
         `X509Store.add_cert` adds a `X509` instance to the certificate store.
         """
-        cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
+        cert = load_certificate(FILETYPE_PEM, root_cert_pem)
         store = X509Store()
         store.add_cert(cert)
 
-    @pytest.mark.parametrize('cert', [None, 1.0, 'cert', object()])
+    @pytest.mark.parametrize("cert", [None, 1.0, "cert", object()])
     def test_add_cert_wrong_args(self, cert):
         """
         `X509Store.add_cert` raises `TypeError` if passed a non-X509 object
@@ -2032,24 +2251,84 @@
         `X509Store.add_cert` doesn't raise `OpenSSL.crypto.Error` if an attempt
         is made to add the same certificate to the store more than once.
         """
-        cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
+        cert = load_certificate(FILETYPE_PEM, root_cert_pem)
         store = X509Store()
         store.add_cert(cert)
         store.add_cert(cert)
 
+    @pytest.mark.parametrize(
+        "cafile, capath, call_cafile, call_capath",
+        [
+            (
+                "/cafile" + NON_ASCII,
+                None,
+                b"/cafile" + NON_ASCII.encode(sys.getfilesystemencoding()),
+                _ffi.NULL,
+            ),
+            (
+                b"/cafile" + NON_ASCII.encode("utf-8"),
+                None,
+                b"/cafile" + NON_ASCII.encode("utf-8"),
+                _ffi.NULL,
+            ),
+            (
+                None,
+                "/capath" + NON_ASCII,
+                _ffi.NULL,
+                b"/capath" + NON_ASCII.encode(sys.getfilesystemencoding()),
+            ),
+            (
+                None,
+                b"/capath" + NON_ASCII.encode("utf-8"),
+                _ffi.NULL,
+                b"/capath" + NON_ASCII.encode("utf-8"),
+            ),
+        ],
+    )
+    def test_load_locations_parameters(
+        self, cafile, capath, call_cafile, call_capath, monkeypatch
+    ):
+        class LibMock(object):
+            def load_locations(self, store, cafile, capath):
+                self.cafile = cafile
+                self.capath = capath
+                return 1
+
+        lib_mock = LibMock()
+        monkeypatch.setattr(
+            _lib, "X509_STORE_load_locations", lib_mock.load_locations
+        )
+
+        store = X509Store()
+        store.load_locations(cafile=cafile, capath=capath)
+
+        assert call_cafile == lib_mock.cafile
+        assert call_capath == lib_mock.capath
+
+    def test_load_locations_fails_when_all_args_are_none(self):
+        store = X509Store()
+        with pytest.raises(Error):
+            store.load_locations(None, None)
+
+    def test_load_locations_raises_error_on_failure(self, tmpdir):
+        invalid_ca_file = tmpdir.join("invalid.pem")
+        invalid_ca_file.write("This is not a certificate")
+
+        store = X509Store()
+        with pytest.raises(Error):
+            store.load_locations(cafile=str(invalid_ca_file))
+
 
 class TestPKCS12(object):
     """
     Test for `OpenSSL.crypto.PKCS12` and `OpenSSL.crypto.load_pkcs12`.
     """
-    pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
 
     def test_type(self):
         """
-        `PKCS12Type` is a type object.
+        `PKCS12` is a type object.
         """
-        assert PKCS12 is PKCS12Type
-        assert is_consistent_type(PKCS12, 'PKCS12')
+        assert is_consistent_type(PKCS12, "PKCS12")
 
     def test_empty_construction(self):
         """
@@ -2072,13 +2351,13 @@
         for bad_arg in [3, PKey(), X509]:
             with pytest.raises(TypeError):
                 p12.set_certificate(bad_arg)
-        for bad_arg in [3, 'legbone', X509()]:
+        for bad_arg in [3, "legbone", X509()]:
             with pytest.raises(TypeError):
                 p12.set_privatekey(bad_arg)
         for bad_arg in [3, X509(), (3, 4), (PKey(),)]:
             with pytest.raises(TypeError):
                 p12.set_ca_certificates(bad_arg)
-        for bad_arg in [6, ('foo', 'bar')]:
+        for bad_arg in [6, ("foo", "bar")]:
             with pytest.raises(TypeError):
                 p12.set_friendlyname(bad_arg)
 
@@ -2089,7 +2368,7 @@
         """
         passwd = b"blah"
         p12 = PKCS12()
-        pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
         p12.set_privatekey(pkey)
         assert None is p12.get_certificate()
         assert pkey == p12.get_privatekey()
@@ -2115,7 +2394,7 @@
         """
         passwd = b"blah"
         p12 = PKCS12()
-        cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
+        cert = load_certificate(FILETYPE_PEM, root_cert_pem)
         p12.set_certificate(cert)
         assert cert == p12.get_certificate()
         assert None is p12.get_privatekey()
@@ -2138,12 +2417,13 @@
         # it to.  At some point, hopefully this will change so that
         # p12.get_certificate() is actually what returns the loaded
         # certificate.
-        assert (
-            cleartextCertificatePEM ==
-            dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
+        assert root_cert_pem == dump_certificate(
+            FILETYPE_PEM, p12.get_ca_certificates()[0]
+        )
 
-    def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
-                   friendly_name=None):
+    def gen_pkcs12(
+        self, cert_pem=None, key_pem=None, ca_pem=None, friendly_name=None
+    ):
         """
         Generate a PKCS12 object with components from PEM.  Verify that the set
         functions return None.
@@ -2165,27 +2445,48 @@
             assert ret is None
         return p12
 
-    def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
-                       extra=()):
+    def check_recovery(
+        self, p12_str, key=None, cert=None, ca=None, passwd=b"", extra=()
+    ):
         """
         Use openssl program to confirm three components are recoverable from a
         PKCS12 string.
         """
         if key:
             recovered_key = _runopenssl(
-                p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
-                b"pass:" + passwd, *extra)
-            assert recovered_key[-len(key):] == key
+                p12_str,
+                b"pkcs12",
+                b"-nocerts",
+                b"-nodes",
+                b"-passin",
+                b"pass:" + passwd,
+                *extra
+            )
+            assert recovered_key[-len(key) :] == key
         if cert:
             recovered_cert = _runopenssl(
-                p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
-                b"pass:" + passwd, b"-nokeys", *extra)
-            assert recovered_cert[-len(cert):] == cert
+                p12_str,
+                b"pkcs12",
+                b"-clcerts",
+                b"-nodes",
+                b"-passin",
+                b"pass:" + passwd,
+                b"-nokeys",
+                *extra
+            )
+            assert recovered_cert[-len(cert) :] == cert
         if ca:
             recovered_cert = _runopenssl(
-                p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
-                b"pass:" + passwd, b"-nokeys", *extra)
-            assert recovered_cert[-len(ca):] == ca
+                p12_str,
+                b"pkcs12",
+                b"-cacerts",
+                b"-nodes",
+                b"-passin",
+                b"pass:" + passwd,
+                b"-nokeys",
+                *extra
+            )
+            assert recovered_cert[-len(ca) :] == ca
 
     def verify_pkcs12_container(self, p12):
         """
@@ -2197,9 +2498,11 @@
         """
         cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
         key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
-        assert (
-            (client_cert_pem, client_key_pem, None) ==
-            (cert_pem, key_pem, p12.get_ca_certificates()))
+        assert (client_cert_pem, client_key_pem, None) == (
+            cert_pem,
+            key_pem,
+            p12.get_ca_certificates(),
+        )
 
     def test_load_pkcs12(self):
         """
@@ -2214,7 +2517,7 @@
             b"-export",
             b"-clcerts",
             b"-passout",
-            b"pass:" + passwd
+            b"pass:" + passwd,
         )
         p12 = load_pkcs12(p12_str, passphrase=passwd)
         self.verify_pkcs12_container(p12)
@@ -2227,15 +2530,21 @@
         """
         pem = client_key_pem + client_cert_pem
         passwd = b"whatever"
-        p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
-                              b"-passout", b"pass:" + passwd)
+        p12_str = _runopenssl(
+            pem,
+            b"pkcs12",
+            b"-export",
+            b"-clcerts",
+            b"-passout",
+            b"pass:" + passwd,
+        )
         with pytest.warns(DeprecationWarning) as w:
             simplefilter("always")
             p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
-            assert (
-                "{0} for passphrase is no longer accepted, use bytes".format(
-                    WARNING_TYPE_EXPECTED
-                ) == str(w[-1].message))
+            msg = "{0} for passphrase is no longer accepted, use bytes".format(
+                WARNING_TYPE_EXPECTED
+            )
+            assert msg == str(w[-1].message)
 
         self.verify_pkcs12_container(p12)
 
@@ -2247,7 +2556,8 @@
         """
         pem = client_key_pem + client_cert_pem
         p12_str = _runopenssl(
-            pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
+            pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:"
+        )
         p12 = load_pkcs12(p12_str)
         self.verify_pkcs12_container(p12)
 
@@ -2266,7 +2576,8 @@
         extracted and examined.
         """
         self.verify_pkcs12_container(
-            self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
+            self._dump_and_load(dump_passphrase=None, load_passphrase=b"")
+        )
 
     def test_load_pkcs12_null_passphrase_load_null(self):
         """
@@ -2275,7 +2586,8 @@
         extracted and examined.
         """
         self.verify_pkcs12_container(
-            self._dump_and_load(dump_passphrase=None, load_passphrase=None))
+            self._dump_and_load(dump_passphrase=None, load_passphrase=None)
+        )
 
     def test_load_pkcs12_empty_passphrase_load_empty(self):
         """
@@ -2284,7 +2596,8 @@
         extracted and examined.
         """
         self.verify_pkcs12_container(
-            self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
+            self._dump_and_load(dump_passphrase=b"", load_passphrase=b"")
+        )
 
     def test_load_pkcs12_empty_passphrase_load_null(self):
         """
@@ -2293,17 +2606,18 @@
         extracted and examined.
         """
         self.verify_pkcs12_container(
-            self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
+            self._dump_and_load(dump_passphrase=b"", load_passphrase=None)
+        )
 
     def test_load_pkcs12_garbage(self):
         """
         `load_pkcs12` raises `OpenSSL.crypto.Error` when passed
         a string which is not a PKCS12 dump.
         """
-        passwd = 'whatever'
+        passwd = b"whatever"
         with pytest.raises(Error) as err:
-            load_pkcs12(b'fruit loops', passwd)
-        assert err.value.args[0][0][0] == 'asn1 encoding routines'
+            load_pkcs12(b"fruit loops", passwd)
+        assert err.value.args[0][0][0] == "asn1 encoding routines"
         assert len(err.value.args[0][0]) == 3
 
     def test_replace(self):
@@ -2333,7 +2647,7 @@
         """
         passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
         p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
-        for friendly_name in [b'Serverlicious', None, b'###']:
+        for friendly_name in [b"Serverlicious", None, b"###"]:
             p12.set_friendlyname(friendly_name)
             assert p12.get_friendlyname() == friendly_name
             dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
@@ -2344,8 +2658,12 @@
             # does not store the friendly name in the cert's
             # alias, which we could then extract.
             self.check_recovery(
-                dumped_p12, key=server_key_pem, cert=server_cert_pem,
-                ca=root_cert_pem, passwd=passwd)
+                dumped_p12,
+                key=server_key_pem,
+                cert=server_cert_pem,
+                ca=root_cert_pem,
+                passwd=passwd,
+            )
 
     def test_various_empty_passphrases(self):
         """
@@ -2359,8 +2677,12 @@
         dumped_p12_nopw = p12.export(iter=9, maciter=4)
         for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
             self.check_recovery(
-                dumped_p12, key=client_key_pem, cert=client_cert_pem,
-                ca=root_cert_pem, passwd=passwd)
+                dumped_p12,
+                key=client_key_pem,
+                cert=client_cert_pem,
+                ca=root_cert_pem,
+                passwd=passwd,
+            )
 
     def test_removing_ca_cert(self):
         """
@@ -2379,8 +2701,12 @@
         p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
         dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
         self.check_recovery(
-            dumped_p12, key=server_key_pem, cert=server_cert_pem,
-            passwd=passwd, extra=(b"-nomacver",))
+            dumped_p12,
+            key=server_key_pem,
+            cert=server_cert_pem,
+            passwd=passwd,
+            extra=(b"-nomacver",),
+        )
 
     def test_load_without_mac(self):
         """
@@ -2406,14 +2732,14 @@
         """
         A PKCS12 with an empty CA certificates list can be exported.
         """
-        passwd = b'Hobie 18'
+        passwd = b"Hobie 18"
         p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
         p12.set_ca_certificates([])
         assert () == p12.get_ca_certificates()
         dumped_p12 = p12.export(passphrase=passwd, iter=3)
         self.check_recovery(
-            dumped_p12, key=server_key_pem, cert=server_cert_pem,
-            passwd=passwd)
+            dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=passwd
+        )
 
     def test_export_without_args(self):
         """
@@ -2422,7 +2748,8 @@
         p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
         dumped_p12 = p12.export()  # no args
         self.check_recovery(
-            dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
+            dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b""
+        )
 
     def test_export_without_bytes(self):
         """
@@ -2433,15 +2760,15 @@
         with pytest.warns(DeprecationWarning) as w:
             simplefilter("always")
             dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
-            assert (
-                "{0} for passphrase is no longer accepted, use bytes".format(
-                    WARNING_TYPE_EXPECTED
-                ) == str(w[-1].message))
+            msg = "{0} for passphrase is no longer accepted, use bytes".format(
+                WARNING_TYPE_EXPECTED
+            )
+            assert msg == str(w[-1].message)
         self.check_recovery(
             dumped_p12,
             key=server_key_pem,
             cert=server_cert_pem,
-            passwd=b"randomtext"
+            passwd=b"randomtext",
         )
 
     def test_key_cert_mismatch(self):
@@ -2472,6 +2799,7 @@
     """
     Tests for :func:`load_publickey`.
     """
+
     def test_loading_works(self):
         """
         load_publickey loads public keys and sets correct attributes.
@@ -2500,7 +2828,7 @@
         """
         load_publickey works with text strings, not just bytes.
         """
-        serialized = cleartextPublicKeyPEM.decode('ascii')
+        serialized = cleartextPublicKeyPEM.decode("ascii")
         key = load_publickey(FILETYPE_PEM, serialized)
         dumped_pem = dump_publickey(FILETYPE_PEM, key)
 
@@ -2526,7 +2854,8 @@
         """
         with pytest.raises(TypeError):
             load_privatekey(
-                FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
+                FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object()
+            )
 
     def test_load_privatekey_wrongPassphrase(self):
         """
@@ -2543,7 +2872,7 @@
         with a private key encoded in a format, that doesn't support
         encryption.
         """
-        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        key = load_privatekey(FILETYPE_PEM, root_key_pem)
         blob = dump_privatekey(FILETYPE_ASN1, key)
         with pytest.raises(ValueError):
             load_privatekey(FILETYPE_ASN1, blob, "secret")
@@ -2554,15 +2883,18 @@
         string if given the passphrase.
         """
         key = load_privatekey(
-            FILETYPE_PEM, encryptedPrivateKeyPEM,
-            encryptedPrivateKeyPEMPassphrase)
-        assert isinstance(key, PKeyType)
+            FILETYPE_PEM,
+            encryptedPrivateKeyPEM,
+            encryptedPrivateKeyPEMPassphrase,
+        )
+        assert isinstance(key, PKey)
 
     def test_load_privatekey_passphrase_exception(self):
         """
         If the passphrase callback raises an exception, that exception is
         raised by `load_privatekey`.
         """
+
         def cb(ignored):
             raise ArithmeticError
 
@@ -2580,6 +2912,7 @@
         def cb(*a):
             called.append(None)
             return b"quack"
+
         with pytest.raises(Error) as err:
             load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
         assert called
@@ -2596,8 +2929,9 @@
         def cb(writing):
             called.append(writing)
             return encryptedPrivateKeyPEMPassphrase
+
         key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
-        assert isinstance(key, PKeyType)
+        assert isinstance(key, PKey)
         assert called == [False]
 
     def test_load_privatekey_passphrase_wrong_return_type(self):
@@ -2607,7 +2941,8 @@
         """
         with pytest.raises(ValueError):
             load_privatekey(
-                FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
+                FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3
+            )
 
     def test_dump_privatekey_wrong_args(self):
         """
@@ -2668,6 +3003,7 @@
         `crypto.load_privatekey` should raise an error when the passphrase
         provided by the callback is too long, not silently truncate it.
         """
+
         def cb(ignored):
             return "a" * 1025
 
@@ -2679,11 +3015,11 @@
         `dump_privatekey` writes an encrypted PEM when given a passphrase.
         """
         passphrase = b"foo"
-        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        key = load_privatekey(FILETYPE_PEM, root_key_pem)
         pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
-        assert isinstance(pem, binary_type)
+        assert isinstance(pem, bytes)
         loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
-        assert isinstance(loadedKey, PKeyType)
+        assert isinstance(loadedKey, PKey)
         assert loadedKey.type() == key.type()
         assert loadedKey.bits() == key.bits()
 
@@ -2693,7 +3029,7 @@
         with a private key encoded in a format, that doesn't support
         encryption.
         """
-        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        key = load_privatekey(FILETYPE_PEM, root_key_pem)
         with pytest.raises(ValueError):
             dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
 
@@ -2701,27 +3037,25 @@
         """
         `dump_certificate` writes PEM, DER, and text.
         """
-        pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
+        pemData = root_cert_pem + root_key_pem
         cert = load_certificate(FILETYPE_PEM, pemData)
         dumped_pem = dump_certificate(FILETYPE_PEM, cert)
-        assert dumped_pem == cleartextCertificatePEM
+        assert dumped_pem == root_cert_pem
         dumped_der = dump_certificate(FILETYPE_ASN1, cert)
         good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
         assert dumped_der == good_der
         cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
         dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
-        assert dumped_pem2 == cleartextCertificatePEM
+        assert dumped_pem2 == root_cert_pem
         dumped_text = dump_certificate(FILETYPE_TEXT, cert)
-        good_text = _runopenssl(
-            dumped_pem, b"x509", b"-noout", b"-text", b"-nameopt", b"")
-        assert dumped_text == good_text
+        assert len(dumped_text) > 500
 
     def test_dump_certificate_bad_type(self):
         """
         `dump_certificate` raises a `ValueError` if it's called with
         a bad type.
         """
-        cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
+        cert = load_certificate(FILETYPE_PEM, root_cert_pem)
         with pytest.raises(ValueError):
             dump_certificate(object(), cert)
 
@@ -2729,36 +3063,35 @@
         """
         `dump_privatekey` writes a PEM
         """
-        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        key = load_privatekey(FILETYPE_PEM, root_key_pem)
         assert key.check()
         dumped_pem = dump_privatekey(FILETYPE_PEM, key)
-        assert dumped_pem == cleartextPrivateKeyPEM
+        assert dumped_pem == normalized_root_key_pem
 
     def test_dump_privatekey_asn1(self):
         """
         `dump_privatekey` writes a DER
         """
-        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
-        dumped_pem = dump_privatekey(FILETYPE_PEM, key)
+        key = load_privatekey(FILETYPE_PEM, root_key_pem)
 
         dumped_der = dump_privatekey(FILETYPE_ASN1, key)
-        # XXX This OpenSSL call writes "writing RSA key" to standard out.  Sad.
-        good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
-        assert dumped_der == good_der
-        key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
-        dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
-        assert dumped_pem2 == cleartextPrivateKeyPEM
+        assert dumped_der == root_key_der
+
+    def test_load_privatekey_asn1(self):
+        """
+        `dump_privatekey` writes a DER
+        """
+        key = load_privatekey(FILETYPE_ASN1, root_key_der)
+        assert key.bits() == 3072
+        assert key.type() == TYPE_RSA
 
     def test_dump_privatekey_text(self):
         """
         `dump_privatekey` writes a text
         """
-        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
-        dumped_pem = dump_privatekey(FILETYPE_PEM, key)
-
+        key = load_privatekey(FILETYPE_PEM, root_key_pem)
         dumped_text = dump_privatekey(FILETYPE_TEXT, key)
-        good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
-        assert dumped_text == good_text
+        assert len(dumped_text) > 500
 
     def test_dump_publickey_pem(self):
         """
@@ -2792,7 +3125,8 @@
         `dump_certificate_request` writes a PEM, DER, and text.
         """
         req = load_certificate_request(
-            FILETYPE_PEM, cleartextCertificateRequestPEM)
+            FILETYPE_PEM, cleartextCertificateRequestPEM
+        )
         dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
         assert dumped_pem == cleartextCertificateRequestPEM
         dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
@@ -2802,9 +3136,7 @@
         dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
         assert dumped_pem2 == cleartextCertificateRequestPEM
         dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
-        good_text = _runopenssl(
-            dumped_pem, b"req", b"-noout", b"-text", b"-nameopt", b"")
-        assert dumped_text == good_text
+        assert len(dumped_text) > 500
         with pytest.raises(ValueError):
             dump_certificate_request(100, req)
 
@@ -2819,12 +3151,13 @@
         def cb(writing):
             called.append(writing)
             return passphrase
-        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+
+        key = load_privatekey(FILETYPE_PEM, root_key_pem)
         pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
-        assert isinstance(pem, binary_type)
+        assert isinstance(pem, bytes)
         assert called == [True]
         loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
-        assert isinstance(loadedKey, PKeyType)
+        assert isinstance(loadedKey, PKey)
         assert loadedKey.type() == key.type()
         assert loadedKey.bits() == key.bits()
 
@@ -2833,10 +3166,11 @@
         `dump_privatekey` should not overwrite the exception raised
         by the passphrase callback.
         """
+
         def cb(ignored):
             raise ArithmeticError
 
-        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        key = load_privatekey(FILETYPE_PEM, root_key_pem)
         with pytest.raises(ArithmeticError):
             dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
 
@@ -2845,13 +3179,52 @@
         `crypto.dump_privatekey` should raise an error when the passphrase
         provided by the callback is too long, not silently truncate it.
         """
+
         def cb(ignored):
             return "a" * 1025
 
-        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        key = load_privatekey(FILETYPE_PEM, root_key_pem)
         with pytest.raises(ValueError):
             dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
 
+    def test_dump_privatekey_truncated(self):
+        """
+        `crypto.dump_privatekey` should not truncate a passphrase that contains
+        a null byte.
+        """
+        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        passphrase = b"foo\x00bar"
+        truncated_passphrase = passphrase.split(b"\x00", 1)[0]
+
+        # By dumping with the full passphrase load should raise an error if we
+        # try to load using the truncated passphrase. If dump truncated the
+        # passphrase, then we WILL load the privatekey and the test fails
+        encrypted_key_pem = dump_privatekey(
+            FILETYPE_PEM, key, "AES-256-CBC", passphrase
+        )
+        with pytest.raises(Error):
+            load_privatekey(
+                FILETYPE_PEM, encrypted_key_pem, truncated_passphrase
+            )
+
+    def test_load_privatekey_truncated(self):
+        """
+        `crypto.load_privatekey` should not truncate a passphrase that contains
+        a null byte.
+        """
+        key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+        passphrase = b"foo\x00bar"
+        truncated_passphrase = passphrase.split(b"\x00", 1)[0]
+
+        # By dumping using the truncated passphrase load should raise an error
+        # if we try to load using the full passphrase. If load truncated the
+        # passphrase, then we WILL load the privatekey and the test fails
+        encrypted_key_pem = dump_privatekey(
+            FILETYPE_PEM, key, "AES-256-CBC", truncated_passphrase
+        )
+        with pytest.raises(Error):
+            load_privatekey(FILETYPE_PEM, encrypted_key_pem, passphrase)
+
     def test_load_pkcs7_data_pem(self):
         """
         `load_pkcs7_data` accepts a PKCS#7 string and returns an instance of
@@ -2912,14 +3285,6 @@
     Tests for `PKCS7`.
     """
 
-    def test_type(self):
-        """
-        `PKCS7` is a type object.
-        """
-        assert isinstance(PKCS7, type)
-        assert PKCS7Type.__name__ == 'PKCS7'
-        assert PKCS7 is PKCS7Type
-
     def test_type_is_signed(self):
         """
         `PKCS7.type_is_signed` returns `True` if the PKCS7 object is of
@@ -2958,7 +3323,7 @@
         type name.
         """
         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
-        assert pkcs7.get_type_name() == b'pkcs7-signedData'
+        assert pkcs7.get_type_name() == b"pkcs7-signedData"
 
     def test_attribute(self):
         """
@@ -2983,18 +3348,16 @@
 
     def test_type(self):
         """
-        `NetscapeSPKI` and `NetscapeSPKIType` refer to the same type object
-        and can be used to create instances of that type.
+        `NetscapeSPKI` can be used to create instances of that type.
         """
-        assert NetscapeSPKI is NetscapeSPKIType
-        assert is_consistent_type(NetscapeSPKI, 'NetscapeSPKI')
+        assert is_consistent_type(NetscapeSPKI, "NetscapeSPKI")
 
     def test_construction(self):
         """
-        `NetscapeSPKI` returns an instance of `NetscapeSPKIType`.
+        `NetscapeSPKI` returns an instance of `NetscapeSPKI`.
         """
         nspki = NetscapeSPKI()
-        assert isinstance(nspki, NetscapeSPKIType)
+        assert isinstance(nspki, NetscapeSPKI)
 
     def test_invalid_attribute(self):
         """
@@ -3011,13 +3374,14 @@
         """
         nspki = NetscapeSPKI()
         blob = nspki.b64_encode()
-        assert isinstance(blob, binary_type)
+        assert isinstance(blob, bytes)
 
 
 class TestRevoked(object):
     """
     Tests for `OpenSSL.crypto.Revoked`.
     """
+
     def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
         """
         The get_reason method on the Revoked class checks to see if the
@@ -3027,7 +3391,7 @@
         crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
         revoked = crl.get_revoked()
         reason = revoked[1].get_reason()
-        assert reason == b'Unspecified'
+        assert reason == b"Unspecified"
 
     def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
         crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
@@ -3044,7 +3408,7 @@
         revoked = Revoked()
         assert isinstance(revoked, Revoked)
         assert type(revoked) == Revoked
-        assert revoked.get_serial() == b'00'
+        assert revoked.get_serial() == b"00"
         assert revoked.get_rev_date() is None
         assert revoked.get_reason() is None
 
@@ -3054,17 +3418,17 @@
         `OpenSSL.crypto.Revoked`.  Confirm errors are handled with grace.
         """
         revoked = Revoked()
-        ret = revoked.set_serial(b'10b')
+        ret = revoked.set_serial(b"10b")
         assert ret is None
         ser = revoked.get_serial()
-        assert ser == b'010B'
+        assert ser == b"010B"
 
-        revoked.set_serial(b'31ppp')  # a type error would be nice
+        revoked.set_serial(b"31ppp")  # a type error would be nice
         ser = revoked.get_serial()
-        assert ser == b'31'
+        assert ser == b"31"
 
         with pytest.raises(ValueError):
-            revoked.set_serial(b'pqrst')
+            revoked.set_serial(b"pqrst")
         with pytest.raises(TypeError):
             revoked.set_serial(100)
 
@@ -3095,15 +3459,15 @@
                 ret = revoked.set_reason(r)
                 assert ret is None
                 reason = revoked.get_reason()
-                assert (
-                    reason.lower().replace(b' ', b'') ==
-                    r.lower().replace(b' ', b''))
+                assert reason.lower().replace(b" ", b"") == r.lower().replace(
+                    b" ", b""
+                )
                 r = reason  # again with the resp of get
 
         revoked.set_reason(None)
         assert revoked.get_reason() is None
 
-    @pytest.mark.parametrize('reason', [object(), 1.0, u'foo'])
+    @pytest.mark.parametrize("reason", [object(), 1.0, u"foo"])
     def test_set_reason_wrong_args(self, reason):
         """
         `Revoked.set_reason` raises `TypeError` if called with an argument
@@ -3120,24 +3484,27 @@
         """
         revoked = Revoked()
         with pytest.raises(ValueError):
-            revoked.set_reason(b'blue')
+            revoked.set_reason(b"blue")
 
 
 class TestCRL(object):
     """
     Tests for `OpenSSL.crypto.CRL`.
     """
-    cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
-    pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
+
+    cert = load_certificate(FILETYPE_PEM, root_cert_pem)
+    pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
 
     root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
     root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
     intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
     intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
     intermediate_server_cert = load_certificate(
-        FILETYPE_PEM, intermediate_server_cert_pem)
+        FILETYPE_PEM, intermediate_server_cert_pem
+    )
     intermediate_server_key = load_privatekey(
-        FILETYPE_PEM, intermediate_server_key_pem)
+        FILETYPE_PEM, intermediate_server_key_pem
+    )
 
     def test_construction(self):
         """
@@ -3156,8 +3523,8 @@
         revoked = Revoked()
         now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
         revoked.set_rev_date(now)
-        revoked.set_serial(b'3ab')
-        revoked.set_reason(b'sUpErSeDEd')
+        revoked.set_serial(b"3ab")
+        revoked.set_reason(b"sUpErSeDEd")
         crl.add_revoked(revoked)
         return crl
 
@@ -3174,13 +3541,17 @@
         crl = x509.load_pem_x509_crl(dumped_crl, backend)
         revoked = crl.get_revoked_certificate_by_serial_number(0x03AB)
         assert revoked is not None
-        assert crl.issuer == x509.Name([
-            x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
-            x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
-            x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
-            x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
-            x509.NameAttribute(x509.NameOID.COMMON_NAME, u"Testing Root CA"),
-        ])
+        assert crl.issuer == x509.Name(
+            [
+                x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
+                x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
+                x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
+                x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
+                x509.NameAttribute(
+                    x509.NameOID.COMMON_NAME, u"Testing Root CA"
+                ),
+            ]
+        )
 
     def test_export_der(self):
         """
@@ -3197,17 +3568,18 @@
         crl = x509.load_der_x509_crl(dumped_crl, backend)
         revoked = crl.get_revoked_certificate_by_serial_number(0x03AB)
         assert revoked is not None
-        assert crl.issuer == x509.Name([
-            x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
-            x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
-            x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
-            x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
-            x509.NameAttribute(x509.NameOID.COMMON_NAME, u"Testing Root CA"),
-        ])
+        assert crl.issuer == x509.Name(
+            [
+                x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
+                x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
+                x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
+                x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
+                x509.NameAttribute(
+                    x509.NameOID.COMMON_NAME, u"Testing Root CA"
+                ),
+            ]
+        )
 
-    # Flaky because we compare the output of running commands which sometimes
-    # varies by 1 second
-    @flaky.flaky
     def test_export_text(self):
         """
         If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
@@ -3216,19 +3588,11 @@
         """
         crl = self._get_crl()
 
-        dumped_crl = crl.export(
-            self.cert, self.pkey, FILETYPE_ASN1, digest=b"md5"
-        )
-        text = _runopenssl(
-            dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER",
-            b"-nameopt", b""
-        )
-
         # text format
         dumped_text = crl.export(
             self.cert, self.pkey, type=FILETYPE_TEXT, digest=b"md5"
         )
-        assert text == dumped_text
+        assert len(dumped_text) > 500
 
     def test_export_custom_digest(self):
         """
@@ -3238,7 +3602,7 @@
         crl = self._get_crl()
         dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
         text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
-        text.index(b'Signature Algorithm: sha1')
+        text.index(b"Signature Algorithm: sha1")
 
     def test_export_md5_digest(self):
         """
@@ -3251,7 +3615,7 @@
         assert 0 == len(catcher)
         dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
         text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
-        text.index(b'Signature Algorithm: md5')
+        text.index(b"Signature Algorithm: md5")
 
     def test_export_default_digest(self):
         """
@@ -3317,7 +3681,8 @@
         crl = CRL()
         with pytest.raises(ValueError):
             crl.export(
-                self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest")
+                self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
+            )
 
     def test_get_revoked(self):
         """
@@ -3329,18 +3694,18 @@
         revoked = Revoked()
         now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
         revoked.set_rev_date(now)
-        revoked.set_serial(b'3ab')
+        revoked.set_serial(b"3ab")
         crl.add_revoked(revoked)
-        revoked.set_serial(b'100')
-        revoked.set_reason(b'sUpErSeDEd')
+        revoked.set_serial(b"100")
+        revoked.set_reason(b"sUpErSeDEd")
         crl.add_revoked(revoked)
 
         revs = crl.get_revoked()
         assert len(revs) == 2
         assert type(revs[0]) == Revoked
         assert type(revs[1]) == Revoked
-        assert revs[0].get_serial() == b'03AB'
-        assert revs[1].get_serial() == b'0100'
+        assert revs[0].get_serial() == b"03AB"
+        assert revs[1].get_serial() == b"0100"
         assert revs[0].get_rev_date() == now
         assert revs[1].get_rev_date() == now
 
@@ -3352,19 +3717,19 @@
         crl = load_crl(FILETYPE_PEM, crlData)
         revs = crl.get_revoked()
         assert len(revs) == 2
-        assert revs[0].get_serial() == b'03AB'
+        assert revs[0].get_serial() == b"03AB"
         assert revs[0].get_reason() is None
-        assert revs[1].get_serial() == b'0100'
-        assert revs[1].get_reason() == b'Superseded'
+        assert revs[1].get_serial() == b"0100"
+        assert revs[1].get_reason() == b"Superseded"
 
         der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
         crl = load_crl(FILETYPE_ASN1, der)
         revs = crl.get_revoked()
         assert len(revs) == 2
-        assert revs[0].get_serial() == b'03AB'
+        assert revs[0].get_serial() == b"03AB"
         assert revs[0].get_reason() is None
-        assert revs[1].get_serial() == b'0100'
-        assert revs[1].get_reason() == b'Superseded'
+        assert revs[1].get_serial() == b"0100"
+        assert revs[1].get_reason() == b"Superseded"
 
     def test_load_crl_bad_filetype(self):
         """
@@ -3389,7 +3754,7 @@
         """
         crl = load_crl(FILETYPE_PEM, crlData)
         assert isinstance(crl.get_issuer(), X509Name)
-        assert crl.get_issuer().CN == 'Testing Root CA'
+        assert crl.get_issuer().CN == "Testing Root CA"
 
     def test_dump_crl(self):
         """
@@ -3412,15 +3777,15 @@
             # FIXME: This string splicing is an unfortunate implementation
             # detail that has been reported in
             # https://github.com/pyca/pyopenssl/issues/258
-            serial = hex(cert.get_serial_number())[2:].encode('utf-8')
+            serial = hex(cert.get_serial_number())[2:].encode("utf-8")
             revoked.set_serial(serial)
-            revoked.set_reason(b'unspecified')
-            revoked.set_rev_date(b'20140601000000Z')
+            revoked.set_reason(b"unspecified")
+            revoked.set_rev_date(b"20140601000000Z")
             crl.add_revoked(revoked)
         crl.set_version(1)
-        crl.set_lastUpdate(b'20140601000000Z')
-        crl.set_nextUpdate(b'20180601000000Z')
-        crl.sign(issuer_cert, issuer_key, digest=b'sha512')
+        crl.set_lastUpdate(b"20140601000000Z")
+        crl.set_nextUpdate(b"20180601000000Z")
+        crl.sign(issuer_cert, issuer_key, digest=b"sha512")
         return crl
 
     def test_verify_with_revoked(self):
@@ -3432,17 +3797,20 @@
         store.add_cert(self.root_cert)
         store.add_cert(self.intermediate_cert)
         root_crl = self._make_test_crl(
-            self.root_cert, self.root_key, certs=[self.intermediate_cert])
+            self.root_cert, self.root_key, certs=[self.intermediate_cert]
+        )
         intermediate_crl = self._make_test_crl(
-            self.intermediate_cert, self.intermediate_key, certs=[])
+            self.intermediate_cert, self.intermediate_key, certs=[]
+        )
         store.add_crl(root_crl)
         store.add_crl(intermediate_crl)
         store.set_flags(
-            X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
+            X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL
+        )
         store_ctx = X509StoreContext(store, self.intermediate_server_cert)
         with pytest.raises(X509StoreContextError) as err:
             store_ctx.verify_certificate()
-        assert err.value.args[0][2] == 'certificate revoked'
+        assert err.value.args[0][2] == "certificate revoked"
 
     def test_verify_with_missing_crl(self):
         """
@@ -3453,15 +3821,17 @@
         store.add_cert(self.root_cert)
         store.add_cert(self.intermediate_cert)
         root_crl = self._make_test_crl(
-            self.root_cert, self.root_key, certs=[self.intermediate_cert])
+            self.root_cert, self.root_key, certs=[self.intermediate_cert]
+        )
         store.add_crl(root_crl)
         store.set_flags(
-            X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
+            X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL
+        )
         store_ctx = X509StoreContext(store, self.intermediate_server_cert)
         with pytest.raises(X509StoreContextError) as err:
             store_ctx.verify_certificate()
-        assert err.value.args[0][2] == 'unable to get certificate CRL'
-        assert err.value.certificate.get_subject().CN == 'intermediate-service'
+        assert err.value.args[0][2] == "unable to get certificate CRL"
+        assert err.value.certificate.get_subject().CN == "intermediate-service"
 
     def test_convert_from_cryptography(self):
         crypto_crl = x509.load_pem_x509_crl(crlData, backend)
@@ -3482,10 +3852,12 @@
     """
     Tests for `OpenSSL.crypto.X509StoreContext`.
     """
+
     root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
     intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
     intermediate_server_cert = load_certificate(
-        FILETYPE_PEM, intermediate_server_cert_pem)
+        FILETYPE_PEM, intermediate_server_cert_pem
+    )
 
     def test_valid(self):
         """
@@ -3510,6 +3882,145 @@
         assert store_ctx.verify_certificate() is None
         assert store_ctx.verify_certificate() is None
 
+    @pytest.mark.parametrize(
+        "root_cert, chain, verified_cert",
+        [
+            pytest.param(
+                root_cert,
+                [intermediate_cert],
+                intermediate_server_cert,
+                id="intermediate in chain",
+            ),
+            pytest.param(
+                root_cert,
+                [],
+                intermediate_cert,
+                id="empty chain",
+            ),
+            pytest.param(
+                root_cert,
+                [root_cert, intermediate_server_cert, intermediate_cert],
+                intermediate_server_cert,
+                id="extra certs in chain",
+            ),
+        ],
+    )
+    def test_verify_success_with_chain(self, root_cert, chain, verified_cert):
+        store = X509Store()
+        store.add_cert(root_cert)
+        store_ctx = X509StoreContext(store, verified_cert, chain=chain)
+        assert store_ctx.verify_certificate() is None
+
+    def test_valid_untrusted_chain_reuse(self):
+        """
+        `verify_certificate` using an untrusted chain can be called multiple
+        times with the same ``X509StoreContext`` instance to produce the same
+        result.
+        """
+        store = X509Store()
+        store.add_cert(self.root_cert)
+        chain = [self.intermediate_cert]
+
+        store_ctx = X509StoreContext(
+            store, self.intermediate_server_cert, chain=chain
+        )
+        assert store_ctx.verify_certificate() is None
+        assert store_ctx.verify_certificate() is None
+
+    def test_chain_reference(self):
+        """
+        ``X509StoreContext`` properly keeps references to the untrusted chain
+        certificates.
+        """
+        store = X509Store()
+        store.add_cert(self.root_cert)
+        chain = [load_certificate(FILETYPE_PEM, intermediate_cert_pem)]
+
+        store_ctx = X509StoreContext(
+            store, self.intermediate_server_cert, chain=chain
+        )
+
+        del chain
+        assert store_ctx.verify_certificate() is None
+
+    @pytest.mark.parametrize(
+        "root_cert, chain, verified_cert",
+        [
+            pytest.param(
+                root_cert,
+                [],
+                intermediate_server_cert,
+                id="intermediate missing",
+            ),
+            pytest.param(
+                None,
+                [intermediate_cert],
+                intermediate_server_cert,
+                id="no trusted root",
+            ),
+            pytest.param(
+                None,
+                [root_cert, intermediate_cert],
+                intermediate_server_cert,
+                id="untrusted root, full chain is available",
+            ),
+            pytest.param(
+                intermediate_cert,
+                [root_cert, intermediate_cert],
+                intermediate_server_cert,
+                id="untrusted root, intermediate is trusted and in chain",
+            ),
+        ],
+    )
+    def test_verify_fail_with_chain(self, root_cert, chain, verified_cert):
+        store = X509Store()
+        if root_cert:
+            store.add_cert(root_cert)
+
+        store_ctx = X509StoreContext(store, verified_cert, chain=chain)
+
+        with pytest.raises(X509StoreContextError):
+            store_ctx.verify_certificate()
+
+    @pytest.mark.parametrize(
+        "chain, expected_error",
+        [
+            pytest.param(
+                [intermediate_cert, "This is not a certificate"],
+                TypeError,
+                id="non-certificate in chain",
+            ),
+            pytest.param(
+                42,
+                TypeError,
+                id="non-list chain",
+            ),
+        ],
+    )
+    def test_untrusted_chain_wrong_args(self, chain, expected_error):
+        """
+        Creating ``X509StoreContext`` with wrong chain raises an exception.
+        """
+        store = X509Store()
+        store.add_cert(self.root_cert)
+
+        with pytest.raises(expected_error):
+            X509StoreContext(store, self.intermediate_server_cert, chain=chain)
+
+    def test_failure_building_untrusted_chain_raises(self, monkeypatch):
+        """
+        Creating ``X509StoreContext`` raises ``OpenSSL.crypto.Error`` when
+        the underlying lib fails to add the certificate to the stack.
+        """
+        monkeypatch.setattr(_lib, "sk_X509_push", lambda _stack, _x509: -1)
+
+        store = X509Store()
+        store.add_cert(self.root_cert)
+        chain = [self.intermediate_cert]
+
+        with pytest.raises(Error):
+            X509StoreContext(store, self.intermediate_server_cert, chain=chain)
+
     def test_trusted_self_signed(self):
         """
         `verify_certificate` returns ``None`` when called with a self-signed
@@ -3530,8 +4041,8 @@
         with pytest.raises(X509StoreContextError) as exc:
             store_ctx.verify_certificate()
 
-        assert exc.value.args[0][2] == 'self signed certificate'
-        assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
+        assert exc.value.args[0][2] == "self signed certificate"
+        assert exc.value.certificate.get_subject().CN == "Testing Root CA"
 
     def test_invalid_chain_no_root(self):
         """
@@ -3545,8 +4056,8 @@
         with pytest.raises(X509StoreContextError) as exc:
             store_ctx.verify_certificate()
 
-        assert exc.value.args[0][2] == 'unable to get issuer certificate'
-        assert exc.value.certificate.get_subject().CN == 'intermediate'
+        assert exc.value.args[0][2] == "unable to get issuer certificate"
+        assert exc.value.certificate.get_subject().CN == "intermediate"
 
     def test_invalid_chain_no_intermediate(self):
         """
@@ -3560,8 +4071,8 @@
         with pytest.raises(X509StoreContextError) as exc:
             store_ctx.verify_certificate()
 
-        assert exc.value.args[0][2] == 'unable to get local issuer certificate'
-        assert exc.value.certificate.get_subject().CN == 'intermediate-service'
+        assert exc.value.args[0][2] == "unable to get local issuer certificate"
+        assert exc.value.certificate.get_subject().CN == "intermediate-service"
 
     def test_modification_pre_verify(self):
         """
@@ -3578,8 +4089,8 @@
         with pytest.raises(X509StoreContextError) as exc:
             store_ctx.verify_certificate()
 
-        assert exc.value.args[0][2] == 'unable to get issuer certificate'
-        assert exc.value.certificate.get_subject().CN == 'intermediate'
+        assert exc.value.args[0][2] == "unable to get issuer certificate"
+        assert exc.value.certificate.get_subject().CN == "intermediate"
 
         store_ctx.set_store(store_good)
         assert store_ctx.verify_certificate() is None
@@ -3595,7 +4106,7 @@
 
         expire_time = self.intermediate_server_cert.get_notAfter()
         expire_datetime = datetime.strptime(
-            expire_time.decode('utf-8'), '%Y%m%d%H%M%SZ'
+            expire_time.decode("utf-8"), "%Y%m%d%H%M%SZ"
         )
         store.set_time(expire_datetime)
 
@@ -3603,7 +4114,106 @@
         with pytest.raises(X509StoreContextError) as exc:
             store_ctx.verify_certificate()
 
-        assert exc.value.args[0][2] == 'certificate has expired'
+        assert exc.value.args[0][2] == "certificate has expired"
+
+    def test_get_verified_chain(self):
+        """
+        `get_verified_chain` returns the verified chain.
+        """
+        store = X509Store()
+        store.add_cert(self.root_cert)
+        store.add_cert(self.intermediate_cert)
+        store_ctx = X509StoreContext(store, self.intermediate_server_cert)
+        chain = store_ctx.get_verified_chain()
+        assert len(chain) == 3
+        intermediate_subject = self.intermediate_server_cert.get_subject()
+        assert chain[0].get_subject() == intermediate_subject
+        assert chain[1].get_subject() == self.intermediate_cert.get_subject()
+        assert chain[2].get_subject() == self.root_cert.get_subject()
+        # Test reuse
+        chain = store_ctx.get_verified_chain()
+        assert len(chain) == 3
+        assert chain[0].get_subject() == intermediate_subject
+        assert chain[1].get_subject() == self.intermediate_cert.get_subject()
+        assert chain[2].get_subject() == self.root_cert.get_subject()
+
+    def test_get_verified_chain_invalid_chain_no_root(self):
+        """
+        `get_verified_chain` raises error when cert verification fails.
+        """
+        store = X509Store()
+        store.add_cert(self.intermediate_cert)
+        store_ctx = X509StoreContext(store, self.intermediate_server_cert)
+
+        with pytest.raises(X509StoreContextError) as exc:
+            store_ctx.get_verified_chain()
+
+        assert exc.value.args[0][2] == "unable to get issuer certificate"
+        assert exc.value.certificate.get_subject().CN == "intermediate"
+
+    @pytest.fixture
+    def root_ca_file(self, tmpdir):
+        return self._create_ca_file(tmpdir, "root_ca_hash_dir", self.root_cert)
+
+    @pytest.fixture
+    def intermediate_ca_file(self, tmpdir):
+        return self._create_ca_file(
+            tmpdir, "intermediate_ca_hash_dir", self.intermediate_cert
+        )
+
+    @staticmethod
+    def _create_ca_file(base_path, hash_directory, cacert):
+        ca_hash = "{:08x}.0".format(cacert.subject_name_hash())
+        cafile = base_path.join(hash_directory, ca_hash)
+        cafile.write_binary(
+            dump_certificate(FILETYPE_PEM, cacert), ensure=True
+        )
+        return cafile
+
+    def test_verify_with_ca_file_location(self, root_ca_file):
+        store = X509Store()
+        store.load_locations(str(root_ca_file))
+
+        store_ctx = X509StoreContext(store, self.intermediate_cert)
+        store_ctx.verify_certificate()
+
+    def test_verify_with_ca_path_location(self, root_ca_file):
+        store = X509Store()
+        store.load_locations(None, str(root_ca_file.dirname))
+
+        store_ctx = X509StoreContext(store, self.intermediate_cert)
+        store_ctx.verify_certificate()
+
+    def test_verify_with_cafile_and_capath(
+        self, root_ca_file, intermediate_ca_file
+    ):
+        store = X509Store()
+        store.load_locations(
+            cafile=str(root_ca_file), capath=str(intermediate_ca_file.dirname)
+        )
+
+        store_ctx = X509StoreContext(store, self.intermediate_server_cert)
+        store_ctx.verify_certificate()
+
+    def test_verify_with_multiple_ca_files(
+        self, root_ca_file, intermediate_ca_file
+    ):
+        store = X509Store()
+        store.load_locations(str(root_ca_file))
+        store.load_locations(str(intermediate_ca_file))
+
+        store_ctx = X509StoreContext(store, self.intermediate_server_cert)
+        store_ctx.verify_certificate()
+
+    def test_verify_failure_with_empty_ca_directory(self, tmpdir):
+        store = X509Store()
+        store.load_locations(None, str(tmpdir))
+
+        store_ctx = X509StoreContext(store, self.intermediate_cert)
+        with pytest.raises(X509StoreContextError) as exc:
+            store_ctx.verify_certificate()
+
+        assert exc.value.args[0][2] == "unable to get local issuer certificate"
 
 
 class TestSignVerify(object):
@@ -3620,7 +4230,8 @@
             b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
             b"effort to escape the vile wind, slipped quickly through the "
             b"glass doors of Victory Mansions, though not quickly enough to "
-            b"prevent a swirl of gritty dust from entering along with him.")
+            b"prevent a swirl of gritty dust from entering along with him."
+        )
 
         # sign the content with this private key
         priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
@@ -3629,7 +4240,7 @@
         # certificate unrelated to priv_key, used to trigger an error
         bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
-        for digest in ['md5', 'sha1']:
+        for digest in ["md5", "sha1"]:
             sig = sign(priv_key, content, digest)
 
             # Verify the signature of content, will throw an exception if
@@ -3668,22 +4279,20 @@
 
         priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
         cert = load_certificate(FILETYPE_PEM, root_cert_pem)
-        for digest in ['md5', 'sha1']:
+        for digest in ["md5", "sha1"]:
             with pytest.warns(DeprecationWarning) as w:
                 simplefilter("always")
                 sig = sign(priv_key, content, digest)
-            assert (
-                "{0} for data is no longer accepted, use bytes".format(
-                    WARNING_TYPE_EXPECTED
-                ) == str(w[-1].message))
+            assert "{0} for data is no longer accepted, use bytes".format(
+                WARNING_TYPE_EXPECTED
+            ) == str(w[-1].message)
 
             with pytest.warns(DeprecationWarning) as w:
                 simplefilter("always")
                 verify(cert, sig, content, digest)
-            assert (
-                "{0} for data is no longer accepted, use bytes".format(
-                    WARNING_TYPE_EXPECTED
-                ) == str(w[-1].message))
+            assert "{0} for data is no longer accepted, use bytes".format(
+                WARNING_TYPE_EXPECTED
+            ) == str(w[-1].message)
 
     def test_sign_verify_ecdsa(self):
         """
@@ -3697,7 +4306,7 @@
             b"effort to escape the vile wind, slipped quickly through the "
             b"glass doors of Victory Mansions, though not quickly enough to "
             b"prevent a swirl of gritty dust from entering along with him."
-        ).decode("ascii")
+        )
         priv_key = load_privatekey(FILETYPE_PEM, ec_root_key_pem)
         cert = load_certificate(FILETYPE_PEM, ec_root_cert_pem)
         sig = sign(priv_key, content, "sha1")
@@ -3722,7 +4331,8 @@
             b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
             b"effort to escape the vile wind, slipped quickly through the "
             b"glass doors of Victory Mansions, though not quickly enough to "
-            b"prevent a swirl of gritty dust from entering along with him.")
+            b"prevent a swirl of gritty dust from entering along with him."
+        )
 
         priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
         sign(priv_key, content, "sha1")
@@ -3794,6 +4404,7 @@
     """
     Tests `_EllipticCurve`'s implementation of ``==`` and ``!=``.
     """
+
     curve_factory = EllipticCurveFactory()
 
     if curve_factory.curve_name is None:
@@ -3818,6 +4429,7 @@
     Tests for `_EllipticCurve`'s implementation of hashing (thus use as
     an item in a `dict` or `set`).
     """
+
     curve_factory = EllipticCurveFactory()
 
     if curve_factory.curve_name is None:
@@ -3838,7 +4450,7 @@
         does not contain that curve.
         """
         curve = get_elliptic_curve(self.curve_factory.curve_name)
-        curves = set([
-            get_elliptic_curve(self.curve_factory.another_curve_name)
-        ])
+        curves = set(
+            [get_elliptic_curve(self.curve_factory.another_curve_name)]
+        )
         assert curve not in curves
diff --git a/tests/test_rand.py b/tests/test_rand.py
index e04a24c..763d711 100644
--- a/tests/test_rand.py
+++ b/tests/test_rand.py
@@ -11,11 +11,7 @@
 
 
 class TestRand(object):
-
-    @pytest.mark.parametrize('args', [
-        (b"foo", None),
-        (None, 3),
-    ])
+    @pytest.mark.parametrize("args", [(b"foo", None), (None, 3)])
     def test_add_wrong_args(self, args):
         """
         `OpenSSL.rand.add` raises `TypeError` if called with arguments not of
@@ -28,7 +24,7 @@
         """
         `OpenSSL.rand.add` adds entropy to the PRNG.
         """
-        rand.add(b'hamburger', 3)
+        rand.add(b"hamburger", 3)
 
     def test_status(self):
         """
diff --git a/tests/test_ssl.py b/tests/test_ssl.py
index bddeaa9..8fdcae2 100644
--- a/tests/test_ssl.py
+++ b/tests/test_ssl.py
@@ -6,23 +6,33 @@
 """
 
 import datetime
+import gc
 import sys
 import uuid
 
 from gc import collect, get_referrers
-from errno import ECONNREFUSED, EINPROGRESS, EWOULDBLOCK, EPIPE, ESHUTDOWN
+from errno import (
+    EAFNOSUPPORT,
+    ECONNREFUSED,
+    EINPROGRESS,
+    EWOULDBLOCK,
+    EPIPE,
+    ESHUTDOWN,
+)
 from sys import platform, getfilesystemencoding
-from socket import MSG_PEEK, SHUT_RDWR, error, socket
+from socket import AF_INET, AF_INET6, MSG_PEEK, SHUT_RDWR, error, socket
 from os import makedirs
 from os.path import join
 from weakref import ref
 from warnings import simplefilter
 
+import flaky
+
 import pytest
 
 from pretend import raiser
 
-from six import PY3, text_type
+from six import PY2, text_type
 
 from cryptography import x509
 from cryptography.hazmat.backends import default_backend
@@ -42,63 +52,125 @@
 from OpenSSL.SSL import SSLEAY_PLATFORM, SSLEAY_DIR, SSLEAY_BUILT_ON
 from OpenSSL.SSL import SENT_SHUTDOWN, RECEIVED_SHUTDOWN
 from OpenSSL.SSL import (
-    SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD,
-    TLSv1_1_METHOD, TLSv1_2_METHOD)
+    SSLv2_METHOD,
+    SSLv3_METHOD,
+    SSLv23_METHOD,
+    TLSv1_METHOD,
+    TLSv1_1_METHOD,
+    TLSv1_2_METHOD,
+)
 from OpenSSL.SSL import OP_SINGLE_DH_USE, OP_NO_SSLv2, OP_NO_SSLv3
 from OpenSSL.SSL import (
-    VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE, VERIFY_NONE)
+    VERIFY_PEER,
+    VERIFY_FAIL_IF_NO_PEER_CERT,
+    VERIFY_CLIENT_ONCE,
+    VERIFY_NONE,
+)
 
 from OpenSSL import SSL
 from OpenSSL.SSL import (
-    SESS_CACHE_OFF, SESS_CACHE_CLIENT, SESS_CACHE_SERVER, SESS_CACHE_BOTH,
-    SESS_CACHE_NO_AUTO_CLEAR, SESS_CACHE_NO_INTERNAL_LOOKUP,
-    SESS_CACHE_NO_INTERNAL_STORE, SESS_CACHE_NO_INTERNAL)
+    SESS_CACHE_OFF,
+    SESS_CACHE_CLIENT,
+    SESS_CACHE_SERVER,
+    SESS_CACHE_BOTH,
+    SESS_CACHE_NO_AUTO_CLEAR,
+    SESS_CACHE_NO_INTERNAL_LOOKUP,
+    SESS_CACHE_NO_INTERNAL_STORE,
+    SESS_CACHE_NO_INTERNAL,
+)
 
 from OpenSSL.SSL import (
-    Error, SysCallError, WantReadError, WantWriteError, ZeroReturnError)
-from OpenSSL.SSL import (
-    Context, ContextType, Session, Connection, ConnectionType, SSLeay_version)
+    Error,
+    SysCallError,
+    WantReadError,
+    WantWriteError,
+    ZeroReturnError,
+)
+from OpenSSL.SSL import Context, Session, Connection, SSLeay_version
 from OpenSSL.SSL import _make_requires
 
 from OpenSSL._util import ffi as _ffi, lib as _lib
 
 from OpenSSL.SSL import (
-    OP_NO_QUERY_MTU, OP_COOKIE_EXCHANGE, OP_NO_TICKET, OP_NO_COMPRESSION,
-    MODE_RELEASE_BUFFERS)
+    OP_NO_QUERY_MTU,
+    OP_COOKIE_EXCHANGE,
+    OP_NO_TICKET,
+    OP_NO_COMPRESSION,
+    MODE_RELEASE_BUFFERS,
+    NO_OVERLAPPING_PROTOCOLS,
+)
 
 from OpenSSL.SSL import (
-    SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK,
-    SSL_CB_LOOP, SSL_CB_EXIT, SSL_CB_READ, SSL_CB_WRITE, SSL_CB_ALERT,
-    SSL_CB_READ_ALERT, SSL_CB_WRITE_ALERT, SSL_CB_ACCEPT_LOOP,
-    SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP, SSL_CB_CONNECT_EXIT,
-    SSL_CB_HANDSHAKE_START, SSL_CB_HANDSHAKE_DONE)
+    SSL_ST_CONNECT,
+    SSL_ST_ACCEPT,
+    SSL_ST_MASK,
+    SSL_CB_LOOP,
+    SSL_CB_EXIT,
+    SSL_CB_READ,
+    SSL_CB_WRITE,
+    SSL_CB_ALERT,
+    SSL_CB_READ_ALERT,
+    SSL_CB_WRITE_ALERT,
+    SSL_CB_ACCEPT_LOOP,
+    SSL_CB_ACCEPT_EXIT,
+    SSL_CB_CONNECT_LOOP,
+    SSL_CB_CONNECT_EXIT,
+    SSL_CB_HANDSHAKE_START,
+    SSL_CB_HANDSHAKE_DONE,
+)
 
 try:
     from OpenSSL.SSL import (
-        SSL_ST_INIT, SSL_ST_BEFORE, SSL_ST_OK, SSL_ST_RENEGOTIATE
+        SSL_ST_INIT,
+        SSL_ST_BEFORE,
+        SSL_ST_OK,
+        SSL_ST_RENEGOTIATE,
     )
 except ImportError:
     SSL_ST_INIT = SSL_ST_BEFORE = SSL_ST_OK = SSL_ST_RENEGOTIATE = None
 
 from .util import WARNING_TYPE_EXPECTED, NON_ASCII, is_consistent_type
 from .test_crypto import (
-    cleartextCertificatePEM, cleartextPrivateKeyPEM,
-    client_cert_pem, client_key_pem, server_cert_pem, server_key_pem,
-    root_cert_pem)
+    client_cert_pem,
+    client_key_pem,
+    server_cert_pem,
+    server_key_pem,
+    root_cert_pem,
+    root_key_pem,
+)
 
 
-# openssl dhparam 1024 -out dh-1024.pem (note that 1024 is a small number of
-# bits to use)
+# openssl dhparam 2048 -out dh-2048.pem
 dhparam = """\
 -----BEGIN DH PARAMETERS-----
-MIGHAoGBALdUMvn+C9MM+y5BWZs11mSeH6HHoEq0UVbzVq7UojC1hbsZUuGukQ3a
-Qh2/pwqb18BZFykrWB0zv/OkLa0kx4cuUgNrUVq1EFheBiX6YqryJ7t2sO09NQiO
-V7H54LmltOT/hEh6QWsJqb6BQgH65bswvV/XkYGja8/T0GzvbaVzAgEC
+MIIBCAKCAQEA2F5e976d/GjsaCdKv5RMWL/YV7fq1UUWpPAer5fDXflLMVUuYXxE
+3m3ayZob9lbpgEU0jlPAsXHfQPGxpKmvhv+xV26V/DEoukED8JeZUY/z4pigoptl
++8+TYdNNE/rFSZQFXIp+v2D91IEgmHBnZlKFSbKR+p8i0KjExXGjU6ji3S5jkOku
+ogikc7df1Ui0hWNJCmTjExq07aXghk97PsdFSxjdawuG3+vos5bnNoUwPLYlFc/z
+ITYG0KXySiCLi4UDlXTZTz7u/+OYczPEgqa/JPUddbM/kfvaRAnjY38cfQ7qXf8Y
+i5s5yYK7a/0eWxxRr2qraYaUj8RwDpH9CwIBAg==
 -----END DH PARAMETERS-----
 """
 
 
-skip_if_py3 = pytest.mark.skipif(PY3, reason="Python 2 only")
+skip_if_py3 = pytest.mark.skipif(not PY2, reason="Python 2 only")
+
+
+def socket_any_family():
+    try:
+        return socket(AF_INET)
+    except error as e:
+        if e.errno == EAFNOSUPPORT:
+            return socket(AF_INET6)
+        raise
+
+
+def loopback_address(socket):
+    if socket.family == AF_INET:
+        return "127.0.0.1"
+    else:
+        assert socket.family == AF_INET6
+        return "::1"
 
 
 def join_bytes_or_unicode(prefix, suffix):
@@ -127,12 +199,12 @@
     Establish and return a pair of network sockets connected to each other.
     """
     # Connect a pair of sockets
-    port = socket()
-    port.bind(('', 0))
+    port = socket_any_family()
+    port.bind(("", 0))
     port.listen(1)
-    client = socket()
+    client = socket(port.family)
     client.setblocking(False)
-    client.connect_ex(("127.0.0.1", port.getsockname()[1]))
+    client.connect_ex((loopback_address(port), port.getsockname()[1]))
     client.setblocking(True)
     server = port.accept()[0]
 
@@ -171,47 +243,53 @@
         2. A new intermediate certificate signed by cacert (icert)
         3. A new server certificate signed by icert (scert)
     """
-    caext = X509Extension(b'basicConstraints', False, b'CA:true')
+    caext = X509Extension(b"basicConstraints", False, b"CA:true")
+    not_after_date = datetime.date.today() + datetime.timedelta(days=365)
+    not_after = not_after_date.strftime("%Y%m%d%H%M%SZ").encode("ascii")
 
     # Step 1
     cakey = PKey()
-    cakey.generate_key(TYPE_RSA, 1024)
+    cakey.generate_key(TYPE_RSA, 2048)
     cacert = X509()
+    cacert.set_version(2)
     cacert.get_subject().commonName = "Authority Certificate"
     cacert.set_issuer(cacert.get_subject())
     cacert.set_pubkey(cakey)
     cacert.set_notBefore(b"20000101000000Z")
-    cacert.set_notAfter(b"20200101000000Z")
+    cacert.set_notAfter(not_after)
     cacert.add_extensions([caext])
     cacert.set_serial_number(0)
-    cacert.sign(cakey, "sha1")
+    cacert.sign(cakey, "sha256")
 
     # Step 2
     ikey = PKey()
-    ikey.generate_key(TYPE_RSA, 1024)
+    ikey.generate_key(TYPE_RSA, 2048)
     icert = X509()
+    icert.set_version(2)
     icert.get_subject().commonName = "Intermediate Certificate"
     icert.set_issuer(cacert.get_subject())
     icert.set_pubkey(ikey)
     icert.set_notBefore(b"20000101000000Z")
-    icert.set_notAfter(b"20200101000000Z")
+    icert.set_notAfter(not_after)
     icert.add_extensions([caext])
     icert.set_serial_number(0)
-    icert.sign(cakey, "sha1")
+    icert.sign(cakey, "sha256")
 
     # Step 3
     skey = PKey()
-    skey.generate_key(TYPE_RSA, 1024)
+    skey.generate_key(TYPE_RSA, 2048)
     scert = X509()
+    scert.set_version(2)
     scert.get_subject().commonName = "Server Certificate"
     scert.set_issuer(icert.get_subject())
     scert.set_pubkey(skey)
     scert.set_notBefore(b"20000101000000Z")
-    scert.set_notAfter(b"20200101000000Z")
-    scert.add_extensions([
-        X509Extension(b'basicConstraints', True, b'CA:false')])
+    scert.set_notAfter(not_after)
+    scert.add_extensions(
+        [X509Extension(b"basicConstraints", True, b"CA:false")]
+    )
     scert.set_serial_number(0)
-    scert.sign(ikey, "sha1")
+    scert.sign(ikey, "sha256")
 
     return [(cakey, cacert), (ikey, icert), (skey, scert)]
 
@@ -268,8 +346,10 @@
 
         # Copy stuff from each side's send buffer to the other side's
         # receive buffer.
-        for (read, write) in [(client_conn, server_conn),
-                              (server_conn, client_conn)]:
+        for (read, write) in [
+            (client_conn, server_conn),
+            (server_conn, client_conn),
+        ]:
 
             # Give the side a chance to generate some more bytes, or succeed.
             try:
@@ -319,6 +399,7 @@
     Tests for version information exposed by `OpenSSL.SSL.SSLeay_version` and
     `OpenSSL.SSL.OPENSSL_VERSION_NUMBER`.
     """
+
     def test_OPENSSL_VERSION_NUMBER(self):
         """
         `OPENSSL_VERSION_NUMBER` is an integer with status in the low byte and
@@ -332,8 +413,13 @@
         number of version strings based on that indicator.
         """
         versions = {}
-        for t in [SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON,
-                  SSLEAY_PLATFORM, SSLEAY_DIR]:
+        for t in [
+            SSLEAY_VERSION,
+            SSLEAY_CFLAGS,
+            SSLEAY_BUILT_ON,
+            SSLEAY_PLATFORM,
+            SSLEAY_DIR,
+        ]:
             version = SSLeay_version(t)
             versions[version] = t
             assert isinstance(version, bytes)
@@ -346,31 +432,29 @@
     Create a valid PEM file with CA certificates and return the path.
     """
     key = rsa.generate_private_key(
-        public_exponent=65537,
-        key_size=2048,
-        backend=default_backend()
+        public_exponent=65537, key_size=2048, backend=default_backend()
     )
     public_key = key.public_key()
 
     builder = x509.CertificateBuilder()
-    builder = builder.subject_name(x509.Name([
-        x509.NameAttribute(NameOID.COMMON_NAME, u"pyopenssl.org"),
-    ]))
-    builder = builder.issuer_name(x509.Name([
-        x509.NameAttribute(NameOID.COMMON_NAME, u"pyopenssl.org"),
-    ]))
+    builder = builder.subject_name(
+        x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, u"pyopenssl.org")])
+    )
+    builder = builder.issuer_name(
+        x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, u"pyopenssl.org")])
+    )
     one_day = datetime.timedelta(1, 0, 0)
     builder = builder.not_valid_before(datetime.datetime.today() - one_day)
     builder = builder.not_valid_after(datetime.datetime.today() + one_day)
     builder = builder.serial_number(int(uuid.uuid4()))
     builder = builder.public_key(public_key)
     builder = builder.add_extension(
-        x509.BasicConstraints(ca=True, path_length=None), critical=True,
+        x509.BasicConstraints(ca=True, path_length=None),
+        critical=True,
     )
 
     certificate = builder.sign(
-        private_key=key, algorithm=hashes.SHA256(),
-        backend=default_backend()
+        private_key=key, algorithm=hashes.SHA256(), backend=default_backend()
     )
 
     ca_file = tmpdir.join("test.pem")
@@ -386,19 +470,20 @@
 @pytest.fixture
 def context():
     """
-    A simple TLS 1.0 context.
+    A simple "best TLS you can get" context. TLS 1.2+ in any reasonable OpenSSL
     """
-    return Context(TLSv1_METHOD)
+    return Context(SSLv23_METHOD)
 
 
 class TestContext(object):
     """
     Unit tests for `OpenSSL.SSL.Context`.
     """
-    @pytest.mark.parametrize("cipher_string", [
-        b"hello world:AES128-SHA",
-        u"hello world:AES128-SHA",
-    ])
+
+    @pytest.mark.parametrize(
+        "cipher_string",
+        [b"hello world:AES128-SHA", u"hello world:AES128-SHA"],
+    )
     def test_set_cipher_list(self, context, cipher_string):
         """
         `Context.set_cipher_list` accepts both byte and unicode strings
@@ -410,18 +495,32 @@
 
         assert "AES128-SHA" in conn.get_cipher_list()
 
-    @pytest.mark.parametrize("cipher_list,error", [
-        (object(), TypeError),
-        ("imaginary-cipher", Error),
-    ])
-    def test_set_cipher_list_wrong_args(self, context, cipher_list, error):
+    def test_set_cipher_list_wrong_type(self, context):
         """
         `Context.set_cipher_list` raises `TypeError` when passed a non-string
-        argument and raises `OpenSSL.SSL.Error` when passed an incorrect cipher
-        list string.
+        argument.
         """
-        with pytest.raises(error):
-            context.set_cipher_list(cipher_list)
+        with pytest.raises(TypeError):
+            context.set_cipher_list(object())
+
+    @flaky.flaky
+    def test_set_cipher_list_no_cipher_match(self, context):
+        """
+        `Context.set_cipher_list` raises `OpenSSL.SSL.Error` with a
+        `"no cipher match"` reason string regardless of the TLS
+        version.
+        """
+        with pytest.raises(Error) as excinfo:
+            context.set_cipher_list(b"imaginary-cipher")
+        assert excinfo.value.args == (
+            [
+                (
+                    "SSL routines",
+                    "SSL_CTX_set_cipher_list",
+                    "no cipher match",
+                )
+            ],
+        )
 
     def test_load_client_ca(self, context, ca_file):
         """
@@ -445,9 +544,7 @@
         """
         Passing the path as unicode raises a warning but works.
         """
-        pytest.deprecated_call(
-            context.load_client_ca, ca_file.decode("ascii")
-        )
+        pytest.deprecated_call(context.load_client_ca, ca_file.decode("ascii"))
 
     def test_set_session_id(self, context):
         """
@@ -463,9 +560,11 @@
             context.set_session_id(b"abc" * 1000)
 
         assert [
-            ("SSL routines",
-             "SSL_CTX_set_session_id_context",
-             "ssl session id context too long")
+            (
+                "SSL routines",
+                "SSL_CTX_set_session_id_context",
+                "ssl session id context too long",
+            )
         ] == e.value.args[0]
 
     def test_set_session_id_unicode(self, context):
@@ -499,28 +598,19 @@
         with pytest.raises(ValueError):
             Context(10)
 
-    @skip_if_py3
-    def test_method_long(self):
-        """
-        On Python 2 `Context` accepts values of type `long` as well as `int`.
-        """
-        Context(long(TLSv1_METHOD))
-
     def test_type(self):
         """
-        `Context` and `ContextType` refer to the same type object and can
-        be used to create instances of that type.
+        `Context` can be used to create instances of that type.
         """
-        assert Context is ContextType
-        assert is_consistent_type(Context, 'Context', TLSv1_METHOD)
+        assert is_consistent_type(Context, "Context", TLSv1_METHOD)
 
     def test_use_privatekey(self):
         """
         `Context.use_privatekey` takes an `OpenSSL.crypto.PKey` instance.
         """
         key = PKey()
-        key.generate_key(TYPE_RSA, 512)
-        ctx = Context(TLSv1_METHOD)
+        key.generate_key(TYPE_RSA, 1024)
+        ctx = Context(SSLv23_METHOD)
         ctx.use_privatekey(key)
         with pytest.raises(TypeError):
             ctx.use_privatekey("")
@@ -530,7 +620,7 @@
         `Context.use_privatekey_file` raises `OpenSSL.SSL.Error` when passed
         the name of a file which does not exist.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         with pytest.raises(Error):
             ctx.use_privatekey_file(tmpfile)
 
@@ -540,23 +630,21 @@
         arguments does not raise an exception.
         """
         key = PKey()
-        key.generate_key(TYPE_RSA, 512)
+        key.generate_key(TYPE_RSA, 1024)
 
         with open(pemfile, "wt") as pem:
-            pem.write(
-                dump_privatekey(FILETYPE_PEM, key).decode("ascii")
-            )
+            pem.write(dump_privatekey(FILETYPE_PEM, key).decode("ascii"))
 
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         ctx.use_privatekey_file(pemfile, filetype)
 
-    @pytest.mark.parametrize('filetype', [object(), "", None, 1.0])
+    @pytest.mark.parametrize("filetype", [object(), "", None, 1.0])
     def test_wrong_privatekey_file_wrong_args(self, tmpfile, filetype):
         """
         `Context.use_privatekey_file` raises `TypeError` when called with
         a `filetype` which is not a valid file encoding.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             ctx.use_privatekey_file(tmpfile, filetype)
 
@@ -580,20 +668,12 @@
             FILETYPE_PEM,
         )
 
-    @skip_if_py3
-    def test_use_privatekey_file_long(self, tmpfile):
-        """
-        On Python 2 `Context.use_privatekey_file` accepts a filetype of
-        type `long` as well as `int`.
-        """
-        self._use_privatekey_file_test(tmpfile, long(FILETYPE_PEM))
-
     def test_use_certificate_wrong_args(self):
         """
         `Context.use_certificate_wrong_args` raises `TypeError` when not passed
         exactly one `OpenSSL.crypto.X509` instance as an argument.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             ctx.use_certificate("hello, world")
 
@@ -603,7 +683,7 @@
         `OpenSSL.crypto.X509` instance which has not been initialized
         (ie, which does not actually have any certificate data).
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         with pytest.raises(Error):
             ctx.use_certificate(X509())
 
@@ -616,17 +696,15 @@
         # Hard to assert anything.  But we could set a privatekey then ask
         # OpenSSL if the cert and key agree using check_privatekey.  Then as
         # long as check_privatekey works right we're good...
-        ctx = Context(TLSv1_METHOD)
-        ctx.use_certificate(
-            load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
-        )
+        ctx = Context(SSLv23_METHOD)
+        ctx.use_certificate(load_certificate(FILETYPE_PEM, root_cert_pem))
 
     def test_use_certificate_file_wrong_args(self):
         """
         `Context.use_certificate_file` raises `TypeError` if the first
         argument is not a byte string or the second argument is not an integer.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             ctx.use_certificate_file(object(), FILETYPE_PEM)
         with pytest.raises(TypeError):
@@ -639,7 +717,7 @@
         `Context.use_certificate_file` raises `OpenSSL.SSL.Error` if passed
         the name of a file which does not exist.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         with pytest.raises(Error):
             ctx.use_certificate_file(tmpfile)
 
@@ -653,9 +731,9 @@
         # OpenSSL if the cert and key agree using check_privatekey.  Then as
         # long as check_privatekey works right we're good...
         with open(certificate_file, "wb") as pem_file:
-            pem_file.write(cleartextCertificatePEM)
+            pem_file.write(root_cert_pem)
 
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         ctx.use_certificate_file(certificate_file)
 
     def test_use_certificate_file_bytes(self, tmpfile):
@@ -676,19 +754,6 @@
         filename = tmpfile.decode(getfilesystemencoding()) + NON_ASCII
         self._use_certificate_file_test(filename)
 
-    @skip_if_py3
-    def test_use_certificate_file_long(self, tmpfile):
-        """
-        On Python 2 `Context.use_certificate_file` accepts a
-        filetype of type `long` as well as `int`.
-        """
-        pem_filename = tmpfile
-        with open(pem_filename, "wb") as pem_file:
-            pem_file.write(cleartextCertificatePEM)
-
-        ctx = Context(TLSv1_METHOD)
-        ctx.use_certificate_file(pem_filename, long(FILETYPE_PEM))
-
     def test_check_privatekey_valid(self):
         """
         `Context.check_privatekey` returns `None` if the `Context` instance
@@ -696,7 +761,7 @@
         """
         key = load_privatekey(FILETYPE_PEM, client_key_pem)
         cert = load_certificate(FILETYPE_PEM, client_cert_pem)
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.use_privatekey(key)
         context.use_certificate(cert)
         assert None is context.check_privatekey()
@@ -709,7 +774,7 @@
         """
         key = load_privatekey(FILETYPE_PEM, client_key_pem)
         cert = load_certificate(FILETYPE_PEM, server_cert_pem)
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.use_privatekey(key)
         context.use_certificate(cert)
         with pytest.raises(Error):
@@ -721,7 +786,7 @@
         using `Context.get_app_data`.
         """
         app_data = object()
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.set_app_data(app_data)
         assert context.get_app_data() is app_data
 
@@ -730,7 +795,7 @@
         `Context.set_options` raises `TypeError` if called with
         a non-`int` argument.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.set_options(None)
 
@@ -738,26 +803,16 @@
         """
         `Context.set_options` returns the new options value.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         options = context.set_options(OP_NO_SSLv2)
         assert options & OP_NO_SSLv2 == OP_NO_SSLv2
 
-    @skip_if_py3
-    def test_set_options_long(self):
-        """
-        On Python 2 `Context.set_options` accepts values of type
-        `long` as well as `int`.
-        """
-        context = Context(TLSv1_METHOD)
-        options = context.set_options(long(OP_NO_SSLv2))
-        assert options & OP_NO_SSLv2 == OP_NO_SSLv2
-
     def test_set_mode_wrong_args(self):
         """
         `Context.set_mode` raises `TypeError` if called with
         a non-`int` argument.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.set_mode(None)
 
@@ -766,25 +821,15 @@
         `Context.set_mode` accepts a mode bitvector and returns the
         newly set mode.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         assert MODE_RELEASE_BUFFERS & context.set_mode(MODE_RELEASE_BUFFERS)
 
-    @skip_if_py3
-    def test_set_mode_long(self):
-        """
-        On Python 2 `Context.set_mode` accepts values of type `long` as well
-        as `int`.
-        """
-        context = Context(TLSv1_METHOD)
-        mode = context.set_mode(long(MODE_RELEASE_BUFFERS))
-        assert MODE_RELEASE_BUFFERS & mode
-
     def test_set_timeout_wrong_args(self):
         """
         `Context.set_timeout` raises `TypeError` if called with
         a non-`int` argument.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.set_timeout(None)
 
@@ -794,26 +839,16 @@
         created using the context object. `Context.get_timeout` retrieves
         this value.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.set_timeout(1234)
         assert context.get_timeout() == 1234
 
-    @skip_if_py3
-    def test_timeout_long(self):
-        """
-        On Python 2 `Context.set_timeout` accepts values of type `long` as
-        well as int.
-        """
-        context = Context(TLSv1_METHOD)
-        context.set_timeout(long(1234))
-        assert context.get_timeout() == 1234
-
     def test_set_verify_depth_wrong_args(self):
         """
         `Context.set_verify_depth` raises `TypeError` if called with a
         non-`int` argument.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.set_verify_depth(None)
 
@@ -823,30 +858,20 @@
         a chain to follow before giving up.  The value can be retrieved with
         `Context.get_verify_depth`.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.set_verify_depth(11)
         assert context.get_verify_depth() == 11
 
-    @skip_if_py3
-    def test_verify_depth_long(self):
-        """
-        On Python 2 `Context.set_verify_depth` accepts values of type `long`
-        as well as int.
-        """
-        context = Context(TLSv1_METHOD)
-        context.set_verify_depth(long(11))
-        assert context.get_verify_depth() == 11
-
     def _write_encrypted_pem(self, passphrase, tmpfile):
         """
         Write a new private key out to a new file, encrypted using the given
         passphrase.  Return the path to the new file.
         """
         key = PKey()
-        key.generate_key(TYPE_RSA, 512)
+        key.generate_key(TYPE_RSA, 1024)
         pem = dump_privatekey(FILETYPE_PEM, key, "blowfish", passphrase)
-        with open(tmpfile, 'w') as fObj:
-            fObj.write(pem.decode('ascii'))
+        with open(tmpfile, "w") as fObj:
+            fObj.write(pem.decode("ascii"))
         return tmpfile
 
     def test_set_passwd_cb_wrong_args(self):
@@ -854,7 +879,7 @@
         `Context.set_passwd_cb` raises `TypeError` if called with a
         non-callable first argument.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.set_passwd_cb(None)
 
@@ -870,7 +895,8 @@
         def passphraseCallback(maxlen, verify, extra):
             calledWith.append((maxlen, verify, extra))
             return passphrase
-        context = Context(TLSv1_METHOD)
+
+        context = Context(SSLv23_METHOD)
         context.set_passwd_cb(passphraseCallback)
         context.use_privatekey_file(pemFile)
         assert len(calledWith) == 1
@@ -888,7 +914,7 @@
         def passphraseCallback(maxlen, verify, extra):
             raise RuntimeError("Sorry, I am a fail.")
 
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.set_passwd_cb(passphraseCallback)
         with pytest.raises(RuntimeError):
             context.use_privatekey_file(pemFile)
@@ -903,7 +929,7 @@
         def passphraseCallback(maxlen, verify, extra):
             return b""
 
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.set_passwd_cb(passphraseCallback)
         with pytest.raises(Error):
             context.use_privatekey_file(pemFile)
@@ -918,7 +944,7 @@
         def passphraseCallback(maxlen, verify, extra):
             return 10
 
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.set_passwd_cb(passphraseCallback)
         # TODO: Surely this is the wrong error?
         with pytest.raises(ValueError):
@@ -937,7 +963,7 @@
             assert maxlen == 1024
             return passphrase + b"y"
 
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.set_passwd_cb(passphraseCallback)
         # This shall succeed because the truncated result is the correct
         # passphrase.
@@ -950,19 +976,18 @@
         """
         (server, client) = socket_pair()
 
-        clientSSL = Connection(Context(TLSv1_METHOD), client)
+        clientSSL = Connection(Context(SSLv23_METHOD), client)
         clientSSL.set_connect_state()
 
         called = []
 
         def info(conn, where, ret):
             called.append((conn, where, ret))
-        context = Context(TLSv1_METHOD)
+
+        context = Context(SSLv23_METHOD)
         context.set_info_callback(info)
-        context.use_certificate(
-            load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
-        context.use_privatekey(
-            load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
+        context.use_certificate(load_certificate(FILETYPE_PEM, root_cert_pem))
+        context.use_privatekey(load_privatekey(FILETYPE_PEM, root_key_pem))
 
         serverSSL = Connection(context, server)
         serverSSL.set_accept_state()
@@ -975,10 +1000,44 @@
         # assert it is called with the right Connection instance.  It would
         # also be good to assert *something* about `where` and `ret`.
         notConnections = [
-            conn for (conn, where, ret) in called
-            if not isinstance(conn, Connection)]
-        assert [] == notConnections, (
-            "Some info callback arguments were not Connection instances.")
+            conn
+            for (conn, where, ret) in called
+            if not isinstance(conn, Connection)
+        ]
+        assert (
+            [] == notConnections
+        ), "Some info callback arguments were not Connection instances."
+
+    @pytest.mark.skipif(
+        not getattr(_lib, "Cryptography_HAS_KEYLOG", None),
+        reason="SSL_CTX_set_keylog_callback unavailable",
+    )
+    def test_set_keylog_callback(self):
+        """
+        `Context.set_keylog_callback` accepts a callable which will be
+        invoked when key material is generated or received.
+        """
+        called = []
+
+        def keylog(conn, line):
+            called.append((conn, line))
+
+        server_context = Context(TLSv1_2_METHOD)
+        server_context.set_keylog_callback(keylog)
+        server_context.use_certificate(
+            load_certificate(FILETYPE_PEM, root_cert_pem)
+        )
+        server_context.use_privatekey(
+            load_privatekey(FILETYPE_PEM, root_key_pem)
+        )
+
+        client_context = Context(SSLv23_METHOD)
+
+        self._handshake_test(server_context, client_context)
+
+        assert called
+        assert all(isinstance(conn, Connection) for conn, line in called)
+        assert all(b"CLIENT_RANDOM" in line for conn, line in called)
 
     def _load_verify_locations_test(self, *args):
         """
@@ -988,22 +1047,25 @@
         """
         (server, client) = socket_pair()
 
-        clientContext = Context(TLSv1_METHOD)
+        clientContext = Context(SSLv23_METHOD)
         clientContext.load_verify_locations(*args)
         # Require that the server certificate verify properly or the
         # connection will fail.
         clientContext.set_verify(
             VERIFY_PEER,
-            lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
+            lambda conn, cert, errno, depth, preverify_ok: preverify_ok,
+        )
 
         clientSSL = Connection(clientContext, client)
         clientSSL.set_connect_state()
 
-        serverContext = Context(TLSv1_METHOD)
+        serverContext = Context(SSLv23_METHOD)
         serverContext.use_certificate(
-            load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
+            load_certificate(FILETYPE_PEM, root_cert_pem)
+        )
         serverContext.use_privatekey(
-            load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
+            load_privatekey(FILETYPE_PEM, root_key_pem)
+        )
 
         serverSSL = Connection(serverContext, server)
         serverSSL.set_accept_state()
@@ -1015,7 +1077,7 @@
         handshake(clientSSL, serverSSL)
 
         cert = clientSSL.get_peer_certificate()
-        assert cert.get_subject().CN == 'Testing Root CA'
+        assert cert.get_subject().CN == "Testing Root CA"
 
     def _load_verify_cafile(self, cafile):
         """
@@ -1024,8 +1086,8 @@
         certificate is used as a trust root for the purposes of verifying
         connections created using that `Context`.
         """
-        with open(cafile, 'w') as fObj:
-            fObj.write(cleartextCertificatePEM.decode('ascii'))
+        with open(cafile, "w") as fObj:
+            fObj.write(root_cert_pem.decode("ascii"))
 
         self._load_verify_locations_test(cafile)
 
@@ -1051,7 +1113,7 @@
         `Context.load_verify_locations` raises `Error` when passed a
         non-existent cafile.
         """
-        clientContext = Context(TLSv1_METHOD)
+        clientContext = Context(SSLv23_METHOD)
         with pytest.raises(Error):
             clientContext.load_verify_locations(tmpfile)
 
@@ -1066,10 +1128,10 @@
         # Hash values computed manually with c_rehash to avoid depending on
         # c_rehash in the test suite.  One is from OpenSSL 0.9.8, the other
         # from OpenSSL 1.0.0.
-        for name in [b'c7adac82.0', b'c3705638.0']:
+        for name in [b"c7adac82.0", b"c3705638.0"]:
             cafile = join_bytes_or_unicode(capath, name)
-            with open(cafile, 'w') as fObj:
-                fObj.write(cleartextCertificatePEM.decode('ascii'))
+            with open(cafile, "w") as fObj:
+                fObj.write(root_cert_pem.decode("ascii"))
 
         self._load_verify_locations_test(None, capath)
 
@@ -1096,7 +1158,7 @@
         `Context.load_verify_locations` raises `TypeError` if with non-`str`
         arguments.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.load_verify_locations(object())
         with pytest.raises(TypeError):
@@ -1105,7 +1167,7 @@
     @pytest.mark.skipif(
         not platform.startswith("linux"),
         reason="Loading fallback paths is a linux-specific behavior to "
-        "accommodate pyca/cryptography manylinux1 wheels"
+        "accommodate pyca/cryptography manylinux1 wheels",
     )
     def test_fallback_default_verify_paths(self, monkeypatch):
         """
@@ -1116,19 +1178,19 @@
         SSL_CTX_SET_default_verify_paths so that it can't find certs unless
         it loads via fallback.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         monkeypatch.setattr(
             _lib, "SSL_CTX_set_default_verify_paths", lambda x: 1
         )
         monkeypatch.setattr(
             SSL,
             "_CRYPTOGRAPHY_MANYLINUX1_CA_FILE",
-            _ffi.string(_lib.X509_get_default_cert_file())
+            _ffi.string(_lib.X509_get_default_cert_file()),
         )
         monkeypatch.setattr(
             SSL,
             "_CRYPTOGRAPHY_MANYLINUX1_CA_DIR",
-            _ffi.string(_lib.X509_get_default_cert_dir())
+            _ffi.string(_lib.X509_get_default_cert_dir()),
         )
         context.set_default_verify_paths()
         store = context.get_cert_store()
@@ -1141,7 +1203,7 @@
         """
         Test that we return True/False appropriately if the env vars are set.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         dir_var = "CUSTOM_DIR_VAR"
         file_var = "CUSTOM_FILE_VAR"
         assert context._check_env_vars_set(dir_var, file_var) is False
@@ -1154,13 +1216,13 @@
         """
         Test that we don't use the fallback path if env vars are set.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         monkeypatch.setattr(
             _lib, "SSL_CTX_set_default_verify_paths", lambda x: 1
         )
-        dir_env_var = _ffi.string(
-            _lib.X509_get_default_cert_dir_env()
-        ).decode("ascii")
+        dir_env_var = _ffi.string(_lib.X509_get_default_cert_dir_env()).decode(
+            "ascii"
+        )
         file_env_var = _ffi.string(
             _lib.X509_get_default_cert_file_env()
         ).decode("ascii")
@@ -1169,16 +1231,14 @@
         context.set_default_verify_paths()
 
         monkeypatch.setattr(
-            context,
-            "_fallback_default_verify_paths",
-            raiser(SystemError)
+            context, "_fallback_default_verify_paths", raiser(SystemError)
         )
         context.set_default_verify_paths()
 
     @pytest.mark.skipif(
         platform == "win32",
         reason="set_default_verify_paths appears not to work on Windows.  "
-        "See LP#404343 and LP#404344."
+        "See LP#404343 and LP#404344.",
     )
     def test_set_default_verify_paths(self):
         """
@@ -1196,9 +1256,10 @@
         context.set_default_verify_paths()
         context.set_verify(
             VERIFY_PEER,
-            lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
+            lambda conn, cert, errno, depth, preverify_ok: preverify_ok,
+        )
 
-        client = socket()
+        client = socket_any_family()
         client.connect(("encrypted.google.com", 443))
         clientSSL = Connection(context, client)
         clientSSL.set_connect_state()
@@ -1212,18 +1273,16 @@
         Test that when passed empty arrays or paths that do not exist no
         errors are raised.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context._fallback_default_verify_paths([], [])
-        context._fallback_default_verify_paths(
-            ["/not/a/file"], ["/not/a/dir"]
-        )
+        context._fallback_default_verify_paths(["/not/a/file"], ["/not/a/dir"])
 
     def test_add_extra_chain_cert_invalid_cert(self):
         """
         `Context.add_extra_chain_cert` raises `TypeError` if called with an
         object which is not an instance of `X509`.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.add_extra_chain_cert(object())
 
@@ -1254,11 +1313,13 @@
         The first argument passed to the verify callback is the
         `Connection` instance for which verification is taking place.
         """
-        serverContext = Context(TLSv1_METHOD)
+        serverContext = Context(SSLv23_METHOD)
         serverContext.use_privatekey(
-            load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
+            load_privatekey(FILETYPE_PEM, root_key_pem)
+        )
         serverContext.use_certificate(
-            load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
+            load_certificate(FILETYPE_PEM, root_cert_pem)
+        )
         serverConnection = Connection(serverContext, None)
 
         class VerifyCallback(object):
@@ -1267,7 +1328,7 @@
                 return 1
 
         verify = VerifyCallback()
-        clientContext = Context(TLSv1_METHOD)
+        clientContext = Context(SSLv23_METHOD)
         clientContext.set_verify(VERIFY_PEER, verify.callback)
         clientConnection = Connection(clientContext, None)
         clientConnection.set_connect_state()
@@ -1283,18 +1344,20 @@
         get_subject. This test sets up a handshake where we call get_subject
         on the cert provided to the verify callback.
         """
-        serverContext = Context(TLSv1_METHOD)
+        serverContext = Context(SSLv23_METHOD)
         serverContext.use_privatekey(
-            load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
+            load_privatekey(FILETYPE_PEM, root_key_pem)
+        )
         serverContext.use_certificate(
-            load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
+            load_certificate(FILETYPE_PEM, root_cert_pem)
+        )
         serverConnection = Connection(serverContext, None)
 
         def verify_cb_get_subject(conn, cert, errnum, depth, ok):
             assert cert.get_subject()
             return 1
 
-        clientContext = Context(TLSv1_METHOD)
+        clientContext = Context(SSLv23_METHOD)
         clientContext.set_verify(VERIFY_PEER, verify_cb_get_subject)
         clientConnection = Connection(clientContext, None)
         clientConnection.set_connect_state()
@@ -1309,14 +1372,17 @@
         """
         serverContext = Context(TLSv1_2_METHOD)
         serverContext.use_privatekey(
-            load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
+            load_privatekey(FILETYPE_PEM, root_key_pem)
+        )
         serverContext.use_certificate(
-            load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
+            load_certificate(FILETYPE_PEM, root_cert_pem)
+        )
 
         clientContext = Context(TLSv1_2_METHOD)
 
         def verify_callback(*args):
             raise Exception("silly verify failure")
+
         clientContext.set_verify(VERIFY_PEER, verify_callback)
 
         with pytest.raises(Exception) as exc:
@@ -1324,6 +1390,74 @@
 
         assert "silly verify failure" == str(exc.value)
 
+    def test_set_verify_callback_reference(self):
+        """
+        If the verify callback passed to `Context.set_verify` is set multiple
+        times, the pointers to the old call functions should not be dangling
+        and trigger a segfault.
+        """
+        serverContext = Context(TLSv1_2_METHOD)
+        serverContext.use_privatekey(
+            load_privatekey(FILETYPE_PEM, root_key_pem)
+        )
+        serverContext.use_certificate(
+            load_certificate(FILETYPE_PEM, root_cert_pem)
+        )
+
+        clientContext = Context(TLSv1_2_METHOD)
+
+        clients = []
+
+        for i in range(5):
+
+            def verify_callback(*args):
+                return True
+
+            serverSocket, clientSocket = socket_pair()
+            client = Connection(clientContext, clientSocket)
+
+            clients.append((serverSocket, client))
+
+            clientContext.set_verify(VERIFY_PEER, verify_callback)
+
+        gc.collect()
+
+        # Make them talk to each other.
+        for serverSocket, client in clients:
+            server = Connection(serverContext, serverSocket)
+            server.set_accept_state()
+            client.set_connect_state()
+
+            for _ in range(5):
+                for s in [client, server]:
+                    try:
+                        s.do_handshake()
+                    except WantReadError:
+                        pass
+
+    @pytest.mark.parametrize("mode", [SSL.VERIFY_PEER, SSL.VERIFY_NONE])
+    def test_set_verify_default_callback(self, mode):
+        """
+        If the verify callback is omitted, the preverify value is used.
+        """
+        serverContext = Context(TLSv1_2_METHOD)
+        serverContext.use_privatekey(
+            load_privatekey(FILETYPE_PEM, root_key_pem)
+        )
+        serverContext.use_certificate(
+            load_certificate(FILETYPE_PEM, root_cert_pem)
+        )
+
+        clientContext = Context(TLSv1_2_METHOD)
+        clientContext.set_verify(mode, None)
+
+        if mode == SSL.VERIFY_PEER:
+            with pytest.raises(Exception) as exc:
+                self._handshake_test(serverContext, clientContext)
+            assert "certificate verify failed" in str(exc.value)
+        else:
+            self._handshake_test(serverContext, clientContext)
+
     def test_add_extra_chain_cert(self, tmpdir):
         """
         `Context.add_extra_chain_cert` accepts an `X509`
@@ -1341,29 +1475,30 @@
 
         # Dump the CA certificate to a file because that's the only way to load
         # it as a trusted CA in the client context.
-        for cert, name in [(cacert, 'ca.pem'),
-                           (icert, 'i.pem'),
-                           (scert, 's.pem')]:
-            with tmpdir.join(name).open('w') as f:
-                f.write(dump_certificate(FILETYPE_PEM, cert).decode('ascii'))
+        for cert, name in [
+            (cacert, "ca.pem"),
+            (icert, "i.pem"),
+            (scert, "s.pem"),
+        ]:
+            with tmpdir.join(name).open("w") as f:
+                f.write(dump_certificate(FILETYPE_PEM, cert).decode("ascii"))
 
-        for key, name in [(cakey, 'ca.key'),
-                          (ikey, 'i.key'),
-                          (skey, 's.key')]:
-            with tmpdir.join(name).open('w') as f:
-                f.write(dump_privatekey(FILETYPE_PEM, key).decode('ascii'))
+        for key, name in [(cakey, "ca.key"), (ikey, "i.key"), (skey, "s.key")]:
+            with tmpdir.join(name).open("w") as f:
+                f.write(dump_privatekey(FILETYPE_PEM, key).decode("ascii"))
 
         # Create the server context
-        serverContext = Context(TLSv1_METHOD)
+        serverContext = Context(SSLv23_METHOD)
         serverContext.use_privatekey(skey)
         serverContext.use_certificate(scert)
         # The client already has cacert, we only need to give them icert.
         serverContext.add_extra_chain_cert(icert)
 
         # Create the client
-        clientContext = Context(TLSv1_METHOD)
+        clientContext = Context(SSLv23_METHOD)
         clientContext.set_verify(
-            VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
+            VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb
+        )
         clientContext.load_verify_locations(str(tmpdir.join("ca.pem")))
 
         # Try it out.
@@ -1387,22 +1522,23 @@
         caFile = join_bytes_or_unicode(certdir, "ca.pem")
 
         # Write out the chain file.
-        with open(chainFile, 'wb') as fObj:
+        with open(chainFile, "wb") as fObj:
             # Most specific to least general.
             fObj.write(dump_certificate(FILETYPE_PEM, scert))
             fObj.write(dump_certificate(FILETYPE_PEM, icert))
             fObj.write(dump_certificate(FILETYPE_PEM, cacert))
 
-        with open(caFile, 'w') as fObj:
-            fObj.write(dump_certificate(FILETYPE_PEM, cacert).decode('ascii'))
+        with open(caFile, "w") as fObj:
+            fObj.write(dump_certificate(FILETYPE_PEM, cacert).decode("ascii"))
 
-        serverContext = Context(TLSv1_METHOD)
+        serverContext = Context(SSLv23_METHOD)
         serverContext.use_certificate_chain_file(chainFile)
         serverContext.use_privatekey(skey)
 
-        clientContext = Context(TLSv1_METHOD)
+        clientContext = Context(SSLv23_METHOD)
         clientContext.set_verify(
-            VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
+            VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb
+        )
         clientContext.load_verify_locations(caFile)
 
         self._handshake_test(serverContext, clientContext)
@@ -1432,7 +1568,7 @@
         `Context.use_certificate_chain_file` raises `TypeError` if passed a
         non-byte string single argument.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.use_certificate_chain_file(object())
 
@@ -1442,7 +1578,7 @@
         passed a bad chain file name (for example, the name of a file which
         does not exist).
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(Error):
             context.use_certificate_chain_file(tmpfile)
 
@@ -1451,42 +1587,28 @@
         `Context.get_verify_mode` returns the verify mode flags previously
         passed to `Context.set_verify`.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         assert context.get_verify_mode() == 0
-        context.set_verify(
-            VERIFY_PEER | VERIFY_CLIENT_ONCE, lambda *args: None)
+        context.set_verify(VERIFY_PEER | VERIFY_CLIENT_ONCE)
         assert context.get_verify_mode() == (VERIFY_PEER | VERIFY_CLIENT_ONCE)
 
-    @skip_if_py3
-    def test_set_verify_mode_long(self):
-        """
-        On Python 2 `Context.set_verify_mode` accepts values of type `long`
-        as well as `int`.
-        """
-        context = Context(TLSv1_METHOD)
-        assert context.get_verify_mode() == 0
-        context.set_verify(
-            long(VERIFY_PEER | VERIFY_CLIENT_ONCE), lambda *args: None
-        )  # pragma: nocover
-        assert context.get_verify_mode() == (VERIFY_PEER | VERIFY_CLIENT_ONCE)
-
-    @pytest.mark.parametrize('mode', [None, 1.0, object(), 'mode'])
+    @pytest.mark.parametrize("mode", [None, 1.0, object(), "mode"])
     def test_set_verify_wrong_mode_arg(self, mode):
         """
         `Context.set_verify` raises `TypeError` if the first argument is
         not an integer.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
-            context.set_verify(mode=mode, callback=lambda *args: None)
+            context.set_verify(mode=mode)
 
-    @pytest.mark.parametrize('callback', [None, 1.0, 'mode', ('foo', 'bar')])
+    @pytest.mark.parametrize("callback", [1.0, "mode", ("foo", "bar")])
     def test_set_verify_wrong_callable_arg(self, callback):
         """
         `Context.set_verify` raises `TypeError` if the second argument
         is not callable.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.set_verify(mode=VERIFY_PEER, callback=callback)
 
@@ -1495,7 +1617,7 @@
         `Context.load_tmp_dh` raises `TypeError` if called with a
         non-`str` argument.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.load_tmp_dh(object())
 
@@ -1504,7 +1626,7 @@
         `Context.load_tmp_dh` raises `OpenSSL.SSL.Error` if the
         specified file does not exist.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(Error):
             context.load_tmp_dh(b"hello")
 
@@ -1513,12 +1635,11 @@
         Verify that calling ``Context.load_tmp_dh`` with the given filename
         does not raise an exception.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with open(dhfilename, "w") as dhfile:
             dhfile.write(dhparam)
 
         context.load_tmp_dh(dhfilename)
-        # XXX What should I assert here? -exarkun
 
     def test_load_tmp_dh_bytes(self, tmpfile):
         """
@@ -1543,7 +1664,7 @@
         `Context.set_tmp_ecdh` sets the elliptic curve for Diffie-Hellman to
         the specified curve.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         for curve in get_elliptic_curves():
             if curve.name.startswith(u"Oakley-"):
                 # Setting Oakley-EC2N-4 and Oakley-EC2N-3 adds
@@ -1560,7 +1681,7 @@
         a non-integer argument.
         called with other than one integer argument.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             context.set_session_cache_mode(object())
 
@@ -1569,27 +1690,17 @@
         `Context.set_session_cache_mode` specifies how sessions are cached.
         The setting can be retrieved via `Context.get_session_cache_mode`.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.set_session_cache_mode(SESS_CACHE_OFF)
         off = context.set_session_cache_mode(SESS_CACHE_BOTH)
         assert SESS_CACHE_OFF == off
         assert SESS_CACHE_BOTH == context.get_session_cache_mode()
 
-    @skip_if_py3
-    def test_session_cache_mode_long(self):
-        """
-        On Python 2 `Context.set_session_cache_mode` accepts values
-        of type `long` as well as `int`.
-        """
-        context = Context(TLSv1_METHOD)
-        context.set_session_cache_mode(long(SESS_CACHE_BOTH))
-        assert SESS_CACHE_BOTH == context.get_session_cache_mode()
-
     def test_get_cert_store(self):
         """
         `Context.get_cert_store` returns a `X509Store` instance.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         store = context.get_cert_store()
         assert isinstance(store, X509Store)
 
@@ -1599,9 +1710,9 @@
 
         It raises a TypeError if the list of profiles is not a byte string.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
-            context.set_tlsext_use_srtp(text_type('SRTP_AES128_CM_SHA1_80'))
+            context.set_tlsext_use_srtp(text_type("SRTP_AES128_CM_SHA1_80"))
 
     def test_set_tlsext_use_srtp_invalid_profile(self):
         """
@@ -1609,9 +1720,9 @@
 
         It raises an Error if the call to OpenSSL fails.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         with pytest.raises(Error):
-            context.set_tlsext_use_srtp(b'SRTP_BOGUS')
+            context.set_tlsext_use_srtp(b"SRTP_BOGUS")
 
     def test_set_tlsext_use_srtp_valid(self):
         """
@@ -1619,8 +1730,8 @@
 
         It does not return anything.
         """
-        context = Context(TLSv1_METHOD)
-        assert context.set_tlsext_use_srtp(b'SRTP_AES128_CM_SHA1_80') is None
+        context = Context(SSLv23_METHOD)
+        assert context.set_tlsext_use_srtp(b"SRTP_AES128_CM_SHA1_80") is None
 
 
 class TestServerNameCallback(object):
@@ -1628,18 +1739,20 @@
     Tests for `Context.set_tlsext_servername_callback` and its
     interaction with `Connection`.
     """
+
     def test_old_callback_forgotten(self):
         """
         If `Context.set_tlsext_servername_callback` is used to specify
         a new callback, the one it replaces is dereferenced.
         """
+
         def callback(connection):  # pragma: no cover
             pass
 
         def replacement(connection):  # pragma: no cover
             pass
 
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.set_tlsext_servername_callback(callback)
 
         tracker = ref(callback)
@@ -1670,7 +1783,8 @@
 
         def servername(conn):
             args.append((conn, conn.get_servername()))
-        context = Context(TLSv1_METHOD)
+
+        context = Context(SSLv23_METHOD)
         context.set_tlsext_servername_callback(servername)
 
         # Lose our reference to it.  The Context is responsible for keeping it
@@ -1681,13 +1795,14 @@
         # Necessary to actually accept the connection
         context.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
         context.use_certificate(
-            load_certificate(FILETYPE_PEM, server_cert_pem))
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
 
         # Do a little connection to trigger the logic
         server = Connection(context, None)
         server.set_accept_state()
 
-        client = Connection(Context(TLSv1_METHOD), None)
+        client = Connection(Context(SSLv23_METHOD), None)
         client.set_connect_state()
 
         interact_in_memory(server, client)
@@ -1705,19 +1820,21 @@
 
         def servername(conn):
             args.append((conn, conn.get_servername()))
-        context = Context(TLSv1_METHOD)
+
+        context = Context(SSLv23_METHOD)
         context.set_tlsext_servername_callback(servername)
 
         # Necessary to actually accept the connection
         context.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
         context.use_certificate(
-            load_certificate(FILETYPE_PEM, server_cert_pem))
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
 
         # Do a little connection to trigger the logic
         server = Connection(context, None)
         server.set_accept_state()
 
-        client = Connection(Context(TLSv1_METHOD), None)
+        client = Connection(Context(SSLv23_METHOD), None)
         client.set_connect_state()
         client.set_tlsext_host_name(b"foo1.example.com")
 
@@ -1726,38 +1843,36 @@
         assert args == [(server, b"foo1.example.com")]
 
 
-class TestNextProtoNegotiation(object):
+class TestApplicationLayerProtoNegotiation(object):
     """
-    Test for Next Protocol Negotiation in PyOpenSSL.
+    Tests for ALPN in PyOpenSSL.
     """
-    def test_npn_success(self):
-        """
-        Tests that clients and servers that agree on the negotiated next
-        protocol can correct establish a connection, and that the agreed
-        protocol is reported by the connections.
-        """
-        advertise_args = []
-        select_args = []
 
-        def advertise(conn):
-            advertise_args.append((conn,))
-            return [b'http/1.1', b'spdy/2']
+    def test_alpn_success(self):
+        """
+        Clients and servers that agree on the negotiated ALPN protocol can
+        correct establish a connection, and the agreed protocol is reported
+        by the connections.
+        """
+        select_args = []
 
         def select(conn, options):
             select_args.append((conn, options))
-            return b'spdy/2'
+            return b"spdy/2"
 
-        server_context = Context(TLSv1_METHOD)
-        server_context.set_npn_advertise_callback(advertise)
+        client_context = Context(SSLv23_METHOD)
+        client_context.set_alpn_protos([b"http/1.1", b"spdy/2"])
 
-        client_context = Context(TLSv1_METHOD)
-        client_context.set_npn_select_callback(select)
+        server_context = Context(SSLv23_METHOD)
+        server_context.set_alpn_select_callback(select)
 
         # Necessary to actually accept the connection
         server_context.use_privatekey(
-            load_privatekey(FILETYPE_PEM, server_key_pem))
+            load_privatekey(FILETYPE_PEM, server_key_pem)
+        )
         server_context.use_certificate(
-            load_certificate(FILETYPE_PEM, server_cert_pem))
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
 
         # Do a little connection to trigger the logic
         server = Connection(server_context, None)
@@ -1768,39 +1883,76 @@
 
         interact_in_memory(server, client)
 
-        assert advertise_args == [(server,)]
-        assert select_args == [(client, [b'http/1.1', b'spdy/2'])]
+        assert select_args == [(server, [b"http/1.1", b"spdy/2"])]
 
-        assert server.get_next_proto_negotiated() == b'spdy/2'
-        assert client.get_next_proto_negotiated() == b'spdy/2'
+        assert server.get_alpn_proto_negotiated() == b"spdy/2"
+        assert client.get_alpn_proto_negotiated() == b"spdy/2"
 
-    def test_npn_client_fail(self):
+    def test_alpn_set_on_connection(self):
         """
-        Tests that when clients and servers cannot agree on what protocol
-        to use next that the TLS connection does not get established.
+        The same as test_alpn_success, but setting the ALPN protocols on
+        the connection rather than the context.
         """
-        advertise_args = []
         select_args = []
 
-        def advertise(conn):
-            advertise_args.append((conn,))
-            return [b'http/1.1', b'spdy/2']
-
         def select(conn, options):
             select_args.append((conn, options))
-            return b''
+            return b"spdy/2"
 
-        server_context = Context(TLSv1_METHOD)
-        server_context.set_npn_advertise_callback(advertise)
+        # Setup the client context but don't set any ALPN protocols.
+        client_context = Context(SSLv23_METHOD)
 
-        client_context = Context(TLSv1_METHOD)
-        client_context.set_npn_select_callback(select)
+        server_context = Context(SSLv23_METHOD)
+        server_context.set_alpn_select_callback(select)
 
         # Necessary to actually accept the connection
         server_context.use_privatekey(
-            load_privatekey(FILETYPE_PEM, server_key_pem))
+            load_privatekey(FILETYPE_PEM, server_key_pem)
+        )
         server_context.use_certificate(
-            load_certificate(FILETYPE_PEM, server_cert_pem))
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
+
+        # Do a little connection to trigger the logic
+        server = Connection(server_context, None)
+        server.set_accept_state()
+
+        # Set the ALPN protocols on the client connection.
+        client = Connection(client_context, None)
+        client.set_alpn_protos([b"http/1.1", b"spdy/2"])
+        client.set_connect_state()
+
+        interact_in_memory(server, client)
+
+        assert select_args == [(server, [b"http/1.1", b"spdy/2"])]
+
+        assert server.get_alpn_proto_negotiated() == b"spdy/2"
+        assert client.get_alpn_proto_negotiated() == b"spdy/2"
+
+    def test_alpn_server_fail(self):
+        """
+        When clients and servers cannot agree on what protocol to use next
+        the TLS connection does not get established.
+        """
+        select_args = []
+
+        def select(conn, options):
+            select_args.append((conn, options))
+            return b""
+
+        client_context = Context(SSLv23_METHOD)
+        client_context.set_alpn_protos([b"http/1.1", b"spdy/2"])
+
+        server_context = Context(SSLv23_METHOD)
+        server_context.set_alpn_select_callback(select)
+
+        # Necessary to actually accept the connection
+        server_context.use_privatekey(
+            load_privatekey(FILETYPE_PEM, server_key_pem)
+        )
+        server_context.use_certificate(
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
 
         # Do a little connection to trigger the logic
         server = Connection(server_context, None)
@@ -1813,34 +1965,33 @@
         with pytest.raises(Error):
             interact_in_memory(server, client)
 
-        assert advertise_args == [(server,)]
-        assert select_args == [(client, [b'http/1.1', b'spdy/2'])]
+        assert select_args == [(server, [b"http/1.1", b"spdy/2"])]
 
-    def test_npn_select_error(self):
+    def test_alpn_no_server_overlap(self):
         """
-        Test that we can handle exceptions in the select callback. If
-        select fails it should be fatal to the connection.
+        A server can allow a TLS handshake to complete without
+        agreeing to an application protocol by returning
+        ``NO_OVERLAPPING_PROTOCOLS``.
         """
-        advertise_args = []
+        refusal_args = []
 
-        def advertise(conn):
-            advertise_args.append((conn,))
-            return [b'http/1.1', b'spdy/2']
+        def refusal(conn, options):
+            refusal_args.append((conn, options))
+            return NO_OVERLAPPING_PROTOCOLS
 
-        def select(conn, options):
-            raise TypeError
+        client_context = Context(SSLv23_METHOD)
+        client_context.set_alpn_protos([b"http/1.1", b"spdy/2"])
 
-        server_context = Context(TLSv1_METHOD)
-        server_context.set_npn_advertise_callback(advertise)
-
-        client_context = Context(TLSv1_METHOD)
-        client_context.set_npn_select_callback(select)
+        server_context = Context(SSLv23_METHOD)
+        server_context.set_alpn_select_callback(refusal)
 
         # Necessary to actually accept the connection
         server_context.use_privatekey(
-            load_privatekey(FILETYPE_PEM, server_key_pem))
+            load_privatekey(FILETYPE_PEM, server_key_pem)
+        )
         server_context.use_certificate(
-            load_certificate(FILETYPE_PEM, server_cert_pem))
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
 
         # Do a little connection to trigger the logic
         server = Connection(server_context, None)
@@ -1849,39 +2000,107 @@
         client = Connection(client_context, None)
         client.set_connect_state()
 
-        # If the callback throws an exception it should be raised here.
+        # Do the dance.
+        interact_in_memory(server, client)
+
+        assert refusal_args == [(server, [b"http/1.1", b"spdy/2"])]
+
+        assert client.get_alpn_proto_negotiated() == b""
+
+    def test_alpn_select_cb_returns_invalid_value(self):
+        """
+        If the ALPN selection callback returns anything other than
+        a bytestring or ``NO_OVERLAPPING_PROTOCOLS``, a
+        :py:exc:`TypeError` is raised.
+        """
+        invalid_cb_args = []
+
+        def invalid_cb(conn, options):
+            invalid_cb_args.append((conn, options))
+            return u"can't return unicode"
+
+        client_context = Context(SSLv23_METHOD)
+        client_context.set_alpn_protos([b"http/1.1", b"spdy/2"])
+
+        server_context = Context(SSLv23_METHOD)
+        server_context.set_alpn_select_callback(invalid_cb)
+
+        # Necessary to actually accept the connection
+        server_context.use_privatekey(
+            load_privatekey(FILETYPE_PEM, server_key_pem)
+        )
+        server_context.use_certificate(
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
+
+        # Do a little connection to trigger the logic
+        server = Connection(server_context, None)
+        server.set_accept_state()
+
+        client = Connection(client_context, None)
+        client.set_connect_state()
+
+        # Do the dance.
         with pytest.raises(TypeError):
             interact_in_memory(server, client)
-        assert advertise_args == [(server,), ]
 
-    def test_npn_advertise_error(self):
+        assert invalid_cb_args == [(server, [b"http/1.1", b"spdy/2"])]
+
+        assert client.get_alpn_proto_negotiated() == b""
+
+    def test_alpn_no_server(self):
         """
-        Test that we can handle exceptions in the advertise callback. If
-        advertise fails no NPN is advertised to the client.
+        When clients and servers cannot agree on what protocol to use next
+        because the server doesn't offer ALPN, no protocol is negotiated.
+        """
+        client_context = Context(SSLv23_METHOD)
+        client_context.set_alpn_protos([b"http/1.1", b"spdy/2"])
+
+        server_context = Context(SSLv23_METHOD)
+
+        # Necessary to actually accept the connection
+        server_context.use_privatekey(
+            load_privatekey(FILETYPE_PEM, server_key_pem)
+        )
+        server_context.use_certificate(
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
+
+        # Do a little connection to trigger the logic
+        server = Connection(server_context, None)
+        server.set_accept_state()
+
+        client = Connection(client_context, None)
+        client.set_connect_state()
+
+        # Do the dance.
+        interact_in_memory(server, client)
+
+        assert client.get_alpn_proto_negotiated() == b""
+
+    def test_alpn_callback_exception(self):
+        """
+        We can handle exceptions in the ALPN select callback.
         """
         select_args = []
 
-        def advertise(conn):
-            raise TypeError
-
-        def select(conn, options):  # pragma: nocover
-            """
-            Assert later that no args are actually appended.
-            """
+        def select(conn, options):
             select_args.append((conn, options))
-            return b''
+            raise TypeError()
 
-        server_context = Context(TLSv1_METHOD)
-        server_context.set_npn_advertise_callback(advertise)
+        client_context = Context(SSLv23_METHOD)
+        client_context.set_alpn_protos([b"http/1.1", b"spdy/2"])
 
-        client_context = Context(TLSv1_METHOD)
-        client_context.set_npn_select_callback(select)
+        server_context = Context(SSLv23_METHOD)
+        server_context.set_alpn_select_callback(select)
 
         # Necessary to actually accept the connection
         server_context.use_privatekey(
-            load_privatekey(FILETYPE_PEM, server_key_pem))
+            load_privatekey(FILETYPE_PEM, server_key_pem)
+        )
         server_context.use_certificate(
-            load_certificate(FILETYPE_PEM, server_cert_pem))
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
 
         # Do a little connection to trigger the logic
         server = Connection(server_context, None)
@@ -1890,216 +2109,16 @@
         client = Connection(client_context, None)
         client.set_connect_state()
 
-        # If the client doesn't return anything, the connection will fail.
         with pytest.raises(TypeError):
             interact_in_memory(server, client)
-        assert select_args == []
-
-
-class TestApplicationLayerProtoNegotiation(object):
-    """
-    Tests for ALPN in PyOpenSSL.
-    """
-    # Skip tests on versions that don't support ALPN.
-    if _lib.Cryptography_HAS_ALPN:
-
-        def test_alpn_success(self):
-            """
-            Clients and servers that agree on the negotiated ALPN protocol can
-            correct establish a connection, and the agreed protocol is reported
-            by the connections.
-            """
-            select_args = []
-
-            def select(conn, options):
-                select_args.append((conn, options))
-                return b'spdy/2'
-
-            client_context = Context(TLSv1_METHOD)
-            client_context.set_alpn_protos([b'http/1.1', b'spdy/2'])
-
-            server_context = Context(TLSv1_METHOD)
-            server_context.set_alpn_select_callback(select)
-
-            # Necessary to actually accept the connection
-            server_context.use_privatekey(
-                load_privatekey(FILETYPE_PEM, server_key_pem))
-            server_context.use_certificate(
-                load_certificate(FILETYPE_PEM, server_cert_pem))
-
-            # Do a little connection to trigger the logic
-            server = Connection(server_context, None)
-            server.set_accept_state()
-
-            client = Connection(client_context, None)
-            client.set_connect_state()
-
-            interact_in_memory(server, client)
-
-            assert select_args == [(server, [b'http/1.1', b'spdy/2'])]
-
-            assert server.get_alpn_proto_negotiated() == b'spdy/2'
-            assert client.get_alpn_proto_negotiated() == b'spdy/2'
-
-        def test_alpn_set_on_connection(self):
-            """
-            The same as test_alpn_success, but setting the ALPN protocols on
-            the connection rather than the context.
-            """
-            select_args = []
-
-            def select(conn, options):
-                select_args.append((conn, options))
-                return b'spdy/2'
-
-            # Setup the client context but don't set any ALPN protocols.
-            client_context = Context(TLSv1_METHOD)
-
-            server_context = Context(TLSv1_METHOD)
-            server_context.set_alpn_select_callback(select)
-
-            # Necessary to actually accept the connection
-            server_context.use_privatekey(
-                load_privatekey(FILETYPE_PEM, server_key_pem))
-            server_context.use_certificate(
-                load_certificate(FILETYPE_PEM, server_cert_pem))
-
-            # Do a little connection to trigger the logic
-            server = Connection(server_context, None)
-            server.set_accept_state()
-
-            # Set the ALPN protocols on the client connection.
-            client = Connection(client_context, None)
-            client.set_alpn_protos([b'http/1.1', b'spdy/2'])
-            client.set_connect_state()
-
-            interact_in_memory(server, client)
-
-            assert select_args == [(server, [b'http/1.1', b'spdy/2'])]
-
-            assert server.get_alpn_proto_negotiated() == b'spdy/2'
-            assert client.get_alpn_proto_negotiated() == b'spdy/2'
-
-        def test_alpn_server_fail(self):
-            """
-            When clients and servers cannot agree on what protocol to use next
-            the TLS connection does not get established.
-            """
-            select_args = []
-
-            def select(conn, options):
-                select_args.append((conn, options))
-                return b''
-
-            client_context = Context(TLSv1_METHOD)
-            client_context.set_alpn_protos([b'http/1.1', b'spdy/2'])
-
-            server_context = Context(TLSv1_METHOD)
-            server_context.set_alpn_select_callback(select)
-
-            # Necessary to actually accept the connection
-            server_context.use_privatekey(
-                load_privatekey(FILETYPE_PEM, server_key_pem))
-            server_context.use_certificate(
-                load_certificate(FILETYPE_PEM, server_cert_pem))
-
-            # Do a little connection to trigger the logic
-            server = Connection(server_context, None)
-            server.set_accept_state()
-
-            client = Connection(client_context, None)
-            client.set_connect_state()
-
-            # If the client doesn't return anything, the connection will fail.
-            with pytest.raises(Error):
-                interact_in_memory(server, client)
-
-            assert select_args == [(server, [b'http/1.1', b'spdy/2'])]
-
-        def test_alpn_no_server(self):
-            """
-            When clients and servers cannot agree on what protocol to use next
-            because the server doesn't offer ALPN, no protocol is negotiated.
-            """
-            client_context = Context(TLSv1_METHOD)
-            client_context.set_alpn_protos([b'http/1.1', b'spdy/2'])
-
-            server_context = Context(TLSv1_METHOD)
-
-            # Necessary to actually accept the connection
-            server_context.use_privatekey(
-                load_privatekey(FILETYPE_PEM, server_key_pem))
-            server_context.use_certificate(
-                load_certificate(FILETYPE_PEM, server_cert_pem))
-
-            # Do a little connection to trigger the logic
-            server = Connection(server_context, None)
-            server.set_accept_state()
-
-            client = Connection(client_context, None)
-            client.set_connect_state()
-
-            # Do the dance.
-            interact_in_memory(server, client)
-
-            assert client.get_alpn_proto_negotiated() == b''
-
-        def test_alpn_callback_exception(self):
-            """
-            We can handle exceptions in the ALPN select callback.
-            """
-            select_args = []
-
-            def select(conn, options):
-                select_args.append((conn, options))
-                raise TypeError()
-
-            client_context = Context(TLSv1_METHOD)
-            client_context.set_alpn_protos([b'http/1.1', b'spdy/2'])
-
-            server_context = Context(TLSv1_METHOD)
-            server_context.set_alpn_select_callback(select)
-
-            # Necessary to actually accept the connection
-            server_context.use_privatekey(
-                load_privatekey(FILETYPE_PEM, server_key_pem))
-            server_context.use_certificate(
-                load_certificate(FILETYPE_PEM, server_cert_pem))
-
-            # Do a little connection to trigger the logic
-            server = Connection(server_context, None)
-            server.set_accept_state()
-
-            client = Connection(client_context, None)
-            client.set_connect_state()
-
-            with pytest.raises(TypeError):
-                interact_in_memory(server, client)
-            assert select_args == [(server, [b'http/1.1', b'spdy/2'])]
-
-    else:
-        # No ALPN.
-        def test_alpn_not_implemented(self):
-            """
-            If ALPN is not in OpenSSL, we should raise NotImplementedError.
-            """
-            # Test the context methods first.
-            context = Context(TLSv1_METHOD)
-            with pytest.raises(NotImplementedError):
-                context.set_alpn_protos(None)
-            with pytest.raises(NotImplementedError):
-                context.set_alpn_select_callback(None)
-
-            # Now test a connection.
-            conn = Connection(context)
-            with pytest.raises(NotImplementedError):
-                conn.set_alpn_protos(None)
+        assert select_args == [(server, [b"http/1.1", b"spdy/2"])]
 
 
 class TestSession(object):
     """
     Unit tests for :py:obj:`OpenSSL.SSL.Session`.
     """
+
     def test_construction(self):
         """
         :py:class:`Session` can be constructed with no arguments, creating
@@ -2113,6 +2132,7 @@
     """
     Unit tests for `OpenSSL.SSL.Connection`.
     """
+
     # XXX get_peer_certificate -> None
     # XXX sock_shutdown
     # XXX master_key -> TypeError
@@ -2129,14 +2149,12 @@
 
     def test_type(self):
         """
-        `Connection` and `ConnectionType` refer to the same type object and
-        can be used to create instances of that type.
+        `Connection` can be used to create instances of that type.
         """
-        assert Connection is ConnectionType
-        ctx = Context(TLSv1_METHOD)
-        assert is_consistent_type(Connection, 'Connection', ctx, None)
+        ctx = Context(SSLv23_METHOD)
+        assert is_consistent_type(Connection, "Connection", ctx, None)
 
-    @pytest.mark.parametrize('bad_context', [object(), 'context', None, 1])
+    @pytest.mark.parametrize("bad_context", [object(), "context", None, 1])
     def test_wrong_args(self, bad_context):
         """
         `Connection.__init__` raises `TypeError` if called with a non-`Context`
@@ -2145,12 +2163,35 @@
         with pytest.raises(TypeError):
             Connection(bad_context)
 
+    @pytest.mark.parametrize("bad_bio", [object(), None, 1, [1, 2, 3]])
+    def test_bio_write_wrong_args(self, bad_bio):
+        """
+        `Connection.bio_write` raises `TypeError` if called with a non-bytes
+        (or text) argument.
+        """
+        context = Context(SSLv23_METHOD)
+        connection = Connection(context, None)
+        with pytest.raises(TypeError):
+            connection.bio_write(bad_bio)
+
+    def test_bio_write(self):
+        """
+        `Connection.bio_write` does not raise if called with bytes or
+        bytearray, warns if called with text.
+        """
+        context = Context(SSLv23_METHOD)
+        connection = Connection(context, None)
+        connection.bio_write(b"xy")
+        connection.bio_write(bytearray(b"za"))
+        with pytest.warns(DeprecationWarning):
+            connection.bio_write(u"deprecated")
+
     def test_get_context(self):
         """
         `Connection.get_context` returns the `Context` instance used to
         construct the `Connection` instance.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         connection = Connection(context, None)
         assert connection.get_context() is context
 
@@ -2159,7 +2200,7 @@
         `Connection.set_context` raises `TypeError` if called with a
         non-`Context` instance argument.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         connection = Connection(ctx, None)
         with pytest.raises(TypeError):
             connection.set_context(object())
@@ -2175,7 +2216,7 @@
         used for the connection.
         """
         original = Context(SSLv23_METHOD)
-        replacement = Context(TLSv1_METHOD)
+        replacement = Context(SSLv23_METHOD)
         connection = Connection(original, None)
         connection.set_context(replacement)
         assert replacement is connection.get_context()
@@ -2190,13 +2231,13 @@
         If `Connection.set_tlsext_host_name` is called with a non-byte string
         argument or a byte string with an embedded NUL, `TypeError` is raised.
         """
-        conn = Connection(Context(TLSv1_METHOD), None)
+        conn = Connection(Context(SSLv23_METHOD), None)
         with pytest.raises(TypeError):
             conn.set_tlsext_host_name(object())
         with pytest.raises(TypeError):
             conn.set_tlsext_host_name(b"with\0null")
 
-        if PY3:
+        if not PY2:
             # On Python 3.x, don't accidentally implicitly convert from text.
             with pytest.raises(TypeError):
                 conn.set_tlsext_host_name(b"example.com".decode("ascii"))
@@ -2206,7 +2247,7 @@
         `Connection.pending` returns the number of bytes available for
         immediate read.
         """
-        connection = Connection(Context(TLSv1_METHOD), None)
+        connection = Connection(Context(SSLv23_METHOD), None)
         assert connection.pending() == 0
 
     def test_peek(self):
@@ -2215,17 +2256,17 @@
         passed.
         """
         server, client = loopback()
-        server.send(b'xy')
-        assert client.recv(2, MSG_PEEK) == b'xy'
-        assert client.recv(2, MSG_PEEK) == b'xy'
-        assert client.recv(2) == b'xy'
+        server.send(b"xy")
+        assert client.recv(2, MSG_PEEK) == b"xy"
+        assert client.recv(2, MSG_PEEK) == b"xy"
+        assert client.recv(2) == b"xy"
 
     def test_connect_wrong_args(self):
         """
         `Connection.connect` raises `TypeError` if called with a non-address
         argument.
         """
-        connection = Connection(Context(TLSv1_METHOD), socket())
+        connection = Connection(Context(SSLv23_METHOD), socket_any_family())
         with pytest.raises(TypeError):
             connection.connect(None)
 
@@ -2234,13 +2275,13 @@
         `Connection.connect` raises `socket.error` if the underlying socket
         connect method raises it.
         """
-        client = socket()
-        context = Context(TLSv1_METHOD)
+        client = socket_any_family()
+        context = Context(SSLv23_METHOD)
         clientSSL = Connection(context, client)
         # pytest.raises here doesn't work because of a bug in py.test on Python
         # 2.6: https://github.com/pytest-dev/pytest/issues/988
         try:
-            clientSSL.connect(("127.0.0.1", 1))
+            clientSSL.connect((loopback_address(client), 1))
         except error as e:
             exc = e
         assert exc.args[0] == ECONNREFUSED
@@ -2249,28 +2290,28 @@
         """
         `Connection.connect` establishes a connection to the specified address.
         """
-        port = socket()
-        port.bind(('', 0))
+        port = socket_any_family()
+        port.bind(("", 0))
         port.listen(3)
 
-        clientSSL = Connection(Context(TLSv1_METHOD), socket())
-        clientSSL.connect(('127.0.0.1', port.getsockname()[1]))
+        clientSSL = Connection(Context(SSLv23_METHOD), socket(port.family))
+        clientSSL.connect((loopback_address(port), port.getsockname()[1]))
         # XXX An assertion?  Or something?
 
     @pytest.mark.skipif(
         platform == "darwin",
-        reason="connect_ex sometimes causes a kernel panic on OS X 10.6.4"
+        reason="connect_ex sometimes causes a kernel panic on OS X 10.6.4",
     )
     def test_connect_ex(self):
         """
         If there is a connection error, `Connection.connect_ex` returns the
         errno instead of raising an exception.
         """
-        port = socket()
-        port.bind(('', 0))
+        port = socket_any_family()
+        port.bind(("", 0))
         port.listen(3)
 
-        clientSSL = Connection(Context(TLSv1_METHOD), socket())
+        clientSSL = Connection(Context(SSLv23_METHOD), socket(port.family))
         clientSSL.setblocking(False)
         result = clientSSL.connect_ex(port.getsockname())
         expected = (EINPROGRESS, EWOULDBLOCK)
@@ -2282,19 +2323,19 @@
         tuple of a new `Connection` (the accepted client) and the address the
         connection originated from.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
         ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
-        port = socket()
+        port = socket_any_family()
         portSSL = Connection(ctx, port)
-        portSSL.bind(('', 0))
+        portSSL.bind(("", 0))
         portSSL.listen(3)
 
-        clientSSL = Connection(Context(TLSv1_METHOD), socket())
+        clientSSL = Connection(Context(SSLv23_METHOD), socket(port.family))
 
         # Calling portSSL.getsockname() here to get the server IP address
         # sounds great, but frequently fails on Windows.
-        clientSSL.connect(('127.0.0.1', portSSL.getsockname()[1]))
+        clientSSL.connect((loopback_address(port), portSSL.getsockname()[1]))
 
         serverSSL, address = portSSL.accept()
 
@@ -2307,7 +2348,7 @@
         `Connection.set_shutdown` raises `TypeError` if called with arguments
         other than integers.
         """
-        connection = Connection(Context(TLSv1_METHOD), None)
+        connection = Connection(Context(SSLv23_METHOD), None)
         with pytest.raises(TypeError):
             connection.set_shutdown(None)
 
@@ -2346,12 +2387,14 @@
         If the underlying connection is truncated, `Connection.shutdown`
         raises an `Error`.
         """
-        server_ctx = Context(TLSv1_METHOD)
-        client_ctx = Context(TLSv1_METHOD)
+        server_ctx = Context(SSLv23_METHOD)
+        client_ctx = Context(SSLv23_METHOD)
         server_ctx.use_privatekey(
-            load_privatekey(FILETYPE_PEM, server_key_pem))
+            load_privatekey(FILETYPE_PEM, server_key_pem)
+        )
         server_ctx.use_certificate(
-            load_certificate(FILETYPE_PEM, server_cert_pem))
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
         server = Connection(server_ctx, None)
         client = Connection(client_ctx, None)
         handshake_in_memory(client, server)
@@ -2367,20 +2410,10 @@
         `Connection.set_shutdown` sets the state of the SSL connection
         shutdown process.
         """
-        connection = Connection(Context(TLSv1_METHOD), socket())
+        connection = Connection(Context(SSLv23_METHOD), socket_any_family())
         connection.set_shutdown(RECEIVED_SHUTDOWN)
         assert connection.get_shutdown() == RECEIVED_SHUTDOWN
 
-    @skip_if_py3
-    def test_set_shutdown_long(self):
-        """
-        On Python 2 `Connection.set_shutdown` accepts an argument
-        of type `long` as well as `int`.
-        """
-        connection = Connection(Context(TLSv1_METHOD), socket())
-        connection.set_shutdown(long(RECEIVED_SHUTDOWN))
-        assert connection.get_shutdown() == RECEIVED_SHUTDOWN
-
     def test_state_string(self):
         """
         `Connection.state_string` verbosely describes the current state of
@@ -2391,10 +2424,12 @@
         client = loopback_client_factory(client)
 
         assert server.get_state_string() in [
-            b"before/accept initialization", b"before SSL initialization"
+            b"before/accept initialization",
+            b"before SSL initialization",
         ]
         assert client.get_state_string() in [
-            b"before/connect initialization", b"before SSL initialization"
+            b"before/connect initialization",
+            b"before SSL initialization",
         ]
 
     def test_app_data(self):
@@ -2403,7 +2438,7 @@
         `Connection.set_app_data` and later retrieved with
         `Connection.get_app_data`.
         """
-        conn = Connection(Context(TLSv1_METHOD), None)
+        conn = Connection(Context(SSLv23_METHOD), None)
         assert None is conn.get_app_data()
         app_data = object()
         conn.set_app_data(app_data)
@@ -2414,7 +2449,7 @@
         `Connection.makefile` is not implemented and calling that
         method raises `NotImplementedError`.
         """
-        conn = Connection(Context(TLSv1_METHOD), None)
+        conn = Connection(Context(SSLv23_METHOD), None)
         with pytest.raises(NotImplementedError):
             conn.makefile()
 
@@ -2425,7 +2460,7 @@
         chain = _create_certificate_chain()
         [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
 
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         context.use_certificate(scert)
         client = Connection(context, None)
         cert = client.get_certificate()
@@ -2438,7 +2473,7 @@
 
         If there is no certificate, it returns None.
         """
-        context = Context(TLSv1_METHOD)
+        context = Context(SSLv23_METHOD)
         client = Connection(context, None)
         cert = client.get_certificate()
         assert cert is None
@@ -2451,7 +2486,7 @@
         chain = _create_certificate_chain()
         [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
 
-        serverContext = Context(TLSv1_METHOD)
+        serverContext = Context(SSLv23_METHOD)
         serverContext.use_privatekey(skey)
         serverContext.use_certificate(scert)
         serverContext.add_extra_chain_cert(icert)
@@ -2460,7 +2495,7 @@
         server.set_accept_state()
 
         # Create the client
-        clientContext = Context(TLSv1_METHOD)
+        clientContext = Context(SSLv23_METHOD)
         clientContext.set_verify(VERIFY_NONE, verify_cb)
         client = Connection(clientContext, None)
         client.set_connect_state()
@@ -2478,22 +2513,79 @@
         `Connection.get_peer_cert_chain` returns `None` if the peer sends
         no certificate chain.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
         ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
         server = Connection(ctx, None)
         server.set_accept_state()
-        client = Connection(Context(TLSv1_METHOD), None)
+        client = Connection(Context(SSLv23_METHOD), None)
         client.set_connect_state()
         interact_in_memory(client, server)
         assert None is server.get_peer_cert_chain()
 
+    def test_get_verified_chain(self):
+        """
+        `Connection.get_verified_chain` returns a list of certificates
+        which the connected server returned for the certification verification.
+        """
+        chain = _create_certificate_chain()
+        [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
+
+        serverContext = Context(SSLv23_METHOD)
+        serverContext.use_privatekey(skey)
+        serverContext.use_certificate(scert)
+        serverContext.add_extra_chain_cert(icert)
+        serverContext.add_extra_chain_cert(cacert)
+        server = Connection(serverContext, None)
+        server.set_accept_state()
+
+        # Create the client
+        clientContext = Context(SSLv23_METHOD)
+        # cacert is self-signed so the client must trust it for verification
+        # to succeed.
+        clientContext.get_cert_store().add_cert(cacert)
+        clientContext.set_verify(VERIFY_PEER, verify_cb)
+        client = Connection(clientContext, None)
+        client.set_connect_state()
+
+        interact_in_memory(client, server)
+
+        chain = client.get_verified_chain()
+        assert len(chain) == 3
+        assert "Server Certificate" == chain[0].get_subject().CN
+        assert "Intermediate Certificate" == chain[1].get_subject().CN
+        assert "Authority Certificate" == chain[2].get_subject().CN
+
+    def test_get_verified_chain_none(self):
+        """
+        `Connection.get_verified_chain` returns `None` if the peer sends
+        no certificate chain.
+        """
+        ctx = Context(SSLv23_METHOD)
+        ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
+        ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
+        server = Connection(ctx, None)
+        server.set_accept_state()
+        client = Connection(Context(SSLv23_METHOD), None)
+        client.set_connect_state()
+        interact_in_memory(client, server)
+        assert None is server.get_verified_chain()
+
+    def test_get_verified_chain_unconnected(self):
+        """
+        `Connection.get_verified_chain` returns `None` when used with an object
+        which has not been connected.
+        """
+        ctx = Context(SSLv23_METHOD)
+        server = Connection(ctx, None)
+        assert None is server.get_verified_chain()
+
     def test_get_session_unconnected(self):
         """
         `Connection.get_session` returns `None` when used with an object
         which has not been connected.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         server = Connection(ctx, None)
         session = server.get_session()
         assert None is session
@@ -2522,7 +2614,7 @@
         `Connection.set_session` raises `TypeError` if called with an object
         that is not an instance of `Session`.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         connection = Connection(ctx, None)
         with pytest.raises(TypeError):
             connection.set_session(123)
@@ -2549,17 +2641,17 @@
             server.set_accept_state()
             return server
 
-        originalServer, originalClient = loopback(
-            server_factory=makeServer)
+        originalServer, originalClient = loopback(server_factory=makeServer)
         originalSession = originalClient.get_session()
 
         def makeClient(socket):
             client = loopback_client_factory(socket)
             client.set_session(originalSession)
             return client
+
         resumedServer, resumedClient = loopback(
-            server_factory=makeServer,
-            client_factory=makeClient)
+            server_factory=makeServer, client_factory=makeClient
+        )
 
         # This is a proxy: in general, we have no access to any unique
         # identifier for the session (new enough versions of OpenSSL expose
@@ -2575,24 +2667,15 @@
         with a context using a different SSL method than the `Connection`
         is using, a `OpenSSL.SSL.Error` is raised.
         """
-        # Make this work on both OpenSSL 1.0.0, which doesn't support TLSv1.2
-        # and also on OpenSSL 1.1.0 which doesn't support SSLv3. (SSL_ST_INIT
-        # is a way to check for 1.1.0)
-        if SSL_ST_INIT is None:
-            v1 = TLSv1_2_METHOD
-            v2 = TLSv1_METHOD
-        elif hasattr(_lib, "SSLv3_method"):
-            v1 = TLSv1_METHOD
-            v2 = SSLv3_METHOD
-        else:
-            pytest.skip("Test requires either OpenSSL 1.1.0 or SSLv3")
+        v1 = TLSv1_2_METHOD
+        v2 = TLSv1_METHOD
 
         key = load_privatekey(FILETYPE_PEM, server_key_pem)
         cert = load_certificate(FILETYPE_PEM, server_cert_pem)
         ctx = Context(v1)
         ctx.use_privatekey(key)
         ctx.use_certificate(cert)
-        ctx.set_session_id("unity-test")
+        ctx.set_session_id(b"unity-test")
 
         def makeServer(socket):
             server = Connection(ctx, socket)
@@ -2605,7 +2688,8 @@
             return client
 
         originalServer, originalClient = loopback(
-            server_factory=makeServer, client_factory=makeOriginalClient)
+            server_factory=makeServer, client_factory=makeOriginalClient
+        )
         originalSession = originalClient.get_session()
 
         def makeClient(socket):
@@ -2641,9 +2725,10 @@
                 raise
         else:
             pytest.fail(
-                "Failed to fill socket buffer, cannot test BIO want write")
+                "Failed to fill socket buffer, cannot test BIO want write"
+            )
 
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         conn = Connection(ctx, client_socket)
         # Client's speak first, so make it an SSL client
         conn.set_connect_state()
@@ -2657,7 +2742,7 @@
         `Connection.get_finished` returns `None` before TLS handshake
         is completed.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         connection = Connection(ctx, None)
         assert connection.get_finished() is None
 
@@ -2666,7 +2751,7 @@
         `Connection.get_peer_finished` returns `None` before TLS handshake
         is completed.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         connection = Connection(ctx, None)
         assert connection.get_peer_finished() is None
 
@@ -2710,7 +2795,7 @@
         `Connection.get_cipher_name` returns `None` if no connection
         has been established.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         conn = Connection(ctx, None)
         assert conn.get_cipher_name() is None
 
@@ -2720,8 +2805,10 @@
         name of the currently used cipher.
         """
         server, client = loopback()
-        server_cipher_name, client_cipher_name = \
-            server.get_cipher_name(), client.get_cipher_name()
+        server_cipher_name, client_cipher_name = (
+            server.get_cipher_name(),
+            client.get_cipher_name(),
+        )
 
         assert isinstance(server_cipher_name, text_type)
         assert isinstance(client_cipher_name, text_type)
@@ -2733,7 +2820,7 @@
         `Connection.get_cipher_version` returns `None` if no connection
         has been established.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         conn = Connection(ctx, None)
         assert conn.get_cipher_version() is None
 
@@ -2743,8 +2830,10 @@
         the protocol name of the currently used cipher.
         """
         server, client = loopback()
-        server_cipher_version, client_cipher_version = \
-            server.get_cipher_version(), client.get_cipher_version()
+        server_cipher_version, client_cipher_version = (
+            server.get_cipher_version(),
+            client.get_cipher_version(),
+        )
 
         assert isinstance(server_cipher_version, text_type)
         assert isinstance(client_cipher_version, text_type)
@@ -2756,7 +2845,7 @@
         `Connection.get_cipher_bits` returns `None` if no connection has
         been established.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         conn = Connection(ctx, None)
         assert conn.get_cipher_bits() is None
 
@@ -2766,8 +2855,10 @@
         of the currently used cipher.
         """
         server, client = loopback()
-        server_cipher_bits, client_cipher_bits = \
-            server.get_cipher_bits(), client.get_cipher_bits()
+        server_cipher_bits, client_cipher_bits = (
+            server.get_cipher_bits(),
+            client.get_cipher_bits(),
+        )
 
         assert isinstance(server_cipher_bits, int)
         assert isinstance(client_cipher_bits, int)
@@ -2807,18 +2898,18 @@
         `Connection.bio_read` raises `OpenSSL.SSL.WantReadError` if there are
         no bytes available to be read from the BIO.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         conn = Connection(ctx, None)
         with pytest.raises(WantReadError):
             conn.bio_read(1024)
 
-    @pytest.mark.parametrize('bufsize', [1.0, None, object(), 'bufsize'])
+    @pytest.mark.parametrize("bufsize", [1.0, None, object(), "bufsize"])
     def test_bio_read_wrong_args(self, bufsize):
         """
         `Connection.bio_read` raises `TypeError` if passed a non-integer
         argument.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         conn = Connection(ctx, None)
         with pytest.raises(TypeError):
             conn.bio_read(bufsize)
@@ -2828,7 +2919,7 @@
         `Connection.bio_read` accepts an integer giving the maximum number
         of bytes to read and return.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         conn = Connection(ctx, None)
         conn.set_connect_state()
         try:
@@ -2838,33 +2929,18 @@
         data = conn.bio_read(2)
         assert 2 == len(data)
 
-    @skip_if_py3
-    def test_buffer_size_long(self):
-        """
-        On Python 2 `Connection.bio_read` accepts values of type `long` as
-        well as `int`.
-        """
-        ctx = Context(TLSv1_METHOD)
-        conn = Connection(ctx, None)
-        conn.set_connect_state()
-        try:
-            conn.do_handshake()
-        except WantReadError:
-            pass
-        data = conn.bio_read(long(2))
-        assert 2 == len(data)
-
 
 class TestConnectionGetCipherList(object):
     """
     Tests for `Connection.get_cipher_list`.
     """
+
     def test_result(self):
         """
         `Connection.get_cipher_list` returns a list of `bytes` giving the
         names of the ciphers which might be used.
         """
-        connection = Connection(Context(TLSv1_METHOD), None)
+        connection = Connection(Context(SSLv23_METHOD), None)
         ciphers = connection.get_cipher_list()
         assert isinstance(ciphers, list)
         for cipher in ciphers:
@@ -2875,22 +2951,26 @@
     """
     Mock object so that we don't have to allocate 2**31 bytes
     """
+
     def __len__(self):
-        return 2**31
+        return 2 ** 31
 
 
 class TestConnectionSend(object):
     """
     Tests for `Connection.send`.
     """
+
     def test_wrong_args(self):
         """
         When called with arguments other than string argument for its first
         parameter, `Connection.send` raises `TypeError`.
         """
-        connection = Connection(Context(TLSv1_METHOD), None)
+        connection = Connection(Context(SSLv23_METHOD), None)
         with pytest.raises(TypeError):
             connection.send(object())
+        with pytest.raises(TypeError):
+            connection.send([1, 2, 3])
 
     def test_short_bytes(self):
         """
@@ -2898,9 +2978,9 @@
         and returns the number of bytes sent.
         """
         server, client = loopback()
-        count = server.send(b'xy')
+        count = server.send(b"xy")
         assert count == 2
-        assert client.recv(2) == b'xy'
+        assert client.recv(2) == b"xy"
 
     def test_text(self):
         """
@@ -2911,12 +2991,11 @@
         with pytest.warns(DeprecationWarning) as w:
             simplefilter("always")
             count = server.send(b"xy".decode("ascii"))
-            assert (
-                "{0} for buf is no longer accepted, use bytes".format(
-                    WARNING_TYPE_EXPECTED
-                ) == str(w[-1].message))
+            assert "{0} for buf is no longer accepted, use bytes".format(
+                WARNING_TYPE_EXPECTED
+            ) == str(w[-1].message)
         assert count == 2
-        assert client.recv(2) == b'xy'
+        assert client.recv(2) == b"xy"
 
     def test_short_memoryview(self):
         """
@@ -2925,9 +3004,19 @@
         of bytes sent.
         """
         server, client = loopback()
-        count = server.send(memoryview(b'xy'))
+        count = server.send(memoryview(b"xy"))
         assert count == 2
-        assert client.recv(2) == b'xy'
+        assert client.recv(2) == b"xy"
+
+    def test_short_bytearray(self):
+        """
+        When passed a short bytearray, `Connection.send` transmits all of
+        it and returns the number of bytes sent.
+        """
+        server, client = loopback()
+        count = server.send(bytearray(b"xy"))
+        assert count == 2
+        assert client.recv(2) == b"xy"
 
     @skip_if_py3
     def test_short_buffer(self):
@@ -2937,13 +3026,13 @@
         of bytes sent.
         """
         server, client = loopback()
-        count = server.send(buffer(b'xy'))
+        count = server.send(buffer(b"xy"))  # noqa: F821
         assert count == 2
-        assert client.recv(2) == b'xy'
+        assert client.recv(2) == b"xy"
 
     @pytest.mark.skipif(
-        sys.maxsize < 2**31,
-        reason="sys.maxsize < 2**31 - test requires 64 bit"
+        sys.maxsize < 2 ** 31,
+        reason="sys.maxsize < 2**31 - test requires 64 bit",
     )
     def test_buf_too_large(self):
         """
@@ -2951,7 +3040,7 @@
         `Connection.send` bails out as SSL_write only
         accepts an int for the buffer length.
         """
-        connection = Connection(Context(TLSv1_METHOD), None)
+        connection = Connection(Context(SSLv23_METHOD), None)
         with pytest.raises(ValueError) as exc_info:
             connection.send(VeryLarge())
         exc_info.match(r"Cannot send more than .+ bytes at once")
@@ -2969,6 +3058,7 @@
     """
     Tests for `Connection.recv_into`.
     """
+
     def _no_length_test(self, factory):
         """
         Assert that when the given buffer is passed to `Connection.recv_into`,
@@ -2978,10 +3068,10 @@
         output_buffer = factory(5)
 
         server, client = loopback()
-        server.send(b'xy')
+        server.send(b"xy")
 
         assert client.recv_into(output_buffer) == 2
-        assert output_buffer == bytearray(b'xy\x00\x00\x00')
+        assert output_buffer == bytearray(b"xy\x00\x00\x00")
 
     def test_bytearray_no_length(self):
         """
@@ -2999,10 +3089,10 @@
         output_buffer = factory(10)
 
         server, client = loopback()
-        server.send(b'abcdefghij')
+        server.send(b"abcdefghij")
 
         assert client.recv_into(output_buffer, 5) == 5
-        assert output_buffer == bytearray(b'abcde\x00\x00\x00\x00\x00')
+        assert output_buffer == bytearray(b"abcde\x00\x00\x00\x00\x00")
 
     def test_bytearray_respects_length(self):
         """
@@ -3021,12 +3111,12 @@
         output_buffer = factory(5)
 
         server, client = loopback()
-        server.send(b'abcdefghij')
+        server.send(b"abcdefghij")
 
         assert client.recv_into(output_buffer) == 5
-        assert output_buffer == bytearray(b'abcde')
+        assert output_buffer == bytearray(b"abcde")
         rest = client.recv(5)
-        assert b'fghij' == rest
+        assert b"fghij" == rest
 
     def test_bytearray_doesnt_overfill(self):
         """
@@ -3047,12 +3137,12 @@
 
     def test_peek(self):
         server, client = loopback()
-        server.send(b'xy')
+        server.send(b"xy")
 
         for _ in range(2):
             output_buffer = bytearray(5)
             assert client.recv_into(output_buffer, flags=MSG_PEEK) == 2
-            assert output_buffer == bytearray(b'xy\x00\x00\x00')
+            assert output_buffer == bytearray(b"xy\x00\x00\x00")
 
     def test_memoryview_no_length(self):
         """
@@ -3091,14 +3181,17 @@
     """
     Tests for `Connection.sendall`.
     """
+
     def test_wrong_args(self):
         """
         When called with arguments other than a string argument for its first
         parameter, `Connection.sendall` raises `TypeError`.
         """
-        connection = Connection(Context(TLSv1_METHOD), None)
+        connection = Connection(Context(SSLv23_METHOD), None)
         with pytest.raises(TypeError):
             connection.sendall(object())
+        with pytest.raises(TypeError):
+            connection.sendall([1, 2, 3])
 
     def test_short(self):
         """
@@ -3106,8 +3199,8 @@
         passed to it.
         """
         server, client = loopback()
-        server.sendall(b'x')
-        assert client.recv(1) == b'x'
+        server.sendall(b"x")
+        assert client.recv(1) == b"x"
 
     def test_text(self):
         """
@@ -3118,10 +3211,9 @@
         with pytest.warns(DeprecationWarning) as w:
             simplefilter("always")
             server.sendall(b"x".decode("ascii"))
-            assert (
-                "{0} for buf is no longer accepted, use bytes".format(
-                    WARNING_TYPE_EXPECTED
-                ) == str(w[-1].message))
+            assert "{0} for buf is no longer accepted, use bytes".format(
+                WARNING_TYPE_EXPECTED
+            ) == str(w[-1].message)
         assert client.recv(1) == b"x"
 
     def test_short_memoryview(self):
@@ -3130,8 +3222,8 @@
         `Connection.sendall` transmits all of them.
         """
         server, client = loopback()
-        server.sendall(memoryview(b'x'))
-        assert client.recv(1) == b'x'
+        server.sendall(memoryview(b"x"))
+        assert client.recv(1) == b"x"
 
     @skip_if_py3
     def test_short_buffers(self):
@@ -3140,8 +3232,9 @@
         `Connection.sendall` transmits all of them.
         """
         server, client = loopback()
-        server.sendall(buffer(b'x'))
-        assert client.recv(1) == b'x'
+        count = server.sendall(buffer(b"xy"))  # noqa: F821
+        assert count == 2
+        assert client.recv(2) == b"xy"
 
     def test_long(self):
         """
@@ -3152,7 +3245,7 @@
         # Should be enough, underlying SSL_write should only do 16k at a time.
         # On Windows, after 32k of bytes the write will block (forever
         # - because no one is yet reading).
-        message = b'x' * (1024 * 32 - 1) + b'y'
+        message = b"x" * (1024 * 32 - 1) + b"y"
         server.sendall(message)
         accum = []
         received = 0
@@ -3160,7 +3253,7 @@
             data = client.recv(1024)
             accum.append(data)
             received += len(data)
-        assert message == b''.join(accum)
+        assert message == b"".join(accum)
 
     def test_closed(self):
         """
@@ -3181,12 +3274,13 @@
     """
     Tests for SSL renegotiation APIs.
     """
+
     def test_total_renegotiations(self):
         """
         `Connection.total_renegotiations` returns `0` before any renegotiations
         have happened.
         """
-        connection = Connection(Context(TLSv1_METHOD), None)
+        connection = Connection(Context(SSLv23_METHOD), None)
         assert connection.total_renegotiations() == 0
 
     def test_renegotiate(self):
@@ -3224,12 +3318,13 @@
     """
     Unit tests for `OpenSSL.SSL.Error`.
     """
+
     def test_type(self):
         """
         `Error` is an exception type.
         """
         assert issubclass(Error, Exception)
-        assert Error.__name__ == 'Error'
+        assert Error.__name__ == "Error"
 
 
 class TestConstants(object):
@@ -3240,9 +3335,10 @@
     OpenSSL APIs.  The only assertions it seems can be made about them is
     their values.
     """
+
     @pytest.mark.skipif(
         OP_NO_QUERY_MTU is None,
-        reason="OP_NO_QUERY_MTU unavailable - OpenSSL version may be too old"
+        reason="OP_NO_QUERY_MTU unavailable - OpenSSL version may be too old",
     )
     def test_op_no_query_mtu(self):
         """
@@ -3254,7 +3350,7 @@
     @pytest.mark.skipif(
         OP_COOKIE_EXCHANGE is None,
         reason="OP_COOKIE_EXCHANGE unavailable - "
-        "OpenSSL version may be too old"
+        "OpenSSL version may be too old",
     )
     def test_op_cookie_exchange(self):
         """
@@ -3265,7 +3361,7 @@
 
     @pytest.mark.skipif(
         OP_NO_TICKET is None,
-        reason="OP_NO_TICKET unavailable - OpenSSL version may be too old"
+        reason="OP_NO_TICKET unavailable - OpenSSL version may be too old",
     )
     def test_op_no_ticket(self):
         """
@@ -3276,7 +3372,9 @@
 
     @pytest.mark.skipif(
         OP_NO_COMPRESSION is None,
-        reason="OP_NO_COMPRESSION unavailable - OpenSSL version may be too old"
+        reason=(
+            "OP_NO_COMPRESSION unavailable - OpenSSL version may be too old"
+        ),
     )
     def test_op_no_compression(self):
         """
@@ -3350,23 +3448,26 @@
     """
     Tests for `OpenSSL.SSL.Connection` using a memory BIO.
     """
+
     def _server(self, sock):
         """
         Create a new server-side SSL `Connection` object wrapped around `sock`.
         """
         # Create the server side Connection.  This is mostly setup boilerplate
         # - use TLSv1, use a particular certificate, etc.
-        server_ctx = Context(TLSv1_METHOD)
+        server_ctx = Context(SSLv23_METHOD)
         server_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE)
         server_ctx.set_verify(
             VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT | VERIFY_CLIENT_ONCE,
-            verify_cb
+            verify_cb,
         )
         server_store = server_ctx.get_cert_store()
         server_ctx.use_privatekey(
-            load_privatekey(FILETYPE_PEM, server_key_pem))
+            load_privatekey(FILETYPE_PEM, server_key_pem)
+        )
         server_ctx.use_certificate(
-            load_certificate(FILETYPE_PEM, server_cert_pem))
+            load_certificate(FILETYPE_PEM, server_cert_pem)
+        )
         server_ctx.check_privatekey()
         server_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem))
         # Here the Connection is actually created.  If None is passed as the
@@ -3381,17 +3482,19 @@
         """
         # Now create the client side Connection.  Similar boilerplate to the
         # above.
-        client_ctx = Context(TLSv1_METHOD)
+        client_ctx = Context(SSLv23_METHOD)
         client_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE)
         client_ctx.set_verify(
             VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT | VERIFY_CLIENT_ONCE,
-            verify_cb
+            verify_cb,
         )
         client_store = client_ctx.get_cert_store()
         client_ctx.use_privatekey(
-            load_privatekey(FILETYPE_PEM, client_key_pem))
+            load_privatekey(FILETYPE_PEM, client_key_pem)
+        )
         client_ctx.use_certificate(
-            load_certificate(FILETYPE_PEM, client_cert_pem))
+            load_certificate(FILETYPE_PEM, client_cert_pem)
+        )
         client_ctx.check_privatekey()
         client_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem))
         client_conn = Connection(client_ctx, sock)
@@ -3428,39 +3531,41 @@
         assert client_conn.client_random() != client_conn.server_random()
 
         # Export key material for other uses.
-        cekm = client_conn.export_keying_material(b'LABEL', 32)
-        sekm = server_conn.export_keying_material(b'LABEL', 32)
+        cekm = client_conn.export_keying_material(b"LABEL", 32)
+        sekm = server_conn.export_keying_material(b"LABEL", 32)
         assert cekm is not None
         assert sekm is not None
         assert cekm == sekm
         assert len(sekm) == 32
 
         # Export key material for other uses with additional context.
-        cekmc = client_conn.export_keying_material(b'LABEL', 32, b'CONTEXT')
-        sekmc = server_conn.export_keying_material(b'LABEL', 32, b'CONTEXT')
+        cekmc = client_conn.export_keying_material(b"LABEL", 32, b"CONTEXT")
+        sekmc = server_conn.export_keying_material(b"LABEL", 32, b"CONTEXT")
         assert cekmc is not None
         assert sekmc is not None
         assert cekmc == sekmc
         assert cekmc != cekm
         assert sekmc != sekm
         # Export with alternate label
-        cekmt = client_conn.export_keying_material(b'test', 32, b'CONTEXT')
-        sekmt = server_conn.export_keying_material(b'test', 32, b'CONTEXT')
+        cekmt = client_conn.export_keying_material(b"test", 32, b"CONTEXT")
+        sekmt = server_conn.export_keying_material(b"test", 32, b"CONTEXT")
         assert cekmc != cekmt
         assert sekmc != sekmt
 
         # Here are the bytes we'll try to send.
-        important_message = b'One if by land, two if by sea.'
+        important_message = b"One if by land, two if by sea."
 
         server_conn.write(important_message)
-        assert (
-            interact_in_memory(client_conn, server_conn) ==
-            (client_conn, important_message))
+        assert interact_in_memory(client_conn, server_conn) == (
+            client_conn,
+            important_message,
+        )
 
         client_conn.write(important_message[::-1])
-        assert (
-            interact_in_memory(client_conn, server_conn) ==
-            (server_conn, important_message[::-1]))
+        assert interact_in_memory(client_conn, server_conn) == (
+            server_conn,
+            important_message[::-1],
+        )
 
     def test_socket_connect(self):
         """
@@ -3490,13 +3595,13 @@
         Test that `OpenSSL.SSL.bio_read` and `OpenSSL.SSL.bio_write` don't
         work on `OpenSSL.SSL.Connection`() that use sockets.
         """
-        context = Context(TLSv1_METHOD)
-        client = socket()
+        context = Context(SSLv23_METHOD)
+        client = socket_any_family()
         clientSSL = Connection(context, client)
         with pytest.raises(TypeError):
             clientSSL.bio_read(100)
         with pytest.raises(TypeError):
-            clientSSL.bio_write("foo")
+            clientSSL.bio_write(b"foo")
         with pytest.raises(TypeError):
             clientSSL.bio_shutdown()
 
@@ -3580,7 +3685,7 @@
         `Context.set_client_ca_list` raises a `TypeError` if called with a
         non-list or a list that contains objects other than X509Names.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             ctx.set_client_ca_list("spam")
         with pytest.raises(TypeError):
@@ -3593,9 +3698,11 @@
         client sides, `Connection.get_client_ca_list` returns an empty list
         after the connection is set up.
         """
+
         def no_ca(ctx):
             ctx.set_client_ca_list([])
             return []
+
         self._check_client_ca_list(no_ca)
 
     def test_set_one_ca_list(self):
@@ -3612,6 +3719,7 @@
         def single_ca(ctx):
             ctx.set_client_ca_list([cadesc])
             return [cadesc]
+
         self._check_client_ca_list(single_ca)
 
     def test_set_multiple_ca_list(self):
@@ -3632,6 +3740,7 @@
             L = [sedesc, cldesc]
             ctx.set_client_ca_list(L)
             return L
+
         self._check_client_ca_list(multiple_ca)
 
     def test_reset_ca_list(self):
@@ -3652,6 +3761,7 @@
             ctx.set_client_ca_list([sedesc, cldesc])
             ctx.set_client_ca_list([cadesc])
             return [cadesc]
+
         self._check_client_ca_list(changed_ca)
 
     def test_mutated_ca_list(self):
@@ -3671,6 +3781,7 @@
             ctx.set_client_ca_list([cadesc])
             L.append(sedesc)
             return [cadesc]
+
         self._check_client_ca_list(mutated_ca)
 
     def test_add_client_ca_wrong_args(self):
@@ -3678,7 +3789,7 @@
         `Context.add_client_ca` raises `TypeError` if called with
         a non-X509 object.
         """
-        ctx = Context(TLSv1_METHOD)
+        ctx = Context(SSLv23_METHOD)
         with pytest.raises(TypeError):
             ctx.add_client_ca("spam")
 
@@ -3693,6 +3804,7 @@
         def single_ca(ctx):
             ctx.add_client_ca(cacert)
             return [cadesc]
+
         self._check_client_ca_list(single_ca)
 
     def test_multiple_add_client_ca(self):
@@ -3710,6 +3822,7 @@
             ctx.add_client_ca(cacert)
             ctx.add_client_ca(secert)
             return [cadesc, sedesc]
+
         self._check_client_ca_list(multiple_ca)
 
     def test_set_and_add_client_ca(self):
@@ -3730,6 +3843,7 @@
             ctx.set_client_ca_list([cadesc, sedesc])
             ctx.add_client_ca(clcert)
             return [cadesc, sedesc, cldesc]
+
         self._check_client_ca_list(mixed_set_add_ca)
 
     def test_set_after_add_client_ca(self):
@@ -3750,6 +3864,7 @@
             ctx.set_client_ca_list([cadesc])
             ctx.add_client_ca(secert)
             return [cadesc, sedesc]
+
         self._check_client_ca_list(set_replaces_add_ca)
 
 
@@ -3757,6 +3872,7 @@
     """
     Tests for assorted constants exposed for use in info callbacks.
     """
+
     def test_integers(self):
         """
         All of the info constants are integers.
@@ -3766,17 +3882,31 @@
         info callback matches up with the constant exposed by OpenSSL.SSL.
         """
         for const in [
-            SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK,
-            SSL_CB_LOOP, SSL_CB_EXIT, SSL_CB_READ, SSL_CB_WRITE, SSL_CB_ALERT,
-            SSL_CB_READ_ALERT, SSL_CB_WRITE_ALERT, SSL_CB_ACCEPT_LOOP,
-            SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP, SSL_CB_CONNECT_EXIT,
-            SSL_CB_HANDSHAKE_START, SSL_CB_HANDSHAKE_DONE
+            SSL_ST_CONNECT,
+            SSL_ST_ACCEPT,
+            SSL_ST_MASK,
+            SSL_CB_LOOP,
+            SSL_CB_EXIT,
+            SSL_CB_READ,
+            SSL_CB_WRITE,
+            SSL_CB_ALERT,
+            SSL_CB_READ_ALERT,
+            SSL_CB_WRITE_ALERT,
+            SSL_CB_ACCEPT_LOOP,
+            SSL_CB_ACCEPT_EXIT,
+            SSL_CB_CONNECT_LOOP,
+            SSL_CB_CONNECT_EXIT,
+            SSL_CB_HANDSHAKE_START,
+            SSL_CB_HANDSHAKE_DONE,
         ]:
             assert isinstance(const, int)
 
         # These constants don't exist on OpenSSL 1.1.0
         for const in [
-            SSL_ST_INIT, SSL_ST_BEFORE, SSL_ST_OK, SSL_ST_RENEGOTIATE
+            SSL_ST_INIT,
+            SSL_ST_BEFORE,
+            SSL_ST_OK,
+            SSL_ST_RENEGOTIATE,
         ]:
             assert const is None or isinstance(const, int)
 
@@ -3786,6 +3916,7 @@
     Tests for the decorator factory used to conditionally raise
     NotImplementedError when older OpenSSLs are used.
     """
+
     def test_available(self):
         """
         When the OpenSSL functionality is available the decorated functions
@@ -3823,6 +3954,7 @@
     """
     Tests for PyOpenSSL's OCSP stapling support.
     """
+
     sample_ocsp_data = b"this is totally ocsp data"
 
     def _client_connection(self, callback, data, request_ocsp=True):
@@ -3867,6 +3999,7 @@
         the client does not send the OCSP request, neither callback gets
         called.
         """
+
         def ocsp_callback(*args, **kwargs):  # pragma: nocover
             pytest.fail("Should not be called")
 
@@ -3892,7 +4025,7 @@
         handshake_in_memory(client, server)
 
         assert len(called) == 1
-        assert called[0] == b''
+        assert called[0] == b""
 
     def test_client_receives_servers_data(self):
         """
@@ -3975,7 +4108,7 @@
         client_calls = []
 
         def server_callback(*args):
-            return b''
+            return b""
 
         def client_callback(conn, ocsp_data, ignored):
             client_calls.append(ocsp_data)
@@ -3986,12 +4119,13 @@
         handshake_in_memory(client, server)
 
         assert len(client_calls) == 1
-        assert client_calls[0] == b''
+        assert client_calls[0] == b""
 
     def test_client_returns_false_terminates_handshake(self):
         """
         If the client returns False from its callback, the handshake fails.
         """
+
         def server_callback(*args):
             return self.sample_ocsp_data
 
@@ -4008,6 +4142,7 @@
         """
         The callbacks thrown in the client callback bubble up to the caller.
         """
+
         class SentinelException(Exception):
             pass
 
@@ -4027,6 +4162,7 @@
         """
         The callbacks thrown in the server callback bubble up to the caller.
         """
+
         class SentinelException(Exception):
             pass
 
@@ -4046,8 +4182,9 @@
         """
         The server callback must return a bytestring, or a TypeError is thrown.
         """
+
         def server_callback(*args):
-            return self.sample_ocsp_data.decode('ascii')
+            return self.sample_ocsp_data.decode("ascii")
 
         def client_callback(*args):  # pragma: nocover
             pytest.fail("Should not be called")
diff --git a/tests/test_tsafe.py b/tests/test_tsafe.py
deleted file mode 100644
index 8ffe35a..0000000
--- a/tests/test_tsafe.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) Jean-Paul Calderone
-# See LICENSE for details.
-
-"""
-Unit tests for `OpenSSL.tsafe`.
-"""
-
-from OpenSSL.SSL import TLSv1_METHOD, Context
-from OpenSSL.tsafe import Connection
-
-
-class TestConnection(object):
-    """
-    Tests for `OpenSSL.tsafe.Connection`.
-    """
-    def test_instantiation(self):
-        """
-        `OpenSSL.tsafe.Connection` can be instantiated.
-        """
-        # The following line should not throw an error.  This isn't an ideal
-        # test.  It would be great to refactor the other Connection tests so
-        # they could automatically be applied to this class too.
-        Connection(Context(TLSv1_METHOD), None)
diff --git a/tests/test_util.py b/tests/test_util.py
index 91847e0..6224448 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -7,6 +7,7 @@
     """
     Tests for handling of certain OpenSSL error cases.
     """
+
     def test_exception_from_error_queue_nonexistent_reason(self):
         """
         :func:`exception_from_error_queue` raises ``ValueError`` when it
diff --git a/tests/util.py b/tests/util.py
index 4464379..75d2c8d 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -6,7 +6,7 @@
 U{Twisted<http://twistedmatrix.com/>}.
 """
 
-from six import PY3
+from six import PY2
 
 
 # This is the UTF-8 encoding of the SNOWMAN unicode code point.
@@ -59,7 +59,7 @@
         An object compares equal to itself using the C{==} operator.
         """
         o = self.anInstance()
-        assert (o == o)
+        assert o == o
 
     def test_identicalNe(self):
         """
@@ -75,7 +75,7 @@
         """
         a = self.anInstance()
         b = self.anInstance()
-        assert (a == b)
+        assert a == b
 
     def test_sameNe(self):
         """
@@ -102,7 +102,7 @@
         """
         a = self.anInstance()
         b = self.anotherInstance()
-        assert (a != b)
+        assert a != b
 
     def test_anotherTypeEq(self):
         """
@@ -120,13 +120,14 @@
         """
         a = self.anInstance()
         b = object()
-        assert (a != b)
+        assert a != b
 
     def test_delegatedEq(self):
         """
         The result of comparison using C{==} is delegated to the right-hand
         operand if it is of an unrelated type.
         """
+
         class Delegate(object):
             def __eq__(self, other):
                 # Do something crazy and obvious.
@@ -141,6 +142,7 @@
         The result of comparison using C{!=} is delegated to the right-hand
         operand if it is of an unrelated type.
         """
+
         class Delegate(object):
             def __ne__(self, other):
                 # Do something crazy and obvious.
@@ -152,7 +154,7 @@
 
 
 # The type name expected in warnings about using the wrong string type.
-if PY3:
-    WARNING_TYPE_EXPECTED = "str"
-else:
+if PY2:
     WARNING_TYPE_EXPECTED = "unicode"
+else:
+    WARNING_TYPE_EXPECTED = "str"
diff --git a/tox.ini b/tox.ini
index 8bef9e3..90a4c6a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = {pypy,pypy3,py27,py34,py35,py36,py37}{,-cryptographyMaster,-cryptographyMinimum},py27-twistedMaster,pypi-readme,check-manifest,flake8,docs,coverage-report
+envlist = {pypy,pypy3,py27,py35,py36,py37,py38,py39}{,-cryptographyMaster,-cryptographyMinimum}{,-randomorder},py37-twistedMaster,pypi-readme,check-manifest,flake8,docs,coverage-report
 
 [testenv]
 whitelist_externals =
@@ -10,7 +10,8 @@
 deps =
     coverage>=4.2
     cryptographyMaster: git+https://github.com/pyca/cryptography.git
-    cryptographyMinimum: cryptography==2.3.0
+    cryptographyMinimum: cryptography==3.2
+    randomorder: pytest-randomly
 setenv =
     # Do not allow the executing environment to pollute the test environment
     # with extra packages.
@@ -21,40 +22,25 @@
     coverage run --parallel -m OpenSSL.debug
     coverage run --parallel -m pytest -v {posargs}
 
-[testenv:py27-twistedMaster]
+[testenv:py37-twistedMaster]
 deps =
-    # [tls,conch] syntax doesn't work here so we enumerate all dependencies.
-    git+https://github.com/twisted/twisted
-    idna
-    service_identity
-    bcrypt
+    Twisted[all_non_platform] @ git+https://github.com/twisted/twisted
+setenv =
 passenv = ARCHFLAGS CFLAGS LC_ALL LDFLAGS PATH LD_LIBRARY_PATH TERM
 commands =
     python -c "import OpenSSL.SSL; print(OpenSSL.SSL.SSLeay_version(OpenSSL.SSL.SSLEAY_VERSION))"
     python -c "import cryptography; print(cryptography.__version__)"
     python -m twisted.trial --reporter=text twisted
 
-[testenv:py35-urllib3Master]
-basepython=python3.5
-deps =
-    pyasn1
-    ndg-httpsclient
-passenv = ARCHFLAGS CFLAGS LC_ALL LDFLAGS PATH LD_LIBRARY_PATH TERM TRAVIS_INFRA
-whitelist_externals =
-    rm
-commands =
-    python -c "import OpenSSL.SSL; print(OpenSSL.SSL.SSLeay_version(OpenSSL.SSL.SSLEAY_VERSION))"
-    python -c "import cryptography; print(cryptography.__version__)"
-    {toxinidir}/.travis/install_urllib3.sh
-    pytest urllib3/test
-    rm -rf ./urllib3
-
 [testenv:flake8]
+basepython = python3
 deps =
-     flake8
+    black
+    flake8
 skip_install = true
 commands =
-     flake8 src tests examples setup.py
+    black --check .
+    flake8 .
 
 [testenv:pypi-readme]
 deps =
@@ -83,3 +69,6 @@
 commands =
     coverage combine
     coverage report
+
+[flake8]
+ignore = E203,W503,W504