[Python-modules-commits] [pyopenssl] 01/09: Import pyopenssl_16.1.0.orig.tar.gz

Sandro Tosi morph at moszumanska.debian.org
Sat Sep 3 18:21:29 UTC 2016


This is an automated email from the git hooks/post-receive script.

morph pushed a commit to branch master
in repository pyopenssl.

commit dbefbd4ee7b71855ac350dcdb98bd582f0c6529a
Author: Sandro Tosi <morph at debian.org>
Date:   Sat Sep 3 19:09:53 2016 +0100

    Import pyopenssl_16.1.0.orig.tar.gz
---
 .coveragerc                         |   4 +-
 CHANGELOG.rst                       |  32 +-
 MANIFEST.in                         |   1 +
 PKG-INFO                            |  66 +---
 README.rst                          |   4 +-
 doc/ChangeLog_old.txt               |   2 +-
 doc/api/crypto.rst                  |  28 +-
 examples/simple/CA.cert             |  17 -
 examples/simple/CA.pkey             |  28 --
 examples/simple/client.cert         |  17 -
 examples/simple/client.pkey         |  28 --
 examples/simple/server.cert         |  17 -
 examples/simple/server.pkey         |  28 --
 setup.cfg                           |   6 +-
 setup.py                            |   2 +-
 src/OpenSSL/SSL.py                  | 148 ++++-----
 src/OpenSSL/crypto.py               | 646 ++++++++++++++++++++----------------
 src/OpenSSL/version.py              |   4 +-
 src/pyOpenSSL.egg-info/PKG-INFO     |  66 +---
 src/pyOpenSSL.egg-info/SOURCES.txt  |   6 -
 src/pyOpenSSL.egg-info/requires.txt |   2 +-
 tests/test_crypto.py                | 314 +++++++++++++++---
 tests/test_ssl.py                   | 121 ++++---
 tox.ini                             |  15 +-
 24 files changed, 863 insertions(+), 739 deletions(-)

diff --git a/.coveragerc b/.coveragerc
index 5bc0e03..e989503 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,6 +1,8 @@
 [run]
 branch = True
-source = OpenSSL
+source =
+   OpenSSL
+   tests/
 
 [paths]
 source =
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 55a4006..564abeb 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -5,13 +5,43 @@ Versions are year-based with a strict backward-compatibility policy.
 The third digit is only for regressions.
 
 
+16.1.0 (2016-08-26)
+-------------------
+
+Backward-incompatible changes:
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*none*
+
+
+Deprecations:
+^^^^^^^^^^^^^
+
+*none*
+
+
+Changes:
+^^^^^^^^
+
+- Fix memory leak in ``OpenSSL.crypto.dump_privatekey()`` with ``FILETYPE_TEXT``.
+  `#496 <https://github.com/pyca/pyopenssl/pull/496>`_
+- Enable use of CRL (and more) in verify context.
+  `#483 <https://github.com/pyca/pyopenssl/pull/483>`_
+- ``OpenSSL.crypto.PKey`` can now be constructed from ``cryptography`` objects and also exported as such.
+  `#439 <https://github.com/pyca/pyopenssl/pull/439>`_
+- Support newer versions of ``cryptography`` which use opaque structs for OpenSSL 1.1.0 compatibility.
+
+
+----
+
+
 16.0.0 (2016-03-19)
 -------------------
 
 This is the first release under full stewardship of PyCA.
 We have made *many* changes to make local development more pleasing.
 The test suite now passes both on Linux and OS X with OpenSSL 0.9.8, 1.0.1, and 1.0.2.
-It has been moved to `py.test <https://pytest.org/>`_, all CI test runs are part of `tox <https://testrun.org/tox/>`_ and the source code has been made fully `flake8 <https://flake8.readthedocs.org/>`_ compliant.
+It has been moved to `py.test <https://pytest.org/>`_, all CI test runs are part of `tox <https://testrun.org/tox/>`_ and the source code has been made fully `flake8 <https://flake8.readthedocs.io/>`_ compliant.
 
 We hope to have lowered the barrier for contributions significantly but are open to hear about any remaining frustrations.
 
diff --git a/MANIFEST.in b/MANIFEST.in
index 50cdc78..72b419c 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -7,3 +7,4 @@ recursive-include   rpm         *
 recursive-exclude   leakcheck   *.py *.pem
 prune               doc/_build
 prune               .travis
+prune               .mention-bot
diff --git a/PKG-INFO b/PKG-INFO
index ed2970a..a0cb731 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,8 +1,8 @@
 Metadata-Version: 1.1
 Name: pyOpenSSL
-Version: 16.0.0
+Version: 16.1.0
 Summary: Python wrapper module around the OpenSSL library
-Home-page: https://pyopenssl.readthedocs.org/
+Home-page: https://pyopenssl.readthedocs.io/
 Author: Hynek Schlawack
 Author-email: hs at ox.cx
 License: Apache License, Version 2.0
@@ -11,7 +11,7 @@ Description: ========================================================
         ========================================================
         
         .. image:: https://readthedocs.org/projects/pyopenssl/badge/?version=stable
-           :target: https://pyopenssl.readthedocs.org/
+           :target: https://pyopenssl.readthedocs.io/
            :alt: Stable Docs
         
         .. image:: https://travis-ci.org/pyca/pyopenssl.svg?branch=master
@@ -45,7 +45,7 @@ Description: ========================================================
         You can also join ``#cryptography-dev`` on Freenode to ask questions or get involved.
         
         
-        .. _documentation: https://pyopenssl.readthedocs.org/
+        .. _documentation: https://pyopenssl.readthedocs.io/
         .. _`issue tracker`: https://github.com/pyca/pyopenssl/issues
         .. _cryptography-dev: https://mail.python.org/mailman/listinfo/cryptography-dev
         .. _GitHub: https://github.com/pyca/pyopenssl
@@ -54,67 +54,33 @@ Description: ========================================================
         Release Information
         ===================
         
-        16.0.0 (2016-03-19)
+        16.1.0 (2016-08-26)
         -------------------
         
