Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fcd93e4

Browse files
committed
Support OpenSSL 1.1.0.
Changes needed to build at all: - Check for SSL_new in configure, now that SSL_library_init is a macro. - Do not access struct members directly. This includes some new code in pgcrypto, to use the resource owner mechanism to ensure that we don't leak OpenSSL handles, now that we can't embed them in other structs anymore. - RAND_SSLeay() -> RAND_OpenSSL() Changes that were needed to silence deprecation warnings, but were not strictly necessary: - RAND_pseudo_bytes() -> RAND_bytes(). - SSL_library_init() and OpenSSL_config() -> OPENSSL_init_ssl() - ASN1_STRING_data() -> ASN1_STRING_get0_data() - DH_generate_parameters() -> DH_generate_parameters() - Locking callbacks are not needed with OpenSSL 1.1.0 anymore. (Good riddance!) Also change references to SSLEAY_VERSION_NUMBER with OPENSSL_VERSION_NUMBER, for the sake of consistency. OPENSSL_VERSION_NUMBER has existed since time immemorial. Fix SSL test suite to work with OpenSSL 1.1.0. CA certificates must have the "CA:true" basic constraint extension now, or OpenSSL will refuse them. Regenerate the test certificates with that. The "openssl" binary, used to generate the certificates, is also now more picky, and throws an error if an X509 extension is specified in "req_extensions", but that section is empty. Backpatch to 9.5 and 9.6, per popular demand. The file structure was somewhat different in earlier branches, so I didn't bother to go further than that. In back-branches, we still support OpenSSL 0.9.7 and above. OpenSSL 0.9.6 should still work too, but I didn't test it. In master, we only support 0.9.8 and above. Patch by Andreas Karlsson, with additional changes by me. Discussion: <20160627151604.GD1051@msg.df7cb.de>
1 parent 18ae680 commit fcd93e4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+716
-539
lines changed

configure

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9538,9 +9538,9 @@ else
95389538
as_fn_error $? "library 'crypto' is required for OpenSSL" "$LINENO" 5
95399539
fi
95409540

9541-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_library_init in -lssl" >&5
9542-
$as_echo_n "checking for SSL_library_init in -lssl... " >&6; }
9543-
if ${ac_cv_lib_ssl_SSL_library_init+:} false; then :
9541+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_new in -lssl" >&5
9542+
$as_echo_n "checking for SSL_new in -lssl... " >&6; }
9543+
if ${ac_cv_lib_ssl_SSL_new+:} false; then :
95449544
$as_echo_n "(cached) " >&6
95459545
else
95469546
ac_check_lib_save_LIBS=$LIBS
@@ -9554,27 +9554,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
95549554
#ifdef __cplusplus
95559555
extern "C"
95569556
#endif
9557-
char SSL_library_init ();
9557+
char SSL_new ();
95589558
int
95599559
main ()
95609560
{
9561-
return SSL_library_init ();
9561+
return SSL_new ();
95629562
;
95639563
return 0;
95649564
}
95659565
_ACEOF
95669566
if ac_fn_c_try_link "$LINENO"; then :
9567-
ac_cv_lib_ssl_SSL_library_init=yes
9567+
ac_cv_lib_ssl_SSL_new=yes
95689568
else
9569-
ac_cv_lib_ssl_SSL_library_init=no
9569+
ac_cv_lib_ssl_SSL_new=no
95709570
fi
95719571
rm -f core conftest.err conftest.$ac_objext \
95729572
conftest$ac_exeext conftest.$ac_ext
95739573
LIBS=$ac_check_lib_save_LIBS
95749574
fi
9575-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_library_init" >&5
9576-
$as_echo "$ac_cv_lib_ssl_SSL_library_init" >&6; }
9577-
if test "x$ac_cv_lib_ssl_SSL_library_init" = xyes; then :
9575+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_new" >&5
9576+
$as_echo "$ac_cv_lib_ssl_SSL_new" >&6; }
9577+
if test "x$ac_cv_lib_ssl_SSL_new" = xyes; then :
95789578
cat >>confdefs.h <<_ACEOF
95799579
#define HAVE_LIBSSL 1
95809580
_ACEOF
@@ -9644,9 +9644,9 @@ else
96449644
as_fn_error $? "library 'eay32' or 'crypto' is required for OpenSSL" "$LINENO" 5
96459645
fi
96469646

