Perform an OPENSSL_cleanup before checking the heap in our memleak tests (#4293)

* Perform an OPENSSL_cleanup before checking the heap in our memleak tests

* Make this binding conditional

* typo

* need to put this call before we reset the function ptrs
diff --git a/src/_cffi_src/openssl/crypto.py b/src/_cffi_src/openssl/crypto.py
index 449fff5..03672d5 100644
--- a/src/_cffi_src/openssl/crypto.py
+++ b/src/_cffi_src/openssl/crypto.py
@@ -11,6 +11,7 @@
 TYPES = """
 static const long Cryptography_HAS_LOCKING_CALLBACKS;
 static const long Cryptography_HAS_MEM_FUNCTIONS;
+static const long Cryptography_HAS_OPENSSL_CLEANUP;
 
 static const int SSLEAY_VERSION;
 static const int SSLEAY_CFLAGS;
@@ -34,8 +35,9 @@
 
 FUNCTIONS = """
 int CRYPTO_mem_ctrl(int);
-/* CRYPTO_cleanup_all_ex_data became a macro in 1.1.0 */
+
 void CRYPTO_cleanup_all_ex_data(void);
+void OPENSSL_cleanup(void);
 
 /* as of 1.1.0 OpenSSL does its own locking *angelic chorus*. These functions
    have become macros that are no ops */
@@ -112,6 +114,10 @@
 #endif
 
 #if CRYPTOGRAPHY_OPENSSL_LESS_THAN_110
+static const long Cryptography_HAS_OPENSSL_CLEANUP = 0;
+
+void (*OPENSSL_cleanup)(void) = NULL;
+
 /* This function has a significantly different signature pre-1.1.0. since it is
  * for testing only, we don't bother to expose it on older OpenSSLs.
  */
@@ -122,6 +128,7 @@
     void (*)(void *, const char *, int)) = NULL;
 
 #else
+static const long Cryptography_HAS_OPENSSL_CLEANUP = 1;
 static const long Cryptography_HAS_MEM_FUNCTIONS = 1;
 
 int Cryptography_CRYPTO_set_mem_functions(
diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py
index 761124f..b3e4e8b 100644
--- a/src/cryptography/hazmat/bindings/openssl/_conditional.py
+++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py
@@ -240,6 +240,12 @@
     ]
 
 
+def cryptography_has_openssl_cleanup():
+    return [
+        "OPENSSL_cleanup",
+    ]
+
+
 # This is a mapping of
 # {condition: function-returning-names-dependent-on-that-condition} so we can
 # loop over them and delete unsupported names at runtime. It will be removed
@@ -292,4 +298,5 @@
     "Cryptography_HAS_SIGALGS": cryptography_has_ssl_sigalgs,
     "Cryptography_HAS_PSK": cryptography_has_psk,
     "Cryptography_HAS_CUSTOM_EXT": cryptography_has_custom_ext,
+    "Cryptography_HAS_OPENSSL_CLEANUP": cryptography_has_openssl_cleanup,
 }
diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py
index 74973fe..cd45354 100644
--- a/tests/hazmat/backends/test_openssl_memleak.py
+++ b/tests/hazmat/backends/test_openssl_memleak.py
@@ -60,6 +60,9 @@
     gc.collect()
     gc.collect()
 
+    if lib.Cryptography_HAS_OPENSSL_CLEANUP:
+        lib.OPENSSL_cleanup()
+
     # Swap back to the original functions so that if OpenSSL tries to free
     # something from its atexit handle it won't be going through a Python
     # function, which will be deallocated when this function returns