>From 0e6d78ad199bde8c4e698952a3b5e4375371f072 Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Tue, 28 Jun 2016 05:55:03 +0200 Subject: [PATCH 1/3] 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