9647-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_library_init" >&5
9648-
$as_echo_n "checking for library containing SSL_library_init... " >&6; }
9649-
if ${ac_cv_search_SSL_library_init+:} false; then :
9647+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_new" >&5
9648+
$as_echo_n "checking for library containing SSL_new... " >&6; }
9649+
if ${ac_cv_search_SSL_new+:} false; then :
96509650
$as_echo_n "(cached) " >&6
96519651
else
96529652
ac_func_search_save_LIBS=$LIBS
@@ -9659,11 +9659,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
96599659
#ifdef __cplusplus
96609660
extern "C"
96619661
#endif
9662-
char SSL_library_init ();
9662+
char SSL_new ();
96639663
int
96649664
main ()
96659665
{
9666-
return SSL_library_init ();
9666+
return SSL_new ();
96679667
;
96689668
return 0;
96699669
}
@@ -9676,25 +9676,25 @@ for ac_lib in '' ssleay32 ssl; do
96769676
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
96779677
fi
96789678
if ac_fn_c_try_link "$LINENO"; then :
9679-
ac_cv_search_SSL_library_init=$ac_res
9679+
ac_cv_search_SSL_new=$ac_res
96809680
fi
96819681
rm -f core conftest.err conftest.$ac_objext \
96829682
conftest$ac_exeext
9683-
if ${ac_cv_search_SSL_library_init+:} false; then :
9683+
if ${ac_cv_search_SSL_new+:} false; then :
96849684
break
96859685
fi
96869686
done
9687-
if ${ac_cv_search_SSL_library_init+:} false; then :
9687+
if ${ac_cv_search_SSL_new+:} false; then :
96889688

96899689
else
9690-
ac_cv_search_SSL_library_init=no
9690+
ac_cv_search_SSL_new=no
96919691
fi
96929692
rm conftest.$ac_ext
96939693
LIBS=$ac_func_search_save_LIBS
96949694
fi
9695-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSL_library_init" >&5
9696-
$as_echo "$ac_cv_search_SSL_library_init" >&6; }
9697-
ac_res=$ac_cv_search_SSL_library_init
9695+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSL_new" >&5
9696+
$as_echo "$ac_cv_search_SSL_new" >&6; }
9697+
ac_res=$ac_cv_search_SSL_new
96989698
if test "$ac_res" != no; then :
96999699
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
97009700

configure.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,10 +1112,10 @@ if test "$with_openssl" = yes ; then
11121112
dnl Order matters!
11131113
if test "$PORTNAME" != "win32"; then
11141114
AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])])
1115-
AC_CHECK_LIB(ssl, SSL_library_init, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
1115+
AC_CHECK_LIB(ssl, SSL_new, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
11161116
else
11171117
AC_SEARCH_LIBS(CRYPTO_new_ex_data, eay32 crypto, [], [AC_MSG_ERROR([library 'eay32' or 'crypto' is required for OpenSSL])])
1118-
AC_SEARCH_LIBS(SSL_library_init, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])])
1118+
AC_SEARCH_LIBS(SSL_new, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])])
11191119
fi
11201120
AC_CHECK_FUNCS([SSL_get_current_compression])
11211121
fi

contrib/pgcrypto/internal.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -620,15 +620,6 @@ px_find_cipher(const char *name, PX_Cipher **res)
620620
* Randomness provider
621621
*/
622622

623-
/*
624-
* Use always strong randomness.
625-
*/
626-
int
627-
px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
628-
{
629-
return px_get_random_bytes(dst, count);
630-
}
631-
632623
static time_t seed_time = 0;
633624
static time_t check_time = 0;
634625

