diff options
author | Martin Willi <martin@revosec.ch> | 2010-02-01 10:25:44 +0000 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-08-03 15:39:24 +0200 |
commit | 4ef946dd64876df4ffabf49d4d7cbf42c6958008 (patch) | |
tree | 12d65bc1913dd808ea5ab8d77ff3a8a99b0b292b /src/charon/plugins/eap_tls/tls/tls_fragmentation.c | |
parent | 3e962b0843c17e220592718f498c513aa52796fd (diff) | |
download | strongswan-4ef946dd64876df4ffabf49d4d7cbf42c6958008.tar.bz2 strongswan-4ef946dd64876df4ffabf49d4d7cbf42c6958008.tar.xz |
Implemented a tls_reader class to simplify TLS data parsing
Diffstat (limited to 'src/charon/plugins/eap_tls/tls/tls_fragmentation.c')
-rw-r--r-- | src/charon/plugins/eap_tls/tls/tls_fragmentation.c | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/src/charon/plugins/eap_tls/tls/tls_fragmentation.c b/src/charon/plugins/eap_tls/tls/tls_fragmentation.c index 0d38e4890..e23b96fea 100644 --- a/src/charon/plugins/eap_tls/tls/tls_fragmentation.c +++ b/src/charon/plugins/eap_tls/tls/tls_fragmentation.c @@ -15,6 +15,8 @@ #include "tls_fragmentation.h" +#include "tls_reader.h" + #include <daemon.h> typedef struct private_tls_fragmentation_t private_tls_fragmentation_t; @@ -73,15 +75,17 @@ typedef union { * Process TLS handshake protocol data */ static status_t process_handshake(private_tls_fragmentation_t *this, - chunk_t data) + tls_reader_t *reader) { - while (data.len) + while (reader->remaining(reader)) { + tls_reader_t *msg; + u_int8_t type; u_int32_t len; status_t status; - tls_handshake_header_t *hdr; + chunk_t data; - if (data.len == 0 || data.len > MAX_TLS_FRAGMENT_LEN) + if (reader->remaining(reader) > MAX_TLS_FRAGMENT_LEN) { DBG1(DBG_IKE, "TLS fragment has invalid length"); return FAILED; @@ -89,33 +93,38 @@ static status_t process_handshake(private_tls_fragmentation_t *this, if (this->input.len == 0) { /* new handshake message */ - if (data.len < sizeof(tls_handshake_header_t)) + if (!reader->read_uint8(reader, &type) || + !reader->read_uint24(reader, &len)) { - DBG1(DBG_IKE, "initial TLS fragment too short %B", &data); return FAILED; } - hdr = (tls_handshake_header_t*)data.ptr; - len = untoh32(&hdr->length) & 0x00FFFFFF; - this->type = hdr->type; + this->type = type; if (len > MAX_TLS_HANDSHAKE_LEN) { DBG1(DBG_IKE, "TLS handshake message exceeds maximum length"); return FAILED; } - this->input = len ? chunk_alloc(len) : chunk_empty; + chunk_free(&this->input); this->inpos = 0; - data = chunk_skip(data, sizeof(tls_handshake_header_t)); + if (len) + { + this->input = chunk_alloc(len); + } } - len = min(this->input.len - this->inpos, data.len); + len = min(this->input.len - this->inpos, reader->remaining(reader)); + if (!reader->read_data(reader, len, &data)) + { + return FAILED; + } memcpy(this->input.ptr + this->inpos, data.ptr, len); this->inpos += len; - data = chunk_skip(data, len); if (this->input.len == this->inpos) { /* message completely defragmented, process */ - status = this->handshake->process(this->handshake, - this->type, this->input); + msg = tls_reader_create(this->input); + status = this->handshake->process(this->handshake, this->type, msg); + msg->destroy(msg); chunk_free(&this->input); if (status != NEED_MORE) { @@ -129,23 +138,34 @@ static status_t process_handshake(private_tls_fragmentation_t *this, METHOD(tls_fragmentation_t, process, status_t, private_tls_fragmentation_t *this, tls_content_type_t type, chunk_t data) { + tls_reader_t *reader; + status_t status; + + reader = tls_reader_create(data); switch (type) { case TLS_CHANGE_CIPHER_SPEC: /* TODO: handle ChangeCipherSpec */ - return FAILED; + status = FAILED; + break; case TLS_ALERT: /* TODO: handle Alert */ - return FAILED; + status = FAILED; + break; case TLS_HANDSHAKE: - return process_handshake(this, data); + status = process_handshake(this, reader); + break; case TLS_APPLICATION_DATA: /* skip application data */ - return NEED_MORE; + status = NEED_MORE; + break; default: DBG1(DBG_IKE, "received unknown TLS content type %d, ignored", type); - return NEED_MORE; + status = NEED_MORE; + break; } + reader->destroy(reader); + return status; } METHOD(tls_fragmentation_t, build, status_t, |