-        This is the first release under full stewardship of PyCA.
-        We have made *many* changes to make local development more pleasing.
-        The test suite now passes both on Linux and OS X with OpenSSL 0.9.8, 1.0.1, and 1.0.2.
-        It has been moved to `py.test <https://pytest.org/>`_, all CI test runs are part of `tox <https://testrun.org/tox/>`_ and the source code has been made fully `flake8 <https://flake8.readthedocs.org/>`_ compliant.
-        
-        We hope to have lowered the barrier for contributions significantly but are open to hear about any remaining frustrations.
-        
-        
         Backward-incompatible changes:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         
-        - Python 3.2 support has been dropped.
-          It never had significant real world usage and has been dropped by our main dependency ``cryptography``.
-          Affected users should upgrade to Python 3.3 or later.
+        *none*
         
         
         Deprecations:
         ^^^^^^^^^^^^^
         
-        - The support for EGD has been removed.
-          The only affected function ``OpenSSL.rand.egd()`` now uses ``os.urandom()`` to seed the internal PRNG instead.
-          Please see `pyca/cryptography#1636 <https://github.com/pyca/cryptography/pull/1636>`_ for more background information on this decision.
-          In accordance with our backward compatibility policy ``OpenSSL.rand.egd()`` will be *removed* no sooner than a year from the release of 16.0.0.
-        
-          Please note that you should `use urandom <http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/>`_ for all your secure random number needs.
-        - Python 2.6 support has been deprecated.
-          Our main dependency ``cryptography`` deprecated 2.6 in version 0.9 (2015-05-14) with no time table for actually dropping it.
-          pyOpenSSL will drop Python 2.6 support once ``cryptography`` does.
+        *none*
         
         
         Changes:
         ^^^^^^^^
         
-        - Fixed ``OpenSSL.SSL.Context.set_session_id``, ``OpenSSL.SSL.Connection.renegotiate``, ``OpenSSL.SSL.Connection.renegotiate_pending``, and ``OpenSSL.SSL.Context.load_client_ca``.
-          They were lacking an implementation since 0.14.
-          `#422 <https://github.com/pyca/pyopenssl/pull/422>`_
-        - Fixed segmentation fault when using keys larger than 4096-bit to sign data.
-          `#428 <https://github.com/pyca/pyopenssl/pull/428>`_
-        - Fixed ``AttributeError`` when ``OpenSSL.SSL.Connection.get_app_data()`` was called before setting any app data.
-          `#304 <https://github.com/pyca/pyopenssl/pull/304>`_
-        - Added ``OpenSSL.crypto.dump_publickey()`` to dump ``OpenSSL.crypto.PKey`` objects that represent public keys, and ``OpenSSL.crypto.load_publickey()`` to load such objects from serialized representations.
-          `#382 <https://github.com/pyca/pyopenssl/pull/382>`_
-        - Added ``OpenSSL.crypto.dump_crl()`` to dump a certificate revocation list out to a string buffer.
-          `#368 <https://github.com/pyca/pyopenssl/pull/368>`_
-        - Added ``OpenSSL.SSL.Connection.get_state_string()`` using the OpenSSL binding ``state_string_long``.
-          `#358 <https://github.com/pyca/pyopenssl/pull/358>`_
-        - Added support for the ``socket.MSG_PEEK`` flag to ``OpenSSL.SSL.Connection.recv()`` and ``OpenSSL.SSL.Connection.recv_into()``.
-          `#294 <https://github.com/pyca/pyopenssl/pull/294>`_
-        - Added ``OpenSSL.SSL.Connection.get_protocol_version()`` and ``OpenSSL.SSL.Connection.get_protocol_version_name()``.
-          `#244 <https://github.com/pyca/pyopenssl/pull/244>`_
-        - Switched to ``utf8string`` mask by default.
-          OpenSSL formerly defaulted to a ``T61String`` if there were UTF-8 characters present.
-          This was changed to default to ``UTF8String`` in the config around 2005, but the actual code didn't change it until late last year.
-          This will default us to the setting that actually works.
-          To revert this you can call ``OpenSSL.crypto._lib.ASN1_STRING_set_default_mask_asc(b"default")``.
-          `#234 <https://github.com/pyca/pyopenssl/pull/234>`_
-        
-        `Full changelog <https://pyopenssl.readthedocs.org/en/stable/changelog.html>`_.
+        - Fix memory leak in ``OpenSSL.crypto.dump_privatekey()`` with ``FILETYPE_TEXT``.
+          `#496 <https://github.com/pyca/pyopenssl/pull/496>`_
+        - Enable use of CRL (and more) in verify context.
+          `#483 <https://github.com/pyca/pyopenssl/pull/483>`_
+        - ``OpenSSL.crypto.PKey`` can now be constructed from ``cryptography`` objects and also exported as such.
+          `#439 <https://github.com/pyca/pyopenssl/pull/439>`_
+        - Support newer versions of ``cryptography`` which use opaque structs for OpenSSL 1.1.0 compatibility.
+        
+        `Full changelog <https://pyopenssl.readthedocs.io/en/stable/changelog.html>`_.
         
         
 Platform: UNKNOWN
diff --git a/README.rst b/README.rst
index 3ba5fe1..6fe3df7 100644
--- a/README.rst
+++ b/README.rst
@@ -3,7 +3,7 @@ pyOpenSSL -- A Python wrapper around the OpenSSL library
 ========================================================
 
 .. image:: https://readthedocs.org/projects/pyopenssl/badge/?version=stable
-   :target: https://pyopenssl.readthedocs.org/
+   :target: https://pyopenssl.readthedocs.io/
    :alt: Stable Docs
 
 .. image:: https://travis-ci.org/pyca/pyopenssl.svg?branch=master
@@ -37,7 +37,7 @@ We maintain a cryptography-dev_ mailing list for both user and development discu
 You can also join ``#cryptography-dev`` on Freenode to ask questions or get involved.
 
 
-.. _documentation: https://pyopenssl.readthedocs.org/
+.. _documentation: https://pyopenssl.readthedocs.io/
 .. _`issue tracker`: https://github.com/pyca/pyopenssl/issues
 .. _cryptography-dev: https://mail.python.org/mailman/listinfo/cryptography-dev
 .. _GitHub: https://github.com/pyca/pyopenssl
diff --git a/doc/ChangeLog_old.txt b/doc/ChangeLog_old.txt
index 88174d5..214a26d 100644
--- a/doc/ChangeLog_old.txt
+++ b/doc/ChangeLog_old.txt
@@ -1,5 +1,5 @@
 This file only contains the changes up to release 0.15.1.  Newer changes can be
