implemented get|set_identifier() for tls_eap_t

This commit is contained in:
Andreas Steffen
2011-04-05 18:14:58 +02:00
parent 2e44a2753f
commit 6f69fb0134
2 changed files with 85 additions and 24 deletions
+70 -24
View File
@@ -40,6 +40,11 @@ struct private_tls_eap_t {
*/
eap_type_t type;
/**
* Current value of EAP identifier
*/
u_int8_t identifier;
/**
* TLS stack
*/
@@ -75,14 +80,15 @@ struct private_tls_eap_t {
* Flags of an EAP-TLS/TTLS/TNC message
*/
typedef enum {
EAP_TLS_LENGTH = (1<<7), /* shared with EAP-TTLS/TNC */
EAP_TLS_MORE_FRAGS = (1<<6), /* shared with EAP-TTLS/TNC */
EAP_TLS_START = (1<<5), /* shared with EAP-TTLS/TNC */
EAP_TTLS_VERSION = (0x07), /* shared with EAP-TNC */
EAP_TLS_LENGTH = (1<<7), /* shared with EAP-TTLS/TNC/PEAP */
EAP_TLS_MORE_FRAGS = (1<<6), /* shared with EAP-TTLS/TNC/PEAP */
EAP_TLS_START = (1<<5), /* shared with EAP-TTLS/TNC/PEAP */
EAP_TTLS_VERSION = (0x07), /* shared with EAP-TNC/PEAP */
} eap_tls_flags_t;
#define EAP_TTLS_SUPPORTED_VERSION 0
#define EAP_TNC_SUPPORTED_VERSION 1
#define EAP_PEAP_SUPPORTED_VERSION 0
/**
* EAP-TLS/TTLS packet format
@@ -113,15 +119,14 @@ METHOD(tls_eap_t, initiate, status_t,
case EAP_TNC:
pkt.flags |= EAP_TNC_SUPPORTED_VERSION;
break;
case EAP_PEAP:
pkt.flags |= EAP_PEAP_SUPPORTED_VERSION;
break;
default:
break;
}
htoun16(&pkt.length, sizeof(eap_tls_packet_t));
do
{ /* start with non-zero random identifier */
pkt.identifier = random();
}
while (!pkt.identifier);
pkt.identifier = this->identifier;
DBG2(DBG_IKE, "sending %N start packet", eap_type_names, this->type);
*out = chunk_clone(chunk_from_thing(pkt));
@@ -163,8 +168,7 @@ static status_t process_pkt(private_tls_eap_t *this, eap_tls_packet_t *pkt)
/**
* Build a packet to send
*/
static status_t build_pkt(private_tls_eap_t *this,
u_int8_t identifier, chunk_t *out)
static status_t build_pkt(private_tls_eap_t *this, chunk_t *out)
{
char buf[this->frag_size];
eap_tls_packet_t *pkt;
@@ -172,9 +176,13 @@ static status_t build_pkt(private_tls_eap_t *this,
status_t status;
char *kind;
if (this->is_server)
{
this->identifier++;
}
pkt = (eap_tls_packet_t*)buf;
pkt->code = this->is_server ? EAP_REQUEST : EAP_RESPONSE;
pkt->identifier = this->is_server ? identifier + 1 : identifier;
pkt->identifier = this->identifier;
pkt->type = this->type;
pkt->flags = 0;
@@ -186,6 +194,9 @@ static status_t build_pkt(private_tls_eap_t *this,
case EAP_TNC:
pkt->flags |= EAP_TNC_SUPPORTED_VERSION;
break;
case EAP_PEAP:
pkt->flags |= EAP_PEAP_SUPPORTED_VERSION;
break;
default:
break;
}
@@ -242,22 +253,31 @@ static status_t build_pkt(private_tls_eap_t *this,
/**
* Send an ack to request next fragment
*/
static chunk_t create_ack(private_tls_eap_t *this, u_int8_t identifier)
static chunk_t create_ack(private_tls_eap_t *this)
{
eap_tls_packet_t pkt = {
.code = this->is_server ? EAP_REQUEST : EAP_RESPONSE,
.identifier = this->is_server ? identifier + 1 : identifier,
.type = this->type,
};
if (this->is_server)
{
this->identifier++;
}
pkt.identifier = this->identifier;
htoun16(&pkt.length, sizeof(pkt));
switch (this->type)
{
case EAP_TTLS:
pkt.flags |= EAP_TTLS_SUPPORTED_VERSION;
break;
break;
case EAP_TNC:
pkt.flags |= EAP_TNC_SUPPORTED_VERSION;
break;
case EAP_PEAP:
pkt.flags |= EAP_PEAP_SUPPORTED_VERSION;
break;
default:
break;
}
@@ -281,16 +301,19 @@ METHOD(tls_eap_t, process, status_t,
}
pkt = (eap_tls_packet_t*)in.ptr;
if (in.len < sizeof(eap_tls_packet_t) ||
untoh16(&pkt->length) != in.len)
if (in.len < sizeof(eap_tls_packet_t) || untoh16(&pkt->length) != in.len)
{
DBG1(DBG_IKE, "invalid %N packet length",
eap_type_names, this->type);
DBG1(DBG_IKE, "invalid %N packet length", eap_type_names, this->type);
return FAILED;
}
/* update EAP identifier */
this->identifier = pkt->identifier;
if (pkt->flags & EAP_TLS_START)
{
if (this->type == EAP_TTLS || this->type == EAP_TNC)
if (this->type == EAP_TTLS || this->type == EAP_TNC ||
this->type == EAP_PEAP)
{
DBG1(DBG_TLS, "%N version is v%u", eap_type_names, this->type,
pkt->flags & EAP_TTLS_VERSION);
@@ -302,7 +325,7 @@ METHOD(tls_eap_t, process, status_t,
{
DBG2(DBG_TLS, "received %N acknowledgement packet",
eap_type_names, this->type);
status = build_pkt(this, pkt->identifier, out);
status = build_pkt(this, out);
if (status == INVALID_STATE && this->tls->is_complete(this->tls))
{
return SUCCESS;
@@ -320,16 +343,16 @@ METHOD(tls_eap_t, process, status_t,
return status;
}
}
status = build_pkt(this, pkt->identifier, out);
status = build_pkt(this, out);
switch (status)
{
case INVALID_STATE:
*out = create_ack(this, pkt->identifier);
*out = create_ack(this);
return NEED_MORE;
case FAILED:
if (!this->is_server)
{
*out = create_ack(this, pkt->identifier);
*out = create_ack(this);
return NEED_MORE;
}
return FAILED;
@@ -344,6 +367,18 @@ METHOD(tls_eap_t, get_msk, chunk_t,
return this->tls->get_eap_msk(this->tls);
}
METHOD(tls_eap_t, get_identifier, u_int8_t,
private_tls_eap_t *this)
{
return this->identifier;
}
METHOD(tls_eap_t, set_identifier, void,
private_tls_eap_t *this, u_int8_t identifier)
{
this->identifier = identifier;
}
METHOD(tls_eap_t, destroy, void,
private_tls_eap_t *this)
{
@@ -369,6 +404,8 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
.initiate = _initiate,
.process = _process,
.get_msk = _get_msk,
.get_identifier = _get_identifier,
.set_identifier = _set_identifier,
.destroy = _destroy,
},
.type = type,
@@ -379,5 +416,14 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
.tls = tls,
);
if (this->is_server)
{
do
{ /* start with non-zero random identifier */
this->identifier = random();
}
while (!this->identifier);
}
return &this->public;
}
+15
View File
@@ -61,6 +61,21 @@ struct tls_eap_t {
*/
chunk_t (*get_msk)(tls_eap_t *this);
/**
* Get the current EAP identifier.
*
* @return identifier
*/
u_int8_t (*get_identifier)(tls_eap_t *this);
/**
* Set the EAP identifier to a deterministic value, overwriting
* the randomly initialized default value.
*
* @param identifier EAP identifier
*/
void (*set_identifier) (tls_eap_t *this, u_int8_t identifier);
/**
* Destroy a tls_eap_t.
*/