Added stubs for handshake handling, server and peer variants
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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_ @}*/
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_ @}*/
|
||||
Reference in New Issue
Block a user