File CVE-2018-1000807-8_use_after_free_X509.patch of Package python-pyOpenSSL.33804
From e73818600065821d588af475b024f4eb518c3509 Mon Sep 17 00:00:00 2001
From: Paul Kehrer <paul.l.kehrer@gmail.com>
Date: Thu, 30 Nov 2017 20:55:25 +0800
Subject: [PATCH] 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
---
CHANGELOG.rst | 6 +++---
setup.py | 2 +-
src/OpenSSL/SSL.py | 5 +++--
src/OpenSSL/crypto.py | 7 +++----
tests/test_ssl.py | 25 +++++++++++++++++++++++++
tox.ini | 2 +-
6 files changed, 36 insertions(+), 11 deletions(-)
Index: pyOpenSSL-17.1.0/src/OpenSSL/SSL.py
===================================================================
--- pyOpenSSL-17.1.0.orig/src/OpenSSL/SSL.py
+++ pyOpenSSL-17.1.0/src/OpenSSL/SSL.py
@@ -218,8 +218,9 @@ class _VerifyHelper(_CallbackExceptionHe
@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)
Index: pyOpenSSL-17.1.0/src/OpenSSL/crypto.py
===================================================================
--- pyOpenSSL-17.1.0.orig/src/OpenSSL/crypto.py
+++ pyOpenSSL-17.1.0/src/OpenSSL/crypto.py
@@ -2997,8 +2997,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(
@@ -3012,8 +3011,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
Index: pyOpenSSL-17.1.0/tests/test_ssl.py
===================================================================
--- pyOpenSSL-17.1.0.orig/tests/test_ssl.py
+++ pyOpenSSL-17.1.0/tests/test_ssl.py
@@ -1280,6 +1280,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