mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Support OpenSSL 1.1.0 in 9.3 and 9.2.
This commit back-patches the equivalent of the 9.5-branch commitse2838c580
and48e5ba61e
, 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:
@ -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);
|
||||
|
Reference in New Issue
Block a user