contrib/pgcrypto/openssl.c

Lines changed: 101 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
#include <openssl/rand.h>
4141
#include <openssl/err.h>
4242

43+
#include "utils/memutils.h"
44+
#include "utils/resowner.h"
45+
4346
/*
4447
* Max lengths we might want to handle.
4548
*/
@@ -199,60 +202,113 @@ compat_find_digest(const char *name, PX_MD **res)
199202
* Hashes
200203
*/
201204

205+
/*
206+
* To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
207+
* objects in a linked list, allocated in TopMemoryContext. We use the
208+
* ResourceOwner mechanism to free them on abort.
209+
*/
202210
typedef struct OSSLDigest
203211
{
204212
const EVP_MD *algo;
205-
EVP_MD_CTX ctx;
213+
EVP_MD_CTX *ctx;
214+
215+
ResourceOwner owner;
216+
struct OSSLDigest *next;
217+
struct OSSLDigest *prev;
206218
} OSSLDigest;
207219

220+
static OSSLDigest *open_digests = NULL;
221+
static bool resowner_callback_registered = false;
222+
223+
static void
224+
free_openssldigest(OSSLDigest *digest)
225+
{
226+
EVP_MD_CTX_destroy(digest->ctx);
227+
if (digest->prev)
228+
digest->prev->next = digest->next;
229+
else
230+
open_digests = digest->next;
231+
if (digest->next)
232+
digest->next->prev = digest->prev;
233+
pfree(digest);
234+
}
235+
236+
/*
237+
* Close any open OpenSSL handles on abort.
238+
*/
239+
static void
240+
digest_free_callback(ResourceReleasePhase phase,
241+
bool isCommit,
242+
bool isTopLevel,
243+
void *arg)
244+
{
245+
OSSLDigest *curr;
246+
OSSLDigest *next;
247+
248+
if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
249+
return;
250+
251+
next = open_digests;
252+
while (next)
253+
{
254+
curr = next;
255+
next = curr->next;
256+
257+
if (curr->owner == CurrentResourceOwner)
258+
{
259+
if (isCommit)
260+
elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
261+
free_openssldigest(curr);
262+
}
263+
}
264+
}
265+
208266
static unsigned
209267
digest_result_size(PX_MD *h)
210268
{
211269
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
212270

213-
return EVP_MD_CTX_size(&digest->ctx);
271+
return EVP_MD_CTX_size(digest->ctx);
214272
}
215273

216274
static unsigned
217275
digest_block_size(PX_MD *h)
218276
{
219277
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
220278

221-
return EVP_MD_CTX_block_size(&digest->ctx);
279+
return EVP_MD_CTX_block_size(digest->ctx);
222280
}
223281

224282
static void
225283
digest_reset(PX_MD *h)
226284
{
227285
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
228286

229-
EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
287+
EVP_DigestInit_ex(digest->ctx, digest->algo, NULL);
230288
}
231289

232290
static void
233291
digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
234292
{
235293
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
236294

237-
EVP_DigestUpdate(&digest->ctx, data, dlen);
295+
EVP_DigestUpdate(digest->ctx, data, dlen);
238296
}
239297

240298
static void
241299
digest_finish(PX_MD *h, uint8 *dst)
242300
{
243301
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
244302

245-
EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
303+
EVP_DigestFinal_ex(digest->ctx, dst, NULL);
246304
}
247305

248306
static void
249307
digest_free(PX_MD *h)
250308
{
251309
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
252310

253-
EVP_MD_CTX_cleanup(&digest->ctx);
254-
255-
px_free(digest);
311+
free_openssldigest(digest);
256312
px_free(h);
257313
}
258314

@@ -264,6 +320,7 @@ int
264320
px_find_digest(const char *name, PX_MD **res)
265321
{
266322
const EVP_MD *md;
323+
EVP_MD_CTX *ctx;
267324
PX_MD *h;
268325
OSSLDigest *digest;
269326

@@ -273,17 +330,43 @@ px_find_digest(const char *name, PX_MD **res)
273330
OpenSSL_add_all_algorithms();
274331
}
275332

