Skip to content

Commit e2838c5

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 caad70c commit e2838c5

Some content is hidden

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

50 files changed

+714
-527
lines changed

configure

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

8707-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_library_init in -lssl" >&5
8708-
$as_echo_n "checking for SSL_library_init in -lssl... " >&6; }
8709-
if ${ac_cv_lib_ssl_SSL_library_init+:} false; then :
8707+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_new in -lssl" >&5
8708+
$as_echo_n "checking for SSL_new in -lssl... " >&6; }
8709+
if ${ac_cv_lib_ssl_SSL_new+:} false; then :
87108710
$as_echo_n "(cached) " >&6
87118711
else
87128712
ac_check_lib_save_LIBS=$LIBS
@@ -8720,27 +8720,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
87208720
#ifdef __cplusplus
87218721
extern "C"
87228722
#endif
8723-
char SSL_library_init ();
8723+
char SSL_new ();
87248724
int
87258725
main ()
87268726
{
8727-
return SSL_library_init ();
8727+
return SSL_new ();
87288728
;
87298729
return 0;
87308730
}
87318731
_ACEOF
87328732
if ac_fn_c_try_link "$LINENO"; then :
8733-
ac_cv_lib_ssl_SSL_library_init=yes
8733+
ac_cv_lib_ssl_SSL_new=yes
87348734
else
8735-
ac_cv_lib_ssl_SSL_library_init=no
8735+
ac_cv_lib_ssl_SSL_new=no
87368736
fi
87378737
rm -f core conftest.err conftest.$ac_objext \
87388738
conftest$ac_exeext conftest.$ac_ext
87398739
LIBS=$ac_check_lib_save_LIBS
87408740
fi
8741-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_library_init" >&5
8742-
$as_echo "$ac_cv_lib_ssl_SSL_library_init" >&6; }
8743-
if test "x$ac_cv_lib_ssl_SSL_library_init" = xyes; then :
8741+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_new" >&5
8742+
$as_echo "$ac_cv_lib_ssl_SSL_new" >&6; }
8743+
if test "x$ac_cv_lib_ssl_SSL_new" = xyes; then :
87448744
cat >>confdefs.h <<_ACEOF
87458745
#define HAVE_LIBSSL 1
87468746
_ACEOF
@@ -8810,9 +8810,9 @@ else
88108810
as_fn_error $? "library 'eay32' or 'crypto' is required for OpenSSL" "$LINENO" 5
88118811
fi
88128812

8813-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_library_init" >&5
8814-
$as_echo_n "checking for library containing SSL_library_init... " >&6; }
8815-
if ${ac_cv_search_SSL_library_init+:} false; then :
8813+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing SSL_new" >&5
8814+
$as_echo_n "checking for library containing SSL_new... " >&6; }
8815+
if ${ac_cv_search_SSL_new+:} false; then :
88168816
$as_echo_n "(cached) " >&6
88178817
else
88188818
ac_func_search_save_LIBS=$LIBS
@@ -8825,11 +8825,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
88258825
#ifdef __cplusplus
88268826
extern "C"
88278827
#endif
8828-
char SSL_library_init ();
8828+
char SSL_new ();
88298829
int
88308830
main ()
88318831
{
8832-
return SSL_library_init ();
8832+
return SSL_new ();
88338833
;
88348834
return 0;
88358835
}
@@ -8842,25 +8842,25 @@ for ac_lib in '' ssleay32 ssl; do
88428842
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
88438843
fi
88448844
if ac_fn_c_try_link "$LINENO"; then :
8845-
ac_cv_search_SSL_library_init=$ac_res
8845+
ac_cv_search_SSL_new=$ac_res
88468846
fi
88478847
rm -f core conftest.err conftest.$ac_objext \
88488848
conftest$ac_exeext
8849-
if ${ac_cv_search_SSL_library_init+:} false; then :
8849+
if ${ac_cv_search_SSL_new+:} false; then :
88508850
break
88518851
fi
88528852
done
8853-
if ${ac_cv_search_SSL_library_init+:} false; then :
8853+
if ${ac_cv_search_SSL_new+:} false; then :
88548854

88558855
else
8856-
ac_cv_search_SSL_library_init=no
8856+
ac_cv_search_SSL_new=no
88578857
fi
88588858
rm conftest.$ac_ext
88598859
LIBS=$ac_func_search_save_LIBS
88608860
fi
8861-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSL_library_init" >&5
8862-
$as_echo "$ac_cv_search_SSL_library_init" >&6; }
8863-
ac_res=$ac_cv_search_SSL_library_init
8861+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_SSL_new" >&5
8862+
$as_echo "$ac_cv_search_SSL_new" >&6; }
8863+
ac_res=$ac_cv_search_SSL_new
88648864
if test "$ac_res" != no; then :
88658865
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
88668866

configure.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,10 +1028,10 @@ if test "$with_openssl" = yes ; then
10281028
dnl Order matters!
10291029
if test "$PORTNAME" != "win32"; then
10301030
AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])])
1031-
AC_CHECK_LIB(ssl, SSL_library_init, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
1031+
AC_CHECK_LIB(ssl, SSL_new, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
10321032
else
10331033
AC_SEARCH_LIBS(CRYPTO_new_ex_data, eay32 crypto, [], [AC_MSG_ERROR([library 'eay32' or 'crypto' is required for OpenSSL])])
1034-
AC_SEARCH_LIBS(SSL_library_init, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])])
1034+
AC_SEARCH_LIBS(SSL_new, ssleay32 ssl, [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])])
10351035
fi
10361036
AC_CHECK_FUNCS([SSL_get_current_compression])
10371037
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
@@ -222,13 +222,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo)
222222
case 0:
223223
break;
224224
case 1:
225-
res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
225+
res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
226226
break;
227227
case 3:
228-
res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
228+
res = px_get_random_bytes(s2k->salt, PGP_S2K_SALT);
229229
if (res < 0)
230230
break;
231-
res = px_get_pseudo_random_bytes(&tmp, 1);
231+
res = px_get_random_bytes(&tmp, 1);
232232
if (res < 0)
233233
break;
234234
s2k->iter = decide_count(tmp);

0 commit comments

Comments
 (0)