-found at <https://pyopenssl.readthedocs.org/en/latest/changelog.html>.
+found at <https://pyopenssl.readthedocs.io/en/latest/changelog.html>.
 
 ***
 
diff --git a/doc/api/crypto.rst b/doc/api/crypto.rst
index 7597d7f..c6501b4 100644
--- a/doc/api/crypto.rst
+++ b/doc/api/crypto.rst
@@ -73,14 +73,7 @@ Certificate signing requests
 Private keys
 ~~~~~~~~~~~~
 
-.. py:function:: dump_privatekey(type, pkey[, cipher, passphrase])
-
-    Dump the private key *pkey* into a buffer string encoded with the type
-    *type*, optionally (if *type* is :py:const:`FILETYPE_PEM`) encrypting it
-    using *cipher* and *passphrase*.
-
-    *passphrase* must be either a string or a callback for providing the
-    pass phrase.
+.. autofunction:: dump_privatekey
 
 .. py:function:: load_privatekey(type, buffer[, passphrase])
 
@@ -206,6 +199,25 @@ X509StoreContext objects
 
 .. _openssl-pkey:
 
+X509StoreFlags constants
+------------------------
+
+.. autoclass:: X509StoreFlags
+
+    .. data:: CRL_CHECK
+    .. data:: CRL_CHECK_ALL
+    .. data:: IGNORE_CRITICAL
+    .. data:: X509_STRICT
+    .. data:: ALLOW_PROXY_CERTS
+    .. data:: POLICY_CHECK
+    .. data:: EXPLICIT_POLICY
+    .. data:: INHIBIT_MAP
+    .. data:: NOTIFY_POLICY
+    .. data:: CHECK_SS_SIGNATURE
+    .. data:: CB_ISSUER_CHECK
+
+.. _openssl-x509storeflags:
+
 PKey objects
 ------------
 
