implemented get|set_identifier() for tls_eap_t
This commit is contained in:
+70
-24
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user