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;
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user