diff --git a/examples/simple/CA.cert b/examples/simple/CA.cert
deleted file mode 100644
index 9c5b8e8..0000000
--- a/examples/simple/CA.cert
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICtDCCAZwCAQAwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UEAwwVQ2VydGlmaWNh
-dGUgQXV0aG9yaXR5MB4XDTE2MDMxMzA2NDE1MVoXDTIxMDMxMjA2NDE1MVowIDEe
-MBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEAwcATfB/DKvTl0TiYQt9tYW0Yogd+cpMlY8CgFW9RbdTb
-RYpGFBrVCiXuVymI3IqVQNKUcewhO3rCU/gu3YA1B9ElQ47emTWU8YJyeHqhKk6M
-/7F00hXOhRX34cgCV1M3n/4i0MilDPDyh36yp8dw5L//i4wXhWoKSOtdluKA2mF5
-dpmSthTMxBh4uu99k4dZN48A8GbwwNxI1TBlnXxgfTVFFpRItCdISyKfxtAlvbMU
-+2j4jUZSEzJTlcNhUeYWCbdHSnExfhkxGNkCVJoMfzOPxd4p98ibMCq8IayTObMf
-cn9a3+iOeH/A6fPq5wrCPVMjyA0sC/3c7D8Pq3LiJwIDAQABMA0GCSqGSIb3DQEB
-CwUAA4IBAQCAEhk616JE5W/UTi/U9IRrYWVUI/NpOiHah6fNPU4Sv7lzCMdVAVJ7
-laCSrWk3GhiITWrrF7558puxIxyAZjTIfU8thBTfE2yh1e+kq9VpB7yIcPEcXtrB
-kmtJ2atczwTWr1mQw3SGck7TsaWREmCMWCVQZL0Qh7JMTaSqRhAMlS4QO70qFR1D
-UxoLbXZ92okZIqxYg/nK7zKaHlgZIJLN0IsHs3PI4l4oh+lUbqRCc4d9Aq/taQ7Z
-TiVWd2Ei8zSFJ8sYxagE8Buc3QcvUYJksEtW7XoczmuH3CO8HWQ3ONPDetgwcYDy
-uIEKpv8FBCzWq/40b1YVE4h+5lCa3Lgw
------END CERTIFICATE-----
diff --git a/examples/simple/CA.pkey b/examples/simple/CA.pkey
deleted file mode 100644
index f11b3cf..0000000
--- a/examples/simple/CA.pkey
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDBwBN8H8Mq9OXR
-OJhC321hbRiiB35ykyVjwKAVb1Ft1NtFikYUGtUKJe5XKYjcipVA0pRx7CE7esJT
-+C7dgDUH0SVDjt6ZNZTxgnJ4eqEqToz/sXTSFc6FFffhyAJXUzef/iLQyKUM8PKH
-frKnx3Dkv/+LjBeFagpI612W4oDaYXl2mZK2FMzEGHi6732Th1k3jwDwZvDA3EjV
-MGWdfGB9NUUWlEi0J0hLIp/G0CW9sxT7aPiNRlITMlOVw2FR5hYJt0dKcTF+GTEY
-2QJUmgx/M4/F3in3yJswKrwhrJM5sx9yf1rf6I54f8Dp8+rnCsI9UyPIDSwL/dzs
-Pw+rcuInAgMBAAECggEAXXD8NLXA05vOpovL6xyETSNnaOWCV1GeC7Dfw9avB/BL
-XAtm5tVV/5Hxk7nlVq/DccLdct/12xDGXebo+0yUxtNYTG+/7VYJIjzOZkqGJbhC
-iiKUe6mms0q4BP0IHAN3ZUMUmWrbJxWhcjVphj9KtBfg7/U9dsuAcFCLD3TnvenD
-3wPg6MMMi8ZngDuw7iIr7gWIXx0MkDoHPZuyyvZZ9SveE5AiaYcSe8LI8hXYgMDG
-A18Ypgmbkbuyg1NQ/9Q4UeMEdc/wK2MLqO3exWFk0B+yYJrUgXouwiivKzZWoDfx
-X6LBVWgoRZIaZ71AQRFE9Q3cxZB5cec713fgjlrViQKBgQDkR3OEBSwEPaeTRadk
-OeObQHB2qblqfME4Hnh86ybd2GWPl6WcAI395r4IbyrHIyhbrFPJUqc3IJdTCIQl
-hMqmTE4jTZCaDi68/JzQDae12R8ks7zSyezw/lbWel4EGe7qRFb8uhKrpW1v2h6Y
-6Mz3sqKrmAvkLZXQo/NafQgZvQKBgQDZRzjp368g9velHm3wPRikJpYodi2F5jph
-1Ti0GfUegXueRWqQeDORub40w8aOcUGzb4UvDs0hMIo7+CMZ/BcmkYJDJ+w7CzrE
-fVoDUo1Fjf7zWZ9iNUeaxT4cY/8D9mn9s8xE1/7fOPGUKtC+f8nGLn6YJxXivmqH
-Sp9gBYcfswKBgQDX87gV1oazZFgY/DXEnPbysd0yhJFBac+n9TtqgVJ9X++EDaO/
-ls68uQJhHDlNtbbCMp34wFYr0osVI+NPUvYap+jrgL8g3fXdFuSJ9cEISOQrZlVk
-211pBlLEB3LVUmsv94KLBsQO2SpUO/XiFamBUd6NkgL90xn9DHx0x/9XyQKBgB4d
-A+NOEByWfe4RkJUaMp8VhfwnnNmQ9gh3H7u+WT2YHoTqBAHv1t3ci2MOuyckxUFU
-NHY4K+/spUv4cQz55k9/HTmnf9MTFFsFMIODXncEXhBmHHPlBH6L1bbjmQV4kmoK
-EEZ+VSGk575sTLAKT/G6oer+h8b8MxF7IymQupCHAoGBAMjCM+Vj5yvLlXzOYte/
-C7mOTmvtg38LjtsO9Ny5kSZri3U8c4MQvzTl7xBGYLxY7l1+UKWICXO12aLXG8Z0
-xcGJr2Y/GVb+Bk8zhEmq8ic/pCLMM95y014TpGEDnTBdGl/+mSl1o99oNjxVdElh
-oCAgmZ1iigHV+EMlStoRo+TJ
------END PRIVATE KEY-----
diff --git a/examples/simple/client.cert b/examples/simple/client.cert
deleted file mode 100644
index 565fb1f..0000000
--- a/examples/simple/client.cert
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICrDCCAZQCAQEwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UEAwwVQ2VydGlmaWNh
-dGUgQXV0aG9yaXR5MB4XDTE2MDMxMzA2NDE1MloXDTIxMDMxMjA2NDE1MlowGDEW
-MBQGA1UEAwwNU2ltcGxlIENsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBALW301iodug3FsO/sxcCbIb2kwDAt+/lHBsDyPOpZ4qja/Gz+5Fplmof
-3S1mM67kt6kYRfFSrcf+KSw9x4cnJ11ya6CN24OgL6v+0dWxQRRR0XYNzOoltA/a
-Ayi+Q2puCgsWI/Urb7m04JtcSnKwYhFnDJyTq0px51G2imywYudGJSuMnfA+jPBo
-RZuWz+1TmT6T5q3KKguyPb3S8RTYqK2BfGA7aavM5JxheGPEw1uMuVVXAggtWxM3
-EL0Mu6pwSEZyHJrPoNbkMbqXF89nxiDwbjKxXj/gbZ13zW11FlIt1Cn+epXeo8yU
-sgUXok3T6yzppVsvhIfKmoTOnVuTQikCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
-QN6Q/l5NmuBDTDLtdzdWuxPsgDqi0zOJrzgCgqL7IMD/YsL8dyLuo8OzFtToFmyB
-RClYP5vZZCUVjJ0YrMV6KOdCnmCigfJa6fgr8U+M17IZSBjHhDPkNee9y8M+aWkj
-V+ek6Cb8YcHKS481/am0VyFHb/iqnKrj6gsGuwJYk7SKmvkiGVwTCgtKmHpBup8N
-pk5jJv5xxH5X7U+eU/GswTp19jkIusT7p51TwLGe9NJE6Cqimn/SpZDRPHugeXDO
-LqCiiLH2WghimJl2wK2TVtRaRDH+eEqHGyFxaT5hwPLqfUswZZ7qBLL8VBt6aXc1
-d2L8/qA3dJGTArbQM88ldw==
------END CERTIFICATE-----
diff --git a/examples/simple/client.pkey b/examples/simple/client.pkey
deleted file mode 100644
index be0423d..0000000
--- a/examples/simple/client.pkey
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1t9NYqHboNxbD
-v7MXAmyG9pMAwLfv5RwbA8jzqWeKo2vxs/uRaZZqH90tZjOu5LepGEXxUq3H/iks
-PceHJyddcmugjduDoC+r/tHVsUEUUdF2DczqJbQP2gMovkNqbgoLFiP1K2+5tOCb
-XEpysGIRZwyck6tKcedRtopssGLnRiUrjJ3wPozwaEWbls/tU5k+k+atyioLsj29
-0vEU2KitgXxgO2mrzOScYXhjxMNbjLlVVwIILVsTNxC9DLuqcEhGchyaz6DW5DG6
-lxfPZ8Yg8G4ysV4/4G2dd81tdRZSLdQp/nqV3qPMlLIFF6JN0+ss6aVbL4SHypqE
-zp1bk0IpAgMBAAECggEAWIaYQG25l8EWpwAhyAjXRBylWs2IDidoPMToRcP2fDTG
-5nYPDTUKIOMrBe3vKbmku4zmrfzgSjjIaBQkuvPZGo4eXpYdJY+JCdpW8SqsELEX
-QNLSTBNYGAzWUyf1gcjfvazokYy6nha/ARDB+ANzkxTHsRPDc73vugAaiX6YgB/5
-3xQHUR8fe935XWiXOVtXgRSs95TCJaMRqZ2L0WXg+8CZ6w6cKGZGcH7PV4cetDdZ
-9WuuJPsaKSsjciyXxe8ghxiA6hYJ4XLBCoMhBiNUOSVkYG9NHZjXbP/G8uNdZ62G
-lYa+rs3tlkZlbbgPN0TAjJB6IeU90VryFwtYaSvODQKBgQDtzIDbDF+hHcL4vTA3
-elkJmvC/LZgN8gRo6tvABRnG/SVb9O1AXckjw+ze5Ki/1M82LPnOTOPoJEwfMMNo
-++4eEhBl5bT5T6YTl+Yg1cGCVk3ENrUI1ecsz3PF3e8kKMaG3/UA1FJy4q3+s4z2
-K4jIk+fGpzLLuEgcdLrEdzbplwKBgQDDoHXAfc95HPzVh4n5o6c8ci/kFsPy2d4j
-n1N8mi8SCssibzrkRGWysfENhLwMi1F7AUD1BfOGGEYRBnoTGbSvNdMh4hpn9qCu
-wmHYDfT8SeOHHTldTgWweAB8Yb6JZPbFZx3hZ3L+lMuPmJqY5TwFqkdLc8H3Vyg1
-/pYNeMsqPwKBgQCnI1jiHUVNqexzBg5QwAa60JMr3DEGhDeDQqenxC4FBcJvaqwi
-1IheQgRH+bF9+2aU7nG6BaMec/yo445FSOVpb0rlQ9m6bbgOB3KxW2yCXoSUR9tg
-VXABt+Hojf/ai2pWPC0pIxK8OwUOg0atc5XVXNfIcZYrR+AvWAA5vIz1CwKBgBDz
-o6CFhmf5UhNyxksCmmhLgMjkDCDMLkqp8MMYXUHT+5xFRTYokyNz9e509RKlM+9T
-wXw6Ass46UFqbUOgc57HLD+AZ0dhALWEFJRzSSpfgL7hkmn6a9XJ4Ejm82rWe+fJ
-MraojzduT2FnGOZs3tGi2sC4DDPRsqNTJ0+NixVjAoGAfA661nYxFXMFzHv6R5/Y
-nvi1Tc/6OdWck9PEliZ0OKApKQYN+gV9nmvXVV+1WG6H44anvcWtHFYQJcMJnz6j
-CpArF7VJ6mgpJbKAMqLW8X39YnEf+mfuKFgpr2/XEHirscVkXsfioVrhuaeq2YXP
-FT90TIih3TY3I+xBZBvwYEQ=
------END PRIVATE KEY-----
diff --git a/examples/simple/server.cert b/examples/simple/server.cert
deleted file mode 100644
index a4898aa..0000000
--- a/examples/simple/server.cert
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICrDCCAZQCAQEwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UEAwwVQ2VydGlmaWNh
-dGUgQXV0aG9yaXR5MB4XDTE2MDMxMzA2NDE1MloXDTIxMDMxMjA2NDE1MlowGDEW
-MBQGA1UEAwwNU2ltcGxlIFNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAONn5vsojAnUuFSx8ZW/VNl/hqMG3o5KsdO79ItnLuHL3FGONs1LY7LS
-kHDDNSAGoyAjuL7GgfrCwx1N/wuI63JcO2mobGZ5bBdfHNppKFuKruBV3s2XUoRp
-uSm7AVGvTGQnL2ifgUz2ecXFDvhPSYIEI57eSgcvkvcZHqi7YPQQ2IuzqOrYfOf/
-NG7tfNBJLLScbWflBHukjU6fQr88yOZHeMrx1YdHQVBMwPcJSe0t8pdRUjsPv6Hi
-b6f1grB79PoAz+pU5DxcAhGMxtJkXuqbbadsAAadeC4SWV4RVFpQF6mvTsUVsMwW
-D1/YMcYsak1K6fsolZIyfN1hnIB3mOkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
-vIqV7vupKuwP+ebefhMXK0OYiyGptVzpBBTrwKkvxwE9/Sw8ROoEUYT9oQt3Vh/A
-ajU+7pXHOqKA2Vdaxv9vURoSiJp2BFcSJQTyZXmkMVhx1UzrNk90V55Hj5oTdIr1
-rhWIG1+Hs6449FpLb6SX44gf3VHMYz7/0C3/p2JkS9faj0RYR4kPLWzVSikV8VoU
-G/MAKhdjf4nFT9M5ryEnpkX4X7TpBprQX6fw4ckVwROjCdDNIbPgHkXF4nzi/m8F
-39O8J3zxCn5EdJP7pGLe7jxUoNf/a/IHZ9BLq0xaPU4oqfGviD0tI1El3RIsBvg5
-xMjB90mf5p5ILM3FFZrw3Q==
------END CERTIFICATE-----
diff --git a/examples/simple/server.pkey b/examples/simple/server.pkey
deleted file mode 100644
index a6d2ff1..0000000
--- a/examples/simple/server.pkey
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDjZ+b7KIwJ1LhU
-sfGVv1TZf4ajBt6OSrHTu/SLZy7hy9xRjjbNS2Oy0pBwwzUgBqMgI7i+xoH6wsMd
-Tf8LiOtyXDtpqGxmeWwXXxzaaShbiq7gVd7Nl1KEabkpuwFRr0xkJy9on4FM9nnF
-xQ74T0mCBCOe3koHL5L3GR6ou2D0ENiLs6jq2Hzn/zRu7XzQSSy0nG1n5QR7pI1O
-n0K/PMjmR3jK8dWHR0FQTMD3CUntLfKXUVI7D7+h4m+n9YKwe/T6AM/qVOQ8XAIR
-jMbSZF7qm22nbAAGnXguElleEVRaUBepr07FFbDMFg9f2DHGLGpNSun7KJWSMnzd
-YZyAd5jpAgMBAAECggEBAI6su9DMicAJRHVvB2Gqn3OufSx/vNaNqrBrdmyYGmP0
-YZCRp3R6Xlztm04ES6qCP4qEnv6i0R4hYAVc0C3Og9pGX8hUsV5BxD2NoS6vV3DH
-vBxoA9f9nvoQ0umJuLQlRcp4g1gi6x78bT5V+qR0Kmx2aFreoJeNk6mQixnWJmg5
-koievNP3LWgdRkpS+WaV5t8Umlpv11JigsHBiIEpD2QrywPToIu1JSXl8a9ZDCI7
-XOs258HVtn9b2CFrAJAae0/k5jssaOWATwHAp4FqVrRftf/a2yuSx8rFpVIgrQsS
-fDSBtXd+j/HfyKyyK97jGcTp72rYRRu9w1a/T1S1SAECgYEA+pQ+eB0zN1Wv0JYy
-y3aMSzGz+GmMXXUC6mc8U8592OsYFLlcCrzhut+vSEE/2ve1qsmyPKng5N0jZnYw
-8jvyhKQf+8OdQORCv0W1a6RUpQB85BpPkMRckl/RM1g5WrRD0aVq9lNhbP37wcGQ
-CZu+oU5+Lu+HtLYdwXHHl9j00YECgYEA6FNSCsunOwqkRccQg3FgQQyXvANZzK3j
-I5fg+6ZJKczrLyATQX/WDFq0j2CJPyw2OmOLUSH6UVEqOcL88mhwg3v3rWNHm3Zs
-lhl7Oor6npDJSe/TL41G5BpAmZ2odrFepdQQ4bUIIeIaMA3oknL6/IJOilQWn9w/
-+Jf59cldK2kCgYEAyMk07UZonbRZdwiDlylc7XvcO/dHdDOorG8glf7mNITc/O4y
-ZKBJOFa4u2sdYbYPqdSIr7dn77uK/DVErzV99O8WecSbIz5EhcOzxZceBEFJ0fWL
-P/M4Qkno9f2Bp76+gSTNeqgBbzZtHyqc4jYcIGEnFzD0SseLPFCRoIlGUwECgYBm
-395IYX2fq0qqi0dIrP+OTmEyI9mzxJv7utkpFaz4EYFi0LU2H8FMny2s/3ZGvvEU
-UdfzCTSqpWIpSapwPMb1sgMuh/PBZ2MV5BqpBbmMVViMoOHHAKwPfYB1hVZ/mHLs
-w0bmax86wcAO31nI35k8DwdwQWPzTbgWAFXy/EOBYQKBgQClKEs2xQDKLfdrFk0G
-cYLmj0BrfNb0tFnZJXdLBcwVz8mRx8j0JtrLHwUe2NNVgrB/EE7hGf8a6ZY/7b4C
-+LEQs2IGqaJvSwjq8S1rM9mcP6cTn7BWQF1cr/wrwb0wkcFrEnffwjgGmU/rWaH2
-Bk7BImO4J4giXU0+gGSm60r2yg==
------END PRIVATE KEY-----
diff --git a/setup.cfg b/setup.cfg
index 104b3c9..afb25bf 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,12 +1,12 @@
-[pytest]
-minversion = 2.8.5
+[tool:pytest]
+minversion = 3.0.1
 strict = true
 testpaths = tests
 
 [sdist]
 force_manifest = 1
 
