| This patch has been tested with OpenSSL 1.0.2q, 1.1.0j and 1.1.1a |
| with and without support for deprecated OpenSSL APIs. |
| |
| --- a/configure.ac |
| +++ b/configure.ac |
| @@ -860,26 +860,10 @@ then |
| AC_SEARCH_LIBS([ERR_peek_error], [crypto], , |
| AC_MSG_ERROR([libcrypto not found])) |
| |
| - AC_SEARCH_LIBS([SSL_library_init], [ssl], , |
| - [ |
| - if test x"$enable_shared" = x"yes" |
| - then |
| - AC_MSG_ERROR([Cannot build shared opendkim |
| - against static openssl libraries. |
| - Configure with --disable-shared |
| - to get this working or obtain a |
| - shared libssl library for |
| - opendkim to use.]) |
| - fi |
| - |
| - # avoid caching issue - last result of SSL_library_init |
| - # shouldn't be cached for this next check |
| - unset ac_cv_search_SSL_library_init |
| - LIBCRYPTO_LIBS="$LIBCRYPTO_LIBS -ldl" |
| - AC_SEARCH_LIBS([SSL_library_init], [ssl], , |
| - AC_MSG_ERROR([libssl not found]), [-ldl]) |
| - ] |
| - ) |
| + od_have_ossl="no" |
| + AC_CHECK_LIB(ssl, OPENSSL_init_ssl, [od_have_ossl="yes"]) |
| + AC_CHECK_LIB(ssl, SSL_library_init, [od_have_ossl="yes"]) |
| + AS_IF([test "x$od_have_ossl" = xno], [AC_MSG_ERROR([libssl not found])]) |
| |
| AC_CHECK_DECL([SHA256_DIGEST_LENGTH], |
| AC_DEFINE([HAVE_SHA256], 1, |
| --- a/opendkim/opendkim-crypto.c |
| +++ b/opendkim/opendkim-crypto.c |
| @@ -139,6 +139,7 @@ static unsigned int nmutexes = 0; |
| static unsigned long threadid = 0L; |
| static pthread_mutex_t *mutexes = NULL; |
| |
| +#if OPENSSL_VERSION_NUMBER < 0x10100000 |
| /* |
| ** DKIMF_CRYPTO_LOCK_CALLBACK -- locking callback for libcrypto |
| ** |
| @@ -166,6 +167,7 @@ dkimf_crypto_lock_callback(int mode, int |
| |
| assert(status == 0); |
| } |
| +#endif |
| |
| /* |
| ** DKIMF_CRYPTO_GET_ID -- generate/retrieve thread ID |
| @@ -208,21 +210,15 @@ dkimf_crypto_get_id(void) |
| static void |
| dkimf_crypto_free_id(void *ptr) |
| { |
| - /* |
| - ** Trick dkimf_crypto_get_id(); the thread-specific pointer has |
| - ** already been cleared at this point, but dkimf_crypto_get_id() |
| - ** may be called by ERR_remove_state() which will then allocate a |
| - ** new thread pointer if the thread-specific pointer is NULL. This |
| - ** means a memory leak of thread IDs and, on Solaris, an infinite loop |
| - ** because the destructor (indirectly) re-sets the thread-specific |
| - ** pointer to something not NULL. See pthread_key_create(3). |
| - */ |
| - |
| if (ptr != NULL) |
| { |
| assert(pthread_setspecific(id_key, ptr) == 0); |
| |
| - ERR_remove_state(0); |
| +#if OPENSSL_VERSION_NUMBER >= 0x10100000 |
| + OPENSSL_thread_stop(); |
| +#else |
| + ERR_remove_thread_state(NULL); |
| +#endif |
| |
| free(ptr); |
| |
| @@ -300,6 +296,7 @@ dkimf_crypto_dyn_destroy(struct CRYPTO_d |
| ** None. |
| */ |
| |
| +#if OPENSSL_VERSION_NUMBER < 0x10100000 |
| static void |
| dkimf_crypto_dyn_lock(int mode, struct CRYPTO_dynlock_value *lock, |
| /* UNUSED */ const char *file, |
| @@ -316,6 +313,7 @@ dkimf_crypto_dyn_lock(int mode, struct C |
| |
| assert(status == 0); |
| } |
| +#endif |
| |
| /* |
| ** DKIMF_CRYPTO_INIT -- set up openssl dependencies |
| @@ -335,7 +333,12 @@ dkimf_crypto_init(void) |
| int n; |
| int status; |
| |
| +#if OPENSSL_VERSION_NUMBER < 0x10100000 |
| n = CRYPTO_num_locks(); |
| +#else |
| + // see openssl/crypto.h for more details |
| + n = 1; |
| +#endif |
| mutexes = (pthread_mutex_t *) malloc(n * sizeof(pthread_mutex_t)); |
| if (mutexes == NULL) |
| return errno; |
| @@ -357,15 +360,22 @@ dkimf_crypto_init(void) |
| if (status != 0) |
| return status; |
| |
| +#if OPENSSL_VERSION_NUMBER < 0x10100000 |
| SSL_load_error_strings(); |
| SSL_library_init(); |
| ERR_load_crypto_strings(); |
| +#else |
| + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); |
| + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); |
| +#endif |
| |
| +#if OPENSSL_VERSION_NUMBER < 0x10000000 |
| CRYPTO_set_id_callback(&dkimf_crypto_get_id); |
| CRYPTO_set_locking_callback(&dkimf_crypto_lock_callback); |
| CRYPTO_set_dynlock_create_callback(&dkimf_crypto_dyn_create); |
| CRYPTO_set_dynlock_lock_callback(&dkimf_crypto_dyn_lock); |
| CRYPTO_set_dynlock_destroy_callback(&dkimf_crypto_dyn_destroy); |
| +#endif |
| |
| #ifdef USE_OPENSSL_ENGINE |
| if (!SSL_set_engine(NULL)) |
| @@ -392,11 +402,15 @@ dkimf_crypto_free(void) |
| { |
| if (crypto_init_done) |
| { |
| +#if OPENSSL_VERSION_NUMBER >= 0x10100000 |
| + OPENSSL_thread_stop(); |
| +#else |
| CRYPTO_cleanup_all_ex_data(); |
| CONF_modules_free(); |
| EVP_cleanup(); |
| ERR_free_strings(); |
| - ERR_remove_state(0); |
| + ERR_remove_thread_state(NULL); |
| +#endif |
| |
| if (nmutexes > 0) |
| { |
| --- a/libopendkim/dkim.c |
| +++ b/libopendkim/dkim.c |
| @@ -4195,8 +4195,10 @@ dkim_init_openssl(void) |
| { |
| pthread_mutex_lock(&openssl_lock); |
| |
| +#if OPENSSL_VERSION_NUMBER < 0x10100000 |
| if (openssl_refcount == 0) |
| OpenSSL_add_all_algorithms(); |
| +#endif |
| openssl_refcount++; |
| |
| pthread_mutex_unlock(&openssl_lock); |
| @@ -4220,8 +4222,10 @@ dkim_close_openssl(void) |
| pthread_mutex_lock(&openssl_lock); |
| |
| openssl_refcount--; |
| +#if OPENSSL_VERSION_NUMBER < 0x10100000 |
| if (openssl_refcount == 0) |
| EVP_cleanup(); |
| +#endif |
| |
| pthread_mutex_unlock(&openssl_lock); |
| } |
| --- a/opendkim/opendkim-testkey.c |
| +++ b/opendkim/opendkim-testkey.c |
| @@ -452,7 +452,11 @@ main(int argc, char **argv) |
| memset(err, '\0', sizeof err); |
| |
| #ifndef USE_GNUTLS |
| +#if OPENSSL_VERSION_NUMBER < 0x10100000 |
| ERR_load_crypto_strings(); |
| +#else |
| + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); |
| +#endif |
| #endif /* ! USE_GNUTLS */ |
| |
| /* process a KeyTable if specified and not overridden */ |
| --- a/opendkim/opendkim.c |
| +++ b/opendkim/opendkim.c |
| @@ -15540,7 +15540,11 @@ main(int argc, char **argv) |
| printf("\tCompiled with GnuTLS %s\n", GNUTLS_VERSION); |
| #else /* USE_GNUTLS */ |
| printf("\tCompiled with %s\n", |
| +#if OPENSSL_VERSION_NUMBER < 0x10100000 |
| SSLeay_version(SSLEAY_VERSION)); |
| +#else |
| + OpenSSL_version(OPENSSL_VERSION)); |
| +#endif |
| #endif /* USE_GNUTLS */ |
| printf("\tSMFI_VERSION 0x%x\n", SMFI_VERSION); |
| #ifdef HAVE_SMFI_VERSION |