c2ee7fd
diff --git a/src/lib/crypto/OSSLCryptoFactory.cpp b/src/lib/crypto/OSSLCryptoFactory.cpp
1e209fc
index 32daca2..ace4bcb 100644
c2ee7fd
--- a/src/lib/crypto/OSSLCryptoFactory.cpp
c2ee7fd
+++ b/src/lib/crypto/OSSLCryptoFactory.cpp
1e209fc
@@ -226,31 +226,49 @@ err:
c2ee7fd
 // Destructor
c2ee7fd
 OSSLCryptoFactory::~OSSLCryptoFactory()
c2ee7fd
 {
c2ee7fd
-#ifdef WITH_GOST
c2ee7fd
-	// Finish the GOST engine
c2ee7fd
-	if (eg != NULL)
1e209fc
+	bool ossl_shutdown = false;
1e209fc
+
1e209fc
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
1e209fc
+	// OpenSSL 1.1.0+ will register an atexit() handler to run
1e209fc
+	// OPENSSL_cleanup(). If that has already happened we must
1e209fc
+	// not attempt to free any ENGINEs because they'll already
1e209fc
+	// have been destroyed and the use-after-free would cause
1e209fc
+	// a deadlock or crash.
1e209fc
+	//
1e209fc
+	// Detect that situation because reinitialisation will fail
1e209fc
+	// after OPENSSL_cleanup() has run.
1e209fc
+	(void)ERR_set_mark();
1e209fc
+	ossl_shutdown = !OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_RDRAND, NULL);
1e209fc
+	(void)ERR_pop_to_mark();
1e209fc
+#endif
c2ee7fd
+	if (!ossl_shutdown)
c2ee7fd
 	{
c2ee7fd
-		ENGINE_finish(eg);
c2ee7fd
-		ENGINE_free(eg);
c2ee7fd
-		eg = NULL;
c2ee7fd
-	}
c2ee7fd
+#ifdef WITH_GOST
c2ee7fd
+		// Finish the GOST engine
c2ee7fd
+		if (eg != NULL)
c2ee7fd
+		{
c2ee7fd
+			ENGINE_finish(eg);
c2ee7fd
+			ENGINE_free(eg);
c2ee7fd
+			eg = NULL;
c2ee7fd
+		}
c2ee7fd
 #endif
c2ee7fd
 
c2ee7fd
-	// Finish the rd_rand engine
c2ee7fd
-	ENGINE_finish(rdrand_engine);
c2ee7fd
-	ENGINE_free(rdrand_engine);
c2ee7fd
-	rdrand_engine = NULL;
c2ee7fd
+		// Finish the rd_rand engine
c2ee7fd
+		ENGINE_finish(rdrand_engine);
c2ee7fd
+		ENGINE_free(rdrand_engine);
c2ee7fd
+		rdrand_engine = NULL;
c2ee7fd
 
c2ee7fd
+		// Recycle locks
c2ee7fd
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
c2ee7fd
+		if (setLockingCallback)
c2ee7fd
+		{
c2ee7fd
+			CRYPTO_set_locking_callback(NULL);
c2ee7fd
+		}
c2ee7fd
+#endif
c2ee7fd
+	}
c2ee7fd
 	// Destroy the one-and-only RNG
c2ee7fd
 	delete rng;
c2ee7fd
 
c2ee7fd
-	// Recycle locks
c2ee7fd
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
c2ee7fd
-	if (setLockingCallback)
c2ee7fd
-	{
c2ee7fd
-		CRYPTO_set_locking_callback(NULL);
c2ee7fd
-	}
c2ee7fd
-#endif
c2ee7fd
 	for (unsigned i = 0; i < nlocks; i++)
c2ee7fd
 	{
c2ee7fd
 		MutexFactory::i()->recycleMutex(locks[i]);