Added stubs for handshake handling, server and peer variants

This commit is contained in:
Martin Willi
2010-08-03 15:39:24 +02:00
parent 4c0124a0a2
commit 4c0c2283a5
9 changed files with 446 additions and 6 deletions
+4 -1
View File
@@ -9,5 +9,8 @@ libstrongswan_eap_tls_la_SOURCES = eap_tls_plugin.h eap_tls_plugin.c \
eap_tls.h eap_tls.c tls/tls.h tls/tls.c \
tls/tls_protection.h tls/tls_protection.c \
tls/tls_compression.h tls/tls_compression.c \
tls/tls_fragmentation.h tls/tls_fragmentation.c
tls/tls_fragmentation.h tls/tls_fragmentation.c \
tls/tls_peer.h tls/tls_peer.c \
tls/tls_server.h tls/tls_server.c \
tls/tls_handshake.h
libstrongswan_eap_tls_la_LDFLAGS = -module -avoid-version
+17 -1
View File
@@ -18,6 +18,8 @@
#include "tls_protection.h"
#include "tls_compression.h"
#include "tls_fragmentation.h"
#include "tls_server.h"
#include "tls_peer.h"
#include <daemon.h>
@@ -83,6 +85,11 @@ struct private_tls_t {
* TLS record fragmentation layer
*/
tls_fragmentation_t *fragmentation;
/**
* TLS handshake protocol handler
*/
tls_handshake_t *handshake;
};
METHOD(tls_t, process, status_t,
@@ -103,6 +110,7 @@ METHOD(tls_t, destroy, void,
this->protection->destroy(this->protection);
this->compression->destroy(this->compression);
this->fragmentation->destroy(this->fragmentation);
this->handshake->destroy(this->handshake);
free(this);
}
@@ -123,7 +131,15 @@ tls_t *tls_create(bool is_server)
.is_server = is_server,
);
this->fragmentation = tls_fragmentation_create();
if (is_server)
{
this->handshake = &tls_server_create()->handshake;
}
else
{
this->handshake = &tls_peer_create()->handshake;
}
this->fragmentation = tls_fragmentation_create(this->handshake);
this->compression = tls_compression_create(this->fragmentation);
this->protection = tls_protection_create(this->compression);
@@ -28,30 +28,157 @@ 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;
};
/**
* 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
/**
* TLS handshake message header
*/
typedef union {
u_int8_t type;
/* 24bit length field */
u_int32_t length;
} tls_handshake_header_t;
/**
* Process TLS handshake protocol data
*/
static status_t process_handshake(private_tls_fragmentation_t *this,
chunk_t data)
{
while (data.len)
{
u_int32_t len;
status_t status;
tls_handshake_header_t *hdr;
if (data.len == 0 || data.len > MAX_TLS_FRAGMENT_LEN)
{
DBG1(DBG_IKE, "TLS fragment has invalid length");
return FAILED;
}
if (this->input.len == 0)
{ /* new handshake message */
if (data.len < sizeof(tls_handshake_header_t))
{
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;
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;
this->inpos = 0;
data = chunk_skip(data, sizeof(tls_handshake_header_t));
}
len = min(this->input.len - this->inpos, data.len);
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);
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)
{
return NEED_MORE;
switch (type)
{
case TLS_CHANGE_CIPHER_SPEC:
/* TODO: handle ChangeCipherSpec */
return FAILED;
case TLS_ALERT:
/* TODO: handle Alert */
return FAILED;
case TLS_HANDSHAKE:
return process_handshake(this, data);
case TLS_APPLICATION_DATA:
/* skip application data */
return NEED_MORE;
default:
DBG1(DBG_IKE, "received unknown TLS content type %d, ignored", type);
return NEED_MORE;
}
}
METHOD(tls_fragmentation_t, build, status_t,
private_tls_fragmentation_t *this, tls_content_type_t *type, chunk_t *data)
{
return INVALID_STATE;
tls_handshake_header_t header;
tls_handshake_type_t hs_type;
chunk_t hs_data;
status_t status;
status = this->handshake->build(this->handshake, &hs_type, &hs_data);
if (status != NEED_MORE)
{
return status;
}
htoun32(&header.length, hs_data.len);
header.type |= hs_type;
*data = chunk_cat("cm", chunk_from_thing(header), hs_data);
*type = TLS_HANDSHAKE;
return NEED_MORE;
}
METHOD(tls_fragmentation_t, destroy, void,
private_tls_fragmentation_t *this)
{
free(this->input.ptr);
free(this);
}
/**
* See header
*/
tls_fragmentation_t *tls_fragmentation_create()
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake)
{
private_tls_fragmentation_t *this;
@@ -61,6 +188,7 @@ tls_fragmentation_t *tls_fragmentation_create()
.build = _build,
.destroy = _destroy,
},
.handshake = handshake,
);
return &this->public;
@@ -26,6 +26,7 @@ typedef struct tls_fragmentation_t tls_fragmentation_t;
#include <library.h>
#include "tls.h"
#include "tls_handshake.h"
/**
* TLS record protocol fragmentation layer.
@@ -68,8 +69,9 @@ struct tls_fragmentation_t {
/**
* Create a tls_fragmentation instance.
*
* @param handshake upper layer handshake protocol
* @return TLS fragmentation layer.
*/
tls_fragmentation_t *tls_fragmentation_create();
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake);
#endif /** TLS_FRAGMENTATION_H_ @}*/
@@ -0,0 +1,66 @@
/*
* Copyright (C) 2010 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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.
*/
/**
* @defgroup tls_handshake tls_handshake
* @{ @ingroup tls
*/
#ifndef TLS_HANDSHAKE_H_
#define TLS_HANDSHAKE_H_
typedef struct tls_handshake_t tls_handshake_t;
#include "tls.h"
/**
* TLS handshake state machine interface.
*/
struct tls_handshake_t {
/**
* Process received TLS handshake message.
*
* @param type TLS handshake message type
* @param data TLS handshake data
* @return
* - SUCCESS if handshake complete
* - FAILED if handshake failed
* - NEED_MORE if another invocation of process/build needed
*/
status_t (*process)(tls_handshake_t *this,
tls_handshake_type_t type, chunk_t data);
/**
* Build TLS handshake messages to send out.
*
* @param type type of created handshake message
* @param data allocated TLS handshake message data
* @return
* - SUCCESS if handshake complete
* - FAILED if handshake failed
* - NEED_MORE if more messages ready for delivery
* - INVALID_STATE if more input to process() required
*/
status_t (*build)(tls_handshake_t *this,
tls_handshake_type_t *type, chunk_t *data);
/**
* Destroy a tls_handshake_t.
*/
void (*destroy)(tls_handshake_t *this);
};
#endif /** TLS_HANDSHAKE_H_ @}*/
+69
View File
@@ -0,0 +1,69 @@
/*
* 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_peer.h"
#include <daemon.h>
#include <time.h>
typedef struct private_tls_peer_t private_tls_peer_t;
/**
* Private data of an tls_peer_t object.
*/
struct private_tls_peer_t {
/**
* Public tls_peer_t interface.
*/
tls_peer_t public;
};
METHOD(tls_handshake_t, process, status_t,
private_tls_peer_t *this, tls_handshake_type_t type, chunk_t data)
{
return NEED_MORE;
}
METHOD(tls_handshake_t, build, status_t,
private_tls_peer_t *this, tls_handshake_type_t *type, chunk_t *data)
{
return INVALID_STATE;
}
METHOD(tls_handshake_t, destroy, void,
private_tls_peer_t *this)
{
free(this);
}
/**
* See header
*/
tls_peer_t *tls_peer_create()
{
private_tls_peer_t *this;
INIT(this,
.public.handshake = {
.process = _process,
.build = _build,
.destroy = _destroy,
},
);
return &this->public;
}
+44
View File
@@ -0,0 +1,44 @@
/*
* 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.
*/
/**
* @defgroup tls_peer tls_peer
* @{ @ingroup tls
*/
#ifndef TLS_PEER_H_
#define TLS_PEER_H_
typedef struct tls_peer_t tls_peer_t;
#include "tls_handshake.h"
/**
* TLS handshake protocol handler as peer.
*/
struct tls_peer_t {
/**
* Implements the TLS handshake protocol handler.
*/
tls_handshake_t handshake;
};
/**
* Create a tls_peer instance.
*/
tls_peer_t *tls_peer_create();
#endif /** TLS_PEER_H_ @}*/
@@ -0,0 +1,68 @@
/*
* 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_server.h"
#include <daemon.h>
typedef struct private_tls_server_t private_tls_server_t;
/**
* Private data of an tls_server_t object.
*/
struct private_tls_server_t {
/**
* Public tls_server_t interface.
*/
tls_server_t public;
};
METHOD(tls_handshake_t, process, status_t,
private_tls_server_t *this, tls_handshake_type_t type, chunk_t data)
{
return NEED_MORE;
}
METHOD(tls_handshake_t, build, status_t,
private_tls_server_t *this, tls_handshake_type_t *type, chunk_t *data)
{
return INVALID_STATE;
}
METHOD(tls_handshake_t, destroy, void,
private_tls_server_t *this)
{
free(this);
}
/**
* See header
*/
tls_server_t *tls_server_create()
{
private_tls_server_t *this;
INIT(this,
.public.handshake = {
.process = _process,
.build = _build,
.destroy = _destroy,
},
);
return &this->public;
}
@@ -0,0 +1,44 @@
/*
* 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.
*/
/**
* @defgroup tls_server tls_server
* @{ @ingroup tls
*/
#ifndef TLS_SERVER_H_
#define TLS_SERVER_H_
typedef struct tls_server_t tls_server_t;
#include "tls_handshake.h"
/**
* TLS handshake protocol handler as peer.
*/
struct tls_server_t {
/**
* Implements the TLS handshake protocol handler.
*/
tls_handshake_t handshake;
};
/**
* Create a tls_server instance.
*/
tls_server_t *tls_server_create();
#endif /** TLS_SERVER_H_ @}*/