Ejemplo n.º 1
0
void server_thread(void *arg)
{
	BIO *client = (BIO *)arg;

	pthread_detach(pthread_self());
	fprintf(stderr, "Connection opened\n");
	do_server_loop(client);
	fprintf(stderr,"Connection closed\n");

	BIO_free(client);
	ERR_remove_state(0);
}
Ejemplo n.º 2
0
void shutdown_ssl(void)
{
	BIO_free(bio_err);

	ERR_free_strings();

	ERR_remove_state(0);
	ENGINE_cleanup();
	CONF_modules_free();
	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();
}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
	test_extended_key();
	test_serialize();
	test_vector_1();
	test_vector_2();

	// Keep valgrind happy
	ERR_remove_state(0);

	return 0;
}
Ejemplo n.º 4
0
static int luaclose_openssl(lua_State *L)
{
  if(atomic_fetch_sub(&init, 1) > 1)
    return 0;

#if !defined(LIBRESSL_VERSION_NUMBER)
  FIPS_mode_set(0);
#endif

  OBJ_cleanup();
  EVP_cleanup();
  ENGINE_cleanup();
  RAND_cleanup();

#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
  SSL_COMP_free_compression_methods();
#endif
  COMP_zlib_cleanup();


#if OPENSSL_VERSION_NUMBER < 0x10000000L
  ERR_remove_state(0);
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
  ERR_remove_thread_state(NULL);
#endif
#if defined(OPENSSL_THREADS)
  CRYPTO_thread_cleanup();
#endif
  CRYPTO_set_locking_callback(NULL);
  CRYPTO_set_id_callback(NULL);

  CRYPTO_cleanup_all_ex_data();
  ERR_free_strings();

  CONF_modules_free();
  CONF_modules_unload(1);
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
#if !(defined(OPENSSL_NO_STDIO) || defined(OPENSSL_NO_FP_API))
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L
  CRYPTO_mem_leaks_fp(stderr);
#else
  if(CRYPTO_mem_leaks_fp(stderr)!=1)
  {
    fprintf(stderr,
            "Please report a bug on https://github.com/zhaozg/lua-openssl."
            "And if can, please provide a reproduce method and minimal code.\n"
            "\n\tThank You.");
  }
#endif
#endif /* OPENSSL_NO_STDIO or OPENSSL_NO_FP_API */
#endif /* OPENSSL_NO_CRYPTO_MDEBUG */
  return 0;
}
Ejemplo n.º 5
0
static void _scallion_cleanupOpenSSL() {
	EVP_cleanup();
	ERR_remove_state(0);
	ERR_free_strings();

	#ifndef DISABLE_ENGINES
	  ENGINE_cleanup();
	#endif

	CONF_modules_unload(1);
	CRYPTO_cleanup_all_ex_data();
}
Ejemplo n.º 6
0
static apr_status_t ssl_cleanup_pre_config(void *data)
{
    /*
     * Try to kill the internals of the SSL library.
     */
#ifdef HAVE_FIPS
    FIPS_mode_set(0);
#endif
    /* Corresponds to OBJ_create()s */
    OBJ_cleanup();
    /* Corresponds to OPENSSL_load_builtin_modules() */
    CONF_modules_free();
    /* Corresponds to SSL_library_init: */
    EVP_cleanup();
#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
    ENGINE_cleanup();
#endif
#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_COMP)
    SSL_COMP_free_compression_methods();
#endif

    /* Usually needed per thread, but this parent process is single-threaded */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
    ERR_remove_thread_state(NULL);
#else
    ERR_remove_state(0);
#endif
#endif

    /* Don't call ERR_free_strings in earlier versions, ERR_load_*_strings only
     * actually loaded the error strings once per process due to static
     * variable abuse in OpenSSL. */
#if (OPENSSL_VERSION_NUMBER >= 0x00090805f)
    ERR_free_strings();
#endif

    /* Also don't call CRYPTO_cleanup_all_ex_data when linked statically here;
     * any registered ex_data indices may have been cached in static variables
     * in OpenSSL; removing them may cause havoc.  Notably, with OpenSSL
     * versions >= 0.9.8f, COMP_CTX cleanups would not be run, which
     * could result in a per-connection memory leak (!). */
    if (!modssl_running_statically) {
        CRYPTO_cleanup_all_ex_data();
    }

    /*
     * TODO: determine somewhere we can safely shove out diagnostics
     *       (when enabled) at this late stage in the game:
     * CRYPTO_mem_leaks_fp(stderr);
     */
    return APR_SUCCESS;
}
Ejemplo n.º 7
0
static void openssl_remove_thread_state(void)
{
/*  ERR_remove_thread_state() is available since OpenSSL 1.0.0-beta1, but
 *  deprecated in OpenSSL 1.1.0 */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if OPENSSL_VERSION_NUMBER >= 0x10000001L
	ERR_remove_thread_state(NULL);
#else
	ERR_remove_state(0);
#endif
#endif
}
Ejemplo n.º 8
0
/*!
 * \internal
 * \brief fopencookie()/funopen() stream close function.
 *
 * \param cookie Stream control data.
 *
 * \retval 0 on success.
 * \retval -1 on error.
 */
