eapfast_phase2.c

来自「linux 下通过802.1认证的安装包」· C语言 代码 · 共 1,907 行 · 第 1/4 页

C
1,907
字号
/**
 * EAP-FAST provisioning function implementations
 *
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * \file eapfast_phase2.c
 *
 * \author chris@open1x.org
 *
 * \todo Add IPC error message signaling.
 *
 * $Id: eapfast_phase2.c,v 1.1.2.27 2007/04/20 18:35:53 chessing Exp $
 * $Date: 2007/04/20 18:35:53 $
 **/

#ifdef EAP_FAST

#include <openssl/hmac.h>

#include "xsup_err.h"
#include "xsup_debug.h"
#include "xsup_common.h"
#include "xsupconfig.h"
#include "profile.h"
#include "eap_sm.h"
#include "eap_types/tls/eaptls.h"
#include "eap_types/eap_type_common.h"
#include "eap_types/tls/tls_funcs.h"
#include "eap_types/mschapv2/eapmschapv2.h"
#include "eapfast.h"
#include "eapfast_phase2.h"
#include "eapfast_xml.h"

static uint8_t result_tlv_needed = FALSE, result_tlv_included = FALSE;

// Forward decls for things that need it.
uint8_t *eapfast_phase2_gen_error_tlv(uint32_t, uint16_t);

/***************************************************************
 *
 *  Init phase 2 for EAP-FAST.
 *
 ***************************************************************/
void eapfast_phase2_init(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars;
  struct eapfast_phase2 *phase2;
  struct config_eap_fast *fastconf;

  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;
    }

  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) Phase 2 init.\n");

  fastconf = (struct config_eap_fast *)eapdata->eap_conf_data;
  mytls_vars = (struct tls_vars *)eapdata->eap_data;

  if (mytls_vars->phase2data == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Phase 2 data is not initialized!  Your "
		   "authentication will fail!\n");
      eap_type_common_fail(eapdata);
      return;
    }

  phase2 = mytls_vars->phase2data;

  if (phase2->sm == NULL)
    {
      if (eap_sm_init(&phase2->sm) != XENONE)
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't init inner EAP state machine."
		       "\n");
	  return;
	}
	  phase2->sm->phase = 2;
    }
  else
    {
      phase2->sm->eapRestart = TRUE;
      phase2->sm->eapReq = FALSE;
    }

  FREE(phase2->simckj);

  phase2->sm->portEnabled = TRUE;
  phase2->sm->idleWhile = config_get_idleWhile();
  phase2->sm->curMethods = fastconf->phase2;
  phase2->sm->methodState = INIT;
  if (fastconf->innerid != NULL)
    {
      phase2->sm->ident = strdup(fastconf->innerid);
    }

  eap_sm_run(phase2->sm);
}

/***************************************************************
 *
 *  Clean up our phase 2 after using EAP-FAST.
 *
 ***************************************************************/
void eapfast_phase2_deinit(eap_type_data *eapdata)
{
  struct eapfast_phase2 *phase2;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return;

  if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
		   FALSE))
    return;

  debug_printf(DEBUG_AUTHTYPES, "(EAP-FAST) Phase 2 deinit.\n");

  phase2 = (struct eapfast_phase2 *)eapdata->eap_data;

  eap_sm_deinit(&phase2->sm);

  FREE(phase2->result_data);
  FREE(phase2->pkeys);

  if (phase2->pacs != NULL)
    {
      FREE(phase2->pacs->pac_opaque);
      FREE(phase2->pacs->pacinfo.aid);
      FREE(phase2->pacs->pacinfo.iid);
      FREE(phase2->pacs->pacinfo.aid_info);
    }

  FREE(phase2->simckj);
}

/***************************************************************
 *
 *  Check that everything is in place to allow the authentication to 
 *  continue!
 *
 ***************************************************************/
void eapfast_phase2_check(eap_type_data *eapdata)
{
  // Nothing much to check here.
}

/***************************************************************
 *
 *  Build a TLV NAK.
 *
 ***************************************************************/
