eapfast_phase2.c
来自「linux 下通过802.1认证的安装包」· C语言 代码 · 共 1,907 行 · 第 1/4 页
C
1,907 行
fasttlv = (struct eapfast_tlv *)&phase2->result_data[phase2->result_size];
fasttlv->type = htons(FAST_EAP_PAYLOAD_TLV | MANDATORY_TLV);
fasttlv->length = htons(eapsize);
phase2->result_size += eapsize + 4; // 4 for 2 16 bit numbers that make
// up the EAP-FAST TLV headers.
}
else
{
eap_type_common_fail(eapdata);
return 0;
}
fasttlv = (struct eapfast_tlv *)indata;
return ntohs(fasttlv->length) + 4;
}
/***************************************************************
*
* Generate an error TLV.
*
***************************************************************/
uint8_t *eapfast_phase2_gen_error_tlv(uint32_t reason, uint16_t mandatory)
{
uint8_t *result;
struct eapfast_tlv_error *error;
if (result_tlv_included == FALSE) result_tlv_needed = TRUE;
result = Malloc(sizeof(struct eapfast_tlv_error));
if (result == NULL) return NULL;
error = (struct eapfast_tlv_error *)result;
error->type = htons(FAST_ERROR_TLV | mandatory);
error->length = htons(sizeof(struct eapfast_tlv_error)-4);
error->error_code = htonl(reason);
return result;
}
/********************************************************************
*
* Build a REQUEST_ACTION TLV response.
*
********************************************************************/
uint8_t *eapfast_phase2_gen_request_action_tlv(uint16_t reason)
{
uint8_t *result;
struct eapfast_tlv_request_action *action;
result = Malloc(sizeof(struct eapfast_tlv_request_action));
if (result == NULL) return NULL;
action = (struct eapfast_tlv_request_action *)result;
action->type = htons(FAST_REQUEST_ACTION_TLV | MANDATORY_TLV);
action->length = htons(sizeof(struct eapfast_tlv_request_action) - 4);
action->action = htons(reason);
return result;
}
/***************************************************************
*
* Generate our own result TLV
*
***************************************************************/
uint8_t *eapfast_phase2_get_result_tlv(uint16_t status)
{
uint8_t *result;
struct eapfast_tlv_result *resulttlv;
result = Malloc(sizeof(struct eapfast_tlv_result));
if (result == NULL) return NULL;
resulttlv = (struct eapfast_tlv_result *)result;
resulttlv->type = htons(FAST_RESULT_TLV | MANDATORY_TLV);
resulttlv->length = htons(2);
resulttlv->status = htons(status);
return result;
}
/***************************************************************
*
* Process a phase 2 result TLV message.
*
***************************************************************/
uint16_t eapfast_phase2_process_result_tlv(eap_type_data *eapdata,
uint8_t *indata, uint16_t insize)
{
struct tls_vars *mytls_vars;
struct eapfast_phase2 *phase2;
struct eapfast_tlv_result *fasttlv;
uint8_t *temp;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return 0;
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
{
eap_type_common_fail(eapdata);
return 0;
}
mytls_vars = (struct tls_vars *)eapdata->eap_data;
phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
fasttlv = (struct eapfast_tlv_result *)indata;
if (ntohs(fasttlv->length) != 2)
{
debug_printf(DEBUG_NORMAL, "Got an invalid TLV_RESULT message!\n");
temp = eapfast_phase2_gen_error_tlv(FAST_UNEXPECTED_TLVS_EXCHANGED,
(ntohs(fasttlv->type) & MANDATORY_TLV));
memcpy(&phase2->result_data[phase2->result_size], temp,
sizeof(struct eapfast_tlv_error));
FREE(temp);
phase2->result_size += sizeof(struct eapfast_tlv_error);
return ntohs(fasttlv->length);
}
if ((ntohs(fasttlv->status) < 1) || (ntohs(fasttlv->status) > 2))
{
debug_printf(DEBUG_NORMAL, "Got an invalid result value in TLV_RESULT "
"message! (Value was %d)\n", ntohs(fasttlv->status));
temp = eapfast_phase2_gen_error_tlv(FAST_UNEXPECTED_TLVS_EXCHANGED,
(ntohs(fasttlv->type) & MANDATORY_TLV));
memcpy(&phase2->result_data[phase2->result_size], temp,
sizeof(struct eapfast_tlv_error));
FREE(temp);
phase2->result_size += sizeof(struct eapfast_tlv_error);
return ntohs(fasttlv->length);
}
switch (ntohs(fasttlv->status))
{
case FAST_RESULT_SUCCESS:
debug_printf(DEBUG_NORMAL, "Inner result is a success!\n");
eapdata->methodState = CONT;
eapdata->decision = COND_SUCC;
break;
case FAST_RESULT_FAILURE:
debug_printf(DEBUG_NORMAL, "Inner result is a FAILURE!\n");
eapdata->methodState = DONE;
eapdata->decision = EAP_FAIL;
break;
}
// Create our own result TLV to be sent back.
temp = eapfast_phase2_get_result_tlv(ntohs(fasttlv->status));
memcpy(&phase2->result_data[phase2->result_size], temp,
sizeof(struct eapfast_tlv_result));
phase2->result_size += sizeof(struct eapfast_tlv_result);
return sizeof(struct eapfast_tlv_result);
}
/***************************************************************
*
* Generate our own intermediate result TLV
*
***************************************************************/
uint8_t *eapfast_phase2_get_intermediate_result_tlv(uint16_t status)
{
uint8_t *result;
struct eapfast_tlv_result *resulttlv;
result = Malloc(sizeof(struct eapfast_tlv_result));
if (result == NULL) return NULL;
resulttlv = (struct eapfast_tlv_result *)result;
resulttlv->type = htons(FAST_INTERMEDIATE_RESULT_TLV | MANDATORY_TLV);
resulttlv->length = htons(2);
resulttlv->status = htons(status);
return result;
}
/***************************************************************
*
* Our crypto binding failed. So, wipe out the data that we were
* building, and replace it with a result failure, and an error of
* binding failed.
*
***************************************************************/
void eapfast_phase2_binding_failed(eap_type_data *eapdata)
{
uint8_t *temp;
struct tls_vars *mytls_vars;
struct eapfast_phase2 *phase2;
struct eapfast_tlv *tlv;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return;
mytls_vars = (struct tls_vars *)eapdata->eap_data;
phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
// Clean out the existing data.
FREE(phase2->result_data);
phase2->result_size = 0;
// Now allocate some new memory, and fill it.
phase2->result_data = Malloc(1500);
if (phase2->result_data == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store failure "
"data!\n");
eap_type_common_fail(eapdata);
return;
}
temp = eapfast_phase2_get_result_tlv(FAST_RESULT_FAILURE);
tlv = (struct eapfast_tlv *)temp;
memcpy(phase2->result_data, temp, ntohs(tlv->length)+4);
phase2->result_size = ntohs(tlv->length)+4;
FREE(temp);
temp = eapfast_phase2_gen_error_tlv(FAST_TUNNEL_COMPROMISE_ERROR,
MANDATORY_TLV);
tlv = (struct eapfast_tlv *)temp;
memcpy(&phase2->result_data[phase2->result_size], temp,
ntohs(tlv->length)+4);
phase2->result_size += ntohs(tlv->length)+4;
debug_printf(DEBUG_AUTHTYPES, "Error result (%d) :\n", phase2->result_size);
debug_hex_dump(DEBUG_AUTHTYPES, phase2->result_data, phase2->result_size);
}
/***************************************************************
*
* Process an Intermedia result TLV.
*
***************************************************************/
int eapfast_phase2_intermediate_result_process(eap_type_data *eapdata,
uint8_t *indata,
uint16_t insize)
{
struct eapfast_tlv_result *fasttlv;
struct tls_vars *mytls_vars;
struct eapfast_phase2 *phase2;
uint8_t *temp;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return 0;
if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
{
eap_type_common_fail(eapdata);
return 0;
}
if (!xsup_assert((insize >= 6), "insize >= 6", FALSE))
{
eap_type_common_fail(eapdata);
return 0;
}
fasttlv = (struct eapfast_tlv_result *)indata;
mytls_vars = (struct tls_vars *)eapdata->eap_data;
phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
if ((ntohs(fasttlv->status) < 1) || (ntohs(fasttlv->status) > 2))
{
debug_printf(DEBUG_NORMAL, "Got an invalid result value in TLV_RESULT "
"message! (Value was %d)\n", ntohs(fasttlv->status));
temp = eapfast_phase2_gen_error_tlv(FAST_UNEXPECTED_TLVS_EXCHANGED,
(ntohs(fasttlv->type) & MANDATORY_TLV));
memcpy(&phase2->result_data[phase2->result_size], temp,
sizeof(struct eapfast_tlv_error));
FREE(temp);
phase2->result_size += sizeof(struct eapfast_tlv_error);
return ntohs(fasttlv->length);
}
switch (ntohs(fasttlv->status))
{
case FAST_RESULT_SUCCESS:
debug_printf(DEBUG_NORMAL, "Intermediate result is a success!\n");
break;
case FAST_RESULT_FAILURE:
debug_printf(DEBUG_NORMAL, "Intermediate result is a FAILURE!\n");
break;
}
// Create our own result TLV to be sent back.
temp = eapfast_phase2_get_intermediate_result_tlv(ntohs(fasttlv->status));
memcpy(&phase2->result_data[phase2->result_size], temp,
sizeof(struct eapfast_tlv_result));
phase2->result_size += sizeof(struct eapfast_tlv_result);
return sizeof(struct eapfast_tlv_result);
}
/****************************************************************
*
* The T-PRF as specified in section 5.5 of draft-cam-winget-eap-fast-03.txt.
*
* NOTE : The value of result_size is the target we are shooting for.
* If it isn't a multiple of 20, then we will round up to the next value
* of 20, and return everything. This shouldn't be a problem, since the
* caller will still get the data they need, and when the data is freed
* the extra memory will be freed as well.
*
****************************************************************/
uint8_t *eapfast_phase2_t_prf(uint8_t *key, uint16_t keylen, char *label,
uint8_t *seed, uint16_t seedlen,
uint16_t result_size)
{
uint8_t *s = NULL, *result = NULL, *feed = NULL;
uint16_t length, i, sizeofs, sizeoffeed;
uint8_t mac[20];
unsigned int mdlen;
if (!xsup_assert((key != NULL), "key != NULL", FALSE))
return NULL;
if (!xsup_assert((label != NULL), "label != NULL", FALSE))
return NULL;
if ((result_size % 20) == 0)
{
length = result_size;
}
else
{
length = (20 - (result_size % 20)) + result_size;
}
result = Malloc(length);
if (result == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to create the "
"T-PRF values!\n");
return NULL;
}
s = Malloc(strlen(label) + 1 + seedlen);
if (s == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to create 'S' in "
"the T-PRF!\n");
FREE(result);
return NULL;
}
// Create the "S".
strcpy(s, label);
s[strlen(label)] = 0x00;
if (seed != NULL)
{
memcpy(&s[strlen(label)+1], seed, seedlen);
}
sizeofs = strlen(label) + 1 + seedlen;
// Now, hash the number of times needed to generate the right amount of
// material.
for (i = 0;i < (length/20);i++)
{
if (i == 0)
{
feed = Malloc(sizeofs+4);
if (feed == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate temporary space "
"to store 'to hash' data!\n");
FREE(result);
FREE(s);
return NULL;
}
memcpy(feed, s, sizeofs);
sizeoffeed = sizeofs;
feed[sizeoffeed] = (result_size >> 8);
feed[sizeoffeed+1] = (result_size & 0xff);
sizeoffeed+=2;
feed[sizeoffeed] = 0x01;
sizeoffeed++;
}
else
{
feed = Malloc(sizeofs+20+3);
if (feed == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate temporary space "
"to store 'to hash' data!\n");
FREE(result);
FREE(s);
return NULL;
}
memcpy(feed, &result[(i-1)*20], 20);
memcpy(&feed[20], s, sizeofs);
sizeoffeed = 20 + sizeofs;
feed[sizeoffeed] = (result_size >> 8);
feed[sizeoffeed+1] = (result_size & 0xff);
sizeoffeed += 2;
feed[sizeoffeed] = (i+1);
sizeoffeed++;
}
HMAC(EVP_sha1(), key, keylen, feed, sizeoffeed, (unsigned char *)&mac,
&mdlen);
memcpy(&result[i*20], mac, 20);
FREE(feed);
sizeoffeed = 0;
}
return result;
}
/*****************************************************************
*
* Return the current S-IMCK[j].
*
*****************************************************************/
uint8_t *eapfast_phase2_get_simckj(eap_type_data *eapdata)
{
struct tls_vars *mytls_vars;
struct eapfast_phase2 *phase2;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return NULL;
mytls_vars = (struct tls_vars *)eapdata->eap_data;
phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
return phase2->simckj;
}
/****************************************************************
*
* Generate the CMK[j] needed to check the compound MAC.
*
****************************************************************/
uint8_t *eapfast_phase2_gen_cmkj(eap_type_data *eapdata)
{
struct tls_vars *mytls_vars;
struct eapfast_phase2 *phase2;
uint8_t *keyblock;
uint8_t *key;
uint8_t *cmkj;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return NULL;
mytls_vars = (struct tls_vars *)eapdata->eap_data;
phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
debug_printf(DEBUG_AUTHTYPES, "Key data :\n");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?