⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eapfast.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
 * 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 + -