uint16_t eapfast_phase2_tlv_nak(eap_type_data *eapdata, uint8_t *indata, 
				uint32_t vendor_id, uint16_t tlvtype)
{
  struct nak_tlvs *nak;
  struct eapfast_tlv *tlv, *srctlv;
  struct tls_vars *mytls_vars;
  struct eapfast_phase2 *phase2;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return 0;

  if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
    return 0;

  debug_printf(DEBUG_AUTHTYPES, "Building PAC NAK for Vendor ID %d, TLV type "
	       "%d!\n", vendor_id, tlvtype);

  mytls_vars = (struct tls_vars *)eapdata->eap_data;
  phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;

  srctlv = (struct eapfast_tlv *)indata;

  tlv = (struct eapfast_tlv *)&phase2->result_data[phase2->result_size];

  tlv->type = htons(FAST_NAK_TLV | MANDATORY_TLV);
  tlv->length = htons(6);     // Will always be 6, for now.

  nak = (struct nak_tlvs *)tlv->data;

  nak->vendorid = htonl(vendor_id);
  nak->naktype = htons(tlvtype);

  return srctlv->length+4;
}

/***************************************************************
 *
 *  Handle a vendor specific NAK.  (Since we don't handle vendor 
 *  specific TLVs for now.)
 *
 ***************************************************************/
uint16_t eapfast_phase2_vendor_tlv_nak(eap_type_data *eapdata, uint8_t *indata)
{
  struct vendor_tlv_type *tlv;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return 0;

  if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
    return 0;

  tlv = (struct vendor_tlv_type *)indata;

  return eapfast_phase2_tlv_nak(eapdata, indata, ntohl(tlv->vendor_id), 
				FAST_VENDOR_SPECIFIC_TLV);
}

/***************************************************************
 *
 *  Display the PAC type.
 *
 ***************************************************************/
void eapfast_phase2_PAC_id_to_str(int debuglevel, uint8_t pacid)
{
  switch (pacid)
    {
    case FAST_RESULT_TLV:
      debug_printf_nl(debuglevel, "FAST_RESULT_TLV");
      break;

    case FAST_NAK_TLV:
      debug_printf_nl(debuglevel, "FAST_NAK_TLV");
      break;

    case FAST_ERROR_TLV:
      debug_printf_nl(debuglevel, "FAST_ERROR_TLV");
      break;

    case FAST_VENDOR_SPECIFIC_TLV:
      debug_printf_nl(debuglevel, "FAST_VENDOR_SPECIFIC_TLV");
      break;

    case FAST_EAP_PAYLOAD_TLV:
      debug_printf_nl(debuglevel, "FAST_EAP_PAYLOAD_TLV");
      break;

    case FAST_INTERMEDIATE_RESULT_TLV:
      debug_printf_nl(debuglevel, "FAST_INTERMEDIATE_RESULT_TLV");
      break;

    case FAST_PAC_TLV:
      debug_printf_nl(debuglevel, "FAST_PAC_TLV");
      break;

    case FAST_CRYPTO_BINDING_TLV:
      debug_printf_nl(debuglevel, "FAST_CRYPTO_BINDING_TLV");
      break;

    case FAST_SERVER_TRUSTED_ROOT_TLV:
      debug_printf_nl(debuglevel, "FAST_SERVER_TRUSTED_ROOT_TLV");
      break;

    case FAST_REQUEST_ACTION_TLV:
      debug_printf_nl(debuglevel, "FAST_REQUEST_ACTION_TLV");
      break;

    case FAST_PKCS7_TLV:
      debug_printf_nl(debuglevel, "FAST_PKCS7_TLV");
      break;

    default:
      debug_printf_nl(debuglevel, "UNKNOWN! (%d)", pacid);
      break;
    }
}

/*******************************************************************
 *
 *  Process a PAC-Key TLV.
 *
 *******************************************************************/
uint16_t eapfast_phase2_process_pac_key(uint8_t *indata, uint8_t *pac_key)
{
  struct eapfast_tlv *fasttlv;

  if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
    return 0;

  if (!xsup_assert((pac_key != NULL), "pac_key != NULL", FALSE))
    return 0;

  fasttlv = (struct eapfast_tlv *)indata;

  if (ntohs(fasttlv->length) != 32)
    {
      debug_printf(DEBUG_NORMAL, "Invalid PAC-Key length of %d!\n",
		   ntohs(fasttlv->length));
      return 0;
    }

  memcpy(pac_key, &indata[4], 32);

  return 36;        // Should always be the length of the PAC-Info TLV.
}

/*******************************************************************
 *
 *  Process a PAC-Opaque TLV.
 *
 *******************************************************************/
