diff --git a/configure b/configure index caf6f260ee..5fc8c442a2 100755 --- a/configure +++ b/configure @@ -9711,6 +9711,37 @@ if test "x$ac_cv_func_SSL_get_current_compression" = xyes; then : #define HAVE_SSL_GET_CURRENT_COMPRESSION 1 _ACEOF +fi +done + + # Functions introduced in OpenSSL 1.1.0. We used to check for + # OPENSSL_VERSION_NUMBER, but that didn't work with 1.1.0, because LibreSSL + # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it + # doesn't have these OpenSSL 1.1.0 functions. So check for individual + # functions. + for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + # OpenSSL versions before 1.1.0 required setting callback functions, for + # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock() + # function was removed. + for ac_func in CRYPTO_lock +do : + ac_fn_c_check_func "$LINENO" "CRYPTO_lock" "ac_cv_func_CRYPTO_lock" +if test "x$ac_cv_func_CRYPTO_lock" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CRYPTO_LOCK 1 +_ACEOF + fi done diff --git a/configure.in b/configure.in index c42680607a..96d865de9f 100644 --- a/configure.in +++ b/configure.in @@ -1118,6 +1118,16 @@ if test "$with_openssl" = yes ; then AC_SEARCH_LIBS(SSL_new, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])]) fi AC_CHECK_FUNCS([SSL_get_current_compression]) + # Functions introduced in OpenSSL 1.1.0. We used to check for + # OPENSSL_VERSION_NUMBER, but that didn't work with 1.1.0, because LibreSSL + # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it + # doesn't have these OpenSSL 1.1.0 functions. So check for individual + # functions. + AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL]) + # OpenSSL versions before 1.1.0 required setting callback functions, for + # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock() + # function was removed. + AC_CHECK_FUNCS([CRYPTO_lock]) fi if test "$with_pam" = yes ; then diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index e264aa49df..851cb616cb 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -914,10 +914,6 @@ px_find_cipher(const char *name, PX_Cipher **res) static int openssl_random_init = 0; -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#define RAND_OpenSSL RAND_SSLeay -#endif - /* * OpenSSL random should re-feeded occasionally. From /dev/urandom * preferably. @@ -926,7 +922,13 @@ static void init_openssl_rand(void) { if (RAND_get_rand_method() == NULL) + { +#ifdef HAVE_RAND_OPENSSL RAND_set_rand_method(RAND_OpenSSL()); +#else + RAND_set_rand_method(RAND_SSLeay()); +#endif + } openssl_random_init = 1; } diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 2afd738945..fedb02cd82 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -165,7 +165,7 @@ be_tls_init(void) if (!SSL_context) { -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#ifdef HAVE_OPENSSL_INIT_SSL OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); #else OPENSSL_config(NULL); @@ -672,7 +672,7 @@ be_tls_write(Port *port, void *ptr, size_t len, int *waitfor) * to retry; do we need to adopt their logic for that? */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#ifndef HAVE_BIO_GET_DATA #define BIO_get_data(bio) (bio->ptr) #define BIO_set_data(bio, data) (bio->ptr = data) #endif @@ -726,7 +726,7 @@ my_BIO_s_socket(void) if (!my_bio_methods) { BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket(); -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#ifdef HAVE_BIO_METH_NEW int my_bio_index; my_bio_index = BIO_get_new_index(); diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index b621ff2af5..7dbfa90bf4 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -84,12 +84,21 @@ /* Define to 1 if you have the `append_history' function. */ #undef HAVE_APPEND_HISTORY +/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */ +#undef HAVE_ASN1_STRING_GET0_DATA + /* Define to 1 if you want to use atomics if available. */ #undef HAVE_ATOMICS /* Define to 1 if you have the header file. */ #undef HAVE_ATOMIC_H +/* Define to 1 if you have the `BIO_get_data' function. */ +#undef HAVE_BIO_GET_DATA + +/* Define to 1 if you have the `BIO_meth_new' function. */ +#undef HAVE_BIO_METH_NEW + /* Define to 1 if you have the `cbrt' function. */ #undef HAVE_CBRT @@ -102,6 +111,9 @@ /* Define to 1 if you have the `crypt' function. */ #undef HAVE_CRYPT +/* Define to 1 if you have the `CRYPTO_lock' function. */ +#undef HAVE_CRYPTO_LOCK + /* Define to 1 if you have the header file. */ #undef HAVE_CRYPT_H @@ -364,6 +376,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H +/* Define to 1 if you have the `OPENSSL_init_ssl' function. */ +#undef HAVE_OPENSSL_INIT_SSL + /* Define to 1 if you have the header file. */ #undef HAVE_OSSP_UUID_H @@ -403,6 +418,9 @@ /* Define to 1 if you have the `random' function. */ #undef HAVE_RANDOM +/* Define to 1 if you have the `RAND_OpenSSL' function. */ +#undef HAVE_RAND_OPENSSL + /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_H diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index fe81825144..2dcdce7265 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -506,10 +506,6 @@ wildcard_certificate_match(const char *pattern, const char *string) return 1; } -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#define ASN1_STRING_get0_data ASN1_STRING_data -#endif - /* * Check if a name from a server's certificate matches the peer's hostname. * @@ -544,7 +540,11 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry, * There is no guarantee the string returned from the certificate is * NULL-terminated, so make a copy that is. */ +#ifdef HAVE_ASN1_STRING_GET0_DATA namedata = ASN1_STRING_get0_data(name_entry); +#else + namedata = ASN1_STRING_data(name_entry); +#endif len = ASN1_STRING_length(name_entry); name = malloc(len + 1); if (name == NULL) @@ -732,10 +732,13 @@ verify_peer_name_matches_certificate(PGconn *conn) return found_match && !got_error; } -#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L +#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK) /* - * Callback functions for OpenSSL internal locking. (OpenSSL 1.1.0 - * does its own locking, and doesn't need these anymore.) + * Callback functions for OpenSSL internal locking. (OpenSSL 1.1.0 + * does its own locking, and doesn't need these anymore. The + * CRYPTO_lock() function was removed in 1.1.0, when the callbacks + * were made obsolete, so we assume that if CRYPTO_lock() exists, + * the callbacks are still required.) */ static unsigned long @@ -765,7 +768,7 @@ pq_lockingcallback(int mode, int n, const char *file, int line) PGTHREAD_ERROR("failed to unlock mutex"); } } -#endif /* ENABLE_THREAD_SAFETY && OPENSSL_VERSION_NUMBER < 0x10100000L */ +#endif /* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */ /* * Initialize SSL system, in particular creating the SSL_context object @@ -804,7 +807,7 @@ pgtls_init(PGconn *conn) if (pthread_mutex_lock(&ssl_config_mutex)) return -1; -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#ifdef HAVE_CRYPTO_LOCK if (pq_init_crypto_lib) { /* @@ -845,14 +848,14 @@ pgtls_init(PGconn *conn) CRYPTO_set_locking_callback(pq_lockingcallback); } } -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ +#endif /* HAVE_CRYPTO_LOCK */ #endif /* ENABLE_THREAD_SAFETY */ if (!SSL_context) { if (pq_init_ssl_lib) { -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#ifdef HAVE_OPENSSL_INIT_SSL OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); #else OPENSSL_config(NULL); @@ -913,7 +916,7 @@ pgtls_init(PGconn *conn) static void destroy_ssl_system(void) { -#if defined(ENABLE_THREAD_SAFETY) && OPENSSL_VERSION_NUMBER < 0x10100000L +#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK) /* Mutex is created in initialize_ssl_system() */ if (pthread_mutex_lock(&ssl_config_mutex)) return; @@ -1628,7 +1631,7 @@ PQsslAttribute(PGconn *conn, const char *attribute_name) * to retry; do we need to adopt their logic for that? */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#ifndef HAVE_BIO_GET_DATA #define BIO_get_data(bio) (bio->ptr) #define BIO_set_data(bio, data) (bio->ptr = data) #endif @@ -1701,7 +1704,7 @@ my_BIO_s_socket(void) if (!my_bio_methods) { BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket(); -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#ifdef HAVE_BIO_METH_NEW int my_bio_index; my_bio_index = BIO_get_new_index();