-[wheel]
+[bdist_wheel]
 universal = 1
 
 [bdist_rpm]
diff --git a/setup.py b/setup.py
index 4643f71..d4c27ad 100755
--- a/setup.py
+++ b/setup.py
@@ -95,7 +95,7 @@ if __name__ == "__main__":
         package_dir={"": "src"},
         install_requires=[
             # Fix cryptographyMinimum in tox.ini when changing this!
-            "cryptography>=1.3",
+            "cryptography>=1.3.4",
             "six>=1.5.2"
         ],
     )
diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
index 800ae1e..3f97ccb 100644
--- a/src/OpenSSL/SSL.py
+++ b/src/OpenSSL/SSL.py
@@ -59,10 +59,7 @@ OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
 OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
 OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
 
-try:
-    MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
-except AttributeError:
-    pass
+MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
 
 OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
 OP_SINGLE_ECDH_USE = _lib.SSL_OP_SINGLE_ECDH_USE
@@ -74,10 +71,7 @@ OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = (
 )
 OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
 OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
-try:
-    OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
-except AttributeError:
-    pass
+OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
 OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
 OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
 OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
@@ -90,17 +84,11 @@ OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
 OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = (
     _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
 )
-try:
-    OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
-except AttributeError:
-    pass
+OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
 
 OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
 OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
