diff options
author | Martin Willi <martin@revosec.ch> | 2010-08-03 15:17:40 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-08-03 15:39:26 +0200 |
commit | 0f82a47063f05d8eeae64866ff4787edc8db6328 (patch) | |
tree | 80d2e1fc7d530dc205314b7abafeb25fec48cc73 /src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c | |
parent | 0b71bc7af047f1a20bbad8a38d33b01452c35613 (diff) | |
download | strongswan-0f82a47063f05d8eeae64866ff4787edc8db6328.tar.bz2 strongswan-0f82a47063f05d8eeae64866ff4787edc8db6328.tar.xz |
Moved TLS stack to its own library
Diffstat (limited to 'src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c')
-rw-r--r-- | src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c | 256 |
1 files changed, 0 insertions, 256 deletions
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c b/src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c deleted file mode 100644 index 7a99c9235..000000000 --- a/src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (C) 2010 Martin Willi - * Copyright (C) 2010 revosec AG - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include "tls_fragmentation.h" - -#include "tls_reader.h" - -#include <daemon.h> - -typedef struct private_tls_fragmentation_t private_tls_fragmentation_t; - -/** - * Private data of an tls_fragmentation_t object. - */ -struct private_tls_fragmentation_t { - - /** - * Public tls_fragmentation_t interface. - */ - tls_fragmentation_t public; - - /** - * Upper layer handshake protocol - */ - tls_handshake_t *handshake; - - /** - * Handshake input buffer - */ - chunk_t input; - - /** - * Position in input buffer - */ - size_t inpos; - - /** - * Currently processed handshake message type - */ - tls_handshake_type_t type; - - /** - * Handshake output buffer - */ - chunk_t output; -}; - -/** - * 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 TLS handshake protocol data - */ -static status_t process_handshake(private_tls_fragmentation_t *this, - tls_reader_t *reader) -{ - while (reader->remaining(reader)) - { - tls_reader_t *msg; - u_int8_t type; - u_int32_t len; - status_t status; - chunk_t data; - - if (reader->remaining(reader) > MAX_TLS_FRAGMENT_LEN) - { - DBG1(DBG_IKE, "TLS fragment has invalid length"); - return FAILED; - } - - if (this->input.len == 0) - { /* new handshake message */ - if (!reader->read_uint8(reader, &type) || - !reader->read_uint24(reader, &len)) - { - return FAILED; - } - this->type = type; - if (len > MAX_TLS_HANDSHAKE_LEN) - { - DBG1(DBG_IKE, "TLS handshake message exceeds maximum length"); - return FAILED; - } - chunk_free(&this->input); - this->inpos = 0; - if (len) - { - this->input = chunk_alloc(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; - - if (this->input.len == this->inpos) - { /* message completely defragmented, process */ - 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) - { - return status; - } - } - } - return NEED_MORE; -} - -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: - if (this->handshake->change_cipherspec(this->handshake)) - { - status = NEED_MORE; - break; - } - status = FAILED; - break; - case TLS_ALERT: - /* TODO: handle Alert */ - status = FAILED; - break; - case TLS_HANDSHAKE: - status = process_handshake(this, reader); - break; - case TLS_APPLICATION_DATA: - /* skip application data */ - status = NEED_MORE; - break; - default: - DBG1(DBG_IKE, "received unknown TLS content type %d, ignored", type); - status = NEED_MORE; - break; - } - reader->destroy(reader); - return status; -} - -METHOD(tls_fragmentation_t, build, status_t, - private_tls_fragmentation_t *this, tls_content_type_t *type, chunk_t *data) -{ - tls_handshake_type_t hs_type; - tls_writer_t *writer, *msg; - status_t status; - - if (this->handshake->cipherspec_changed(this->handshake)) - { - *type = TLS_CHANGE_CIPHER_SPEC; - *data = chunk_clone(chunk_from_chars(0x01)); - return NEED_MORE; - } - - if (!this->output.len) - { - msg = tls_writer_create(64); - do - { - writer = tls_writer_create(64); - status = this->handshake->build(this->handshake, &hs_type, writer); - switch (status) - { - case NEED_MORE: - 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) - { - return status; - } - } - - if (this->output.len) - { - *type = TLS_HANDSHAKE; - if (this->output.len <= MAX_TLS_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)); - return NEED_MORE; - } - return status; -} - -METHOD(tls_fragmentation_t, destroy, void, - private_tls_fragmentation_t *this) -{ - free(this->input.ptr); - free(this->output.ptr); - free(this); -} - -/** - * See header - */ -tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake) -{ - private_tls_fragmentation_t *this; - - INIT(this, - .public = { - .process = _process, - .build = _build, - .destroy = _destroy, - }, - .handshake = handshake, - ); - - return &this->public; -} |