static int tcptls_stream_close(void *cookie)
{
	struct ast_tcptls_stream *stream = cookie;

	if (!stream) {
		errno = EBADF;
		return -1;
	}

	if (stream->fd != -1) {
#if defined(DO_SSL)
		if (stream->ssl) {
			int res;

			/*
			 * According to the TLS standard, it is acceptable for an
			 * application to only send its shutdown alert and then
			 * close the underlying connection without waiting for
			 * the peer's response (this way resources can be saved,
			 * as the process can already terminate or serve another
			 * connection).
			 */
			res = SSL_shutdown(stream->ssl);
			if (res < 0) {
				ast_log(LOG_ERROR, "SSL_shutdown() failed: %d\n",
					SSL_get_error(stream->ssl, res));
			}

			if (!stream->ssl->server) {
				/* For client threads, ensure that the error stack is cleared */
				ERR_remove_state(0);
			}

			SSL_free(stream->ssl);
			stream->ssl = NULL;
		}
#endif	/* defined(DO_SSL) */

		/*
		 * Issuing shutdown() is necessary here to avoid a race
		 * condition where the last data written may not appear
		 * in the TCP stream.  See ASTERISK-23548
		 */
		shutdown(stream->fd, SHUT_RDWR);
		if (close(stream->fd)) {
			ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
		}
		stream->fd = -1;
	}
	ao2_t_ref(stream, -1, "Closed tcptls stream cookie");

	return 0;
}
Ejemplo n.º 9
0
static void *new_thread(void *arg)
{
    int ret;
    struct new_thread_args *p = arg;

    /* Make sure we don't start until our parent has entered
     * our thread info in the thread table. */
    lock();
    /* check for initialization errors */
    if (p->failed) {
        /* Must free p before signaling our exit, otherwise there is
        * a race with gw_check_leaks at shutdown. */
        gw_free(p);
        delete_threadinfo();
        unlock();
        return NULL;
    }
    unlock();

    /* This has to be done here, because pthread_setspecific cannot
     * be called by our parent on our behalf.  That's why the ti
     * pointer is passed in the new_thread_args structure. */
    /* Synchronization is not a problem, because the only thread
     * that relies on this call having been made is this one --
     * no other thread can access our TSD anyway. */
    ret = pthread_setspecific(tsd_key, p->ti);
    if (ret != 0) {
        panic(ret, "gwthread-pthread: pthread_setspecific failed");
    }

    p->ti->pid = getpid();
    debug("gwlib.gwthread", 0, "Thread %ld (%s) maps to pid %ld.",
          p->ti->number, p->ti->name, (long) p->ti->pid);

    (p->func)(p->arg);

    lock();
    debug("gwlib.gwthread", 0, "Thread %ld (%s) terminates.",
          p->ti->number, p->ti->name);
    alert_joiners();
#ifdef HAVE_LIBSSL
    /* Clear the OpenSSL thread-specific error queue to avoid
     * memory leaks. */
    ERR_remove_state(gwthread_self());
#endif /* HAVE_LIBSSL */
    /* Must free p before signaling our exit, otherwise there is
     * a race with gw_check_leaks at shutdown. */
    gw_free(p);
    delete_threadinfo();
    unlock();

    return NULL;
}
Ejemplo n.º 10
0
int main(int argc, char *argv[])
	{
	BN_CTX *ctx=NULL;
	int ret=1;
	BIO *out;

	CRYPTO_malloc_debug_init();
	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

#ifdef OPENSSL_SYS_WIN32
	CRYPTO_malloc_init();
#endif

	RAND_seed(rnd_seed, sizeof rnd_seed);

	out=BIO_new(BIO_s_file());
	if (out == NULL) EXIT(1);
	BIO_set_fp(out,stdout,BIO_NOCLOSE);

	if ((ctx=BN_CTX_new()) == NULL) goto err;

	/* NIST PRIME CURVES TESTS */
	if (!test_ecdh_curve(NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err;
	/* NIST BINARY CURVES TESTS */
	if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) goto err;
	if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) goto err;

	ret = 0;

err:
	ERR_print_errors_fp(stderr);
	if (ctx) BN_CTX_free(ctx);
	BIO_free(out);
	CRYPTO_cleanup_all_ex_data();
	ERR_remove_state(0);
	CRYPTO_mem_leaks_fp(stderr);
	EXIT(ret);
	return(ret);
	}
