*/
eap_type_t type;
+ /**
+ * Current value of EAP identifier
+ */
+ u_int8_t identifier;
+
/**
* TLS stack
*/
* 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
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));
/**
* 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;
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;
case EAP_TNC:
pkt->flags |= EAP_TNC_SUPPORTED_VERSION;
break;
+ case EAP_PEAP:
+ pkt->flags |= EAP_PEAP_SUPPORTED_VERSION;
+ break;
default:
break;
}
/**
* 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;
}
}
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);
{
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;
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;
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)
{
.initiate = _initiate,
.process = _process,
.get_msk = _get_msk,
+ .get_identifier = _get_identifier,
+ .set_identifier = _set_identifier,
.destroy = _destroy,
},
.type = type,
.tls = tls,
);
+ if (this->is_server)
+ {
+ do
+ { /* start with non-zero random identifier */
+ this->identifier = random();
+ }
+ while (!this->identifier);
+ }
+
return &this->public;
}