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; eap_type_t type;
/**
* Current value of EAP identifier
*/
u_int8_t identifier;
/** /**
* TLS stack * TLS stack
*/ */
@@ -75,14 +80,15 @@ struct private_tls_eap_t {
* Flags of an EAP-TLS/TTLS/TNC message * Flags of an EAP-TLS/TTLS/TNC message
*/ */
typedef enum { typedef enum {
EAP_TLS_LENGTH = (1<<7), /* shared with EAP-TTLS/TNC */ EAP_TLS_LENGTH = (1<<7), /* shared with EAP-TTLS/TNC/PEAP */
EAP_TLS_MORE_FRAGS = (1<<6), /* shared with EAP-TTLS/TNC */ EAP_TLS_MORE_FRAGS = (1<<6), /* shared with EAP-TTLS/TNC/PEAP */
EAP_TLS_START = (1<<5), /* shared with EAP-TTLS/TNC */ EAP_TLS_START = (1<<5), /* shared with EAP-TTLS/TNC/PEAP */
EAP_TTLS_VERSION = (0x07), /* shared with EAP-TNC */ EAP_TTLS_VERSION = (0x07), /* shared with EAP-TNC/PEAP */
} eap_tls_flags_t; } eap_tls_flags_t;
#define EAP_TTLS_SUPPORTED_VERSION 0 #define EAP_TTLS_SUPPORTED_VERSION 0
#define EAP_TNC_SUPPORTED_VERSION 1 #define EAP_TNC_SUPPORTED_VERSION 1
#define EAP_PEAP_SUPPORTED_VERSION 0
/** /**
* EAP-TLS/TTLS packet format * EAP-TLS/TTLS packet format
@@ -113,15 +119,14 @@ METHOD(tls_eap_t, initiate, status_t,
case EAP_TNC: case EAP_TNC:
pkt.flags |= EAP_TNC_SUPPORTED_VERSION; pkt.flags |= EAP_TNC_SUPPORTED_VERSION;
break; break;
case EAP_PEAP:
pkt.flags |= EAP_PEAP_SUPPORTED_VERSION;
break;
default: default:
break; break;
} }
htoun16(&pkt.length, sizeof(eap_tls_packet_t)); htoun16(&pkt.length, sizeof(eap_tls_packet_t));
do pkt.identifier = this->identifier;
{ /* start with non-zero random identifier */
pkt.identifier = random();
}
while (!pkt.identifier);
DBG2(DBG_IKE, "sending %N start packet", eap_type_names, this->type); DBG2(DBG_IKE, "sending %N start packet", eap_type_names, this->type);
*out = chunk_clone(chunk_from_thing(pkt)); *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 * Build a packet to send
*/ */
static status_t build_pkt(private_tls_eap_t *this, static status_t build_pkt(private_tls_eap_t *this, chunk_t *out)
u_int8_t identifier, chunk_t *out)
{ {
char buf[this->frag_size]; char buf[this->frag_size];
eap_tls_packet_t *pkt; eap_tls_packet_t *pkt;
@@ -172,9 +176,13 @@ static status_t build_pkt(private_tls_eap_t *this,
status_t status; status_t status;
char *kind; char *kind;
if (this->is_server)
{
this->identifier++;
}
pkt = (eap_tls_packet_t*)buf; pkt = (eap_tls_packet_t*)buf;
pkt->code = this->is_server ? EAP_REQUEST : EAP_RESPONSE; 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->type = this->type;
pkt->flags = 0; pkt->flags = 0;
@@ -186,6 +194,9 @@ static status_t build_pkt(private_tls_eap_t *this,
case EAP_TNC: case EAP_TNC:
pkt->flags |= EAP_TNC_SUPPORTED_VERSION; pkt->flags |= EAP_TNC_SUPPORTED_VERSION;
break; break;
case EAP_PEAP:
pkt->flags |= EAP_PEAP_SUPPORTED_VERSION;
break;
default: default:
break; break;
} }
@@ -242,22 +253,31 @@ static status_t build_pkt(private_tls_eap_t *this,
/** /**
* Send an ack to request next fragment * 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 = { eap_tls_packet_t pkt = {
.code = this->is_server ? EAP_REQUEST : EAP_RESPONSE, .code = this->is_server ? EAP_REQUEST : EAP_RESPONSE,
.identifier = this->is_server ? identifier + 1 : identifier,
.type = this->type, .type = this->type,
}; };
if (this->is_server)
{
this->identifier++;
}
pkt.identifier = this->identifier;
htoun16(&pkt.length, sizeof(pkt)); htoun16(&pkt.length, sizeof(pkt));
switch (this->type) switch (this->type)
{ {
case EAP_TTLS: case EAP_TTLS:
pkt.flags |= EAP_TTLS_SUPPORTED_VERSION; pkt.flags |= EAP_TTLS_SUPPORTED_VERSION;
break; break;
case EAP_TNC: case EAP_TNC:
pkt.flags |= EAP_TNC_SUPPORTED_VERSION; pkt.flags |= EAP_TNC_SUPPORTED_VERSION;
break; break;
case EAP_PEAP:
pkt.flags |= EAP_PEAP_SUPPORTED_VERSION;
break;
default: default:
break; break;
} }
@@ -281,16 +301,19 @@ METHOD(tls_eap_t, process, status_t,
} }
pkt = (eap_tls_packet_t*)in.ptr; pkt = (eap_tls_packet_t*)in.ptr;
if (in.len < sizeof(eap_tls_packet_t) || if (in.len < sizeof(eap_tls_packet_t) || untoh16(&pkt->length) != in.len)
untoh16(&pkt->length) != in.len)
{ {
DBG1(DBG_IKE, "invalid %N packet length", DBG1(DBG_IKE, "invalid %N packet length", eap_type_names, this->type);
eap_type_names, this->type);
return FAILED; return FAILED;
} }
/* update EAP identifier */
this->identifier = pkt->identifier;
if (pkt->flags & EAP_TLS_START) 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, DBG1(DBG_TLS, "%N version is v%u", eap_type_names, this->type,
pkt->flags & EAP_TTLS_VERSION); pkt->flags & EAP_TTLS_VERSION);
@@ -302,7 +325,7 @@ METHOD(tls_eap_t, process, status_t,
{ {
DBG2(DBG_TLS, "received %N acknowledgement packet", DBG2(DBG_TLS, "received %N acknowledgement packet",
eap_type_names, this->type); 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)) if (status == INVALID_STATE && this->tls->is_complete(this->tls))
{ {
return SUCCESS; return SUCCESS;
@@ -320,16 +343,16 @@ METHOD(tls_eap_t, process, status_t,
return status; return status;
} }
} }
status = build_pkt(this, pkt->identifier, out); status = build_pkt(this, out);
switch (status) switch (status)
{ {
case INVALID_STATE: case INVALID_STATE:
*out = create_ack(this, pkt->identifier); *out = create_ack(this);
return NEED_MORE; return NEED_MORE;
case FAILED: case FAILED:
if (!this->is_server) if (!this->is_server)
{ {
*out = create_ack(this, pkt->identifier); *out = create_ack(this);
return NEED_MORE; return NEED_MORE;
} }
return FAILED; return FAILED;
@@ -344,6 +367,18 @@ METHOD(tls_eap_t, get_msk, chunk_t,
return this->tls->get_eap_msk(this->tls); 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, METHOD(tls_eap_t, destroy, void,
private_tls_eap_t *this) 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, .initiate = _initiate,
.process = _process, .process = _process,
.get_msk = _get_msk, .get_msk = _get_msk,
.get_identifier = _get_identifier,
.set_identifier = _set_identifier,
.destroy = _destroy, .destroy = _destroy,
}, },
.type = type, .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, .tls = tls,
); );
if (this->is_server)
{
do
{ /* start with non-zero random identifier */
this->identifier = random();
}
while (!this->identifier);
}
return &this->public; return &this->public;
} }
+15
View File
@@ -61,6 +61,21 @@ struct tls_eap_t {
*/ */
chunk_t (*get_msk)(tls_eap_t *this); 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. * Destroy a tls_eap_t.
*/ */