Ejemplo n.º 11
0
LWS_VISIBLE void
lws_ssl_context_destroy(struct libwebsocket_context *context)
{
	if (context->ssl_ctx)
		SSL_CTX_free(context->ssl_ctx);
	if (!context->user_supplied_ssl_ctx && context->ssl_client_ctx)
		SSL_CTX_free(context->ssl_client_ctx);

	ERR_remove_state(0);
	ERR_free_strings();
	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();
}
Ejemplo n.º 12
0
void THREAD_CC server_thread(void *arg) {
	
	BIO *client = (BIO *) arg;
	// Reclaim our thread when its done?
	pthread_detach(pthread_self());
	
	fprintf(stderr, "Server Connection Opened.\n");
	do_server_loop(client);
	fprintf(stderr, "Server Connection Closed.\n");
	
	BIO_free(client);
	ERR_remove_state(0);
}
Ejemplo n.º 13
0
OsSSL::~OsSSL()
{
   // Since error queue data structures are allocated automatically for new threads,
   // they must be freed when threads are terminated in order to avoid memory leaks.
   ERR_remove_state(0);

   if (mCTX)
   {
      OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "OsSSL::~ SSL_CTX free %p", mCTX);
      SSL_CTX_free(mCTX);
      mCTX = NULL;
   }
}
Ejemplo n.º 14
0
ASocketLibrary_SSL::~ASocketLibrary_SSL()
{
  // Have to make all these calls until OpenSSL adds one function to do it all
  // This accounts for memory leaks inherent in the library on shutdown
  // Not really essential since process is exiting but allows better tracking of other
  //  leaks without getting a flood of leaks from OpenSSL on shutdown
  ERR_remove_state(0);
  ENGINE_cleanup();
  CONF_modules_unload(1);
  ERR_free_strings();
  EVP_cleanup();
  CRYPTO_cleanup_all_ex_data();
}
Ejemplo n.º 15
0
void ape_ssl_library_destroy()
{
    return;
    FIPS_mode_set(0);
    ENGINE_cleanup();
    CONF_modules_unload(1);
    CONF_modules_free();
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
    sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
    ERR_remove_state(0);
    ERR_free_strings();
}
Ejemplo n.º 16
0
void tls_engine_stop()
{
    SSL_CTX* ctx = get_tls_ctx();

    SSL_CTX_free(ctx);
    ctx = NULL;

    ERR_remove_state(0);
    ENGINE_cleanup();
    CONF_modules_unload(1);
    ERR_free_strings();
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
}
Ejemplo n.º 17
0
static void SQBIND_ffmpeg_cleanup()
{
	// SSL cleanup sequence
	ERR_remove_state( 0 );
#ifndef OPENSSL_NO_ENGINE
	ENGINE_cleanup();
#endif
	CONF_modules_unload( 1 );
	
	CRYPTO_cleanup_all_ex_data();
	ERR_free_strings();
	ERR_remove_thread_state(NULL);
	EVP_cleanup();
}
Ejemplo n.º 18
0
void free_ssl(void)
{
	/* free context */
	if(ssl_ctx != NULL) {
		SSL_CTX_free(ssl_ctx);
		ssl_ctx = NULL;
	}
	ERR_remove_state(0);
	ENGINE_cleanup();
	CONF_modules_unload(1);
	ERR_free_strings();
	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();
}
Ejemplo n.º 19
0
/*
 * Tear down the TLS subsystem. Should only be called once.
 */
