From: Arran Cudbard-Bell Date: Sun, 20 Jan 2019 10:05:52 +0000 (+0700) Subject: Reset SSL * if we send an alert X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8ddd2b42a50e0bc6eba258fff00201d27764b181;p=thirdparty%2Ffreeradius-server.git Reset SSL * if we send an alert This resets the TLS state machine, which may allow OpenSSL to process a new TLS session --- diff --git a/src/lib/tls/session.c b/src/lib/tls/session.c index 2d8e073e4da..376cf710e5a 100644 --- a/src/lib/tls/session.c +++ b/src/lib/tls/session.c @@ -1159,7 +1159,7 @@ int tls_session_send(REQUEST *request, tls_session_t *session) /** Instruct tls_session_handshake to create a synthesised TLS alert record and send it to the peer * */ -int tls_session_handshake_alert(UNUSED REQUEST *request, tls_session_t *session, uint8_t level, uint8_t description) +int tls_session_alert(UNUSED REQUEST *request, tls_session_t *session, uint8_t level, uint8_t description) { if (session->alerts_sent > 3) return -1; /* Some kind of sate machine brokenness */ @@ -1175,6 +1175,35 @@ int tls_session_handshake_alert(UNUSED REQUEST *request, tls_session_t *session, return 0; } +static void tls_session_alert_send(REQUEST *request, tls_session_t *session) +{ + /* + * Update our internal view of the session + */ + session->info.origin = TLS_INFO_ORIGIN_RECORD_SENT; + session->info.content_type = SSL3_RT_ALERT; + session->info.alert_level = session->pending_alert_level; + session->info.alert_description = session->pending_alert_description; + + session->dirty_out.data[0] = session->info.content_type; + session->dirty_out.data[1] = 3; + session->dirty_out.data[2] = 1; + session->dirty_out.data[3] = 0; + session->dirty_out.data[4] = 2; + session->dirty_out.data[5] = session->pending_alert_level; + session->dirty_out.data[6] = session->pending_alert_description; + + session->dirty_out.used = 7; + + session->pending_alert = false; + session->alerts_sent++; + + SSL_clear(session->ssl); /* Reset the SSL *, to allow the client to restart the session */ + + session_msg_log(request, session); + +} + /** Continue a TLS handshake * * Advance the TLS handshake by feeding OpenSSL data from dirty_in, @@ -1383,35 +1412,7 @@ int tls_session_handshake(REQUEST *request, tls_session_t *session) * do this, and we need to send alerts as part of * RFC 5216, so this is our only option. */ - if (session->pending_alert) { - /* - * FIXME RFC 4851 section 3.6.1 - peer might ACK alert and include a restarted ClientHello - * which eap_tls_session_status() will fail on - */ - - /* - * Update our internal view of the session - */ - session->info.origin = TLS_INFO_ORIGIN_RECORD_SENT; - session->info.content_type = SSL3_RT_ALERT; - session->info.alert_level = session->pending_alert_level; - session->info.alert_description = session->pending_alert_description; - - session->dirty_out.data[0] = session->info.content_type; - session->dirty_out.data[1] = 3; - session->dirty_out.data[2] = 1; - session->dirty_out.data[3] = 0; - session->dirty_out.data[4] = 2; - session->dirty_out.data[5] = session->pending_alert_level; - session->dirty_out.data[6] = session->pending_alert_description; - - session->dirty_out.used = 7; - - session->pending_alert = false; - session->alerts_sent++; - - session_msg_log(request, session); - } + if (session->pending_alert) tls_session_alert_send(request, session); /* We are done with dirty_in, reinitialize it */ record_init(&session->dirty_in); diff --git a/src/modules/rlm_eap/types/rlm_eap_fast/rlm_eap_fast.c b/src/modules/rlm_eap/types/rlm_eap_fast/rlm_eap_fast.c index 7690b2d6cdb..be1fc05cf3f 100644 --- a/src/modules/rlm_eap/types/rlm_eap_fast/rlm_eap_fast.c +++ b/src/modules/rlm_eap/types/rlm_eap_fast/rlm_eap_fast.c @@ -337,7 +337,7 @@ static int _session_ticket(SSL *s, uint8_t const *data, int len, void *arg) errmsg = "PAC is not of type Opaque"; error: RERROR("%s, sending alert to client", errmsg); - if (tls_session_handshake_alert(request, tls_session, SSL3_AL_FATAL, SSL_AD_BAD_CERTIFICATE)) { + if (tls_session_alert(request, tls_session, SSL3_AL_FATAL, SSL_AD_BAD_CERTIFICATE)) { RERROR("too many alerts"); return 0; }