mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
Support OpenSSL 1.1.0 in 9.3 and 9.2.
This commit back-patches the equivalent of the 9.5-branch commits e2838c580 and 48e5ba61e, so that we can work with OpenSSL 1.1.0 in all supported branches. Original patches by Andreas Karlsson and Heikki Linnakangas, back-patching work by Andreas Karlsson. Patch: https://postgr.es/m/0c817abb-3f7d-20fb-583a-58f7593a0bea@proxel.se Discussion: https://postgr.es/m/5129.1492293840@sss.pgh.pa.us
This commit is contained in:
parent
fbfeceb253
commit
4e91330dac
257
configure
vendored
257
configure
vendored
@ -9524,9 +9524,9 @@ $as_echo "$as_me: error: library 'crypto' is required for OpenSSL" >&2;}
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:$LINENO: checking for SSL_library_init in -lssl" >&5
|
||||
$as_echo_n "checking for SSL_library_init in -lssl... " >&6; }
|
||||
if test "${ac_cv_lib_ssl_SSL_library_init+set}" = set; then
|
||||
{ $as_echo "$as_me:$LINENO: checking for SSL_new in -lssl" >&5
|
||||
$as_echo_n "checking for SSL_new in -lssl... " >&6; }
|
||||
if test "${ac_cv_lib_ssl_SSL_new+set}" = set; then
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
@ -9544,11 +9544,11 @@ cat >>conftest.$ac_ext <<_ACEOF
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char SSL_library_init ();
|
||||
char SSL_new ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return SSL_library_init ();
|
||||
return SSL_new ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
@ -9574,12 +9574,12 @@ $as_echo "$ac_try_echo") >&5
|
||||
test "$cross_compiling" = yes ||
|
||||
$as_test_x conftest$ac_exeext
|
||||
}; then
|
||||
ac_cv_lib_ssl_SSL_library_init=yes
|
||||
ac_cv_lib_ssl_SSL_new=yes
|
||||
else
|
||||
$as_echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_lib_ssl_SSL_library_init=no
|
||||
ac_cv_lib_ssl_SSL_new=no
|
||||
fi
|
||||
|
||||
rm -rf conftest.dSYM
|
||||
@ -9587,9 +9587,9 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:$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" = x""yes; then
|
||||
{ $as_echo "$as_me:$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" = x""yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBSSL 1
|
||||
_ACEOF
|
||||
@ -9694,9 +9694,9 @@ $as_echo "$as_me: error: library 'eay32' or 'crypto' is required for OpenSSL" >&
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:$LINENO: checking for library containing SSL_library_init" >&5
|
||||
$as_echo_n "checking for library containing SSL_library_init... " >&6; }
|
||||
if test "${ac_cv_search_SSL_library_init+set}" = set; then
|
||||
{ $as_echo "$as_me:$LINENO: checking for library containing SSL_new" >&5
|
||||
$as_echo_n "checking for library containing SSL_new... " >&6; }
|
||||
if test "${ac_cv_search_SSL_new+set}" = set; then
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
@ -9713,11 +9713,11 @@ cat >>conftest.$ac_ext <<_ACEOF
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char SSL_library_init ();
|
||||
char SSL_new ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return SSL_library_init ();
|
||||
return SSL_new ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
@ -9750,7 +9750,7 @@ $as_echo "$ac_try_echo") >&5
|
||||
test "$cross_compiling" = yes ||
|
||||
$as_test_x conftest$ac_exeext
|
||||
}; then
|
||||
ac_cv_search_SSL_library_init=$ac_res
|
||||
ac_cv_search_SSL_new=$ac_res
|
||||
else
|
||||
$as_echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
@ -9761,21 +9761,21 @@ fi
|
||||
rm -rf conftest.dSYM
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext
|
||||
if test "${ac_cv_search_SSL_library_init+set}" = set; then
|
||||
if test "${ac_cv_search_SSL_new+set}" = set; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test "${ac_cv_search_SSL_library_init+set}" = set; then
|
||||
if test "${ac_cv_search_SSL_new+set}" = set; 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:$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:$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"
|
||||
|
||||
@ -9786,6 +9786,219 @@ $as_echo "$as_me: error: library 'ssleay32' or 'ssl' is required for OpenSSL" >&
|
||||
fi
|
||||
|
||||
fi
|
||||
# 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_meth_new ASN1_STRING_get0_data RAND_OpenSSL
|
||||
do
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
$as_echo_n "checking for $ac_func... " >&6; }
|
||||
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $ac_func innocuous_$ac_func
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef $ac_func
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $ac_func ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$ac_func || defined __stub___$ac_func
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $ac_func ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
|
||||
$as_echo "$ac_try_echo") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext && {
|
||||
test "$cross_compiling" = yes ||
|
||||
$as_test_x conftest$ac_exeext
|
||||
}; then
|
||||
eval "$as_ac_var=yes"
|
||||
else
|
||||
$as_echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
eval "$as_ac_var=no"
|
||||
fi
|
||||
|
||||
rm -rf conftest.dSYM
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
ac_res=`eval 'as_val=${'$as_ac_var'}
|
||||
$as_echo "$as_val"'`
|
||||
{ $as_echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
$as_echo "$ac_res" >&6; }
|
||||
as_val=`eval 'as_val=${'$as_ac_var'}
|
||||
$as_echo "$as_val"'`
|
||||
if test "x$as_val" = 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
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
$as_echo_n "checking for $ac_func... " >&6; }
|
||||
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $ac_func innocuous_$ac_func
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func (); below.
|
||||
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
<limits.h> exists even on freestanding compilers. */
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
#else
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#undef $ac_func
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $ac_func ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$ac_func || defined __stub___$ac_func
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return $ac_func ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
|
||||
$as_echo "$ac_try_echo") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext && {
|
||||
test "$cross_compiling" = yes ||
|
||||
$as_test_x conftest$ac_exeext
|
||||
}; then
|
||||
eval "$as_ac_var=yes"
|
||||
else
|
||||
$as_echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
eval "$as_ac_var=no"
|
||||
fi
|
||||
|
||||
rm -rf conftest.dSYM
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
ac_res=`eval 'as_val=${'$as_ac_var'}
|
||||
$as_echo "$as_val"'`
|
||||
{ $as_echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
$as_echo "$ac_res" >&6; }
|
||||
as_val=`eval 'as_val=${'$as_ac_var'}
|
||||
$as_echo "$as_val"'`
|
||||
if test "x$as_val" = x""yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
if test "$with_pam" = yes ; then
|
||||
|
14
configure.in
14
configure.in
@ -951,11 +951,21 @@ 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
|
||||
# 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_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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -40,6 +40,9 @@
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/resowner.h"
|
||||
|
||||
/*
|
||||
* Max lengths we might want to handle.
|
||||
*/
|
||||
@ -199,18 +202,73 @@ compat_find_digest(const char *name, PX_MD **res)
|
||||
* Hashes
|
||||
*/
|
||||
|
||||
/*
|
||||
* To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
|
||||
* objects in a linked list, allocated in TopMemoryContext. We use the
|
||||
* ResourceOwner mechanism to free them on abort.
|
||||
*/
|
||||
typedef struct OSSLDigest
|
||||
{
|
||||
const EVP_MD *algo;
|
||||
EVP_MD_CTX ctx;
|
||||
EVP_MD_CTX *ctx;
|
||||
|
||||
ResourceOwner owner;
|
||||
struct OSSLDigest *next;
|
||||
struct OSSLDigest *prev;
|
||||
} OSSLDigest;
|
||||
|
||||
static OSSLDigest *open_digests = NULL;
|
||||
static bool resowner_callback_registered = false;
|
||||
|
||||
static void
|
||||
free_openssldigest(OSSLDigest *digest)
|
||||
{
|
||||
EVP_MD_CTX_destroy(digest->ctx);
|
||||
if (digest->prev)
|
||||
digest->prev->next = digest->next;
|
||||
else
|
||||
open_digests = digest->next;
|
||||
if (digest->next)
|
||||
digest->next->prev = digest->prev;
|
||||
pfree(digest);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close any open OpenSSL handles on abort.
|
||||
*/
|
||||
static void
|
||||
digest_free_callback(ResourceReleasePhase phase,
|
||||
bool isCommit,
|
||||
bool isTopLevel,
|
||||
void *arg)
|
||||
{
|
||||
OSSLDigest *curr;
|
||||
OSSLDigest *next;
|
||||
|
||||
if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
|
||||
return;
|
||||
|
||||
next = open_digests;
|
||||
while (next)
|
||||
{
|
||||
curr = next;
|
||||
next = curr->next;
|
||||
|
||||
if (curr->owner == CurrentResourceOwner)
|
||||
{
|
||||
if (isCommit)
|
||||
elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
|
||||
free_openssldigest(curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
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 +276,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 +284,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 +292,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 +300,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,9 +308,7 @@ digest_free(PX_MD *h)
|
||||
{
|
||||
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
|
||||
|
||||
EVP_MD_CTX_cleanup(&digest->ctx);
|
||||
|
||||
px_free(digest);
|
||||
free_openssldigest(digest);
|
||||
px_free(h);
|
||||
}
|
||||
|
||||
@ -264,6 +320,7 @@ int
|
||||
px_find_digest(const char *name, PX_MD **res)
|
||||
{
|
||||
const EVP_MD *md;
|
||||
EVP_MD_CTX *ctx;
|
||||
PX_MD *h;
|
||||
OSSLDigest *digest;
|
||||
|
||||
@ -273,17 +330,43 @@ px_find_digest(const char *name, PX_MD **res)
|
||||
OpenSSL_add_all_algorithms();
|
||||
}
|
||||
|
||||
if (!resowner_callback_registered)
|
||||
{
|
||||
RegisterResourceReleaseCallback(digest_free_callback, NULL);
|
||||
resowner_callback_registered = true;
|
||||
}
|
||||
|
||||
md = EVP_get_digestbyname(name);
|
||||
if (md == NULL)
|
||||
return compat_find_digest(name, res);
|
||||
|
||||
digest = px_alloc(sizeof(*digest));
|
||||
digest->algo = md;
|
||||
/*
|
||||
* Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
|
||||
* The order is crucial, to make sure we don't leak anything on
|
||||
* out-of-memory or other error.
|
||||
*/
|
||||
digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
|
||||
|
||||
EVP_MD_CTX_init(&digest->ctx);
|
||||
if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
|
||||
ctx = EVP_MD_CTX_create();
|
||||
if (!ctx)
|
||||
{
|
||||
pfree(digest);
|
||||
return -1;
|
||||
}
|
||||
if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
|
||||
{
|
||||
pfree(digest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
digest->algo = md;
|
||||
digest->ctx = ctx;
|
||||
digest->owner = CurrentResourceOwner;
|
||||
digest->next = open_digests;
|
||||
digest->prev = NULL;
|
||||
open_digests = digest;
|
||||
|
||||
/* The PX_MD object is allocated in the current memory context. */
|
||||
h = px_alloc(sizeof(*h));
|
||||
h->result_size = digest_result_size;
|
||||
h->block_size = digest_block_size;
|
||||
@ -987,7 +1070,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;
|
||||
}
|
||||
|
||||
@ -1006,21 +1095,6 @@ px_get_random_bytes(uint8 *dst, unsigned count)
|
||||
return PXE_OSSL_RAND_ERROR;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -223,13 +223,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo)
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
|
||||
res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
|
||||
break;
|
||||
case 3:
|
||||
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_count(tmp);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -66,7 +66,7 @@
|
||||
#ifdef USE_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/dh.h>
|
||||
#if SSLEAY_VERSION_NUMBER >= 0x0907000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0907000L
|
||||
#include <openssl/conf.h>
|
||||
#endif
|
||||
#endif /* USE_SSL */
|
||||
@ -80,6 +80,7 @@
|
||||
|
||||
static DH *load_dh_file(int keylength);
|
||||
static DH *load_dh_buffer(const char *, size_t);
|
||||
static DH *generate_dh_parameters(int prime_len, int generator);
|
||||
static DH *tmp_dh_cb(SSL *s, int is_export, int keylength);
|
||||
static int verify_cb(int, X509_STORE_CTX *);
|
||||
static void info_cb(const SSL *ssl, int type, int args);
|
||||
@ -476,8 +477,7 @@ wloop:
|
||||
* to retry; do we need to adopt their logic for that?
|
||||
*/
|
||||
|
||||
static bool my_bio_initialized = false;
|
||||
static BIO_METHOD my_bio_methods;
|
||||
static BIO_METHOD *my_bio_methods = NULL;
|
||||
|
||||
static int
|
||||
my_sock_read(BIO *h, char *buf, int size)
|
||||
@ -488,7 +488,7 @@ my_sock_read(BIO *h, char *buf, int size)
|
||||
|
||||
if (buf != NULL)
|
||||
{
|
||||
res = recv(h->num, buf, size, 0);
|
||||
res = recv(BIO_get_fd(h, NULL), buf, size, 0);
|
||||
BIO_clear_retry_flags(h);
|
||||
if (res <= 0)
|
||||
{
|
||||
@ -510,7 +510,7 @@ my_sock_write(BIO *h, const char *buf, int size)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
res = send(h->num, buf, size, 0);
|
||||
res = send(BIO_get_fd(h, NULL), buf, size, 0);
|
||||
BIO_clear_retry_flags(h);
|
||||
if (res <= 0)
|
||||
{
|
||||
@ -526,14 +526,41 @@ 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();
|
||||
#ifdef HAVE_BIO_METH_NEW
|
||||
int my_bio_index;
|
||||
|
||||
my_bio_index = BIO_get_new_index();
|
||||
if (my_bio_index == -1)
|
||||
return NULL;
|
||||
my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
|
||||
if (!my_bio_methods)
|
||||
return NULL;
|
||||
if (!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_puts(my_bio_methods, BIO_meth_get_puts(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)))
|
||||
{
|
||||
BIO_meth_free(my_bio_methods);
|
||||
my_bio_methods = NULL;
|
||||
return NULL;
|
||||
}
|
||||
return &my_bio_methods;
|
||||
#else
|
||||
my_bio_methods = malloc(sizeof(BIO_METHOD));
|
||||
if (!my_bio_methods)
|
||||
return NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
/* This should exactly match openssl's SSL_set_fd except for using my BIO */
|
||||
@ -541,9 +568,16 @@ static int
|
||||
my_SSL_set_fd(SSL *s, int fd)
|
||||
{
|
||||
int ret = 0;
|
||||
BIO *bio = NULL;
|
||||
BIO *bio;
|
||||
BIO_METHOD *bio_method;
|
||||
|
||||
bio = BIO_new(my_BIO_s_socket());
|
||||
bio_method = my_BIO_s_socket();
|
||||
if (bio_method == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
|
||||
goto err;
|
||||
}
|
||||
bio = BIO_new(bio_method);
|
||||
|
||||
if (bio == NULL)
|
||||
{
|
||||
@ -642,6 +676,31 @@ load_dh_buffer(const char *buffer, size_t len)
|
||||
return dh;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate DH parameters.
|
||||
*
|
||||
* Last resort if we can't load precomputed nor hardcoded
|
||||
* parameters.
|
||||
*/
|
||||
static DH *
|
||||
generate_dh_parameters(int prime_len, int generator)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
|
||||
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
|
||||
@ -711,7 +770,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_parameters(keylength, DH_GENERATOR_2);
|
||||
}
|
||||
|
||||
return r;
|
||||
@ -790,11 +849,15 @@ initialize_SSL(void)
|
||||
|
||||
if (!SSL_context)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_INIT_SSL
|
||||
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
||||
#else
|
||||
#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
|
||||
|
@ -87,6 +87,12 @@
|
||||
/* 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 have the `BIO_meth_new' function. */
|
||||
#undef HAVE_BIO_METH_NEW
|
||||
|
||||
/* Define to 1 if you have the `cbrt' function. */
|
||||
#undef HAVE_CBRT
|
||||
|
||||
@ -99,6 +105,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 <crypt.h> header file. */
|
||||
#undef HAVE_CRYPT_H
|
||||
|
||||
@ -357,6 +366,9 @@
|
||||
/* Define to 1 if you have the <net/if.h> 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 <ossp/uuid.h> header file. */
|
||||
#undef HAVE_OSSP_UUID_H
|
||||
|
||||
@ -396,6 +408,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 <readline.h> header file. */
|
||||
#undef HAVE_READLINE_H
|
||||
|
||||
|
@ -58,7 +58,7 @@
|
||||
#ifdef USE_SSL
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
|
||||
#include <openssl/conf.h>
|
||||
#endif
|
||||
#ifdef USE_SSL_ENGINE
|
||||
@ -835,9 +835,13 @@ verify_peer_name_matches_certificate(PGconn *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
|
||||
/*
|
||||
* Callback functions for OpenSSL internal locking
|
||||
* 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
|
||||
@ -867,7 +871,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 && HAVE_CRYPTO_LOCK */
|
||||
|
||||
/*
|
||||
* Initialize SSL library.
|
||||
@ -905,6 +909,7 @@ init_ssl_system(PGconn *conn)
|
||||
if (pthread_mutex_lock(&ssl_config_mutex))
|
||||
return -1;
|
||||
|
||||
#ifdef HAVE_CRYPTO_LOCK
|
||||
if (pq_init_crypto_lib)
|
||||
{
|
||||
/*
|
||||
@ -940,17 +945,22 @@ init_ssl_system(PGconn *conn)
|
||||
CRYPTO_set_locking_callback(pq_lockingcallback);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_CRYPTO_LOCK */
|
||||
#endif /* ENABLE_THREAD_SAFETY */
|
||||
|
||||
if (!ssl_lib_initialized)
|
||||
{
|
||||
if (pq_init_ssl_lib)
|
||||
{
|
||||
#if SSLEAY_VERSION_NUMBER >= 0x00907000L
|
||||
#ifdef HAVE_OPENSSL_INIT_SSL
|
||||
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
||||
#else
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
|
||||
OPENSSL_config(NULL);
|
||||
#endif
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
#endif
|
||||
}
|
||||
ssl_lib_initialized = true;
|
||||
}
|
||||
@ -970,12 +980,13 @@ init_ssl_system(PGconn *conn)
|
||||
* if we had any.)
|
||||
*
|
||||
* Callbacks are only set when we're compiled in threadsafe mode, so
|
||||
* we only need to remove them in this case.
|
||||
* we only need to remove them in this case. They are also not needed
|
||||
* with OpenSSL 1.1.0 anymore.
|
||||
*/
|
||||
static void
|
||||
destroy_ssl_system(void)
|
||||
{
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
|
||||
/* Mutex is created in initialize_ssl_system() */
|
||||
if (pthread_mutex_lock(&ssl_config_mutex))
|
||||
return;
|
||||
|
@ -77,7 +77,7 @@ typedef struct
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
|
||||
#define USE_SSL_ENGINE
|
||||
#endif
|
||||
#endif /* USE_SSL */
|
||||
|
Loading…
x
Reference in New Issue
Block a user