static void
tlso_destroy( void )
{
	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   

	EVP_cleanup();
	ERR_remove_state(0);
	ERR_free_strings();

	if ( lo->ldo_tls_randfile ) {
		LDAP_FREE( lo->ldo_tls_randfile );
		lo->ldo_tls_randfile = NULL;
	}
}
Ejemplo n.º 20
0
static void BSslThreadExit(void *pPrivate, SYS_THREAD ThreadID, int iMode)
{
	if (iMode == SYS_THREAD_DETACH) {
		/*
		 * This needs to be called at every thread exit, in order to give
		 * a chance to OpenSSL to free its internal state. We do not need
		 * to call ERR_remove_state() if ThreadID is SYS_INVALID_THREAD,
		 * since in such case we would be called from the main thread,
		 * and BSslCleanup() (in BSslFreeOSSL()) takes care of that.
		 */
		if (ThreadID != SYS_INVALID_THREAD)
			ERR_remove_state(0);
	}
}
Ejemplo n.º 21
0
void
dst__openssl_destroy() {

	/*
	 * Sequence taken from apps_shutdown() in <apps/apps.h>.
	 */
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
	CONF_modules_unload(1);
#endif
	EVP_cleanup();
#if defined(USE_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L
	ENGINE_cleanup();
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
	CRYPTO_cleanup_all_ex_data();
#endif
	ERR_clear_error();
	ERR_free_strings();
	ERR_remove_state(0);

#ifdef  DNS_CRYPTO_LEAKS
	CRYPTO_mem_leaks_fp(stderr);
#endif

#if 0
	/*
	 * The old error sequence that leaked.  Remove for 9.4.1 if
	 * there are no issues by then.
	 */
	ERR_clear_error();
#ifdef USE_ENGINE
	if (e != NULL) {
		ENGINE_free(e);
		e = NULL;
	}
#endif
#endif
	if (rm != NULL) {
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
		RAND_cleanup();
#endif
		mem_free(rm);
	}
	if (locks != NULL) {
		CRYPTO_set_locking_callback(NULL);
		DESTROYMUTEXBLOCK(locks, nlocks);
		mem_free(locks);
	}
}
Ejemplo n.º 22
0
void* conn_handler(void *arg)
{
        long err;
        SSL *ssl;
        struct conn_ctx *ctx = (struct conn_ctx *)arg;
        struct freeq_ctx *freeqctx = ctx->srvctx->freeqctx;
        struct freeqd_state *fst = ctx->srvctx->fst;
        BIO *client = ctx->client;

        pthread_detach(pthread_self());

        ssl = freeq_ssl_new(freeqctx);
        SSL_set_bio(ssl, client, client);
        if (SSL_accept(ssl) <= 0)
        {
                int_error("Error accepting SSL connection");
                return NULL;
        }

        if ((err = post_connection_check(freeqctx, ssl, "localhost")) != X509_V_OK)
        {
                err(freeqctx, "error: peer certificate: %s\n", X509_verify_cert_error_string(err));
                int_error("Error checking SSL object after connection");
        }

        BIO  *buf_io, *ssl_bio;
        buf_io = BIO_new(BIO_f_buffer());
        ssl_bio = BIO_new(BIO_f_ssl());
        BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
        BIO_push(buf_io, ssl_bio);

        dbg(freeqctx, "ssl client connection opened\n");
        if (generation_table_merge(freeqctx, fst, buf_io))
        {
                err(freeqctx, "table merge failed\n");
                SSL_shutdown(ssl);
        }
        else
        {
                dbg(freeqctx, "table merged ok\n");
                SSL_clear(ssl);
        }

        dbg(freeqctx, "ssl client connection closed\n");
        SSL_free(ssl);

        ERR_remove_state(0);
        return 0;
}
Ejemplo n.º 23
0
Archivo: openssl.c Proyecto: Tilka/uhub
int net_ssl_library_shutdown()
{
	ERR_clear_error();
	ERR_remove_state(0);

	ENGINE_cleanup();
	CONF_modules_unload(1);

        ERR_free_strings();
	EVP_cleanup();
        CRYPTO_cleanup_all_ex_data();

	// sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
	return 1;
}
Ejemplo n.º 24
0
void* server_thread(void *arg)
{
    SSL *ssl = (SSL *)arg;

    pthread_detach(pthread_self());
    if(SSL_accept(ssl) <= 0)
        log_err("Error accepting SSL connection.");
    fprintf(stderr, "SSL Connection opened.\n");
    if(do_server(ssl))
        SSL_shutdown(ssl);
    else
        SSL_clear(ssl);
    fprintf(stderr, "SSL Connection closed.\n");
    SSL_free(ssl);
    ERR_remove_state(0);
}
Ejemplo n.º 25
0
void
Application::closeSSL()
{
	if ( sRSA )
	{
		RSA_free(sRSA);
		sRSA = NULL;
	}

	ERR_print_errors_fp(stdout);

    CRYPTO_cleanup_all_ex_data();
	EVP_cleanup();
	ERR_remove_state(0);
    CRYPTO_mem_leaks_fp(stderr);
}
Ejemplo n.º 26
0
void GT_finalize(void)
{
	if (--init_count > 0) {
		/* Do nothing: still being used by someone. */
		return;
	}
	/* In theory we should also check for init_count < 0, but
	 * in practice nothing could be done in this case... */

	threadCleanup();
	OBJ_cleanup();
	ERR_free_strings();
	ERR_remove_state(0);
	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();
}
Ejemplo n.º 27
0
LWS_VISIBLE void
lws_ssl_context_destroy(struct libwebsocket_context *context)
{
	if (context->ssl_ctx)
		SSL_CTX_free(context->ssl_ctx);
	if (!context->user_supplied_ssl_ctx && context->ssl_client_ctx)
		SSL_CTX_free(context->ssl_client_ctx);

#if (OPENSSL_VERSION_NUMBER < 0x01000000) || defined(USE_CYASSL)
	ERR_remove_state(0);
#else
	ERR_remove_thread_state(NULL);
#endif
	ERR_free_strings();
	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();
}
Ejemplo n.º 28
0
BOOL WINAPI DLLEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason,
	     LPVOID lpvReserved)
	{
	switch(fdwReason)
		{
	case DLL_PROCESS_ATTACH:
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		ERR_remove_state(0);
		break;
	case DLL_PROCESS_DETACH:
		break;
		}
	return(TRUE);
	}
