diff options
author | Martin Willi <martin@revosec.ch> | 2010-08-24 08:40:28 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-08-24 08:45:49 +0200 |
commit | c5142f110ec8376b8e5cef9bb92fe4a375e4622e (patch) | |
tree | 8c9ef7c4aaf632517d848584c78bc0966a093078 | |
parent | 1475800080d605abb1995bfba1ce8ca98637917c (diff) | |
download | strongswan-c5142f110ec8376b8e5cef9bb92fe4a375e4622e.tar.bz2 strongswan-c5142f110ec8376b8e5cef9bb92fe4a375e4622e.tar.xz |
Check if the application layer has completed successfully
-rw-r--r-- | src/libtls/tls.c | 10 | ||||
-rw-r--r-- | src/libtls/tls_fragmentation.c | 61 | ||||
-rw-r--r-- | src/libtls/tls_fragmentation.h | 7 |
3 files changed, 62 insertions, 16 deletions
diff --git a/src/libtls/tls.c b/src/libtls/tls.c index 1f30f5a4e..142897e59 100644 --- a/src/libtls/tls.c +++ b/src/libtls/tls.c @@ -243,7 +243,15 @@ METHOD(tls_t, get_purpose, tls_purpose_t, METHOD(tls_t, is_complete, bool, private_tls_t *this) { - return this->crypto->get_eap_msk(this->crypto).len != 0; + if (this->handshake->finished(this->handshake)) + { + if (!this->application) + { + return TRUE; + } + return this->fragmentation->application_finished(this->fragmentation); + } + return FALSE; } METHOD(tls_t, get_eap_msk, chunk_t, diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c index d69ef3901..b941c97a5 100644 --- a/src/libtls/tls_fragmentation.c +++ b/src/libtls/tls_fragmentation.c @@ -59,6 +59,11 @@ struct private_tls_fragmentation_t { alert_state_t state; /** + * Did the application layer complete successfully? + */ + bool application_finished; + + /** * Handshake input buffer */ chunk_t input; @@ -200,10 +205,17 @@ static status_t process_application(private_tls_fragmentation_t *this, return NEED_MORE; } status = this->application->process(this->application, reader); - if (status != NEED_MORE) + switch (status) { - this->alert->add(this->alert, TLS_FATAL, TLS_CLOSE_NOTIFY); - return NEED_MORE; + case NEED_MORE: + continue; + case SUCCESS: + this->application_finished = TRUE; + /* FALL */ + case FAILED: + default: + this->alert->add(this->alert, TLS_FATAL, TLS_CLOSE_NOTIFY); + return NEED_MORE; } } return NEED_MORE; @@ -315,21 +327,33 @@ METHOD(tls_fragmentation_t, build, status_t, { if (this->application) { - status = this->application->build(this->application, msg); - if (status == INVALID_STATE) + while (TRUE) { - *type = TLS_APPLICATION_DATA; - this->output = chunk_clone(msg->get_buf(msg)); - } - else if (status != NEED_MORE) - { - this->alert->add(this->alert, TLS_FATAL, TLS_CLOSE_NOTIFY); - if (check_alerts(this, data)) + status = this->application->build(this->application, msg); + switch (status) { - this->state = ALERT_SENDING; - *type = TLS_ALERT; - return NEED_MORE; + case NEED_MORE: + continue; + case INVALID_STATE: + *type = TLS_APPLICATION_DATA; + this->output = chunk_clone(msg->get_buf(msg)); + break; + case SUCCESS: + this->application_finished = TRUE; + /* FALL */ + case FAILED: + default: + this->alert->add(this->alert, TLS_FATAL, + TLS_CLOSE_NOTIFY); + if (check_alerts(this, data)) + { + this->state = ALERT_SENDING; + *type = TLS_ALERT; + msg->destroy(msg); + return NEED_MORE; + } } + break; } } } @@ -382,6 +406,12 @@ METHOD(tls_fragmentation_t, build, status_t, return status; } +METHOD(tls_fragmentation_t, application_finished, bool, + private_tls_fragmentation_t *this) +{ + return this->application_finished; +} + METHOD(tls_fragmentation_t, destroy, void, private_tls_fragmentation_t *this) { @@ -402,6 +432,7 @@ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake, .public = { .process = _process, .build = _build, + .application_finished = _application_finished, .destroy = _destroy, }, .handshake = handshake, diff --git a/src/libtls/tls_fragmentation.h b/src/libtls/tls_fragmentation.h index 699244595..d80278916 100644 --- a/src/libtls/tls_fragmentation.h +++ b/src/libtls/tls_fragmentation.h @@ -62,6 +62,13 @@ struct tls_fragmentation_t { tls_content_type_t *type, chunk_t *data); /** + * Has the application layer finished (returned SUCCESS)?. + * + * @return TRUE if application layer finished + */ + bool (*application_finished)(tls_fragmentation_t *this); + + /** * Destroy a tls_fragmentation_t. */ void (*destroy)(tls_fragmentation_t *this); |