From: Nikos Mavrogiannopoulos Date: Fri, 22 Jan 2010 21:21:16 +0000 (+0100) Subject: Revert "Always allow initial negotiation. Disable subsequent unsafe renegotiations." X-Git-Tag: gnutls_2_9_10~150 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2a10542bf8f7cfbd5e6a4b17c8d502133da93fc5;p=thirdparty%2Fgnutls.git Revert "Always allow initial negotiation. Disable subsequent unsafe renegotiations." This reverts commit 1e4981cfbec360a19cfb7470ce96093aaa95b32e. Ah, this was to twart the attack (description by Daniel Kahn Gilmor): The problem, as i understand it, is that the client is incapable of telling whether the plaintext prefix injection attack has already happened. I don't think disabling renegotiation for the session resolves the problem. For a server which does not announce and enforce safe renegotiation, what the client sees as an initial connection may unknowingly actually be renegotiating an existing session that was started by an attacker. The concern isn't that the (legitimate) client will have their session re-negotiated by an attacker; it's that the MITM attacker can trick the server into viewing the client's initial authentication as a re-negotiation of a TLS session already underway. for servers which do odd things like apply the credentials of the post-renegotiation client to the traffic that happened before the renegotiation (e.g. HTTPS, with client-side certificates required only for certain subdirectories), a safe-renegotiation-aware client *should* refuse to connect to servers which do not announce safe renegotiation if they want to resist this attack. --- diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index fc9de23d71..c0bf83b9b6 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -2428,7 +2428,9 @@ _gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen) return GNUTLS_E_SAFE_RENEGOTIATION_FAILED; } - if (session->internals.initial_negotiation_completed != 0) + /* Clients can't tell if it's an initial negotiation */ + if (session->internals.initial_negotiation_completed || + session->security_parameters.entity == GNUTLS_CLIENT) { if (session->internals.priorities.unsafe_renegotiation != 0) {