diff options
author | Martin Willi <martin@revosec.ch> | 2010-08-23 16:21:49 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-08-24 08:45:49 +0200 |
commit | 1475800080d605abb1995bfba1ce8ca98637917c (patch) | |
tree | 973c91fcd5dd8bcb6c2970227a806516479742f5 | |
parent | 477650005599ffb63c9833daf34be93471eba437 (diff) | |
download | strongswan-1475800080d605abb1995bfba1ce8ca98637917c.tar.bz2 strongswan-1475800080d605abb1995bfba1ce8ca98637917c.tar.xz |
Moved TLS record parsing/generation to tls.c
-rw-r--r-- | src/libcharon/plugins/eap_tls/eap_tls.c | 70 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_ttls/eap_ttls.c | 60 | ||||
-rw-r--r-- | src/libtls/tls.c | 69 | ||||
-rw-r--r-- | src/libtls/tls.h | 13 |
4 files changed, 78 insertions, 134 deletions
diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c index 77458007e..8b5d4cb19 100644 --- a/src/libcharon/plugins/eap_tls/eap_tls.c +++ b/src/libcharon/plugins/eap_tls/eap_tls.c @@ -95,16 +95,6 @@ typedef struct __attribute__((packed)) { u_int8_t flags; } eap_tls_packet_t; -/** - * TLS record - */ -typedef struct __attribute__((packed)) { - u_int8_t type; - u_int16_t version; - u_int16_t length; - char data[]; -} tls_record_t; - METHOD(eap_method_t, initiate, status_t, private_eap_tls_t *this, eap_payload_t **out) { @@ -259,70 +249,18 @@ static eap_payload_t *read_buf(private_eap_tls_t *this, u_int8_t identifier) */ static status_t process_buf(private_eap_tls_t *this) { - tls_record_t *in, out; - chunk_t data; - u_int16_t len; status_t status; - /* pass input buffer to upper layer, record for record */ - data = this->input; - while (data.len > sizeof(tls_record_t)) + status = this->tls->process(this->tls, this->input); + if (status != NEED_MORE) { - in = (tls_record_t*)data.ptr; - len = untoh16(&in->length); - DBG2(DBG_IKE, "received TLS %N record (%u bytes)", - tls_content_type_names, in->type, sizeof(tls_record_t) + len); - if (len > data.len - sizeof(tls_record_t)) - { - DBG1(DBG_IKE, "TLS record length invalid"); - return FAILED; - } - if (untoh16(&in->version) < TLS_1_0) - { - DBG1(DBG_IKE, "%N invalid with EAP-TLS", - tls_version_names, untoh16(&in->version)); - return FAILED; - } - - status = this->tls->process(this->tls, in->type, - chunk_create(in->data, len)); - if (status != NEED_MORE) - { - return status; - } - data = chunk_skip(data, len + sizeof(tls_record_t)); + return status; } chunk_free(&this->input); this->inpos = 0; - /* read in records from upper layer, append to output buffer */ chunk_free(&this->output); - while (TRUE) - { - tls_content_type_t type; - chunk_t header = chunk_from_thing(out); - - status = this->tls->build(this->tls, &type, &data); - switch (status) - { - case NEED_MORE: - break; - case INVALID_STATE: - /* invalid state means we need more input from peer first */ - return NEED_MORE; - case SUCCESS: - return SUCCESS; - case FAILED: - default: - return FAILED; - } - out.type = type; - htoun16(&out.version, this->tls->get_version(this->tls)); - htoun16(&out.length, data.len); - this->output = chunk_cat("mcm", this->output, header, data); - DBG2(DBG_IKE, "sending TLS %N record (%u bytes)", - tls_content_type_names, type, sizeof(tls_record_t) + data.len); - } + return this->tls->build(this->tls, &this->output); } METHOD(eap_method_t, process, status_t, diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c index 80994a37d..d7372fe76 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls.c +++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c @@ -262,70 +262,18 @@ static eap_payload_t *read_buf(private_eap_ttls_t *this, u_int8_t identifier) */ static status_t process_buf(private_eap_ttls_t *this) { - tls_record_t *in, out; - chunk_t data; - u_int16_t len; status_t status; - /* pass input buffer to upper layer, record for record */ - data = this->input; - while (data.len > sizeof(tls_record_t)) + status = this->tls->process(this->tls, this->input); + if (status != NEED_MORE) { - in = (tls_record_t*)data.ptr; - len = untoh16(&in->length); - DBG2(DBG_IKE, "received TLS %N record (%u bytes)", - tls_content_type_names, in->type, sizeof(tls_record_t) + len); - if (len > data.len - sizeof(tls_record_t)) - { - DBG1(DBG_IKE, "TLS record length invalid"); - return FAILED; - } - if (untoh16(&in->version) < TLS_1_0) - { - DBG1(DBG_IKE, "%N invalid with EAP-TLS", - tls_version_names, untoh16(&in->version)); - return FAILED; - } - - status = this->tls->process(this->tls, in->type, - chunk_create(in->data, len)); - if (status != NEED_MORE) - { - return status; - } - data = chunk_skip(data, len + sizeof(tls_record_t)); + return status; } chunk_free(&this->input); this->inpos = 0; - /* read in records from upper layer, append to output buffer */ chunk_free(&this->output); - while (TRUE) - { - tls_content_type_t type; - chunk_t header = chunk_from_thing(out); - - status = this->tls->build(this->tls, &type, &data); - switch (status) - { - case NEED_MORE: - break; - case INVALID_STATE: - /* invalid state means we need more input from peer first */ - return NEED_MORE; - case SUCCESS: - return SUCCESS; - case FAILED: - default: - return FAILED; - } - out.type = type; - htoun16(&out.version, this->tls->get_version(this->tls)); - htoun16(&out.length, data.len); - this->output = chunk_cat("mcm", this->output, header, data); - DBG2(DBG_IKE, "sending TLS %N record (%u bytes)", - tls_content_type_names, type, sizeof(tls_record_t) + data.len); - } + return this->tls->build(this->tls, &this->output); } METHOD(eap_method_t, process, status_t, diff --git a/src/libtls/tls.c b/src/libtls/tls.c index 42f71d753..1f30f5a4e 100644 --- a/src/libtls/tls.c +++ b/src/libtls/tls.c @@ -15,6 +15,8 @@ #include "tls.h" +#include <debug.h> + #include "tls_protection.h" #include "tls_compression.h" #include "tls_fragmentation.h" @@ -127,16 +129,75 @@ struct private_tls_t { tls_application_t *application; }; +/** + * TLS record + */ +typedef struct __attribute__((packed)) { + u_int8_t type; + u_int16_t version; + u_int16_t length; + char data[]; +} tls_record_t; + METHOD(tls_t, process, status_t, - private_tls_t *this, tls_content_type_t type, chunk_t data) + private_tls_t *this, chunk_t data) { - return this->protection->process(this->protection, type, data); + tls_record_t *record; + u_int16_t len; + status_t status; + + while (data.len > sizeof(tls_record_t)) + { + record = (tls_record_t*)data.ptr; + len = untoh16(&record->length); + + DBG2(DBG_TLS, "received TLS %N record (%u bytes)", + tls_content_type_names, record->type, sizeof(tls_record_t) + len); + if (len > data.len - sizeof(tls_record_t)) + { + DBG1(DBG_IKE, "TLS record length invalid"); + return FAILED; + } + status = this->protection->process(this->protection, record->type, + chunk_create(record->data, len)); + if (status != NEED_MORE) + { + return status; + } + data = chunk_skip(data, len + sizeof(tls_record_t)); + } + + return NEED_MORE; } METHOD(tls_t, build, status_t, - private_tls_t *this, tls_content_type_t *type, chunk_t *data) + private_tls_t *this, chunk_t *data) { - return this->protection->build(this->protection, type, data); + tls_record_t record; + status_t status; + + while (TRUE) + { + tls_content_type_t type; + chunk_t body; + + status = this->protection->build(this->protection, &type, &body); + switch (status) + { + case INVALID_STATE: + return NEED_MORE; + case NEED_MORE: + break; + default: + return status; + } + record.type = type; + htoun16(&record.version, this->version); + htoun16(&record.length, body.len); + *data = chunk_cat("mcm", *data, chunk_from_thing(record), body); + DBG2(DBG_TLS, "sending TLS %N record (%u bytes)", + tls_content_type_names, type, sizeof(tls_record_t) + body.len); + } } METHOD(tls_t, is_server, bool, diff --git a/src/libtls/tls.h b/src/libtls/tls.h index 5c06686b7..36ca59201 100644 --- a/src/libtls/tls.h +++ b/src/libtls/tls.h @@ -106,29 +106,26 @@ enum tls_purpose_t { struct tls_t { /** - * Process a TLS record, pass it to upper layers. + * Process one or more TLS records, pass it to upper layers. * - * @param type type of the TLS record to process - * @param data associated TLS record data + * @param data TLS record data, including headers * @return * - SUCCESS if TLS negotiation complete * - FAILED if TLS handshake failed * - NEED_MORE if more invocations to process/build needed */ - status_t (*process)(tls_t *this, tls_content_type_t type, chunk_t data); + status_t (*process)(tls_t *this, chunk_t data); /** * Query upper layer for TLS record, build protected record. * - * @param type type of the built TLS record * @param data allocated data of the built TLS record * @return * - SUCCESS if TLS negotiation complete * - FAILED if TLS handshake failed - * - NEED_MORE if upper layers have more records to send - * - INVALID_STATE if more input records required + * - NEED_MORE if more input records required */ - status_t (*build)(tls_t *this, tls_content_type_t *type, chunk_t *data); + status_t (*build)(tls_t *this, chunk_t *data); /** * Check if TLS stack is acting as a server. |