-try:
-    OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
-except AttributeError:
-    pass
+OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
 
 OP_ALL = _lib.SSL_OP_ALL
 
@@ -406,34 +394,41 @@ def SSLeay_version(type):
     return _ffi.string(_lib.SSLeay_version(type))
 
 
-def _requires_npn(func):
+def _make_requires(flag, error):
     """
-    Wraps any function that requires NPN support in OpenSSL, ensuring that
-    NotImplementedError is raised if NPN is not present.
+    Builds a decorator that ensures that functions that rely on OpenSSL
+    functions that are not present in this build raise NotImplementedError,
+    rather than AttributeError coming out of cryptography.
+
+    :param flag: A cryptography flag that guards the functions, e.g.
+        ``Cryptography_HAS_NEXTPROTONEG``.
+    :param error: The string to be used in the exception if the flag is false.
     """
-    @wraps(func)
-    def wrapper(*args, **kwargs):
-        if not _lib.Cryptography_HAS_NEXTPROTONEG:
-            raise NotImplementedError("NPN not available.")
+    def _requires_decorator(func):
+        if not flag:
+            @wraps(func)
+            def explode(*args, **kwargs):
+                raise NotImplementedError(error)
+            return explode
+        else:
+            return func
+
+    return _requires_decorator
 
-        return func(*args, **kwargs)
 
-    return wrapper
+_requires_npn = _make_requires(
+    _lib.Cryptography_HAS_NEXTPROTONEG, "NPN not available"
+)
 
 
-def _requires_alpn(func):
-    """
-    Wraps any function that requires ALPN support in OpenSSL, ensuring that
-    NotImplementedError is raised if ALPN support is not present.
-    """
-    @wraps(func)
-    def wrapper(*args, **kwargs):
-        if not _lib.Cryptography_HAS_ALPN:
-            raise NotImplementedError("ALPN not available.")
+_requires_alpn = _make_requires(
+    _lib.Cryptography_HAS_ALPN, "ALPN not available"
+)
 
-        return func(*args, **kwargs)
 
-    return wrapper
+_requires_sni = _make_requires(
+    _lib.Cryptography_HAS_TLSEXT_HOSTNAME, "SNI not available"
+)
 
 
 class Session(object):
@@ -472,14 +467,10 @@ class Context(object):
             raise ValueError("No such protocol")
 
         method_obj = method_func()
-        if method_obj == _ffi.NULL:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(method_obj != _ffi.NULL)
 
         context = _lib.SSL_CTX_new(method_obj)
-        if context == _ffi.NULL:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(context != _ffi.NULL)
         context = _ffi.gc(context, _lib.SSL_CTX_free)
 
         self._context = context