333+
if (!resowner_callback_registered)
334+
{
335+
RegisterResourceReleaseCallback(digest_free_callback, NULL);
336+
resowner_callback_registered = true;
337+
}
338+
276339
md = EVP_get_digestbyname(name);
277340
if (md == NULL)
278341
return compat_find_digest(name, res);
279342

280-
digest = px_alloc(sizeof(*digest));
281-
digest->algo = md;
343+
/*
344+
* Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
345+
* The order is crucial, to make sure we don't leak anything on
346+
* out-of-memory or other error.
347+
*/
348+
digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
282349

283-
EVP_MD_CTX_init(&digest->ctx);
284-
if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
350+
ctx = EVP_MD_CTX_create();
351+
if (!ctx)
352+
{
353+
pfree(digest);
285354
return -1;
355+
}
356+
if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
357+
{
358+
pfree(digest);
359+
return -1;
360+
}
361+
362+
digest->algo = md;
363+
digest->ctx = ctx;
364+
digest->owner = CurrentResourceOwner;
365+
digest->next = open_digests;
366+
digest->prev = NULL;
367+
open_digests = digest;
286368

369+
/* The PX_MD object is allocated in the current memory context. */
287370
h = px_alloc(sizeof(*h));
288371
h->result_size = digest_result_size;
289372
h->block_size = digest_block_size;
@@ -979,6 +1062,10 @@ px_find_cipher(const char *name, PX_Cipher **res)
9791062

9801063
static int openssl_random_init = 0;
9811064

1065+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
1066+
#define RAND_OpenSSL RAND_SSLeay
1067+
#endif
1068+
9821069
/*
9831070
* OpenSSL random should re-feeded occasionally. From /dev/urandom
9841071
* preferably.
@@ -987,7 +1074,7 @@ static void
9871074
init_openssl_rand(void)
9881075
{
9891076
if (RAND_get_rand_method() == NULL)
990-
RAND_set_rand_method(RAND_SSLeay());
1077+
RAND_set_rand_method(RAND_OpenSSL());
9911078
openssl_random_init = 1;
9921079
}
9931080

@@ -1006,21 +1093,6 @@ px_get_random_bytes(uint8 *dst, unsigned count)
10061093
return PXE_OSSL_RAND_ERROR;
10071094
}
10081095

1009-
int
1010-
px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
1011-
{
1012-
int res;
1013-
1014-
if (!openssl_random_init)
1015-
init_openssl_rand();
1016-
1017-
res = RAND_pseudo_bytes(dst, count);
1018-
if (res == 0 || res == 1)
1019-
return count;
1020-
1021-
return PXE_OSSL_RAND_ERROR;
1022-
}
1023-
10241096
int
10251097
px_add_entropy(const uint8 *data, unsigned count)
10261098
{

contrib/pgcrypto/pgcrypto.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ pg_random_uuid(PG_FUNCTION_ARGS)
454454
int err;
455455

456456
/* generate random bits */
457-
err = px_get_pseudo_random_bytes(buf, UUID_LEN);
457+
err = px_get_random_bytes(buf, UUID_LEN);
458458
if (err < 0)
459459
ereport(ERROR,
460460
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),

contrib/pgcrypto/pgp-s2k.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count)
233233
case PGP_S2K_SIMPLE:
234234
break;
235235
case PGP_S2K_SALTED:
236-
res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
236+
res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
237237
break;
238238
case PGP_S2K_ISALTED:
239-
res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
239+
res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
240240
if (res < 0)
241241
break;
242-
res = px_get_pseudo_random_bytes(&tmp, 1);
242+
res = px_get_random_bytes(&tmp, 1);
243243
if (res < 0)
244244
break;
245245
s2k->iter = decide_s2k_iter(tmp, count);

0 commit comments

Comments
 (0)