Ejemplo n.º 29
0
int main(void)
{
    int 	ret = 1;
    BIO	*out;

    out = BIO_new_fp(stdout, BIO_NOCLOSE);

    /* enable memory leak checking unless explicitly disabled */
    if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) &&
            (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
    {
        CRYPTO_malloc_debug_init();
        CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
    }
    else
    {
        /* OPENSSL_DEBUG_MEMORY=off */
        CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
    }
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    ERR_load_crypto_strings();

    /* initialize the prng */
    RAND_seed(rnd_seed, sizeof(rnd_seed));

    /* the tests */
    if (!x9_62_tests(out))  goto err;
    if (!test_builtin(out)) goto err;

    ret = 0;
err:
    if (ret)
        BIO_printf(out, "\nECDSA test failed\n");
    else
        BIO_printf(out, "\nECDSA test passed\n");
    if (ret)
        ERR_print_errors(out);
    CRYPTO_cleanup_all_ex_data();
    ERR_remove_state(0);
    ERR_free_strings();
    CRYPTO_mem_leaks(out);
    if (out != NULL)
        BIO_free(out);
    return ret;
}
Ejemplo n.º 30
0
void SSLContext::cleanupOpenSSLLocked() {
  if (!initialized_) {
    return;
  }

  CRYPTO_set_id_callback(nullptr);
  CRYPTO_set_locking_callback(nullptr);
  CRYPTO_set_dynlock_create_callback(nullptr);
  CRYPTO_set_dynlock_lock_callback(nullptr);
  CRYPTO_set_dynlock_destroy_callback(nullptr);
  CRYPTO_cleanup_all_ex_data();
  ERR_free_strings();
  EVP_cleanup();
  ERR_remove_state(0);
  locks.reset();
  initialized_ = false;
}