Send no_renegotiation alert as required by spec.

This commit is contained in:
Dr. Stephen Henson 2009-12-08 19:06:09 +00:00
parent b52a2738d4
commit 6b5f0458fe
2 changed files with 45 additions and 1 deletions

11
CHANGES
View file

@ -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.

View file

@ -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 */
{