Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP5:GA
python-pyOpenSSL.9666
CVE-2018-1000807-8_use_after_free_X509.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2018-1000807-8_use_after_free_X509.patch of Package python-pyOpenSSL.9666
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-16.0.0/src/OpenSSL/SSL.py =================================================================== --- pyOpenSSL-16.0.0.orig/src/OpenSSL/SSL.py +++ pyOpenSSL-16.0.0/src/OpenSSL/SSL.py @@ -210,8 +210,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-16.0.0/src/OpenSSL/crypto.py =================================================================== --- pyOpenSSL-16.0.0.orig/src/OpenSSL/crypto.py +++ pyOpenSSL-16.0.0/src/OpenSSL/crypto.py @@ -2770,8 +2770,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( @@ -2785,8 +2784,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-16.0.0/tests/test_ssl.py =================================================================== --- pyOpenSSL-16.0.0.orig/tests/test_ssl.py +++ pyOpenSSL-16.0.0/tests/test_ssl.py @@ -179,6 +179,68 @@ def handshake(client, server): conns.remove(conn) +def interact_in_memory(client_conn, server_conn): + """ + Try to read application bytes from each of the two `Connection` objects. + Copy bytes back and forth between their send/receive buffers for as long + as there is anything to copy. When there is nothing more to copy, + return `None`. If one of them actually manages to deliver some application + bytes, return a two-tuple of the connection from which the bytes were read + and the bytes themselves. + """ + wrote = True + while wrote: + # Loop until neither side has anything to say + wrote = False + + # 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)]: + + # Give the side a chance to generate some more bytes, or succeed. + try: + data = read.recv(2 ** 16) + except WantReadError: + # It didn't succeed, so we'll hope it generated some output. + pass + else: + # It did succeed, so we'll stop now and let the caller deal + # with it. + return (read, data) + + while True: + # Keep copying as long as there's more stuff there. + try: + dirty = read.bio_read(4096) + except WantReadError: + # Okay, nothing more waiting to be sent. Stop + # processing this send buffer. + break + else: + # Keep track of the fact that someone generated some + # output. + wrote = True + write.bio_write(dirty) + + +def handshake_in_memory(client_conn, server_conn): + """ + Perform the TLS handshake between two `Connection` instances connected to + each other via memory BIOs. + """ + client_conn.set_connect_state() + server_conn.set_accept_state() + + for conn in [client_conn, server_conn]: + try: + conn.do_handshake() + except WantReadError: + pass + + interact_in_memory(client_conn, server_conn) + + def _create_certificate_chain(): """ Construct and return a chain of certificates. @@ -1300,6 +1362,31 @@ class ContextTests(TestCase, _LoopbackMi self.assertIdentical(verify.connection, 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 :py:obj:`Context.set_verify` raises an
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor