From 6b5f0458fe0c935016c5b83e8f42e2ee89313bdb Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 8 Dec 2009 19:06:09 +0000 Subject: [PATCH] Send no_renegotiation alert as required by spec. --- CHANGES | 11 +++++++++++ ssl/s3_pkt.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 427444a9ce..e1d190e378 100644 --- a/CHANGES +++ b/CHANGES @@ -828,6 +828,17 @@ Changes between 0.9.8l (?) and 0.9.8m (?) [xx XXX xxxx] + *) If client attempts to renegotiate and doesn't support RI respond with + a no_renegotiation alert as required by draft-ietf-tls-renegotiation. + Some renegotiating TLS clients will continue a connection gracefully + when they receive the alert. Unfortunately OpenSSL mishandled + this alert and would hang waiting for a server hello which it will never + receive. Now we treat a received no_renegotiation alert as a fatal + error. This is because applications requesting a renegotiation might well + expect it to succeed and would have no code in place to handle the server + denying it so the only safe thing to do is to terminate the connection. + [Steve Henson] + *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if peer supports secure renegotiation and 0 otherwise. Print out peer renegotiation support in s_client/s_server. diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index febc2860e1..32a8b55112 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -1120,7 +1120,25 @@ start: * now try again to obtain the (application) data we were asked for */ goto start; } - + /* If we are a server and get a client hello when renegotiation isn't + * allowed send back a no renegotiation alert and carry on. + * WARNING: experimental code, needs reviewing (steve) + */ + if (s->server && + SSL_is_init_finished(s) && + !s->s3->send_connection_binding && + (s->version > SSL3_VERSION) && + (s->s3->handshake_fragment_len >= 4) && + (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && + (s->session != NULL) && (s->session->cipher != NULL) && + !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) + + { + /*s->s3->handshake_fragment_len = 0;*/ + rr->length = 0; + ssl3_send_alert(s,SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); + goto start; + } if (s->s3->alert_fragment_len >= 2) { int alert_level = s->s3->alert_fragment[0]; @@ -1150,6 +1168,21 @@ start: s->shutdown |= SSL_RECEIVED_SHUTDOWN; return(0); } + /* This is a warning but we receive it if we requested + * renegotiation and the peer denied it. Terminate with + * a fatal alert because if application tried to + * renegotiatie it presumably had a good reason and + * expects it to succeed. + * + * In future we might have a renegotiation where we + * don't care if the peer refused it where we carry on. + */ + else if (alert_descr == SSL_AD_NO_RENEGOTIATION) + { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION); + goto f_err; + } } else if (alert_level == 2) /* fatal */ { -- 2.34.1