aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libpttls/pt_tls.c37
-rw-r--r--src/libpttls/pt_tls.h11
-rw-r--r--src/libpttls/pt_tls_client.c70
-rw-r--r--src/libpttls/pt_tls_server.c116
4 files changed, 107 insertions, 127 deletions
diff --git a/src/libpttls/pt_tls.c b/src/libpttls/pt_tls.c
index b59ef7c89..3c1f874d7 100644
--- a/src/libpttls/pt_tls.c
+++ b/src/libpttls/pt_tls.c
@@ -134,31 +134,32 @@ bio_reader_t* pt_tls_read(tls_socket_t *tls, u_int32_t *vendor,
/**
* Prepend a PT-TLS header to a writer, send data, destroy writer
*/
-bool pt_tls_write(tls_socket_t *tls, bio_writer_t *writer,
- pt_tls_message_type_t type, u_int32_t identifier)
+bool pt_tls_write(tls_socket_t *tls, pt_tls_message_type_t type,
+ u_int32_t identifier, chunk_t data)
{
- bio_writer_t *header;
+ bio_writer_t *writer;
+ chunk_t out;
ssize_t len;
- chunk_t data;
- data = writer->get_buf(writer);
len = PT_TLS_HEADER_LEN + data.len;
- header = bio_writer_create(len);
- header->write_uint8(header, 0);
- header->write_uint24(header, 0);
- header->write_uint32(header, type);
- header->write_uint32(header, len);
- header->write_uint32(header, identifier);
-
- header->write_data(header, data);
- writer->destroy(writer);
+ writer = bio_writer_create(len);
+
+ /* write PT-TLS header */
+ writer->write_uint8 (writer, 0);
+ writer->write_uint24(writer, 0);
+ writer->write_uint32(writer, type);
+ writer->write_uint32(writer, len);
+ writer->write_uint32(writer, identifier);
+
+ /* write PT-TLS body */
+ writer->write_data(writer, data);
DBG2(DBG_TNC, "sending PT-TLS message #%d of type '%N' (%d bytes)",
identifier, pt_tls_message_type_names, type, len);
- data = header->get_buf(header);
- len = tls->write(tls, data.ptr, data.len);
- header->destroy(header);
+ out = writer->get_buf(writer);
+ len = tls->write(tls, out.ptr, out.len);
+ writer->destroy(writer);
- return len == data.len;
+ return len == out.len;
}
diff --git a/src/libpttls/pt_tls.h b/src/libpttls/pt_tls.h
index f7ea75b27..dd3d25055 100644
--- a/src/libpttls/pt_tls.h
+++ b/src/libpttls/pt_tls.h
@@ -38,6 +38,11 @@
#define PT_TLS_HEADER_LEN 16
/**
+ * Maximum size of a PT-TLS message
+ */
+#define PT_TLS_MAX_MESSAGE_LEN 8 * TLS_MAX_FRAGMENT_LEN - PT_TLS_HEADER_LEN
+
+/**
* Default PT-TLS port
*/
#define PT_TLS_PORT 271
@@ -107,13 +112,13 @@ bio_reader_t* pt_tls_read(tls_socket_t *tls, u_int32_t *vendor,
* Prepend a PT-TLS header to a writer, send data, destroy writer.
*
* @param tls TLS socket to write to
- * @param writer prepared Message value to write
* @param type Message Type to write
* @param identifier Message Identifier to write
+ * @param data Message value to write
* @return TRUE if data written successfully
*/
-bool pt_tls_write(tls_socket_t *tls, bio_writer_t *writer,
- pt_tls_message_type_t type, u_int32_t identifier);
+bool pt_tls_write(tls_socket_t *tls, pt_tls_message_type_t type,
+ u_int32_t identifier, chunk_t data);
/**
* @}
diff --git a/src/libpttls/pt_tls_client.c b/src/libpttls/pt_tls_client.c
index 6df32356b..01a84cd14 100644
--- a/src/libpttls/pt_tls_client.c
+++ b/src/libpttls/pt_tls_client.c
@@ -102,6 +102,7 @@ static bool negotiate_version(private_pt_tls_client_t *this)
bio_reader_t *reader;
u_int32_t type, vendor, identifier, reserved;
u_int8_t version;
+ bool res;
DBG1(DBG_TNC, "sending offer for PT-TLS version %d", PT_TLS_VERSION);
@@ -110,8 +111,10 @@ static bool negotiate_version(private_pt_tls_client_t *this)
writer->write_uint8(writer, PT_TLS_VERSION);
writer->write_uint8(writer, PT_TLS_VERSION);
writer->write_uint8(writer, PT_TLS_VERSION);
- if (!pt_tls_write(this->tls, writer, PT_TLS_VERSION_REQUEST,
- this->identifier++))
+ res = pt_tls_write(this->tls, PT_TLS_VERSION_REQUEST, this->identifier++,
+ writer->get_buf(writer));
+ writer->destroy(writer);
+ if (!res)
{
return FALSE;
}
@@ -144,6 +147,7 @@ static status_t do_sasl(private_pt_tls_client_t *this, sasl_mechanism_t *sasl)
bio_reader_t *reader;
bio_writer_t *writer;
chunk_t data;
+ bool res;
writer = bio_writer_create(32);
writer->write_data8(writer, chunk_from_str(sasl->get_name(sasl)));
@@ -164,8 +168,10 @@ static status_t do_sasl(private_pt_tls_client_t *this, sasl_mechanism_t *sasl)
writer->destroy(writer);
return FAILED;
}
- if (!pt_tls_write(this->tls, writer, PT_TLS_SASL_MECH_SELECTION,
- this->identifier++))
+ res = pt_tls_write(this->tls, PT_TLS_SASL_MECH_SELECTION,
+ this->identifier++, writer->get_buf(writer));
+ writer->destroy(writer);
+ if (!res)
{
return FAILED;
}
@@ -253,8 +259,10 @@ static status_t do_sasl(private_pt_tls_client_t *this, sasl_mechanism_t *sasl)
writer->destroy(writer);
return FAILED;
}
- if (!pt_tls_write(this->tls, writer, PT_TLS_SASL_AUTH_DATA,
- this->identifier++))
+ res = pt_tls_write(this->tls, PT_TLS_SASL_AUTH_DATA,
+ this->identifier++, writer->get_buf(writer));
+ writer->destroy(writer);
+ if (!res)
{
return FAILED;
}
@@ -351,44 +359,30 @@ static bool assess(private_pt_tls_client_t *this, tls_t *tnccs)
{
while (TRUE)
{
- bio_writer_t *writer;
+ size_t msglen;
+ size_t buflen = PT_TLS_MAX_MESSAGE_LEN;
+ char buf[buflen];
bio_reader_t *reader;
u_int32_t vendor, type, identifier;
chunk_t data;
- writer = bio_writer_create(32);
- while (TRUE)
+ switch (tnccs->build(tnccs, buf, &buflen, &msglen))
{
- char buf[2048];
- size_t buflen, msglen;
-
- buflen = sizeof(buf);
- switch (tnccs->build(tnccs, buf, &buflen, &msglen))
- {
- case SUCCESS:
- writer->destroy(writer);
- return tnccs->is_complete(tnccs);
- case FAILED:
- default:
- writer->destroy(writer);
+ case SUCCESS:
+ return tnccs->is_complete(tnccs);
+ case ALREADY_DONE:
+ data = chunk_create(buf, buflen);
+ if (!pt_tls_write(this->tls, PT_TLS_PB_TNC_BATCH,
+ this->identifier++, data))
+ {
return FALSE;
- case INVALID_STATE:
- writer->destroy(writer);
- break;
- case NEED_MORE:
- writer->write_data(writer, chunk_create(buf, buflen));
- continue;
- case ALREADY_DONE:
- writer->write_data(writer, chunk_create(buf, buflen));
- if (!pt_tls_write(this->tls, writer, PT_TLS_PB_TNC_BATCH,
- this->identifier++))
- {
- return FALSE;
- }
- writer = bio_writer_create(32);
- continue;
- }
- break;
+ }
+ break;
+ case INVALID_STATE:
+ break;
+ case FAILED:
+ default:
+ return FALSE;
}
reader = pt_tls_read(this->tls, &vendor, &type, &identifier);
diff --git a/src/libpttls/pt_tls_server.c b/src/libpttls/pt_tls_server.c
index 32b50739e..69dcdc08b 100644
--- a/src/libpttls/pt_tls_server.c
+++ b/src/libpttls/pt_tls_server.c
@@ -73,6 +73,7 @@ static bool negotiate_version(private_pt_tls_server_t *this)
bio_writer_t *writer;
u_int32_t vendor, type, identifier;
u_int8_t reserved, vmin, vmax, vpref;
+ bool res;
reader = pt_tls_read(this->tls, &vendor, &type, &identifier);
if (!reader)
@@ -100,9 +101,10 @@ static bool negotiate_version(private_pt_tls_server_t *this)
writer = bio_writer_create(4);
writer->write_uint24(writer, 0);
writer->write_uint8(writer, PT_TLS_VERSION);
-
- return pt_tls_write(this->tls, writer, PT_TLS_VERSION_RESPONSE,
- this->identifier++);
+ res = pt_tls_write(this->tls, PT_TLS_VERSION_RESPONSE,
+ this->identifier++, writer->get_buf(writer));
+ writer->destroy(writer);
+ return res;
}
/**
@@ -114,6 +116,7 @@ static status_t process_sasl(private_pt_tls_server_t *this,
bio_writer_t *writer;
identification_t *client;
tnccs_t *tnccs;
+ bool res;
switch (sasl->process(sasl, data))
{
@@ -135,12 +138,10 @@ static status_t process_sasl(private_pt_tls_server_t *this,
}
writer = bio_writer_create(1);
writer->write_uint8(writer, PT_TLS_SASL_RESULT_SUCCESS);
- if (pt_tls_write(this->tls, writer, PT_TLS_SASL_RESULT,
- this->identifier++))
- {
- return SUCCESS;
- }
- return FAILED;
+ res = pt_tls_write(this->tls, PT_TLS_SASL_RESULT,
+ this->identifier++, writer->get_buf(writer));
+ writer->destroy(writer);
+ return res ? SUCCESS : FAILED;
case FAILED:
default:
DBG1(DBG_TNC, "SASL %s authentication failed",
@@ -148,8 +149,8 @@ static status_t process_sasl(private_pt_tls_server_t *this,
writer = bio_writer_create(1);
/* sending abort does not allow the client to retry */
writer->write_uint8(writer, PT_TLS_SASL_RESULT_ABORT);
- pt_tls_write(this->tls, writer, PT_TLS_SASL_RESULT,
- this->identifier++);
+ pt_tls_write(this->tls, PT_TLS_SASL_RESULT,
+ this->identifier++, writer->get_buf(writer));
return FAILED;
}
}
@@ -189,19 +190,15 @@ static status_t write_sasl(private_pt_tls_server_t *this,
{
bio_writer_t *writer;
chunk_t chunk;
+ bool res;
switch (sasl->build(sasl, &chunk))
{
case NEED_MORE:
- writer = bio_writer_create(chunk.len);
- writer->write_data(writer, chunk);
+ res = pt_tls_write(this->tls, PT_TLS_SASL_AUTH_DATA,
+ this->identifier++, chunk);
free(chunk.ptr);
- if (pt_tls_write(this->tls, writer, PT_TLS_SASL_AUTH_DATA,
- this->identifier++))
- {
- return NEED_MORE;
- }
- return FAILED;
+ return res ? NEED_MORE : FAILED;
case SUCCESS:
DBG1(DBG_TNC, "SASL %s authentication successful",
sasl->get_name(sasl));
@@ -209,21 +206,18 @@ static status_t write_sasl(private_pt_tls_server_t *this,
writer->write_uint8(writer, PT_TLS_SASL_RESULT_SUCCESS);
writer->write_data(writer, chunk);
free(chunk.ptr);
- if (pt_tls_write(this->tls, writer, PT_TLS_SASL_RESULT,
- this->identifier++))
- {
- return SUCCESS;
- }
- return FAILED;
+ res = pt_tls_write(this->tls, PT_TLS_SASL_RESULT,
+ this->identifier++, writer->get_buf(writer));
+ writer->destroy(writer);
+ return res ? SUCCESS : FAILED;
case FAILED:
default:
DBG1(DBG_TNC, "SASL %s authentication failed",
sasl->get_name(sasl));
- writer = bio_writer_create(1);
/* sending abort does not allow the client to retry */
- writer->write_uint8(writer, PT_TLS_SASL_RESULT_ABORT);
- pt_tls_write(this->tls, writer, PT_TLS_SASL_RESULT,
- this->identifier++);
+ chunk = chunk_from_chars(PT_TLS_SASL_RESULT_ABORT);
+ pt_tls_write(this->tls, PT_TLS_SASL_RESULT,
+ this->identifier++, chunk);
return FAILED;
}
}
@@ -236,6 +230,7 @@ static bool send_sasl_mechs(private_pt_tls_server_t *this)
enumerator_t *enumerator;
bio_writer_t *writer = NULL;
char *name;
+ bool res;
enumerator = sasl_mechanism_create_enumerator(TRUE);
while (enumerator->enumerate(enumerator, &name))
@@ -253,8 +248,10 @@ static bool send_sasl_mechs(private_pt_tls_server_t *this)
{ /* no mechanisms available? */
return FALSE;
}
- return pt_tls_write(this->tls, writer, PT_TLS_SASL_MECHS,
- this->identifier++);
+ res = pt_tls_write(this->tls, PT_TLS_SASL_MECHS,
+ this->identifier++, writer->get_buf(writer));
+ writer->destroy(writer);
+ return res;
}
/**
@@ -394,11 +391,8 @@ static bool authenticate(private_pt_tls_server_t *this)
if (do_sasl(this))
{
/* complete SASL with emtpy mechanism list */
- bio_writer_t *writer;
-
- writer = bio_writer_create(0);
- return pt_tls_write(this->tls, writer, PT_TLS_SASL_MECHS,
- this->identifier++);
+ return pt_tls_write(this->tls, PT_TLS_SASL_MECHS, this->identifier++,
+ chunk_empty);
}
return FALSE;
}
@@ -410,44 +404,30 @@ static bool assess(private_pt_tls_server_t *this, tls_t *tnccs)
{
while (TRUE)
{
- bio_writer_t *writer;
+ size_t msglen;
+ size_t buflen = PT_TLS_MAX_MESSAGE_LEN;
+ char buf[buflen];
bio_reader_t *reader;
u_int32_t vendor, type, identifier;
chunk_t data;
- writer = bio_writer_create(32);
- while (TRUE)
+ switch (tnccs->build(tnccs, buf, &buflen, &msglen))
{
- char buf[2048];
- size_t buflen, msglen;
-
- buflen = sizeof(buf);
- switch (tnccs->build(tnccs, buf, &buflen, &msglen))
- {
- case SUCCESS:
- writer->destroy(writer);
- return tnccs->is_complete(tnccs);
- case FAILED:
- default:
- writer->destroy(writer);
+ case SUCCESS:
+ return tnccs->is_complete(tnccs);
+ case ALREADY_DONE:
+ data = chunk_create(buf, buflen);
+ if (!pt_tls_write(this->tls, PT_TLS_PB_TNC_BATCH,
+ this->identifier++, data))
+ {
return FALSE;
- case INVALID_STATE:
- writer->destroy(writer);
- break;
- case NEED_MORE:
- writer->write_data(writer, chunk_create(buf, buflen));
- continue;
- case ALREADY_DONE:
- writer->write_data(writer, chunk_create(buf, buflen));
- if (!pt_tls_write(this->tls, writer, PT_TLS_PB_TNC_BATCH,
- this->identifier++))
- {
- return FALSE;
- }
- writer = bio_writer_create(32);
- continue;
- }
- break;
+ }
+ break;
+ case INVALID_STATE:
+ break;
+ case FAILED:
+ default:
+ return FALSE;
}
reader = pt_tls_read(this->tls, &vendor, &type, &identifier);