added generic TLS application data handler and specific EAP-TTLS instantiation

This commit is contained in:
Andreas Steffen
2010-08-12 23:58:54 +02:00
parent 123a84d3db
commit 1327839da8
14 changed files with 335 additions and 33 deletions
+75 -21
View File
@@ -55,6 +55,11 @@ struct private_tls_fragmentation_t {
* Handshake output buffer
*/
chunk_t output;
/**
* Upper layer application data protocol
*/
tls_application_t *application;
};
/**
@@ -133,6 +138,33 @@ static status_t process_handshake(private_tls_fragmentation_t *this,
return NEED_MORE;
}
/**
* Process TLS application data
*/
static status_t process_application(private_tls_fragmentation_t *this,
tls_reader_t *reader)
{
while (reader->remaining(reader))
{
u_int32_t len;
chunk_t data;
if (reader->remaining(reader) > MAX_TLS_FRAGMENT_LEN)
{
DBG1(DBG_IKE, "TLS fragment has invalid length");
return FAILED;
}
len = reader->remaining(reader);
if (!reader->read_data(reader, len, &data))
{
return FAILED;
}
DBG1(DBG_IKE, "received TLS application data: %B", &data);
}
return NEED_MORE;
}
METHOD(tls_fragmentation_t, process, status_t,
private_tls_fragmentation_t *this, tls_content_type_t type, chunk_t data)
{
@@ -158,8 +190,7 @@ METHOD(tls_fragmentation_t, process, status_t,
status = process_handshake(this, reader);
break;
case TLS_APPLICATION_DATA:
/* skip application data */
status = NEED_MORE;
status = process_application(this, reader);
break;
default:
DBG1(DBG_IKE, "received unknown TLS content type %d, ignored", type);
@@ -175,7 +206,7 @@ METHOD(tls_fragmentation_t, build, status_t,
{
tls_handshake_type_t hs_type;
tls_writer_t *writer, *msg;
status_t status;
status_t status = INVALID_STATE;
if (this->handshake->cipherspec_changed(this->handshake))
{
@@ -187,27 +218,47 @@ METHOD(tls_fragmentation_t, build, status_t,
if (!this->output.len)
{
msg = tls_writer_create(64);
do
if (this->handshake->finished(this->handshake))
{
writer = tls_writer_create(64);
status = this->handshake->build(this->handshake, &hs_type, writer);
switch (status)
if (this->application)
{
case NEED_MORE:
DBG2(DBG_IKE, "sending TLS %N message",
tls_handshake_type_names, hs_type);
msg->write_uint8(msg, hs_type);
msg->write_data24(msg, writer->get_buf(writer));
break;
case INVALID_STATE:
status = this->application->build(this->application, msg);
if (status == INVALID_STATE)
{
this->output = chunk_clone(msg->get_buf(msg));
break;
default:
break;
if (this->output.len)
{
DBG2(DBG_IKE, "sending TLS application data: %B",
&this->output);
}
}
}
writer->destroy(writer);
}
while (status == NEED_MORE);
else
{
do
{
writer = tls_writer_create(64);
status = this->handshake->build(this->handshake, &hs_type, writer);
switch (status)
{
case NEED_MORE:
DBG2(DBG_IKE, "sending TLS %N message",
tls_handshake_type_names, hs_type);
msg->write_uint8(msg, hs_type);
msg->write_data24(msg, writer->get_buf(writer));
break;
case INVALID_STATE:
this->output = chunk_clone(msg->get_buf(msg));
break;
default:
break;
}
writer->destroy(writer);
}
while (status == NEED_MORE);
}
msg->destroy(msg);
if (status != INVALID_STATE)
@@ -218,7 +269,8 @@ METHOD(tls_fragmentation_t, build, status_t,
if (this->output.len)
{
*type = TLS_HANDSHAKE;
*type = this->handshake->finished(this->handshake) ?
TLS_APPLICATION_DATA : TLS_HANDSHAKE;
if (this->output.len <= MAX_TLS_FRAGMENT_LEN)
{
*data = this->output;
@@ -243,7 +295,8 @@ METHOD(tls_fragmentation_t, destroy, void,
/**
* See header
*/
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake)
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
tls_application_t *application)
{
private_tls_fragmentation_t *this;
@@ -254,6 +307,7 @@ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake)
.destroy = _destroy,
},
.handshake = handshake,
.application = application,
);
return &this->public;