aboutsummaryrefslogtreecommitdiffstats
path: root/src/libtls
diff options
context:
space:
mode:
Diffstat (limited to 'src/libtls')
-rw-r--r--src/libtls/tls.c2
-rw-r--r--src/libtls/tls_fragmentation.c35
-rw-r--r--src/libtls/tls_fragmentation.h4
3 files changed, 38 insertions, 3 deletions
diff --git a/src/libtls/tls.c b/src/libtls/tls.c
index 6a8d5030c..201612470 100644
--- a/src/libtls/tls.c
+++ b/src/libtls/tls.c
@@ -487,7 +487,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
this->alert, peer, server)->handshake;
}
this->fragmentation = tls_fragmentation_create(this->handshake, this->alert,
- this->application);
+ this->application, purpose);
this->compression = tls_compression_create(this->fragmentation, this->alert);
this->protection = tls_protection_create(this->compression, this->alert);
this->crypto->set_protection(this->crypto, this->protection);
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,9 +96,32 @@ 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
*/
static status_t process_alert(private_tls_fragmentation_t *this,
@@ -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;
diff --git a/src/libtls/tls_fragmentation.h b/src/libtls/tls_fragmentation.h
index f650e7be8..a49f27b20 100644
--- a/src/libtls/tls_fragmentation.h
+++ b/src/libtls/tls_fragmentation.h
@@ -80,9 +80,11 @@ struct tls_fragmentation_t {
* @param handshake upper layer handshake protocol
* @param alert TLS alert handler
* @param application upper layer application data or NULL
+ * @param purpose type of context this TLS stack is running in
* @return TLS fragmentation layer
*/
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);
#endif /** TLS_FRAGMENTATION_H_ @}*/