diff options
author | Arne Schwabe <arne@rfc2549.org> | 2020-11-27 19:29:49 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-27 12:29:49 -0600 |
commit | 3562df8732f66848342874526d0ce12392d7d62e (patch) | |
tree | 8ff18795804fd4a6fe4675d9dfacdd4bb6444d8b /tests | |
parent | f3667e95188e8c14458a7943c7efab3776b04711 (diff) | |
download | pyopenssl-git-3562df8732f66848342874526d0ce12392d7d62e.tar.gz |
Keep reference to SSL verify_call in Connection object (#956)
* Keep reference to SSL verify_call in Connection object
If a set_verify is used on a context before and after a Connection
the reference in the SSL* object still points to the old _verify_helper
object. Since this object has no longer any references to it, the
callback can result in a segfault.
This commit fixes the issues by ensuring that as long as the
Connection object/SSL* object lives a reference to the callback
function is held.
* Add Unit test for set_verify_callback deference
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test_ssl.py | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/tests/test_ssl.py b/tests/test_ssl.py index aed2367..8fdcae2 100644 --- a/tests/test_ssl.py +++ b/tests/test_ssl.py @@ -6,6 +6,7 @@ Unit tests for :mod:`OpenSSL.SSL`. """ import datetime +import gc import sys import uuid @@ -1389,6 +1390,51 @@ class TestContext(object): 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): """ |