@@ -564,9 +555,7 @@ class Context(object):
         :return: None
         """
         set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
-        if not set_result:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(set_result == 1)
 
     def use_certificate_chain_file(self, certfile):
         """
@@ -854,9 +843,7 @@ class Context(object):
         :return: None
         """
         name_stack = _lib.sk_X509_NAME_new_null()
-        if name_stack == _ffi.NULL:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(name_stack != _ffi.NULL)
 
         try:
             for ca_name in certificate_authorities:
@@ -868,9 +855,7 @@ class Context(object):
                         )
                     )
                 copy = _lib.X509_NAME_dup(ca_name._name)
-                if copy == _ffi.NULL:
-                    # TODO: This is untested.
-                    _raise_current_error()
+                _openssl_assert(copy != _ffi.NULL)
                 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
                 if not push_result:
                     _lib.X509_NAME_free(copy)
@@ -897,9 +882,7 @@ class Context(object):
 
         add_result = _lib.SSL_CTX_add_client_CA(
             self._context, certificate_authority._x509)
-        if not add_result:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(add_result == 1)
 
     def set_timeout(self, timeout):
         """
@@ -991,6 +974,7 @@ class Context(object):
 
         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
@@ -1123,11 +1107,10 @@ class Connection(object):
             self._socket = None
             # Don't set up any gc for these, SSL_free will take care of them.
             self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
-            self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
+            _openssl_assert(self._into_ssl != _ffi.NULL)
 
-            if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
-                # TODO: This is untested.
-                _raise_current_error()
+            self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
+            _openssl_assert(self._from_ssl != _ffi.NULL)
 
             _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
         else:
@@ -1136,9 +1119,7 @@ class Connection(object):
             self._socket = socket
             set_result = _lib.SSL_set_fd(
                 self._ssl, _asFileDescriptor(self._socket))
-            if not set_result:
-                # TODO: This is untested.
-                _raise_current_error()
+            _openssl_assert(set_result == 1)
 
     def __getattr__(self, name):
         """
@@ -1209,6 +1190,7 @@ class Connection(object):
         _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
@@ -1224,6 +1206,7 @@ class Connection(object):
 
         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.
@@ -1304,9 +1287,7 @@ class Connection(object):
 
     def recv(self, bufsiz, flags=None):
         """
-        Receive data on the connection. NOTE: If you get one of the WantRead,
-        WantWrite or WantX509Lookup exceptions on this, you have to call the
-        method again with the SAME buffer.
+        Receive data on the connection.
 
         :param bufsiz: The maximum number of bytes to read
         :param flags: (optional) The only supported flag is ``MSG_PEEK``,
@@ -1557,9 +1538,7 @@ class Connection(object):
         for i in range(_lib.sk_X509_NAME_num(ca_names)):
             name = _lib.sk_X509_NAME_value(ca_names, i)
             copy = _lib.X509_NAME_dup(name)
-            if copy == _ffi.NULL:
-                # TODO: This is untested.
-                _raise_current_error()
+            _openssl_assert(copy != _ffi.NULL)
 
             pyname = X509Name.__new__(X509Name)
             pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
@@ -1629,11 +1608,14 @@ class Connection(object):
 
         :return: A string representing the state
         """
-        if self._ssl.session == _ffi.NULL:
+        session = _lib.SSL_get_session(self._ssl)
+        if session == _ffi.NULL:
             return None
-        return _ffi.buffer(
-            self._ssl.s3.server_random,
-            _lib.SSL3_RANDOM_SIZE)[:]
+        length = _lib.SSL_get_server_random(self._ssl, _ffi.NULL, 0)
+        assert length > 0
+        outp = _ffi.new("char[]", length)
+        _lib.SSL_get_server_random(self._ssl, outp, length)
+        return _ffi.buffer(outp, length)[:]
 
     def client_random(self):
         """
@@ -1641,11 +1623,15 @@ class Connection(object):
 
         :return: A string representing the state
         """
-        if self._ssl.session == _ffi.NULL:
+        session = _lib.SSL_get_session(self._ssl)
+        if session == _ffi.NULL:
             return None
-        return _ffi.buffer(
-            self._ssl.s3.client_random,
-            _lib.SSL3_RANDOM_SIZE)[:]
+
+        length = _lib.SSL_get_client_random(self._ssl, _ffi.NULL, 0)
+        assert length > 0
+        outp = _ffi.new("char[]", length)
+        _lib.SSL_get_client_random(self._ssl, outp, length)
+        return _ffi.buffer(outp, length)[:]
 
     def master_key(self):
         """
@@ -1653,11 +1639,15 @@ class Connection(object):
 
         :return: A string representing the state
         """
-        if self._ssl.session == _ffi.NULL:
+        session = _lib.SSL_get_session(self._ssl)
+        if session == _ffi.NULL:
             return None
-        return _ffi.buffer(
-            self._ssl.session.master_key,
-            self._ssl.session.master_key_length)[:]
+
+        length = _lib.SSL_SESSION_get_master_key(session, _ffi.NULL, 0)
+        assert length > 0
+        outp = _ffi.new("char[]", length)
+        _lib.SSL_SESSION_get_master_key(session, outp, length)
+        return _ffi.buffer(outp, length)[:]
 
     def sock_shutdown(self, *args, **kwargs):
         """
diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py
index 2cb3cbd..116cc51 100644
--- a/src/OpenSSL/crypto.py
+++ b/src/OpenSSL/crypto.py
@@ -10,6 +10,9 @@ from six import (
     text_type as _text_type,
     PY3 as _PY3)
 
