CVE-2018-1000807 (published 2018-10-08T15:29Z)

Python Cryptographic Authority pyopenssl version prior to version 17.5.0 contains a CWE-416: Use After Free vulnerability in X509 object handling that can result in Use after free can lead to possible denial of service or remote code execution.. This attack appear to be exploitable via Depends on the calling application and if it retains a reference to the memory.. This vulnerability appears to have been fixed in 17.5.0.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 8.1, HIGH (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-416
cwe_name: Use After Free
description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
extended_description: 
             
             
             
			 
             
             
         
         

Fix information:
repo_url: https://github.com/pyca/pyopenssl
commit_details: repo_url: https://github.com/pyca/pyopenssl
author: Paul Kehrer
author_date: 2017-11-30 20:55:25+08:00
msg: fix a memory leak and a potential UAF and also #722 (#723)

* fix a memory leak and a potential UAF and also #722

* sanity check

* bump cryptography minimum version, add changelog
repository: repo_url: https://github.com/pyca/pyopenssl
repo_name: pyca/pyopenssl
description: A Python wrapper around the OpenSSL library
repo_language: Python
owner: pyca
file_changes: filename: CHANGELOG.rst
change_type: ModificationType.MODIFY
diff: @@ -11,7 +11,7 @@ The third digit is only for regressions.
 Backward-incompatible changes:
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-*none*
+* The minimum ``cryptography`` version is now 2.1.4.
 
 
 Deprecations:
@@ -23,8 +23,8 @@ Deprecations:
 Changes:
 ^^^^^^^^
 
-
-*none*
+- Fixed a potential use-after-free in the verify callback and resolved a memory leak when loading PKCS12 files with ``cacerts``.
+  `#723 <https://github.com/pyca/pyopenssl/pull/723>`_
 
 ----
 

programming_language: Markdown
filename: setup.py
change_type: ModificationType.MODIFY
diff: @@ -95,7 +95,7 @@ if __name__ == "__main__":
         package_dir={"": "src"},
         install_requires=[
             # Fix cryptographyMinimum in tox.ini when changing this!
-            "cryptography>=1.9",
+            "cryptography>=2.1.4",
             "six>=1.5.2"
         ],
         extras_require={

programming_language: Python
filename: SSL.py
change_type: ModificationType.MODIFY
diff: @@ -309,8 +309,9 @@ class _VerifyHelper(_CallbackExceptionHelper):
 
         @wraps(callback)
         def wrapper(ok, store_ctx):
-            cert = X509.__new__(X509)
-            cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
+            x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
+            _lib.X509_up_ref(x509)
+            cert = X509._from_raw_x509_ptr(x509)
             error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
             error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
 

programming_language: Python
filename: crypto.py
change_type: ModificationType.MODIFY
diff: @@ -3058,8 +3058,7 @@ def load_pkcs12(buffer, passphrase=None):
         pycert = None
         friendlyname = None
     else:
-        pycert = X509.__new__(X509)
-        pycert._x509 = _ffi.gc(cert[0], _lib.X509_free)
+        pycert = X509._from_raw_x509_ptr(cert[0])
 
         friendlyname_length = _ffi.new("int*")
         friendlyname_buffer = _lib.X509_alias_get0(
@@ -3073,8 +3072,8 @@ def load_pkcs12(buffer, passphrase=None):
 
     pycacerts = []
     for i in range(_lib.sk_X509_num(cacerts)):
-        pycacert = X509.__new__(X509)
-        pycacert._x509 = _lib.sk_X509_value(cacerts, i)
+        x509 = _lib.sk_X509_value(cacerts, i)
+        pycacert = X509._from_raw_x509_ptr(x509)
         pycacerts.append(pycacert)
     if not pycacerts:
         pycacerts = None

programming_language: Python
filename: test_ssl.py
change_type: ModificationType.MODIFY
diff: @@ -1279,6 +1279,31 @@ class TestContext(object):
 
         assert verify.connection is clientConnection
 
+    def test_x509_in_verify_works(self):
+        """
+        We had a bug where the X509 cert instantiated in the callback wrapper
+        didn't __init__ so it was missing objects needed when calling
+        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.use_privatekey(
+            load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
+        serverContext.use_certificate(
+            load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
+        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.set_verify(VERIFY_PEER, verify_cb_get_subject)
+        clientConnection = Connection(clientContext, None)
+        clientConnection.set_connect_state()
+
+        handshake_in_memory(clientConnection, serverConnection)
+
     def test_set_verify_callback_exception(self):
         """
         If the verify callback passed to `Context.set_verify` raises an

programming_language: Python
filename: tox.ini
change_type: ModificationType.MODIFY
diff: @@ -10,7 +10,7 @@ extras =
 deps =
     coverage>=4.2
     cryptographyMaster: git+https://github.com/pyca/cryptography.git
-    cryptographyMinimum: cryptography<=1.9
+    cryptographyMinimum: cryptography==2.1.4
 setenv =
     # Do not allow the executing environment to pollute the test environment
     # with extra packages.

programming_language: Shell