Well, the discussion about SSL a bit back perked my interest and I did

some reading on the subject.

1) PostgreSQL uses ephemeral keying, for its connections (good thing)

2) PostgreSQL doesn't set the cipher list that it allows (bad thing,
   fixed)

3) PostgreSQL's renegotiation code wasn't text book correct (could be
   bad, fixed)

4) The rate of renegotiating was insanely low (as Tom pointed out, set
   to a more reasonable level)

I haven't checked around much to see if there are any other SSL bits
that need some review, but I'm doing some OpenSSL work right now
and'll send patches for improvements along the way (if I find them).
At the very least, the changes in this patch will make security folks
happier for sure.  The constant renegotiation of sessions was likely a
boon to systems that had bad entropy gathering means (read: Slowaris
/dev/rand|/dev/urand != ANDIrand).  The new limit for renegotiations
is 512MB which should be much more reasonable.

Sean Chittenden
This commit is contained in:
Bruce Momjian 2003-06-11 15:05:50 +00:00
parent 535756649f
commit 17386ac453
1 changed files with 14 additions and 4 deletions

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/be-secure.c,v 1.33 2003/05/27 17:49:46 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/be-secure.c,v 1.34 2003/06/11 15:05:50 momjian Exp $
*
* Since the server static private key ($DataDir/server.key)
* will normally be stored unencrypted so that the database
@ -124,7 +124,7 @@ static const char *SSLerrmessage(void);
* How much data can be sent across a secure connection
* (total in both directions) before we require renegotiation.
*/
#define RENEGOTIATION_LIMIT (64 * 1024)
#define RENEGOTIATION_LIMIT (512 * 1024 * 1024)
#define CA_PATH NULL
static SSL_CTX *SSL_context = NULL;
#endif
@ -320,8 +320,11 @@ secure_write(Port *port, void *ptr, size_t len)
elog(COMMERROR, "SSL renegotiation failure");
if (SSL_do_handshake(port->ssl) <= 0)
elog(COMMERROR, "SSL renegotiation failure");
port->ssl->state = SSL_ST_ACCEPT;
if (SSL_do_handshake(port->ssl) <= 0)
if (port->ssl->state != SSL_ST_OK)
elog(COMMERROR, "SSL failed to send renegotiation request");
port->ssl->state |= SSL_ST_ACCEPT;
SSL_do_handshake(port->ssl);
if (port->ssl->state != SSL_ST_OK)
elog(COMMERROR, "SSL renegotiation failure");
port->count = 0;
}
@ -639,6 +642,13 @@ initialize_SSL(void)
SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);
/* setup the allowed cipher list */
if (SSL_CTX_set_cipher_list(SSL_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGH") != 1)
{
postmaster_error("unable to set the cipher list (no valid ciphers available)");
ExitPostmaster(1);
}
/* accept client certificates, but don't require them. */
snprintf(fnbuf, sizeof fnbuf, "%s/root.crt", DataDir);
if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, CA_PATH))