+from cryptography.hazmat.backends.openssl.backend import backend
+from cryptography.hazmat.primitives.asymmetric import dsa, rsa
+
 from OpenSSL._util import (
     ffi as _ffi,
     lib as _lib,
@@ -18,6 +21,7 @@ from OpenSSL._util import (
     native as _native,
     UNSPECIFIED as _UNSPECIFIED,
     text_to_bytes_and_warn as _text_to_bytes_and_warn,
+    make_assert as _make_assert,
 )
 
 FILETYPE_PEM = _lib.SSL_FILETYPE_PEM
@@ -37,6 +41,7 @@ class Error(Exception):
 
 
 _raise_current_error = partial(_exception_from_error_queue, Error)
+_openssl_assert = _make_assert(Error)
 
 
 def _untested_error(where):
@@ -68,9 +73,7 @@ def _new_mem_buf(buffer=None):
         def free(bio, ref=data):
             return _lib.BIO_free(bio)
 
-    if bio == _ffi.NULL:
-        # TODO: This is untested.
-        _raise_current_error()
+    _openssl_assert(bio != _ffi.NULL)
 
     bio = _ffi.gc(bio, free)
     return bio
@@ -167,6 +170,45 @@ class PKey(object):
         self._pkey = _ffi.gc(pkey, _lib.EVP_PKEY_free)
         self._initialized = False
 
+    def to_cryptography_key(self):
+        """
+        Export as a ``cryptography`` key.
+
+        :rtype: One of ``cryptography``'s `key interfaces`_.
+
+        .. _key interfaces: https://cryptography.io/en/latest/hazmat/\
+            primitives/asymmetric/rsa/#key-interfaces
+
+        .. versionadded:: 16.1.0
+        """
+        if self._only_public:
+            return backend._evp_pkey_to_public_key(self._pkey)
+        else:
+            return backend._evp_pkey_to_private_key(self._pkey)
+
+    @classmethod
+    def from_cryptography_key(cls, crypto_key):
+        """
+        Construct based on a ``cryptography`` *crypto_key*.
+
+        :param crypto_key: A ``cryptography`` key.
+        :type crypto_key: One of ``cryptography``'s `key interfaces`_.
+
+        :rtype: PKey
+
+        .. versionadded:: 16.1.0
+        """
+        pkey = cls()
+        if not isinstance(crypto_key, (rsa.RSAPublicKey, rsa.RSAPrivateKey,
+                                       dsa.DSAPublicKey, dsa.DSAPrivateKey)):
+            raise TypeError("Unsupported key type")
+
+        pkey._pkey = crypto_key._evp_pkey
+        if isinstance(crypto_key, (rsa.RSAPublicKey, dsa.DSAPublicKey)):
+            pkey._only_public = True
+        pkey._initialized = True
+        return pkey
+
     def generate_key(self, type, bits):
         """
         Generate a key pair of the given type, with the given number of bits.
@@ -181,7 +223,7 @@ class PKey(object):
             of the appropriate type.
         :raises ValueError: If the number of bits isn't an integer of
             the appropriate size.
-        :return: :py:const:`None`
+        :return: ``None``
         """
         if not isinstance(type, int):
             raise TypeError("type must be an integer")
@@ -201,40 +243,23 @@ class PKey(object):
             rsa = _lib.RSA_new()
 
             result = _lib.RSA_generate_key_ex(rsa, bits, exponent, _ffi.NULL)
-            if result == 0:
-                # TODO: The test for this case is commented out.  Different
-                # builds of OpenSSL appear to have different failure modes that
-                # make it hard to test.  Visual inspection of the OpenSSL
-                # source reveals that a return value of 0 signals an error.
-                # Manual testing on a particular build of OpenSSL suggests that
-                # this is probably the appropriate way to handle those errors.
-                _raise_current_error()
+            _openssl_assert(result == 1)
 
             result = _lib.EVP_PKEY_assign_RSA(self._pkey, rsa)
-            if not result:
-                # TODO: It appears as though this can fail if an engine is in
-                # use which does not support RSA.
-                _raise_current_error()
+            _openssl_assert(result == 1)
 
         elif type == TYPE_DSA:
             dsa = _lib.DSA_new()
-            if dsa == _ffi.NULL:
-                # TODO: This is untested.
-                _raise_current_error()
+            _openssl_assert(dsa != _ffi.NULL)
 
             dsa = _ffi.gc(dsa, _lib.DSA_free)
             res = _lib.DSA_generate_parameters_ex(
                 dsa, bits, _ffi.NULL, 0, _ffi.NULL, _ffi.NULL, _ffi.NULL
             )
-            if not res == 1:
-                # TODO: This is untested.
-                _raise_current_error()
-            if not _lib.DSA_generate_key(dsa):
-                # TODO: This is untested.
-                _raise_current_error()
-            if not _lib.EVP_PKEY_set1_DSA(self._pkey, dsa):
-                # TODO: This is untested.
-                _raise_current_error()
+            _openssl_assert(res == 1)
+
+            _openssl_assert(_lib.DSA_generate_key(dsa) == 1)
+            _openssl_assert(_lib.EVP_PKEY_set1_DSA(self._pkey, dsa) == 1)
         else:
             raise Error("No such key type")
 
@@ -523,9 +548,7 @@ class X509Name(object):
 
         result_buffer = _ffi.new("unsigned char**")
         data_length = _lib.ASN1_STRING_to_UTF8(result_buffer, data)
-        if data_length < 0:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(data_length >= 0)
 
         try:
             result = _ffi.buffer(
@@ -560,10 +583,7 @@ class X509Name(object):
         result_buffer = _ffi.new("char[]", 512)
         format_result = _lib.X509_NAME_oneline(
             self._name, result_buffer, len(result_buffer))
-
-        if format_result == _ffi.NULL:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(format_result != _ffi.NULL)
 
         return "<X509Name object '%s'>" % (
             _native(_ffi.string(result_buffer)),)
@@ -589,9 +609,7 @@ class X509Name(object):
         """
         result_buffer = _ffi.new('unsigned char**')
         encode_result = _lib.i2d_X509_NAME(self._name, result_buffer)
-        if encode_result < 0:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(encode_result >= 0)
 
         string_result = _ffi.buffer(result_buffer[0], encode_result)[:]
         _lib.OPENSSL_free(result_buffer[0])
@@ -706,9 +724,7 @@ class X509Extension(object):
 
     def _subjectAltNameString(self):
         method = _lib.X509V3_EXT_get(self._extension)
-        if method == _ffi.NULL:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(method != _ffi.NULL)
         ext_data = _lib.X509_EXTENSION_get_data(self._extension)
         payload = ext_data.data
         length = ext_data.length
@@ -750,9 +766,7 @@ class X509Extension(object):
 
         bio = _new_mem_buf()
         print_result = _lib.X509V3_EXT_print(bio, self._extension, 0, 0)
-        if not print_result:
-            # TODO: This is untested.
-            _raise_current_error()
+        _openssl_assert(print_result != 0)
 
... 1960 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pyopenssl.git



More information about the Python-modules-commits mailing list