From 970378c557412710c01f3100d6f8ffb380e853a3 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 5 Feb 2015 09:13:57 +0100 Subject: libtls: Don't send TLS close notifies in EAP after application succeeds With the introduction of PT-TLS, we started sending TLS close notifies after the application layer completes (7bbf7aa9). While this makes sense for TCP based transports, it is not required in EAP methods. In EAP, handshake completion can be directly signaled using the outer EAP-SUCCESS message. This also saves one round-trip in the EAP exchange. Windows 7/8 does not seem to like TLS close notifies at all in EAP, and either stalls (EAP-TTLS) or disconnects (PEAP). Fixes #556. --- src/libtls/tls_fragmentation.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'src/libtls/tls_fragmentation.c') diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c index 6e4347e3c..a97ca1eaa 100644 --- a/src/libtls/tls_fragmentation.c +++ b/src/libtls/tls_fragmentation.c @@ -96,8 +96,31 @@ struct private_tls_fragmentation_t { * Upper layer application data protocol */ tls_application_t *application; + + /** + * Type of context this TLS instance runs in + */ + tls_purpose_t purpose; }; +/** + * Check if we should send a close notify once the application finishes + */ +static bool send_close_notify(private_tls_fragmentation_t *this) +{ + switch (this->purpose) + { + case TLS_PURPOSE_EAP_TLS: + case TLS_PURPOSE_EAP_TTLS: + case TLS_PURPOSE_EAP_PEAP: + /* not for TLS-in-EAP, as we indicate completion with EAP-SUCCCESS. + * Windows does not like close notifies, and hangs/disconnects. */ + return FALSE; + default: + return TRUE; + } +} + /** * Process a TLS alert */ @@ -223,6 +246,10 @@ static status_t process_application(private_tls_fragmentation_t *this, continue; case SUCCESS: this->application_finished = TRUE; + if (!send_close_notify(this)) + { + return SUCCESS; + } /* FALL */ case FAILED: default: @@ -368,6 +395,10 @@ static status_t build_application(private_tls_fragmentation_t *this) break; case SUCCESS: this->application_finished = TRUE; + if (!send_close_notify(this)) + { + break; + } /* FALL */ case FAILED: default: @@ -463,7 +494,8 @@ METHOD(tls_fragmentation_t, destroy, void, * See header */ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake, - tls_alert_t *alert, tls_application_t *application) + tls_alert_t *alert, tls_application_t *application, + tls_purpose_t purpose) { private_tls_fragmentation_t *this; @@ -478,6 +510,7 @@ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake, .alert = alert, .state = ALERT_NONE, .application = application, + .purpose = purpose, ); return &this->public; -- cgit v1.2.3