uint16_t eapfast_phase2_process_pac_opaque(uint8_t *indata, 
					   uint8_t **pac_opaque, uint16_t *len)
{
  struct eapfast_tlv *fasttlv;
  uint8_t *opaque;

  if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
    return 0;

  if (!xsup_assert((pac_opaque != NULL), "pac_opaque != NULL", FALSE))
    return 0;

  fasttlv = (struct eapfast_tlv *)indata;

  debug_printf(DEBUG_AUTHTYPES, "PAC-Opaque is %d byte(s) long.\n",
	       ntohs(fasttlv->length));
  *len = ntohs(fasttlv->length) + 4;

  opaque = Malloc(ntohs(fasttlv->length)+4);
  if (opaque == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store temporary"
		   " PAC-Opaque value!\n");
      return 0;
    }

  memcpy(opaque, indata, ntohs(fasttlv->length)+4);

  (*pac_opaque) = opaque;

  return (ntohs(fasttlv->length)+4);
}

/*******************************************************************
 *
 *  Process a PAC-Info, PAC-Type TLV.
 *
 *******************************************************************/
uint16_t eapfast_phase2_process_pac_type(uint8_t *indata, uint16_t *pac_type)
{
  struct pac_info_pac_type *pacinfo;

  if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
    return 0;

  if (!xsup_assert((pac_type != NULL), "pac_type != NULL", FALSE))
    return 0;

  pacinfo = (struct pac_info_pac_type *)indata;

  if (ntohs(pacinfo->length) != 2)
    {
      debug_printf(DEBUG_NORMAL, "Invalid PAC-Type length!  Expected 2, got "
		   "%d!\n", ntohs(pacinfo->length));
      return 0;
    }

  (*pac_type) = ntohs(pacinfo->pac_type);

  return sizeof(struct pac_info_pac_type);
}

/*******************************************************************
 *
 *  Process a PAC Info AID TLV.
 *
 *******************************************************************/
uint16_t eapfast_phase2_process_aid(uint8_t *indata, uint8_t **aid, 
				    uint16_t *len)
{
  struct eapfast_tlv *fasttlv;
  uint8_t *myaid;

  if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
    return 0;

  if (!xsup_assert((aid != NULL), "aid != NULL", FALSE))
    return 0;

  fasttlv = (struct eapfast_tlv *)indata;

  debug_printf(DEBUG_AUTHTYPES, "AID is %d byte(s) long.\n",
	       ntohs(fasttlv->length));

  *len = ntohs(fasttlv->length);

  myaid = Malloc(ntohs(fasttlv->length));
  if (myaid == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store the "
		   "AID provided in the PAC-Info TLV.\n");
      return 0;
    }

  memcpy(myaid, indata+4, ntohs(fasttlv->length));

  (*aid) = myaid;

  return ntohs(fasttlv->length)+4;
}

/********************************************************************
 *
 *  Process a PAC-Info Information ID TLV.
 *
 ********************************************************************/
uint16_t eapfast_phase2_process_iid(uint8_t *indata, uint8_t **iid, 
				    uint16_t *len)
{
  struct eapfast_tlv *fasttlv;
  uint8_t *tempiid;

  if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
    return 0;

  if (!xsup_assert((iid != NULL), "iid != NULL", FALSE))
    return 0;

  fasttlv = (struct eapfast_tlv *)indata;

  debug_printf(DEBUG_AUTHTYPES, "IID length is %d byte(s).\n", 
	       ntohs(fasttlv->length));

  *len = ntohs(fasttlv->length);

  tempiid = Malloc(ntohs(fasttlv->length));
  if (tempiid == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store IID "
		   "information!\n");
      return 0;
    }
  
  memcpy(tempiid, indata+4, ntohs(fasttlv->length));

  (*iid) = tempiid;

  return (ntohs(fasttlv->length)+4);
}

/*******************************************************************
 *
 *  Process a PAC-Info AID Info TLV.
 *
 *******************************************************************/
uint16_t eapfast_phase2_process_pac_aidinfo(uint8_t *indata, 
					    uint8_t **aid_info,
					    uint16_t *len)
{
  struct eapfast_tlv *fasttlv;
  uint8_t *tempaidi;

  if (!xsup_assert((indata != NULL), "indata != NULL", FALSE))
    return 0;

  if (!xsup_assert((aid_info != NULL), "aid_info != NULL", FALSE))
    return 0;

  fasttlv = (struct eapfast_tlv *)indata;

  debug_printf(DEBUG_AUTHTYPES, "AID Info is %d byte(s).\n",
	       ntohs(fasttlv->length));

  *len = ntohs(fasttlv->length);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?