From: | Alvaro Herrera <alvherre(at)2ndquadrant(dot)com> |
---|---|
To: | Pg Hackers <pgsql-hackers(at)postgresql(dot)org> |
Cc: | Sean Chittenden <sean(at)chittenden(dot)org> |
Subject: | SSL renegotiation |
Date: | 2013-07-10 21:20:17 |
Message-ID: | 20130710212017.GB4941@eldon.alvh.no-ip.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-committers pgsql-hackers |
Hi,
I'm having a look at the SSL support code, because one of our customers
reported it behaves unstably when the network is unreliable. I have yet
to reproduce the exact problem they're having, but while reading the
code I notice this in be-secure.c:secure_write() :
if (ssl_renegotiation_limit && port->count > ssl_renegotiation_limit * 1024L)
{
SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
sizeof(SSL_context));
if (SSL_renegotiate(port->ssl) <= 0)
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL renegotiation failure")));
if (SSL_do_handshake(port->ssl) <= 0)
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL renegotiation failure")));
if (port->ssl->state != SSL_ST_OK)
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL failed to send renegotiation request")));
port->ssl->state |= SSL_ST_ACCEPT;
SSL_do_handshake(port->ssl);
if (port->ssl->state != SSL_ST_OK)
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL renegotiation failure")));
port->count = 0;
}
I call your attention to the fact that we're calling SSL_do_handshake
twice here; and what's more, we're messing with the internal
port->ssl->state variable by setting the SSL_ST_ACCEPT bit. According
to the commit message that introduces this[1], this is "text book
correct", but I'm unable to find the text book that specifies that this
is correct. Is it? I have gone through the OpenSSL documentation and
can find not a single bit on this; and I have also gone through the
OpenSSL mailing list archives and as far as I can tell they say you have
to call SSL_renegotiate() and then SSL_do_handshake() once, and that's
it. (You can call SSL_renegotiate_pending() afterwards to verify that
the renegotiation completed successfully, which is something we don't
do.)
I have found in our archives several reports of people that get "SSL
renegotiation failed" error messages in the log, and no explanation has
ever been found. I instrumented that block, and I have observed that
after the second handshake call, ssl->state is 0x2111, 0x21c0, 0x21a0
and other values; never SSL_ST_OK. (0x2000 is SSL_ST_ACCEPT which is
the bit we added; SSL_ST_OK is 0x03). If I remove the second
SSL_do_handshake() call and the changes to port->ssl->state, everything
appears to work perfectly well and there's no extra log spam (and
ssl->state is SSL_ST_OK by the time things are finished). So apparently
renegotiation is not actually failing, but we're just adding a confusing
error message for no apparent reason.
Thoughts?
I have still to find where the actual problems are happening in
unreliable networks ...
[1] commit 17386ac45345fe38a10caec9d6e63afa3ce31bb9
Author: Bruce Momjian <bruce(at)momjian(dot)us>
Date: Wed Jun 11 15:05:50 2003 +0000
patch by Sean Chittenden (in CC), posted as [2]
[2] http://www.postgresql.org/message-id/20030419190821.GQ79923@perrin.int.nxad.com
--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
From | Date | Subject | |
---|---|---|---|
Next Message | Alvaro Herrera | 2013-07-10 22:34:44 | Re: SSL renegotiation |
Previous Message | Peter Eisentraut | 2013-07-10 01:13:17 | pgsql: Add coverage/ to .gitignore |
From | Date | Subject | |
---|---|---|---|
Next Message | Andres Freund | 2013-07-10 21:33:18 | Re: changeset generation v5-01 - Patches & git tree |
Previous Message | Kevin Grittner | 2013-07-10 19:21:23 | Re: changeset generation v5-01 - Patches & git tree |