Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bJ8Q9-0002jt-OH for pgsql-hackers@arkaria.postgresql.org; Sat, 02 Jul 2016 00:04:29 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1bJ8Q8-0007op-Rz for pgsql-hackers@arkaria.postgresql.org; Sat, 02 Jul 2016 00:04:28 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1bJ8Oe-0006C4-6z for pgsql-hackers@postgresql.org; Sat, 02 Jul 2016 00:02:56 +0000 Received: from kilimanjaro.scorpionshops.com ([82.118.24.83]) by magus.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bJ8OY-0000Ta-Ai for pgsql-hackers@postgresql.org; Sat, 02 Jul 2016 00:02:54 +0000 Received: from [192.168.1.4] (92-32-205-114.tn.glocalnet.net [92.32.205.114]) by kilimanjaro.scorpionshops.com (Postfix) with ESMTPSA id EF3EB7BC08D; Sat, 2 Jul 2016 02:02:48 +0200 (CEST) Subject: Re: OpenSSL 1.1 breaks configure and more To: Christoph Berg , Tom Lane , PostgreSQL Hackers References: <20160627151604.GD1051@msg.df7cb.de> <1805.1467041061@sss.pgh.pa.us> <8a0a5959-0b83-3dc8-d9e7-66ce8c1c5bc7@proxel.se> <688a438c-ccc2-0431-7100-26e418fc3bca@proxel.se> <20160701094159.GA17882@msg.df7cb.de> From: Andreas Karlsson Message-ID: Date: Sat, 2 Jul 2016 02:02:48 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.1.0 MIME-Version: 1.0 In-Reply-To: <20160701094159.GA17882@msg.df7cb.de> Content-Type: multipart/mixed; boundary="------------4DB1F28AF6A9296C8B774BA1" X-Pg-Spam-Score: -1.9 (-) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org This is a multi-part message in MIME format. --------------4DB1F28AF6A9296C8B774BA1 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit On 07/01/2016 11:41 AM, Christoph Berg wrote: > thanks for the patches. I applied all there patches on top of HEAD > (10c0558f). The server builds and passes "make check", pgcrypto still > needs work, though: Thanks, I had forgotten pgcrypto. When fixing pgcrypto I noticed that the OpenSSL team has deprecated RAND_pseudo_bytes() and recommend using RAND_bytes() instead (see 302d38e3f73d5fd2ba2fd30bb7798778cb9f18dd). As far as I can tell the only difference is that RAND_bytes() adds an error to the error queue if there is not enough entropy for generating secure data. And since we already always use strong random with the Fortuna algorithm, why not just drop px_get_pseudo_random_bytes()? It feels like a potential security problem with to me unclear benefit. I also found that client CA loading is broken in OpenSSL 1.1-pre5 (reported as https://github.com/openssl/openssl/pull/1279). This might be good to be aware of when testing my patches. Attached a new set of patches: 0001-Fixes-for-compiling-with-OpenSSL-1.1-v2.patch The fixes necessary to build with OpenSSL 1.1. Mostly fixes surrounding direct access to struct fields. 0002-Remove-OpenSSL-1.1-deprecation-warnings-v2.patch Fix deprecation warnings. Mostly trusting OpenSSL 1.1 to handle threading and initialization automatically. 0003-Remove-px_get_pseudo_random_bytes-v2.patch Remove the px_get_pseudo_random_bytes() from pgcrypto. Also silcences deprecation warning about RAND_pseudo_bytes(). 0004-Define-CRYPTO_LOCK-for-OpenSSL-1.1-compat-v2.patch Useful if you want to play around with 0001-Fixes-for-compiling-with-OpenSSL-1.1-v2.patch before they release a new version where CRYPTO_LOCK is added back. See https://github.com/openssl/openssl/issues/1260 Andreas --------------4DB1F28AF6A9296C8B774BA1 Content-Type: text/x-patch; name="0001-Fixes-for-compiling-with-OpenSSL-1.1-v2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Fixes-for-compiling-with-OpenSSL-1.1-v2.patch" From 59cb028a38c18cb2f8fff077d355a8a26ecce641 Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Tue, 28 Jun 2016 05:55:03 +0200 Subject: [PATCH 1/4] Fixes for compiling with OpenSSL 1.1 - Check for SSL_new now that SSL_library_init is a macro - Do not access struct members directly - RAND_SSLeay was renamed to RAND_OpenSSL() --- configure | 44 ++++++++++++++++---------------- configure.in | 4 +-- contrib/pgcrypto/openssl.c | 28 ++++++++++++-------- contrib/sslinfo/sslinfo.c | 14 ++-------- src/backend/libpq/be-secure-openssl.c | 39 +++++++++++++++++++--------- src/interfaces/libpq/fe-secure-openssl.c | 39 +++++++++++++++++++--------- 6 files changed, 98 insertions(+), 70 deletions(-) diff --git a/configure b/configure index 1f42c8a..ca83738 100755 --- a/configure +++ b/configure @@ -9538,9 +9538,9 @@ else as_fn_error $? "library 'crypto' is required for OpenSSL" "$LINENO" 5 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_library_init in -lssl" >&5 -$as_echo_n "checking for SSL_library_init in -lssl... " >&6; } -if ${ac_cv_lib_ssl_SSL_library_init+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_new in -lssl" >&5 +$as_echo_n "checking for SSL_new in -lssl... " >&6; } +if ${ac_cv_lib_ssl_SSL_new+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -9554,27 +9554,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char SSL_library_init (); +char SSL_new (); int main () { -return SSL_library_init (); +return SSL_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ssl_SSL_library_init=yes + ac_cv_lib_ssl_SSL_new=yes else - ac_cv_lib_ssl_SSL_library_init=no + ac_cv_lib_ssl_SSL_new=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_library_init" >&5 -$as_echo "$ac_cv_lib_ssl_SSL_library_init" >&6; } -if test "x$ac_cv_lib_ssl_SSL_library_init" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_new" >&5 +$as_echo "$ac_cv_lib_ssl_SSL_new" >&6; } +if test "x$ac_cv_lib_ssl_SSL_new" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSSL 1 _ACEOF @@ -9644,9 +9644,9 @@ else as_fn_error $? "library 'eay32' or 'crypto' is required for OpenSSL" "$LINENO" 5 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_library_init" >&5 -$as_echo_n "checking for library containing SSL_library_init... " >&6; } -if ${ac_cv_search_SSL_library_init+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_new" >&5 +$as_echo_n "checking for library containing SSL_new... " >&6; } +if ${ac_cv_search_SSL_new+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -9659,11 +9659,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char SSL_library_init (); +char SSL_new (); int main () { -return SSL_library_init (); +return SSL_new (); ; return 0; } @@ -9676,25 +9676,25 @@ for ac_lib in '' ssleay32 ssl; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_SSL_library_init=$ac_res + ac_cv_search_SSL_new=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if ${ac_cv_search_SSL_library_init+:} false; then : + if ${ac_cv_search_SSL_new+:} false; then : break fi done -if ${ac_cv_search_SSL_library_init+:} false; then : +if ${ac_cv_search_SSL_new+:} false; then : else - ac_cv_search_SSL_library_init=no + ac_cv_search_SSL_new=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSL_library_init" >&5 -$as_echo "$ac_cv_search_SSL_library_init" >&6; } -ac_res=$ac_cv_search_SSL_library_init +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSL_new" >&5 +$as_echo "$ac_cv_search_SSL_new" >&6; } +ac_res=$ac_cv_search_SSL_new if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" diff --git a/configure.in b/configure.in index c07904e..34bc5ab 100644 --- a/configure.in +++ b/configure.in @@ -1112,10 +1112,10 @@ if test "$with_openssl" = yes ; then dnl Order matters! if test "$PORTNAME" != "win32"; then AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])]) - AC_CHECK_LIB(ssl, SSL_library_init, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])]) + AC_CHECK_LIB(ssl, SSL_new, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])]) else AC_SEARCH_LIBS(CRYPTO_new_ex_data, eay32 crypto, [], [AC_MSG_ERROR([library 'eay32' or 'crypto' is required for OpenSSL])]) - AC_SEARCH_LIBS(SSL_library_init, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])]) + 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]) fi diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index 976af70..a1db35d 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -196,13 +196,20 @@ compat_find_digest(const char *name, PX_MD **res) #endif /* + * RAND_SSLeay() changed name to RAND_OpenSSL() in 1.1 + */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define RAND_OpenSSL() RAND_SSLeay() +#endif + +/* * Hashes */ typedef struct OSSLDigest { const EVP_MD *algo; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; } OSSLDigest; static unsigned @@ -210,7 +217,7 @@ digest_result_size(PX_MD *h) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; - return EVP_MD_CTX_size(&digest->ctx); + return EVP_MD_CTX_size(digest->ctx); } static unsigned @@ -218,7 +225,7 @@ digest_block_size(PX_MD *h) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; - return EVP_MD_CTX_block_size(&digest->ctx); + return EVP_MD_CTX_block_size(digest->ctx); } static void @@ -226,7 +233,7 @@ digest_reset(PX_MD *h) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; - EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL); + EVP_DigestInit_ex(digest->ctx, digest->algo, NULL); } static void @@ -234,7 +241,7 @@ digest_update(PX_MD *h, const uint8 *data, unsigned dlen) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; - EVP_DigestUpdate(&digest->ctx, data, dlen); + EVP_DigestUpdate(digest->ctx, data, dlen); } static void @@ -242,7 +249,7 @@ digest_finish(PX_MD *h, uint8 *dst) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; - EVP_DigestFinal_ex(&digest->ctx, dst, NULL); + EVP_DigestFinal_ex(digest->ctx, dst, NULL); } static void @@ -250,7 +257,7 @@ digest_free(PX_MD *h) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; - EVP_MD_CTX_cleanup(&digest->ctx); + EVP_MD_CTX_destroy(digest->ctx); px_free(digest); px_free(h); @@ -280,8 +287,9 @@ px_find_digest(const char *name, PX_MD **res) digest = px_alloc(sizeof(*digest)); digest->algo = md; - EVP_MD_CTX_init(&digest->ctx); - if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0) + digest->ctx = EVP_MD_CTX_create(); + EVP_MD_CTX_init(digest->ctx); + if (EVP_DigestInit_ex(digest->ctx, digest->algo, NULL) == 0) return -1; h = px_alloc(sizeof(*h)); @@ -987,7 +995,7 @@ static void init_openssl_rand(void) { if (RAND_get_rand_method() == NULL) - RAND_set_rand_method(RAND_SSLeay()); + RAND_set_rand_method(RAND_OpenSSL()); openssl_random_init = 1; } diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c index 82a4c1b..a4b0f9b 100644 --- a/contrib/sslinfo/sslinfo.c +++ b/contrib/sslinfo/sslinfo.c @@ -402,8 +402,6 @@ ssl_extension_info(PG_FUNCTION_ARGS) MemoryContext oldcontext; SSLExtensionInfoContext *fctx; - STACK_OF(X509_EXTENSION) *ext_stack = NULL; - if (SRF_IS_FIRSTCALL()) { @@ -427,16 +425,10 @@ ssl_extension_info(PG_FUNCTION_ARGS) errmsg("function returning record called in context that cannot accept type record"))); fctx->tupdesc = BlessTupleDesc(tupdesc); - /* Get all extensions of certificate */ - if (cert && cert->cert_info) - ext_stack = cert->cert_info->extensions; - /* Set max_calls as a count of extensions in certificate */ max_calls = cert != NULL ? X509_get_ext_count(cert) : 0; - if (cert != NULL && - ext_stack != NULL && - max_calls > 0) + if (max_calls > 0) { /* got results, keep track of them */ funcctx->max_calls = max_calls; @@ -462,8 +454,6 @@ ssl_extension_info(PG_FUNCTION_ARGS) max_calls = funcctx->max_calls; fctx = funcctx->user_fctx; - ext_stack = cert->cert_info->extensions; - /* do while there are more left to send */ if (call_cntr < max_calls) { @@ -486,7 +476,7 @@ ssl_extension_info(PG_FUNCTION_ARGS) errmsg("could not create OpenSSL BIO structure"))); /* Get the extension from the certificate */ - ext = sk_X509_EXTENSION_value(ext_stack, call_cntr); + ext = X509_get_ext(cert, call_cntr); obj = X509_EXTENSION_get_object(ext); /* Get the extension name */ diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index f6adb15..2fa2793 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -673,8 +673,12 @@ be_tls_write(Port *port, void *ptr, size_t len, int *waitfor) * to retry; do we need to adopt their logic for that? */ -static bool my_bio_initialized = false; -static BIO_METHOD my_bio_methods; +#if SSLEAY_VERSION_NUMBER < 0x10100000L +#define BIO_get_data(bio) (bio->ptr) +#define BIO_set_data(bio, data) (bio->ptr = data) +#endif + +static BIO_METHOD *my_bio_methods = NULL; static int my_sock_read(BIO *h, char *buf, int size) @@ -683,7 +687,7 @@ my_sock_read(BIO *h, char *buf, int size) if (buf != NULL) { - res = secure_raw_read(((Port *) h->ptr), buf, size); + res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size); BIO_clear_retry_flags(h); if (res <= 0) { @@ -703,7 +707,7 @@ my_sock_write(BIO *h, const char *buf, int size) { int res = 0; - res = secure_raw_write(((Port *) h->ptr), buf, size); + res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size); BIO_clear_retry_flags(h); if (res <= 0) { @@ -720,14 +724,26 @@ my_sock_write(BIO *h, const char *buf, int size) static BIO_METHOD * my_BIO_s_socket(void) { - if (!my_bio_initialized) + if (!my_bio_methods) { - memcpy(&my_bio_methods, BIO_s_socket(), sizeof(BIO_METHOD)); - my_bio_methods.bread = my_sock_read; - my_bio_methods.bwrite = my_sock_write; - my_bio_initialized = true; + BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket(); +#if SSLEAY_VERSION_NUMBER >= 0x10100000L + my_bio_methods = BIO_meth_new(BIO_TYPE_SOCKET, "pgsocket"); + BIO_meth_set_write(my_bio_methods, my_sock_write); + BIO_meth_set_read(my_bio_methods, my_sock_read); + BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)); + BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)); + BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)); + BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)); + BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)); +#else + my_bio_methods = malloc(sizeof(BIO_METHOD)); + memcpy(my_bio_methods, biom, sizeof(BIO_METHOD)); + my_bio_methods->bread = my_sock_read; + my_bio_methods->bwrite = my_sock_write; +#endif } - return &my_bio_methods; + return my_bio_methods; } /* This should exactly match openssl's SSL_set_fd except for using my BIO */ @@ -744,8 +760,7 @@ my_SSL_set_fd(Port *port, int fd) SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); goto err; } - /* Use 'ptr' to store pointer to PGconn */ - bio->ptr = port; + BIO_set_data(bio, port); BIO_set_fd(bio, fd, BIO_NOCLOSE); SSL_set_bio(port->ssl, bio, bio); diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index f6ce1c7..520dcd7 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -1621,15 +1621,19 @@ PQsslAttribute(PGconn *conn, const char *attribute_name) * to retry; do we need to adopt their logic for that? */ -static bool my_bio_initialized = false; -static BIO_METHOD my_bio_methods; +#if SSLEAY_VERSION_NUMBER < 0x10100000L +#define BIO_get_data(bio) (bio->ptr) +#define BIO_set_data(bio, data) (bio->ptr = data) +#endif + +static BIO_METHOD *my_bio_methods; static int my_sock_read(BIO *h, char *buf, int size) { int res; - res = pqsecure_raw_read((PGconn *) h->ptr, buf, size); + res = pqsecure_raw_read((PGconn *) BIO_get_data(h), buf, size); BIO_clear_retry_flags(h); if (res < 0) { @@ -1659,7 +1663,7 @@ my_sock_write(BIO *h, const char *buf, int size) { int res; - res = pqsecure_raw_write((PGconn *) h->ptr, buf, size); + res = pqsecure_raw_write((PGconn *) BIO_get_data(h), buf, size); BIO_clear_retry_flags(h); if (res <= 0) { @@ -1687,14 +1691,26 @@ my_sock_write(BIO *h, const char *buf, int size) static BIO_METHOD * my_BIO_s_socket(void) { - if (!my_bio_initialized) + if (!my_bio_methods) { - memcpy(&my_bio_methods, BIO_s_socket(), sizeof(BIO_METHOD)); - my_bio_methods.bread = my_sock_read; - my_bio_methods.bwrite = my_sock_write; - my_bio_initialized = true; + BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket(); +#if SSLEAY_VERSION_NUMBER >= 0x10100000L + my_bio_methods = BIO_meth_new(BIO_TYPE_SOCKET, "pgsocket"); + BIO_meth_set_write(my_bio_methods, my_sock_write); + BIO_meth_set_read(my_bio_methods, my_sock_read); + BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)); + BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)); + BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)); + BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)); + BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)); +#else + my_bio_methods = malloc(sizeof(BIO_METHOD)); + memcpy(my_bio_methods, biom, sizeof(BIO_METHOD)); + my_bio_methods->bread = my_sock_read; + my_bio_methods->bwrite = my_sock_write; +#endif } - return &my_bio_methods; + return my_bio_methods; } /* This should exactly match openssl's SSL_set_fd except for using my BIO */ @@ -1710,8 +1726,7 @@ my_SSL_set_fd(PGconn *conn, int fd) SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); goto err; } - /* Use 'ptr' to store pointer to PGconn */ - bio->ptr = conn; + BIO_set_data(bio, conn); SSL_set_bio(conn->ssl, bio, bio); BIO_set_fd(bio, fd, BIO_NOCLOSE); -- 2.8.1 --------------4DB1F28AF6A9296C8B774BA1 Content-Type: text/x-patch; name="0002-Remove-OpenSSL-1.1-deprecation-warnings-v2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0002-Remove-OpenSSL-1.1-deprecation-warnings-v2.patch" From 9d4e6c634bfb82ed07fb5b99ee4c838b9d2573a9 Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Tue, 28 Jun 2016 07:51:49 +0200 Subject: [PATCH 2/4] Remove OpenSSL 1.1 deprecation warnings - Fix deprecation warning about DH_generate_parameters - Fix warnigns resulting from the automatic initialization - Fix warnigns resulting from the new thread support in OpenSSL --- src/backend/libpq/be-secure-openssl.c | 23 ++++++++++++++++++++++- src/interfaces/libpq/fe-secure-openssl.c | 10 +++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 2fa2793..926dbf2 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -166,11 +166,13 @@ be_tls_init(void) if (!SSL_context) { +#if SSLEAY_VERSION_NUMBER < 0x10100000L #if SSLEAY_VERSION_NUMBER >= 0x0907000L OPENSSL_config(NULL); #endif SSL_library_init(); SSL_load_error_strings(); +#endif /* * We use SSLv23_method() because it can negotiate use of the highest @@ -854,6 +856,25 @@ load_dh_buffer(const char *buffer, size_t len) return dh; } +static DH * +generate_dh_params(int prime_len, int generator) +{ +#if SSLEAY_VERSION_NUMBER >= 0x00908000L + DH *dh; + + if ((dh = DH_new()) == NULL) + return NULL; + + if (DH_generate_parameters_ex(dh, prime_len, generator, NULL)) + return dh; + + DH_free(dh); + return NULL; +#else + return DH_generate_parameters(prime_len, generator, NULL, NULL); +#endif +} + /* * Generate an ephemeral DH key. Because this can take a long * time to compute, we can use precomputed parameters of the @@ -923,7 +944,7 @@ tmp_dh_cb(SSL *s, int is_export, int keylength) ereport(DEBUG2, (errmsg_internal("DH: generating parameters (%d bits)", keylength))); - r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL); + r = generate_dh_params(keylength, DH_GENERATOR_2); } return r; diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 520dcd7..aa80284 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -731,7 +731,7 @@ verify_peer_name_matches_certificate(PGconn *conn) return found_match && !got_error; } -#ifdef ENABLE_THREAD_SAFETY +#if defined(ENABLE_THREAD_SAFETY) && SSLEAY_VERSION_NUMBER < 0x10100000L /* * Callback functions for OpenSSL internal locking */ @@ -763,7 +763,7 @@ pq_lockingcallback(int mode, int n, const char *file, int line) PGTHREAD_ERROR("failed to unlock mutex"); } } -#endif /* ENABLE_THREAD_SAFETY */ +#endif /* ENABLE_THREAD_SAFETY && && SSLEAY_VERSION_NUMBER < 0x10100000L */ /* * Initialize SSL system, in particular creating the SSL_context object @@ -802,6 +802,7 @@ pgtls_init(PGconn *conn) if (pthread_mutex_lock(&ssl_config_mutex)) return -1; +#if SSLEAY_VERSION_NUMBER < 0x10100000L if (pq_init_crypto_lib) { /* @@ -842,10 +843,12 @@ pgtls_init(PGconn *conn) CRYPTO_set_locking_callback(pq_lockingcallback); } } +#endif #endif /* ENABLE_THREAD_SAFETY */ if (!SSL_context) { +#if SSLEAY_VERSION_NUMBER < 0x10100000L if (pq_init_ssl_lib) { #if SSLEAY_VERSION_NUMBER >= 0x00907000L @@ -854,6 +857,7 @@ pgtls_init(PGconn *conn) SSL_library_init(); SSL_load_error_strings(); } +#endif /* * We use SSLv23_method() because it can negotiate use of the highest @@ -906,7 +910,7 @@ pgtls_init(PGconn *conn) static void destroy_ssl_system(void) { -#ifdef ENABLE_THREAD_SAFETY +#if defined(ENABLE_THREAD_SAFETY) && SSLEAY_VERSION_NUMBER < 0x10100000L /* Mutex is created in initialize_ssl_system() */ if (pthread_mutex_lock(&ssl_config_mutex)) return; -- 2.8.1 --------------4DB1F28AF6A9296C8B774BA1 Content-Type: text/x-patch; name="0003-Remove-px_get_pseudo_random_bytes-v2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0003-Remove-px_get_pseudo_random_bytes-v2.patch" From 3ece4de28b6deea2281cd805dcbdb93851ddea50 Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Fri, 1 Jul 2016 19:34:31 +0200 Subject: [PATCH 3/4] Remove px_get_pseudo_random_bytes --- contrib/pgcrypto/internal.c | 9 --------- contrib/pgcrypto/openssl.c | 15 --------------- contrib/pgcrypto/pgcrypto.c | 2 +- contrib/pgcrypto/pgp-s2k.c | 6 +++--- contrib/pgcrypto/px-crypt.c | 2 +- contrib/pgcrypto/px.h | 1 - 6 files changed, 5 insertions(+), 30 deletions(-) diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c index cb8ba26..02ff976 100644 --- a/contrib/pgcrypto/internal.c +++ b/contrib/pgcrypto/internal.c @@ -620,15 +620,6 @@ px_find_cipher(const char *name, PX_Cipher **res) * Randomness provider */ -/* - * Use always strong randomness. - */ -int -px_get_pseudo_random_bytes(uint8 *dst, unsigned count) -{ - return px_get_random_bytes(dst, count); -} - static time_t seed_time = 0; static time_t check_time = 0; diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index a1db35d..d20dfdc 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -1015,21 +1015,6 @@ px_get_random_bytes(uint8 *dst, unsigned count) } int -px_get_pseudo_random_bytes(uint8 *dst, unsigned count) -{ - int res; - - if (!openssl_random_init) - init_openssl_rand(); - - res = RAND_pseudo_bytes(dst, count); - if (res == 0 || res == 1) - return count; - - return PXE_OSSL_RAND_ERROR; -} - -int px_add_entropy(const uint8 *data, unsigned count) { /* diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c index 2d446d8..27b96c7 100644 --- a/contrib/pgcrypto/pgcrypto.c +++ b/contrib/pgcrypto/pgcrypto.c @@ -454,7 +454,7 @@ pg_random_uuid(PG_FUNCTION_ARGS) int err; /* generate random bits */ - err = px_get_pseudo_random_bytes(buf, UUID_LEN); + err = px_get_random_bytes(buf, UUID_LEN); if (err < 0) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c index 9937d15..3551d44 100644 --- a/contrib/pgcrypto/pgp-s2k.c +++ b/contrib/pgcrypto/pgp-s2k.c @@ -233,13 +233,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count) case PGP_S2K_SIMPLE: break; case PGP_S2K_SALTED: - res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT); + res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT); break; case PGP_S2K_ISALTED: - res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT); + res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT); if (res < 0) break; - res = px_get_pseudo_random_bytes(&tmp, 1); + res = px_get_random_bytes(&tmp, 1); if (res < 0) break; s2k->iter = decide_s2k_iter(tmp, count); diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c index e3246fc..3d42393 100644 --- a/contrib/pgcrypto/px-crypt.c +++ b/contrib/pgcrypto/px-crypt.c @@ -153,7 +153,7 @@ px_gen_salt(const char *salt_type, char *buf, int rounds) return PXE_BAD_SALT_ROUNDS; } - res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len); + res = px_get_random_bytes((uint8 *) rbuf, g->input_len); if (res < 0) return res; diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h index 0f6bbd7..9174e13 100644 --- a/contrib/pgcrypto/px.h +++ b/contrib/pgcrypto/px.h @@ -190,7 +190,6 @@ int px_find_cipher(const char *name, PX_Cipher **res); int px_find_combo(const char *name, PX_Combo **res); int px_get_random_bytes(uint8 *dst, unsigned count); -int px_get_pseudo_random_bytes(uint8 *dst, unsigned count); int px_add_entropy(const uint8 *data, unsigned count); unsigned px_acquire_system_randomness(uint8 *dst); -- 2.8.1 --------------4DB1F28AF6A9296C8B774BA1 Content-Type: text/x-patch; name="0004-Define-CRYPTO_LOCK-for-OpenSSL-1.1-compat-v2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0004-Define-CRYPTO_LOCK-for-OpenSSL-1.1-compat-v2.patch" From 34f75691e2454924392107940ab61773c09bd2ed Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Tue, 28 Jun 2016 05:58:50 +0200 Subject: [PATCH 4/4] Define CRYPTO_LOCK for OpenSSL 1.1 compat --- src/interfaces/libpq/fe-secure-openssl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index aa80284..998eca4 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -736,6 +736,11 @@ verify_peer_name_matches_certificate(PGconn *conn) * Callback functions for OpenSSL internal locking */ +/* OpenSSL 1.1 no longer defines CRYPTO_LOCK */ +#ifndef CRYPTO_LOCK +#define CRYPTO_LOCK 1 +#endif + static unsigned long pq_threadidcallback(void) { -- 2.8.1 --------------4DB1F28AF6A9296C8B774BA1 Content-Type: text/plain Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers --------------4DB1F28AF6A9296C8B774BA1--