summaryrefslogtreecommitdiff
path: root/src/libtls/tls_fragmentation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libtls/tls_fragmentation.c')
-rw-r--r--src/libtls/tls_fragmentation.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c
index 62e36aaec..6e4347e3c 100644
--- a/src/libtls/tls_fragmentation.c
+++ b/src/libtls/tls_fragmentation.c
@@ -16,7 +16,12 @@
#include "tls_fragmentation.h"
#include <bio/bio_reader.h>
-#include <debug.h>
+#include <utils/debug.h>
+
+/**
+ * Maximum size of a TLS handshake message we accept
+ */
+#define TLS_MAX_HANDSHAKE_LEN 65536
typedef struct private_tls_fragmentation_t private_tls_fragmentation_t;
@@ -94,16 +99,6 @@ struct private_tls_fragmentation_t {
};
/**
- * Maximum size of a TLS fragment
- */
-#define MAX_TLS_FRAGMENT_LEN 16384
-
-/**
- * Maximum size of a TLS handshake message we accept
- */
-#define MAX_TLS_HANDSHAKE_LEN 65536
-
-/**
* Process a TLS alert
*/
static status_t process_alert(private_tls_fragmentation_t *this,
@@ -134,7 +129,7 @@ static status_t process_handshake(private_tls_fragmentation_t *this,
status_t status;
chunk_t data;
- if (reader->remaining(reader) > MAX_TLS_FRAGMENT_LEN)
+ if (reader->remaining(reader) > TLS_MAX_FRAGMENT_LEN)
{
DBG1(DBG_TLS, "TLS fragment has invalid length");
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
@@ -151,7 +146,7 @@ static status_t process_handshake(private_tls_fragmentation_t *this,
return NEED_MORE;
}
this->type = type;
- if (len > MAX_TLS_HANDSHAKE_LEN)
+ if (len > TLS_MAX_HANDSHAKE_LEN)
{
DBG1(DBG_TLS, "TLS handshake exceeds maximum length");
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
@@ -202,12 +197,18 @@ static status_t process_handshake(private_tls_fragmentation_t *this,
static status_t process_application(private_tls_fragmentation_t *this,
bio_reader_t *reader)
{
+ if (!this->handshake->finished(this->handshake))
+ {
+ DBG1(DBG_TLS, "received TLS application data, "
+ "but handshake not finished");
+ return FAILED;
+ }
while (reader->remaining(reader))
{
status_t status;
chunk_t data;
- if (reader->remaining(reader) > MAX_TLS_FRAGMENT_LEN)
+ if (reader->remaining(reader) > TLS_MAX_FRAGMENT_LEN)
{
DBG1(DBG_TLS, "TLS fragment has invalid length");
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
@@ -222,7 +223,7 @@ static status_t process_application(private_tls_fragmentation_t *this,
continue;
case SUCCESS:
this->application_finished = TRUE;
- return SUCCESS;
+ /* FALL */
case FAILED:
default:
this->alert->add(this->alert, TLS_FATAL, TLS_CLOSE_NOTIFY);
@@ -367,7 +368,7 @@ static status_t build_application(private_tls_fragmentation_t *this)
break;
case SUCCESS:
this->application_finished = TRUE;
- break;
+ /* FALL */
case FAILED:
default:
this->alert->add(this->alert, TLS_FATAL, TLS_CLOSE_NOTIFY);
@@ -390,6 +391,10 @@ METHOD(tls_fragmentation_t, build, status_t,
this->state = ALERT_SENT;
return INVALID_STATE;
case ALERT_SENT:
+ if (this->application_finished)
+ {
+ return SUCCESS;
+ }
return FAILED;
case ALERT_NONE:
break;
@@ -427,14 +432,14 @@ METHOD(tls_fragmentation_t, build, status_t,
if (this->output.len)
{
*type = this->output_type;
- if (this->output.len <= MAX_TLS_FRAGMENT_LEN)
+ if (this->output.len <= TLS_MAX_FRAGMENT_LEN)
{
*data = this->output;
this->output = chunk_empty;
return NEED_MORE;
}
- *data = chunk_create(this->output.ptr, MAX_TLS_FRAGMENT_LEN);
- this->output = chunk_clone(chunk_skip(this->output, MAX_TLS_FRAGMENT_LEN));
+ *data = chunk_create(this->output.ptr, TLS_MAX_FRAGMENT_LEN);
+ this->output = chunk_clone(chunk_skip(this->output, TLS_MAX_FRAGMENT_LEN));
return NEED_MORE;
}
return status;