added generic TLS application data handler and specific EAP-TTLS instantiation
This commit is contained in:
parent
123a84d3db
commit
1327839da8
|
@ -433,7 +433,8 @@ static eap_tls_t *eap_tls_create(identification_t *server,
|
||||||
.is_server = is_server,
|
.is_server = is_server,
|
||||||
);
|
);
|
||||||
/* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
|
/* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
|
||||||
this->tls = tls_create(is_server, server, peer, "client EAP encryption");
|
this->tls = tls_create(is_server, server, peer, "client EAP encryption",
|
||||||
|
NULL);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ libstrongswan_eap_ttls_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libstrongswan_eap_ttls_la_SOURCES = \
|
libstrongswan_eap_ttls_la_SOURCES = \
|
||||||
eap_ttls_plugin.h eap_ttls_plugin.c eap_ttls.h eap_ttls.c
|
eap_ttls_plugin.h eap_ttls_plugin.c eap_ttls.h eap_ttls.c \
|
||||||
|
eap_ttls_peer.h eap_ttls_peer.c
|
||||||
|
|
||||||
libstrongswan_eap_ttls_la_LDFLAGS = -module -avoid-version
|
libstrongswan_eap_ttls_la_LDFLAGS = -module -avoid-version
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "eap_ttls.h"
|
#include "eap_ttls.h"
|
||||||
|
#include "eap_ttls_peer.h"
|
||||||
|
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
|
|
||||||
|
@ -423,7 +424,8 @@ METHOD(eap_method_t, destroy, void,
|
||||||
* Generic private constructor
|
* Generic private constructor
|
||||||
*/
|
*/
|
||||||
static eap_ttls_t *eap_ttls_create(identification_t *server,
|
static eap_ttls_t *eap_ttls_create(identification_t *server,
|
||||||
identification_t *peer, bool is_server)
|
identification_t *peer, bool is_server,
|
||||||
|
tls_application_t *application)
|
||||||
{
|
{
|
||||||
private_eap_ttls_t *this;
|
private_eap_ttls_t *this;
|
||||||
|
|
||||||
|
@ -439,19 +441,20 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
|
||||||
.is_server = is_server,
|
.is_server = is_server,
|
||||||
);
|
);
|
||||||
/* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
|
/* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
|
||||||
this->tls = tls_create(is_server, server, peer, "ttls keying material");
|
this->tls = tls_create(is_server, server, peer, "ttls keying material",
|
||||||
|
application);
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
eap_ttls_t *eap_ttls_create_server(identification_t *server,
|
eap_ttls_t *eap_ttls_create_server(identification_t *server,
|
||||||
identification_t *peer)
|
identification_t *peer)
|
||||||
{
|
{
|
||||||
return eap_ttls_create(server, peer, TRUE);
|
return eap_ttls_create(server, peer, TRUE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
eap_ttls_t *eap_ttls_create_peer(identification_t *server,
|
eap_ttls_t *eap_ttls_create_peer(identification_t *server,
|
||||||
identification_t *peer)
|
identification_t *peer)
|
||||||
{
|
{
|
||||||
return eap_ttls_create(server, peer, FALSE);
|
return eap_ttls_create(server, peer, FALSE,
|
||||||
|
&eap_ttls_peer_create(peer)->application);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Andreas Steffen
|
||||||
|
* Copyright (C) 2010 HSR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "eap_ttls_peer.h"
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#define AVP_EAP_MESSAGE 79
|
||||||
|
|
||||||
|
typedef struct private_eap_ttls_peer_t private_eap_ttls_peer_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of an eap_ttls_peer_t object.
|
||||||
|
*/
|
||||||
|
struct private_eap_ttls_peer_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public eap_ttls_peer_t interface.
|
||||||
|
*/
|
||||||
|
eap_ttls_peer_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Peer identity
|
||||||
|
*/
|
||||||
|
identification_t *peer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EAP-TTLS state information
|
||||||
|
*/
|
||||||
|
bool start_phase2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
METHOD(tls_application_t, process, status_t,
|
||||||
|
private_eap_ttls_peer_t *this, tls_reader_t *reader)
|
||||||
|
{
|
||||||
|
return NEED_MORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(tls_application_t, build, status_t,
|
||||||
|
private_eap_ttls_peer_t *this, tls_writer_t *writer)
|
||||||
|
{
|
||||||
|
if (this->start_phase2)
|
||||||
|
{
|
||||||
|
chunk_t data = chunk_from_chars(
|
||||||
|
0x02, 0x00, 0x00, 10, 0x01, 'c', 'a', 'r', 'o', 'l', 0x00, 0x00);
|
||||||
|
u_int8_t avp_flags = 0x40;
|
||||||
|
u_int32_t avp_len;
|
||||||
|
|
||||||
|
avp_len = 8 + data.len - 2;
|
||||||
|
writer->write_uint32(writer, AVP_EAP_MESSAGE);
|
||||||
|
writer->write_uint8(writer, avp_flags);
|
||||||
|
writer->write_uint24(writer, avp_len);
|
||||||
|
writer->write_data(writer, data);
|
||||||
|
this->start_phase2 = FALSE;
|
||||||
|
}
|
||||||
|
return INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(tls_application_t, destroy, void,
|
||||||
|
private_eap_ttls_peer_t *this)
|
||||||
|
{
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
eap_ttls_peer_t *eap_ttls_peer_create(identification_t *peer)
|
||||||
|
{
|
||||||
|
private_eap_ttls_peer_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public.application = {
|
||||||
|
.process = _process,
|
||||||
|
.build = _build,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.peer = peer,
|
||||||
|
.start_phase2 = TRUE,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Andreas Steffen
|
||||||
|
* Copyright (C) 2010 HSR 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_peer tls_peer
|
||||||
|
* @{ @ingroup libtls
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EAP_TTLS_PEER_H_
|
||||||
|
#define EAP_TTLS_PEER_H_
|
||||||
|
|
||||||
|
typedef struct eap_ttls_peer_t eap_ttls_peer_t;
|
||||||
|
|
||||||
|
#include "tls_application.h"
|
||||||
|
|
||||||
|
#include <library.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TLS application data handler as peer.
|
||||||
|
*/
|
||||||
|
struct eap_ttls_peer_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the TLS application data handler.
|
||||||
|
*/
|
||||||
|
tls_application_t application;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an eap_ttls_peer instance.
|
||||||
|
*/
|
||||||
|
eap_ttls_peer_t *eap_ttls_peer_create(identification_t *peer);
|
||||||
|
|
||||||
|
#endif /** EAP_TTLS_PEER_H_ @}*/
|
|
@ -12,4 +12,4 @@ libtls_la_SOURCES = \
|
||||||
tls_writer.h tls_writer.c \
|
tls_writer.h tls_writer.c \
|
||||||
tls_peer.h tls_peer.c \
|
tls_peer.h tls_peer.c \
|
||||||
tls_server.h tls_server.c \
|
tls_server.h tls_server.c \
|
||||||
tls_handshake.h tls.h tls.c
|
tls_handshake.h tls_application.h tls.h tls.c
|
||||||
|
|
|
@ -110,6 +110,11 @@ struct private_tls_t {
|
||||||
* TLS handshake protocol handler
|
* TLS handshake protocol handler
|
||||||
*/
|
*/
|
||||||
tls_handshake_t *handshake;
|
tls_handshake_t *handshake;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TLS application data handler
|
||||||
|
*/
|
||||||
|
tls_application_t *application;
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(tls_t, process, status_t,
|
METHOD(tls_t, process, status_t,
|
||||||
|
@ -164,6 +169,7 @@ METHOD(tls_t, destroy, void,
|
||||||
this->handshake->destroy(this->handshake);
|
this->handshake->destroy(this->handshake);
|
||||||
this->peer->destroy(this->peer);
|
this->peer->destroy(this->peer);
|
||||||
this->server->destroy(this->server);
|
this->server->destroy(this->server);
|
||||||
|
DESTROY_IF(this->application);
|
||||||
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
@ -172,7 +178,8 @@ METHOD(tls_t, destroy, void,
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
tls_t *tls_create(bool is_server, identification_t *server,
|
tls_t *tls_create(bool is_server, identification_t *server,
|
||||||
identification_t *peer, char *msk_label)
|
identification_t *peer, char *msk_label,
|
||||||
|
tls_application_t *application)
|
||||||
{
|
{
|
||||||
private_tls_t *this;
|
private_tls_t *this;
|
||||||
|
|
||||||
|
@ -191,6 +198,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
|
||||||
.version = TLS_1_2,
|
.version = TLS_1_2,
|
||||||
.server = server->clone(server),
|
.server = server->clone(server),
|
||||||
.peer = peer->clone(peer),
|
.peer = peer->clone(peer),
|
||||||
|
.application = application,
|
||||||
);
|
);
|
||||||
|
|
||||||
this->crypto = tls_crypto_create(&this->public, msk_label);
|
this->crypto = tls_crypto_create(&this->public, msk_label);
|
||||||
|
@ -204,7 +212,8 @@ tls_t *tls_create(bool is_server, identification_t *server,
|
||||||
this->handshake = &tls_peer_create(&this->public, this->crypto,
|
this->handshake = &tls_peer_create(&this->public, this->crypto,
|
||||||
this->peer, this->server)->handshake;
|
this->peer, this->server)->handshake;
|
||||||
}
|
}
|
||||||
this->fragmentation = tls_fragmentation_create(this->handshake);
|
this->fragmentation = tls_fragmentation_create(this->handshake,
|
||||||
|
this->application);
|
||||||
this->compression = tls_compression_create(this->fragmentation);
|
this->compression = tls_compression_create(this->fragmentation);
|
||||||
this->protection = tls_protection_create(&this->public, this->compression);
|
this->protection = tls_protection_create(&this->public, this->compression);
|
||||||
this->crypto->set_protection(this->crypto, this->protection);
|
this->crypto->set_protection(this->crypto, this->protection);
|
||||||
|
|
|
@ -33,6 +33,8 @@ typedef struct tls_t tls_t;
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
|
||||||
|
#include "tls_application.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TLS/SSL version numbers
|
* TLS/SSL version numbers
|
||||||
*/
|
*/
|
||||||
|
@ -163,9 +165,11 @@ struct tls_t {
|
||||||
* @param server server identity
|
* @param server server identity
|
||||||
* @param peer peer identity
|
* @param peer peer identity
|
||||||
* @param msk_label ASCII string constant used as seed for MSK PRF
|
* @param msk_label ASCII string constant used as seed for MSK PRF
|
||||||
|
* @param application higher layer application or NULL if none
|
||||||
* @return TLS stack
|
* @return TLS stack
|
||||||
*/
|
*/
|
||||||
tls_t *tls_create(bool is_server, identification_t *server,
|
tls_t *tls_create(bool is_server, identification_t *server,
|
||||||
identification_t *peer, char *msk_label);
|
identification_t *peer, char *msk_label,
|
||||||
|
tls_application_t *application);
|
||||||
|
|
||||||
#endif /** TLS_H_ @}*/
|
#endif /** TLS_H_ @}*/
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Andreas Steffen
|
||||||
|
* Copyright (C) 2010 HSR 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 libtls
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TLS_APPLICATION_H_
|
||||||
|
#define TLS_APPLICATION_H_
|
||||||
|
|
||||||
|
typedef struct tls_application_t tls_application_t;
|
||||||
|
|
||||||
|
#include "tls.h"
|
||||||
|
#include "tls_reader.h"
|
||||||
|
#include "tls_writer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TLS application data interface.
|
||||||
|
*/
|
||||||
|
struct tls_application_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process received TLS application data.
|
||||||
|
*
|
||||||
|
* @param reader TLS data buffer
|
||||||
|
* @return
|
||||||
|
* - SUCCESS if application completed
|
||||||
|
* - FAILED if application data processing failed
|
||||||
|
* - NEED_MORE if another invocation of process/build needed
|
||||||
|
*/
|
||||||
|
status_t (*process)(tls_application_t *this, tls_reader_t *reader);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build TLS application data to send out.
|
||||||
|
*
|
||||||
|
* @param writer TLS data buffer to write to
|
||||||
|
* @return
|
||||||
|
* - SUCCESS if application completed
|
||||||
|
* - FAILED if application data build failed
|
||||||
|
* - NEED_MORE if more data ready for delivery
|
||||||
|
* - INVALID_STATE if more input to process() required
|
||||||
|
*/
|
||||||
|
status_t (*build)(tls_application_t *this, tls_writer_t *writer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a tls_application_t.
|
||||||
|
*/
|
||||||
|
void (*destroy)(tls_application_t *this);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /** TLS_APPLICATION_H_ @}*/
|
|
@ -55,6 +55,11 @@ struct private_tls_fragmentation_t {
|
||||||
* Handshake output buffer
|
* Handshake output buffer
|
||||||
*/
|
*/
|
||||||
chunk_t output;
|
chunk_t output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upper layer application data protocol
|
||||||
|
*/
|
||||||
|
tls_application_t *application;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,6 +138,33 @@ static status_t process_handshake(private_tls_fragmentation_t *this,
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process TLS application data
|
||||||
|
*/
|
||||||
|
static status_t process_application(private_tls_fragmentation_t *this,
|
||||||
|
tls_reader_t *reader)
|
||||||
|
{
|
||||||
|
while (reader->remaining(reader))
|
||||||
|
{
|
||||||
|
u_int32_t len;
|
||||||
|
chunk_t data;
|
||||||
|
|
||||||
|
if (reader->remaining(reader) > MAX_TLS_FRAGMENT_LEN)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "TLS fragment has invalid length");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = reader->remaining(reader);
|
||||||
|
if (!reader->read_data(reader, len, &data))
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
DBG1(DBG_IKE, "received TLS application data: %B", &data);
|
||||||
|
}
|
||||||
|
return NEED_MORE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tls_fragmentation_t, process, status_t,
|
METHOD(tls_fragmentation_t, process, status_t,
|
||||||
private_tls_fragmentation_t *this, tls_content_type_t type, chunk_t data)
|
private_tls_fragmentation_t *this, tls_content_type_t type, chunk_t data)
|
||||||
{
|
{
|
||||||
|
@ -158,8 +190,7 @@ METHOD(tls_fragmentation_t, process, status_t,
|
||||||
status = process_handshake(this, reader);
|
status = process_handshake(this, reader);
|
||||||
break;
|
break;
|
||||||
case TLS_APPLICATION_DATA:
|
case TLS_APPLICATION_DATA:
|
||||||
/* skip application data */
|
status = process_application(this, reader);
|
||||||
status = NEED_MORE;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBG1(DBG_IKE, "received unknown TLS content type %d, ignored", type);
|
DBG1(DBG_IKE, "received unknown TLS content type %d, ignored", type);
|
||||||
|
@ -175,7 +206,7 @@ METHOD(tls_fragmentation_t, build, status_t,
|
||||||
{
|
{
|
||||||
tls_handshake_type_t hs_type;
|
tls_handshake_type_t hs_type;
|
||||||
tls_writer_t *writer, *msg;
|
tls_writer_t *writer, *msg;
|
||||||
status_t status;
|
status_t status = INVALID_STATE;
|
||||||
|
|
||||||
if (this->handshake->cipherspec_changed(this->handshake))
|
if (this->handshake->cipherspec_changed(this->handshake))
|
||||||
{
|
{
|
||||||
|
@ -187,27 +218,47 @@ METHOD(tls_fragmentation_t, build, status_t,
|
||||||
if (!this->output.len)
|
if (!this->output.len)
|
||||||
{
|
{
|
||||||
msg = tls_writer_create(64);
|
msg = tls_writer_create(64);
|
||||||
do
|
|
||||||
|
if (this->handshake->finished(this->handshake))
|
||||||
{
|
{
|
||||||
writer = tls_writer_create(64);
|
if (this->application)
|
||||||
status = this->handshake->build(this->handshake, &hs_type, writer);
|
|
||||||
switch (status)
|
|
||||||
{
|
{
|
||||||
case NEED_MORE:
|
status = this->application->build(this->application, msg);
|
||||||
DBG2(DBG_IKE, "sending TLS %N message",
|
if (status == INVALID_STATE)
|
||||||
tls_handshake_type_names, hs_type);
|
{
|
||||||
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));
|
this->output = chunk_clone(msg->get_buf(msg));
|
||||||
break;
|
if (this->output.len)
|
||||||
default:
|
{
|
||||||
break;
|
DBG2(DBG_IKE, "sending TLS application data: %B",
|
||||||
|
&this->output);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
writer->destroy(writer);
|
|
||||||
}
|
}
|
||||||
while (status == NEED_MORE);
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
writer = tls_writer_create(64);
|
||||||
|
status = this->handshake->build(this->handshake, &hs_type, writer);
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case NEED_MORE:
|
||||||
|
DBG2(DBG_IKE, "sending TLS %N message",
|
||||||
|
tls_handshake_type_names, hs_type);
|
||||||
|
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);
|
msg->destroy(msg);
|
||||||
if (status != INVALID_STATE)
|
if (status != INVALID_STATE)
|
||||||
|
@ -218,7 +269,8 @@ METHOD(tls_fragmentation_t, build, status_t,
|
||||||
|
|
||||||
if (this->output.len)
|
if (this->output.len)
|
||||||
{
|
{
|
||||||
*type = TLS_HANDSHAKE;
|
*type = this->handshake->finished(this->handshake) ?
|
||||||
|
TLS_APPLICATION_DATA : TLS_HANDSHAKE;
|
||||||
if (this->output.len <= MAX_TLS_FRAGMENT_LEN)
|
if (this->output.len <= MAX_TLS_FRAGMENT_LEN)
|
||||||
{
|
{
|
||||||
*data = this->output;
|
*data = this->output;
|
||||||
|
@ -243,7 +295,8 @@ METHOD(tls_fragmentation_t, destroy, void,
|
||||||
/**
|
/**
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake)
|
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
|
||||||
|
tls_application_t *application)
|
||||||
{
|
{
|
||||||
private_tls_fragmentation_t *this;
|
private_tls_fragmentation_t *this;
|
||||||
|
|
||||||
|
@ -254,6 +307,7 @@ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake)
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.handshake = handshake,
|
.handshake = handshake,
|
||||||
|
.application = application,
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|
|
@ -27,6 +27,7 @@ typedef struct tls_fragmentation_t tls_fragmentation_t;
|
||||||
|
|
||||||
#include "tls.h"
|
#include "tls.h"
|
||||||
#include "tls_handshake.h"
|
#include "tls_handshake.h"
|
||||||
|
#include "tls_handshake.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TLS record protocol fragmentation layer.
|
* TLS record protocol fragmentation layer.
|
||||||
|
@ -70,8 +71,10 @@ struct tls_fragmentation_t {
|
||||||
* Create a tls_fragmentation instance.
|
* Create a tls_fragmentation instance.
|
||||||
*
|
*
|
||||||
* @param handshake upper layer handshake protocol
|
* @param handshake upper layer handshake protocol
|
||||||
|
* @param application upper layer application data or NULL
|
||||||
* @return TLS fragmentation layer.
|
* @return TLS fragmentation layer.
|
||||||
*/
|
*/
|
||||||
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake);
|
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
|
||||||
|
tls_application_t *application);
|
||||||
|
|
||||||
#endif /** TLS_FRAGMENTATION_H_ @}*/
|
#endif /** TLS_FRAGMENTATION_H_ @}*/
|
||||||
|
|
|
@ -73,6 +73,13 @@ struct tls_handshake_t {
|
||||||
*/
|
*/
|
||||||
bool (*change_cipherspec)(tls_handshake_t *this);
|
bool (*change_cipherspec)(tls_handshake_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the finished message was decoded successfully.
|
||||||
|
*
|
||||||
|
* @return TRUE if finished message was decoded successfully
|
||||||
|
*/
|
||||||
|
bool (*finished)(tls_handshake_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a tls_handshake_t.
|
* Destroy a tls_handshake_t.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -621,6 +621,12 @@ METHOD(tls_handshake_t, change_cipherspec, bool,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(tls_handshake_t, finished, bool,
|
||||||
|
private_tls_peer_t *this)
|
||||||
|
{
|
||||||
|
return this->state == STATE_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tls_handshake_t, destroy, void,
|
METHOD(tls_handshake_t, destroy, void,
|
||||||
private_tls_peer_t *this)
|
private_tls_peer_t *this)
|
||||||
{
|
{
|
||||||
|
@ -644,6 +650,7 @@ tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto,
|
||||||
.build = _build,
|
.build = _build,
|
||||||
.cipherspec_changed = _cipherspec_changed,
|
.cipherspec_changed = _cipherspec_changed,
|
||||||
.change_cipherspec = _change_cipherspec,
|
.change_cipherspec = _change_cipherspec,
|
||||||
|
.finished = _finished,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.state = STATE_INIT,
|
.state = STATE_INIT,
|
||||||
|
|
|
@ -583,6 +583,12 @@ METHOD(tls_handshake_t, change_cipherspec, bool,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(tls_handshake_t, finished, bool,
|
||||||
|
private_tls_server_t *this)
|
||||||
|
{
|
||||||
|
return this->state == STATE_FINISHED_SENT;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tls_handshake_t, destroy, void,
|
METHOD(tls_handshake_t, destroy, void,
|
||||||
private_tls_server_t *this)
|
private_tls_server_t *this)
|
||||||
{
|
{
|
||||||
|
@ -606,6 +612,7 @@ tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto,
|
||||||
.build = _build,
|
.build = _build,
|
||||||
.cipherspec_changed = _cipherspec_changed,
|
.cipherspec_changed = _cipherspec_changed,
|
||||||
.change_cipherspec = _change_cipherspec,
|
.change_cipherspec = _change_cipherspec,
|
||||||
|
.finished = _finished,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.tls = tls,
|
.tls = tls,
|
||||||
|
|
Loading…
Reference in New Issue