Implemented PT-EAP protocol (RFC 7171)

This commit is contained in:
Andreas Steffen
2014-05-12 06:59:21 +02:00
parent ab21875f50
commit 8d59090349
56 changed files with 337 additions and 236 deletions
+68 -45
View File
@@ -47,7 +47,7 @@ struct private_tls_eap_t {
/**
* Current value of EAP identifier
*/
u_int8_t identifier;
uint8_t identifier;
/**
* TLS stack
@@ -59,6 +59,11 @@ struct private_tls_eap_t {
*/
bool is_server;
/**
* Supported version of the EAP tunnel protocol
*/
uint8_t supported_version;
/**
* If FALSE include the total length of an EAP message
* in the first fragment of fragmented messages only.
@@ -94,22 +99,24 @@ typedef enum {
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_TTLS_VERSION = (0x07), /* shared with EAP-TNC/PEAP/PT-EAP */
EAP_PT_START = (1<<7) /* PT-EAP only */
} eap_tls_flags_t;
#define EAP_TTLS_SUPPORTED_VERSION 0
#define EAP_TNC_SUPPORTED_VERSION 1
#define EAP_PEAP_SUPPORTED_VERSION 0
#define EAP_TTLS_SUPPORTED_VERSION 0
#define EAP_TNC_SUPPORTED_VERSION 1
#define EAP_PEAP_SUPPORTED_VERSION 0
#define EAP_PT_EAP_SUPPORTED_VERSION 1
/**
* EAP-TLS/TTLS packet format
*/
typedef struct __attribute__((packed)) {
u_int8_t code;
u_int8_t identifier;
u_int16_t length;
u_int8_t type;
u_int8_t flags;
uint8_t code;
uint8_t identifier;
uint16_t length;
uint8_t type;
uint8_t flags;
} eap_tls_packet_t;
METHOD(tls_eap_t, initiate, status_t,
@@ -120,18 +127,18 @@ METHOD(tls_eap_t, initiate, status_t,
eap_tls_packet_t pkt = {
.type = this->type,
.code = EAP_REQUEST,
.flags = EAP_TLS_START,
.flags = this->supported_version
};
switch (this->type)
{
case EAP_TLS:
case EAP_TTLS:
pkt.flags |= EAP_TTLS_SUPPORTED_VERSION;
break;
case EAP_TNC:
pkt.flags |= EAP_TNC_SUPPORTED_VERSION;
break;
case EAP_PEAP:
pkt.flags |= EAP_PEAP_SUPPORTED_VERSION;
pkt.flags |= EAP_TLS_START;
break;
case EAP_PT_EAP:
pkt.flags |= EAP_PT_START;
break;
default:
break;
@@ -153,13 +160,25 @@ METHOD(tls_eap_t, initiate, status_t,
*/
static status_t process_pkt(private_tls_eap_t *this, eap_tls_packet_t *pkt)
{
u_int16_t pkt_len;
u_int32_t msg_len;
uint8_t version;
uint16_t pkt_len;
uint32_t msg_len;
size_t msg_len_offset = 0;
/* EAP-TLS doesn't have a version field */
if (this->type != EAP_TLS)
{
version = pkt->flags & EAP_TTLS_VERSION;
if (version != this->supported_version)
{
DBG1(DBG_TLS, "received %N packet with unsupported version v%u",
eap_type_names, this->type, version);
return FAILED;
}
}
pkt_len = untoh16(&pkt->length);
if (pkt->flags & EAP_TLS_LENGTH)
if (this->type != EAP_PT_EAP && (pkt->flags & EAP_TLS_LENGTH))
{
if (pkt_len < sizeof(eap_tls_packet_t) + sizeof(msg_len))
{
@@ -200,27 +219,12 @@ static status_t build_pkt(private_tls_eap_t *this, chunk_t *out)
pkt->code = this->is_server ? EAP_REQUEST : EAP_RESPONSE;
pkt->identifier = this->identifier;
pkt->type = this->type;
pkt->flags = 0;
switch (this->type)
{
case EAP_TTLS:
pkt->flags |= EAP_TTLS_SUPPORTED_VERSION;
break;
case EAP_TNC:
pkt->flags |= EAP_TNC_SUPPORTED_VERSION;
break;
case EAP_PEAP:
pkt->flags |= EAP_PEAP_SUPPORTED_VERSION;
break;
default:
break;
}
pkt->flags = this->supported_version;
if (this->first_fragment)
{
len = sizeof(buf) - sizeof(eap_tls_packet_t) - sizeof(u_int32_t);
msg_len_offset = sizeof(u_int32_t);
len = sizeof(buf) - sizeof(eap_tls_packet_t) - sizeof(uint32_t);
msg_len_offset = sizeof(uint32_t);
}
else
{
@@ -251,7 +255,7 @@ static status_t build_pkt(private_tls_eap_t *this, chunk_t *out)
}
kind = "packet";
}
else if (this->type != EAP_TNC)
else if (this->type != EAP_TNC && this->type != EAP_PT_EAP)
{
this->first_fragment = TRUE;
kind = "final fragment";
@@ -269,14 +273,14 @@ static status_t build_pkt(private_tls_eap_t *this, chunk_t *out)
if (pkt->flags & EAP_TLS_LENGTH)
{
htoun32(pkt + 1, reclen);
len += sizeof(u_int32_t);
len += sizeof(uint32_t);
pkt->flags |= EAP_TLS_LENGTH;
}
else
{
/* get rid of the reserved length field */
memmove(buf + sizeof(eap_tls_packet_t),
buf + sizeof(eap_tls_packet_t) + sizeof(u_int32_t), len);
buf + sizeof(eap_tls_packet_t) + sizeof(uint32_t), len);
}
}
len += sizeof(eap_tls_packet_t);
@@ -352,10 +356,11 @@ METHOD(tls_eap_t, process, status_t,
}
DBG3(DBG_TLS, "%N payload %B", eap_type_names, this->type, &in);
if (pkt->flags & EAP_TLS_START)
if ((this->type == EAP_PT_EAP && (pkt->flags & EAP_PT_START)) ||
(pkt->flags & EAP_TLS_START))
{
if (this->type == EAP_TTLS || this->type == EAP_TNC ||
this->type == EAP_PEAP)
this->type == EAP_PEAP || this->type == EAP_PT_EAP)
{
DBG1(DBG_TLS, "%N version is v%u", eap_type_names, this->type,
pkt->flags & EAP_TTLS_VERSION);
@@ -409,14 +414,14 @@ 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,
METHOD(tls_eap_t, get_identifier, uint8_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)
private_tls_eap_t *this, uint8_t identifier)
{
this->identifier = identifier;
}
@@ -452,13 +457,31 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
},
.type = type,
.is_server = tls->is_server(tls),
.first_fragment = (type != EAP_TNC),
.first_fragment = (type != EAP_TNC && type != EAP_PT_EAP),
.frag_size = frag_size,
.max_msg_count = max_msg_count,
.include_length = include_length,
.tls = tls,
);
switch (type)
{
case EAP_TTLS:
this->supported_version = EAP_TTLS_SUPPORTED_VERSION;
break;
case EAP_TNC:
this->supported_version = EAP_TNC_SUPPORTED_VERSION;
break;
case EAP_PEAP:
this->supported_version = EAP_PEAP_SUPPORTED_VERSION;
break;
case EAP_PT_EAP:
this->supported_version = EAP_PT_EAP_SUPPORTED_VERSION;
break;
default:
break;
}
if (this->is_server)
{
do
+2 -2
View File
@@ -66,7 +66,7 @@ struct tls_eap_t {
*
* @return identifier
*/
u_int8_t (*get_identifier)(tls_eap_t *this);
uint8_t (*get_identifier)(tls_eap_t *this);
/**
* Set the EAP identifier to a deterministic value, overwriting
@@ -74,7 +74,7 @@ struct tls_eap_t {
*
* @param identifier EAP identifier
*/
void (*set_identifier) (tls_eap_t *this, u_int8_t identifier);
void (*set_identifier) (tls_eap_t *this, uint8_t identifier);
/**
* Destroy a tls_eap_t.