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

Commit 9e083fd

Browse files
committed
Replace PostmasterRandom() with a stronger way of generating randomness.
This adds a new routine, pg_strong_random() for generating random bytes, for use in both frontend and backend. At the moment, it's only used in the backend, but the upcoming SCRAM authentication patches need strong random numbers in libpq as well. pg_strong_random() is based on, and replaces, the existing implementation in pgcrypto. It can acquire strong random numbers from a number of sources, depending on what's available: - OpenSSL RAND_bytes(), if built with OpenSSL - On Windows, the native cryptographic functions are used - /dev/urandom - /dev/random Original patch by Magnus Hagander, with further work by Michael Paquier and me. Discussion: <CAB7nPqRy3krN8quR9XujMVVHYtXJ0_60nqgVc6oUk8ygyVkZsA@mail.gmail.com>
1 parent 5dfc198 commit 9e083fd

File tree

9 files changed

+244
-384
lines changed

9 files changed

+244
-384
lines changed

contrib/pgcrypto/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# contrib/pgcrypto/Makefile
22

33
INT_SRCS = md5.c sha1.c sha2.c internal.c internal-sha2.c blf.c rijndael.c \
4-
fortuna.c random.c pgp-mpi-internal.c imath.c
4+
fortuna.c pgp-mpi-internal.c imath.c
55
INT_TESTS = sha2
66

77
OSSL_SRCS = openssl.c pgp-mpi-openssl.c

contrib/pgcrypto/internal.c

+24-16
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,6 @@ static time_t check_time = 0;
626626
static void
627627
system_reseed(void)
628628
{
629-
uint8 buf[1024];
630-
int n;
631629
time_t t;
632630
int skip = 1;
633631

@@ -642,24 +640,34 @@ system_reseed(void)
642640
else if (check_time == 0 ||
643641
(t - check_time) > SYSTEM_RESEED_CHECK_TIME)
644642
{
643+
uint8 buf;
644+
645645
check_time = t;
646646

647647
/* roll dice */
648-
px_get_random_bytes(buf, 1);
649-
skip = buf[0] >= SYSTEM_RESEED_CHANCE;
650-
}
651-
/* clear 1 byte */
652-
px_memset(buf, 0, sizeof(buf));
653-
654-
if (skip)
655-
return;
656-
657-
n = px_acquire_system_randomness(buf);
658-
if (n > 0)
659-
fortuna_add_entropy(buf, n);
648+
px_get_random_bytes(&buf, 1);
649+
skip = (buf >= SYSTEM_RESEED_CHANCE);
660650

661-
seed_time = t;
662-
px_memset(buf, 0, sizeof(buf));
651+
/* clear 1 byte */
652+
px_memset(&buf, 0, sizeof(buf));
653+
}
654+
if (!skip)
655+
{
656+
/*
657+
* fortuna_add_entropy passes the input to SHA-256, so there's no
658+
* point in giving it more than 256 bits of input to begin with.
659+
*/
660+
uint8 buf[32];
661+
662+
if (!pg_strong_random(buf, sizeof(buf)))
663+
ereport(ERROR,
664+
(errcode(ERRCODE_INTERNAL_ERROR),
665+
errmsg("could not acquire random data")));
666+
fortuna_add_entropy(buf, sizeof(buf));
667+
668+
seed_time = t;
669+
px_memset(buf, 0, sizeof(buf));
670+
}
663671
}
664672

665673
int

contrib/pgcrypto/random.c

-247
This file was deleted.

src/backend/libpq/auth.c

+23-4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ static void auth_failed(Port *port, int status, char *logdetail);
4545
static char *recv_password_packet(Port *port);
4646
static int recv_and_check_password_packet(Port *port, char **logdetail);
4747

48+
/*----------------------------------------------------------------
49+
* MD5 authentication
50+
*----------------------------------------------------------------
51+
*/
52+
static int CheckMD5Auth(Port *port, char **logdetail);
53+
4854

4955
/*----------------------------------------------------------------
5056
* Ident authentication
@@ -535,9 +541,7 @@ ClientAuthentication(Port *port)
535541
ereport(FATAL,
536542
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
537543
errmsg("MD5 authentication is not supported when \"db_user_namespace\" is enabled")));
538-
/* include the salt to use for computing the response */
539-
sendAuthRequest(port, AUTH_REQ_MD5, port->md5Salt, 4);
540-
status = recv_and_check_password_packet(port, &logdetail);
544+
status = CheckMD5Auth(port, &logdetail);
541545
break;
542546

543547
case uaPassword:
@@ -692,10 +696,25 @@ recv_password_packet(Port *port)
692696

693697

694698
/*----------------------------------------------------------------
695-
* MD5 authentication
699+
* MD5 and password authentication
696700
*----------------------------------------------------------------
697701
*/
698702

703+
static int
704+
CheckMD5Auth(Port *port, char **logdetail)
705+
{
706+
/* include the salt to use for computing the response */
707+
if (!pg_strong_random(port->md5Salt, sizeof(port->md5Salt)))
708+
{
709+
*logdetail = psprintf(_("Could not generate random salt"));
710+
return STATUS_ERROR;
711+
}
712+
713+
sendAuthRequest(port, AUTH_REQ_MD5, port->md5Salt, 4);
714+
return recv_and_check_password_packet(port, logdetail);
715+
}
716+
717+
699718
/*
700719
* Called when we have sent an authorization request for a password.
701720
* Get the response and check it.

0 commit comments

Comments
 (0)