📄 eapfast.c
字号:
/**
* EAP-FAST Function implementations
*
* Licensed under a dual GPL/BSD license. (See LICENSE file for more info.)
*
* \file eapfast.c
*
* \author chris@open1x.org
*
* \todo Add IPC error message signaling.
* \todo Add support for temporary username/password pairs.
*
* $Id: eapfast.c,v 1.1.2.27 2007/07/11 01:12:35 chessing Exp $
* $Date: 2007/07/11 01:12:35 $
**/
#ifdef EAP_FAST
#include <string.h>
#include <stdlib.h>
#include "profile.h"
#include "xsupconfig.h"
#include "xsup_debug.h"
#include "xsup_err.h"
#include "frame_structs.h"
#include "xsup_common.h"
#include "eap_sm.h"
#include "eapfast.h"
#include "eapfast_phase2.h"
#include "eapfast_xml.h"
#include "eap_types/tls/eaptls.h"
#include "eap_types/tls/tls_funcs.h"
#include "eap_types/eap_type_common.h"
#ifdef USE_EFENCE
#include <efence.h>
#endif
/****************************************************************
*
* This is called if methodState == INIT. It should set up all of the
* memory that we will need to complete the authentication.
*
****************************************************************/
uint8_t eapfast_init(eap_type_data *eapdata)
{
struct tls_vars *mytls_vars;
struct config_eap_fast *fastconf;
struct eapfast_phase2 *fastphase2;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return FALSE;
fastconf = (struct config_eap_fast *)eapdata->eap_conf_data;
if (!xsup_assert((fastconf != NULL), "fastconf != NULL", FALSE))
return FALSE;
if (eapdata->eap_data == NULL)
{
eapdata->eap_data = Malloc(sizeof(struct tls_vars));
if (eapdata->eap_data == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store FAST "
"specific data structures.\n");
return FALSE;
}
}
mytls_vars = eapdata->eap_data;
if (tls_funcs_init(mytls_vars, EAP_TYPE_FAST) != XENONE)
{
debug_printf(DEBUG_NORMAL, "Couldn't initialize SSL engine!\n");
return FALSE;
}
if (tls_funcs_build_new_session(mytls_vars) != XENONE)
{
debug_printf(DEBUG_NORMAL, "Couldn't initialize SSL context!\n");
return FALSE;
}
mytls_vars->cncheck = FALSE;
mytls_vars->cnexact = FALSE;
mytls_vars->resume = RES_NO;
FREE(mytls_vars->keyblock);
fastphase2 = (struct eapfast_phase2 *)Malloc(sizeof(struct eapfast_phase2));
if (fastphase2 == NULL)
{
debug_printf(DEBUG_NORMAL, "Error allocating memory for EAP-FAST phase"
" data!\n");
return FALSE;
}
mytls_vars->phase2data = fastphase2;
mytls_vars->handshake_done = FALSE;
eapfast_phase2_init(eapdata);
eap_type_common_init_eap_data(eapdata);
eapdata->methodState = MAY_CONT;
return TRUE;
}
/****************************************************************
*
* Get the version number we have stored away. If something goes
* wrong, we will return 0, which should cause the server to reject
* our request.
*
****************************************************************/
uint8_t eapfast_get_ver(eap_type_data *eapdata)
{
struct tls_vars *mytls_vars;
struct eapfast_phase2 *fastphase2;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return 0;
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
return 0;
mytls_vars = (struct tls_vars *)eapdata->eap_data;
if (!xsup_assert((mytls_vars->phase2data != NULL),
"mytls_vars->phase2data != NULL", FALSE))
return 0;
fastphase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
return fastphase2->version;
}
/****************************************************************
*
* Set the value of the version number. Store it in a structure
* for later use.
*
****************************************************************/
void eapfast_set_ver(eap_type_data *eapdata, uint8_t ver)
{
struct tls_vars *mytls_vars;
struct eapfast_phase2 *fastphase2;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return;
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
{
eap_type_common_fail(eapdata);
return;
}
mytls_vars = (struct tls_vars *)eapdata->eap_data;
if (!xsup_assert((mytls_vars->phase2data != NULL),
"mytls_vars->phase2data != NULL", FALSE))
{
eap_type_common_fail(eapdata);
return;
}
fastphase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
if (ver == 0)
{
debug_printf(DEBUG_NORMAL, "Invalid version requested for EAP-FAST! "
"Version 0 is not allowed.\n");
eap_type_common_fail(eapdata);
return;
}
if (ver > FAST_MAX_VER)
{
debug_printf(DEBUG_AUTHTYPES, "The server requested version %d. But, "
"the highest we support is %d. Requesting we use %d.\n",
ver, FAST_MAX_VER, FAST_MAX_VER);
fastphase2->version = FAST_MAX_VER;
}
else
{
fastphase2->version = ver;
}
}
/****************************************************************
*
* Check to be sure we are ready to handle an EAP-FAST authentication.
*
****************************************************************/
void eapfast_check(eap_type_data *eapdata)
{
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return;
if (!xsup_assert((eapdata->eap_conf_data != NULL),
"eapdata->eap_conf_data != NULL", FALSE))
{
eap_type_common_fail(eapdata);
return;
}
debug_printf(DEBUG_AUTHTYPES, "(EAP-FAST) Checking...\n");
if (eapdata->methodState == INIT)
{
if (eapfast_init(eapdata) != TRUE)
{
debug_printf(DEBUG_NORMAL, "Failed to init EAP-FAST!\n");
eap_type_common_fail(eapdata);
return;
}
}
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
{
eap_type_common_fail(eapdata);
return;
}
eapfast_phase2_check(eapdata);
}
/***************************************************************
*
* Read an AID from the first packet.
*
***************************************************************/
uint8_t eapfast_get_aid(uint8_t *indata, uint8_t **aid, uint16_t *aid_len)
{
struct eapfast_tlv *fasttlv;
uint8_t *tempaid;
if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
return FALSE;
fasttlv = (struct eapfast_tlv *)indata;
if (ntohs(fasttlv->type) != FAST_AUTHORITY_ID)
{
debug_printf(DEBUG_AUTHTYPES, "Not an authority ID TLV!\n");
return FALSE;
}
// Otherwise, make a copy for later use.
(*aid_len) = ntohs(fasttlv->length);
tempaid = (uint8_t *)Malloc((*aid_len));
if (tempaid == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store AID.\n");
return FALSE;
}
memcpy(tempaid, fasttlv->data, (*aid_len));
(*aid) = tempaid;
return TRUE;
}
/***************************************************************
*
* Given an AID, parse the PAC file and see if we have any valid
* authentication data that can be used. Based on what we find, we
* should prep the TLS library to behave correctly.
*
***************************************************************/
uint8_t eapfast_check_pac(eap_type_data *eapdata, uint8_t *aid,
uint16_t aid_len)
{
struct config_eap_fast *eapfast_config;
struct eapfast_phase2 *fastp2;
struct tls_vars *mytls_vars;
char *straid = NULL;
xmlDocPtr doc;
if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
return FALSE;
if (!xsup_assert((eapdata->eap_conf_data != NULL),
"eapdata->eap_conf_data != NULL", FALSE))
{
eap_type_common_fail(eapdata);
return FALSE;
}
if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
FALSE))
{
eap_type_common_fail(eapdata);
return FALSE;
}
eapfast_config = (struct config_eap_fast *)eapdata->eap_conf_data;
mytls_vars = eapdata->eap_data;
if (!xsup_assert((mytls_vars->phase2data != NULL),
"mytls_vars->phase2data != NULL", FALSE))
{
eap_type_common_fail(eapdata);
return FALSE;
}
fastp2 = mytls_vars->phase2data;
// Convert AID to a string.
straid = eap_type_common_convert_hex(aid, aid_len);
// Search for the AID in the XML file.
eapfast_xml_init();
doc = eapfast_xml_open_pac(eapfast_config->pac_location);
if (doc == NULL)
{
eapfast_xml_deinit(doc);
return FALSE;
}
fastp2->pacs = Malloc(sizeof(struct pac_values));
if (fastp2->pacs == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store PAC data!\n");
return FALSE;
}
if (eapfast_xml_find_pac_data(doc, straid, fastp2->pacs) != 0)
{
eapfast_xml_deinit(doc);
FREE(fastp2->pacs);
return FALSE;
}
// If it is there, then store it and return TRUE.
eapfast_xml_deinit(doc);
return TRUE;
}
/***************************************************************
*
* Given the server random, create the master secret, and pass
* it in to the TLS engine.
*
***************************************************************/
int eapfast_calc_master_secret(struct tls_vars *mytls_vars,
uint8_t *server_random)
{
uint8_t *client_random, *master_secret;
uint8_t randoms[64];
struct eapfast_phase2 *phase2;
if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
return -1;
if (!xsup_assert((server_random != NULL), "server_random != NULL", FALSE))
return -1;
phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
client_random = tls_funcs_get_client_random(mytls_vars);
memcpy(&randoms[0], server_random, 32);
memcpy(&randoms[32], client_random, 32);
debug_printf(DEBUG_AUTHTYPES, "Server Random : \n");
debug_hex_dump(DEBUG_AUTHTYPES, server_random, 32);
debug_printf(DEBUG_AUTHTYPES, "Client Random : \n");
debug_hex_dump(DEBUG_AUTHTYPES, client_random, 32);
debug_printf(DEBUG_AUTHTYPES, "PAC Key : \n");
debug_hex_dump(DEBUG_AUTHTYPES, phase2->pacs->pac_key, 32);
debug_printf(DEBUG_AUTHTYPES, "Randoms : \n");
debug_hex_dump(DEBUG_AUTHTYPES, randoms, 64);
debug_printf(DEBUG_AUTHTYPES, "Label : %s\n", FAST_PAC_TO_MSLH);
master_secret = eapfast_phase2_t_prf(phase2->pacs->pac_key, 32,
FAST_PAC_TO_MSLH, randoms, 64, 48);
debug_printf(DEBUG_AUTHTYPES, "Master Secret :\n");
debug_hex_dump(DEBUG_AUTHTYPES, master_secret, 48);
if (tls_funcs_set_master_secret(mytls_vars, master_secret, 48) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't set master secret!\n");
return -1;
}
FREE(master_secret);
FREE(client_random);
return 0;
}
/***************************************************************
*
* (pre)Process a TLS packet to see if it contains the server random.
* If it does, then calculate the MSK, and feed it back in to the
* SSL engine.
*
***************************************************************/
void eapfast_parse_tls(struct tls_vars *mytls_vars, uint8_t *packet)
{
struct eapfast_phase2 *phase2;
struct tls_server_hello *hello;
if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
return;
if (!xsup_assert((packet != NULL), "packet != NULL", FALSE))
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -