original files of m241
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_aka.h,v $ $Revision: 1.4 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_aka.h,v $
|
||||
* $Author: hchowdhu $ $Date: 2010-06-28 22:03:11 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#if !defined(IPEAP_AKA_H) && defined(IPEAP_USE_EAP_AKA)
|
||||
#define IPEAP_AKA_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPEAP_AKA_VERSION 1
|
||||
|
||||
/* Non-skippable attributes (0-127) */
|
||||
#define IPEAP_AKA_AT_RAND 1
|
||||
#define IPEAP_AKA_AT_AUTN 2
|
||||
#define IPEAP_AKA_AT_RES 3
|
||||
#define IPEAP_AKA_AT_AUTS 4
|
||||
#define IPEAP_AKA_AT_PADDING 6
|
||||
#define IPEAP_AKA_AT_PERMANENT_ID_REQ 10
|
||||
#define IPEAP_AKA_AT_MAC 11
|
||||
#define IPEAP_AKA_AT_NOTIFICATION 12
|
||||
#define IPEAP_AKA_AT_ANY_ID_REQ 13
|
||||
#define IPEAP_AKA_AT_IDENTITY 14
|
||||
#define IPEAP_AKA_AT_VERSION_LIST 15
|
||||
#define IPEAP_AKA_AT_SELECTED_VERSION 16
|
||||
#define IPEAP_AKA_AT_FULLAUTH_ID_REQ 17
|
||||
#define IPEAP_AKA_AT_COUNTER 19
|
||||
#define IPEAP_AKA_AT_COUNTER_TOO_SMALL 20
|
||||
#define IPEAP_AKA_AT_NONCE_S 21
|
||||
#define IPEAP_AKA_AT_CLIENT_ERROR_CODE 22
|
||||
/* Skippable attributes (128-) */
|
||||
#define IPEAP_AKA_AT_IV 129
|
||||
#define IPEAP_AKA_AT_ENCR_DATA 130
|
||||
#define IPEAP_AKA_AT_NEXT_PSEUDONYM 132
|
||||
#define IPEAP_AKA_AT_NEXT_REAUTH_ID 133
|
||||
#define IPEAP_AKA_AT_CHECKCODE 134
|
||||
#define IPEAP_AKA_AT_RESULT_IND 135
|
||||
|
||||
/* Subtypes */
|
||||
#define IPEAP_AKA_SUBTYPE_CHALLENGE 1
|
||||
#define IPEAP_AKA_SUBTYPE_AUTHENTICATION_REJECT 2
|
||||
#define IPEAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE 4
|
||||
#define IPEAP_AKA_SUBTYPE_IDENTITY 5
|
||||
#define IPEAP_AKA_SUBTYPE_NOTIFICATION 12
|
||||
#define IPEAP_AKA_SUBTYPE_REAUTHENTICATION 13
|
||||
#define IPEAP_AKA_SUBTYPE_CLIENT_ERROR 14
|
||||
|
||||
/* AT_CLIENT_ERROR_CODE values */
|
||||
#define IPEAP_AKA_UNABLE_TO_PROCESS_PACKET 0
|
||||
#define IPEAP_AKA_UNSUPPORTED_VERSION 1
|
||||
#define IPEAP_AKA_INSUFFICIENT_NUM_OF_CHAL 2
|
||||
#define IPEAP_AKA_RAND_NOT_FRESH 3
|
||||
|
||||
/* AT_NOTIFICATION values */
|
||||
#define IPEAP_AKA_FAILURE_AFTER_AUTH 0x0000
|
||||
#define IPEAP_AKA_TEMPORARILY_DENIED 0x0402
|
||||
#define IPEAP_AKA_NOT_SUBSCRIBED 0x0407
|
||||
#define IPEAP_AKA_FAILURE_BEFORE_AUTH 0x4000
|
||||
#define IPEAP_AKA_SUCCESS 0x8000
|
||||
|
||||
/* Constants */
|
||||
#define IPEAP_AKA_HEADER_LEN 8
|
||||
#define IPEAP_AKA_RAND_LEN 16
|
||||
#define IPEAP_AKA_AUTN_LEN 16
|
||||
#define IPEAP_AKA_AUTS_LEN 14
|
||||
#define IPEAP_AKA_NONCE_S_LEN 16
|
||||
#define IPEAP_AKA_MAC_LEN 16
|
||||
#define IPEAP_AKA_CHECKCODE_LEN 20
|
||||
#define IPEAP_AKA_RES_LEN 16
|
||||
#define IPEAP_AKA_IK_LEN 16
|
||||
#define IPEAP_AKA_CK_LEN 16
|
||||
#define IPEAP_AKA_K_AUTH_LEN 16
|
||||
#define IPEAP_AKA_K_ENCR_LEN 16
|
||||
#define IPEAP_AKA_MSK_LEN 64
|
||||
#define IPEAP_AKA_SESSION_ID_LEN (1 + IPEAP_AKA_RAND_LEN + IPEAP_AKA_AUTN_LEN)
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_aka_methods_get
|
||||
*===========================================================================
|
||||
* Description: Return a structure containing pointer to all functions
|
||||
* required by EAP.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC Ipeap_methods*
|
||||
ipeap_aka_methods_get(void);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_aka_get_identity
|
||||
*===========================================================================
|
||||
* Description: Read identity from card (IMSI number).
|
||||
* Parameters: identity - buffer that will receive the null-terminated
|
||||
* identity.
|
||||
* identityLen - Size of identity buffer.
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipeap_aka_get_identity(char *identity, Ip_u32 identityLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_common_tls.c,v $ $Revision: 1.6.10.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_common_tls.c,v $
|
||||
* $Author: jli7 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
#include "ipeap_common_tls.h"
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_suppl_ctx_free
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipeap_tls_suppl_ctx_free(Ipeap_tls_suppl_ctx *ctx)
|
||||
{
|
||||
if(!ctx)
|
||||
return;
|
||||
|
||||
if(ctx->ssl_ctx)
|
||||
SSL_CTX_free(ctx->ssl_ctx);
|
||||
|
||||
if(ctx->ssl)
|
||||
SSL_free(ctx->ssl);
|
||||
|
||||
ipcom_memset(ctx, 0, sizeof(Ipeap_tls_suppl_ctx));
|
||||
|
||||
ipcom_free(ctx);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_suppl_setup_ssl
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_tls_suppl_setup_ssl(Ipeap_tls_suppl_ctx *ctx)
|
||||
{
|
||||
ctx->ssl = SSL_new(ctx->ssl_ctx);
|
||||
if(!ctx->ssl)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_tls_suppl_setup_ssl :: SSL_new() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
SSL_set_connect_state(ctx->ssl);
|
||||
(void)SSL_set_options(ctx->ssl, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE);
|
||||
|
||||
ctx->in_bio = BIO_new(BIO_s_mem());
|
||||
ctx->out_bio = BIO_new(BIO_s_mem());
|
||||
if(!ctx->in_bio || !ctx->out_bio)
|
||||
{
|
||||
if(ctx->in_bio)
|
||||
(void)BIO_free(ctx->in_bio);
|
||||
if(ctx->out_bio)
|
||||
(void)BIO_free(ctx->out_bio);
|
||||
IPCOM_LOG0(ERR, "ipeap_tls_suppl_setup_ssl :: BIO_s_mem() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
SSL_set_bio(ctx->ssl, ctx->in_bio, ctx->out_bio);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_common_tls_ctx_new
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipeap_tls_suppl_ctx*
|
||||
ipeap_common_tls_ctx_new(void)
|
||||
{
|
||||
Ipeap_tls_suppl_ctx *tls_suppl_ctx = IP_NULL;
|
||||
EVP_PKEY *tls_key = IP_NULL;
|
||||
X509 *tls_cert = IP_NULL;
|
||||
|
||||
tls_suppl_ctx = ipcom_malloc(sizeof(Ipeap_tls_suppl_ctx));
|
||||
if(!tls_suppl_ctx)
|
||||
return IP_NULL;
|
||||
ipcom_memset(tls_suppl_ctx, 0, sizeof(Ipeap_tls_suppl_ctx));
|
||||
|
||||
tls_suppl_ctx->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
|
||||
if(!tls_suppl_ctx->ssl_ctx)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_tls_suppl_init :: SSL_CTX_new() failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Load server key */
|
||||
tls_key = ipeap_load_tls_key();
|
||||
if(tls_key)
|
||||
{
|
||||
/* load server cert */
|
||||
tls_cert = ipeap_load_tls_cert();
|
||||
if(tls_cert)
|
||||
{
|
||||
/* Check that key and cert match */
|
||||
if(X509_check_private_key(tls_cert, tls_key) != 1)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_tls_suppl_init :: X509_check_private_key() failed");
|
||||
goto error;
|
||||
}
|
||||
if(!SSL_CTX_use_PrivateKey(tls_suppl_ctx->ssl_ctx, tls_key))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_tls_suppl_init :: SSL_CTX_use_PrivateKey() failed");
|
||||
goto error;
|
||||
}
|
||||
if(!SSL_CTX_use_certificate(tls_suppl_ctx->ssl_ctx, tls_cert))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_tls_suppl_init :: SSL_CTX_use_certificate() failed");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(WARNING, "No TLS X509 certificate loaded by ipwebs_load_tls_cert()");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(WARNING, "No TLS key loaded by ipeap_load_tls_key()");
|
||||
}
|
||||
if(tls_key)
|
||||
EVP_PKEY_free(tls_key);
|
||||
if(tls_cert)
|
||||
X509_free(tls_cert);
|
||||
|
||||
/* Load CA certificates */
|
||||
if(ipeap_load_ca_certs(tls_suppl_ctx->ssl_ctx->cert_store) == IPCOM_SUCCESS)
|
||||
SSL_CTX_set_verify(tls_suppl_ctx->ssl_ctx, SSL_VERIFY_PEER, ipeap_tls_cert_verify);
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(WARNING, "No TLS trusted certs loaded by ipeap_load_ca_certs(). Peer certificate validation turned off");
|
||||
}
|
||||
|
||||
if(ipeap_tls_suppl_setup_ssl(tls_suppl_ctx) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_tls_suppl_init :: ipeap_tls_suppl_setup_ssl() failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return tls_suppl_ctx;
|
||||
|
||||
error:
|
||||
ipeap_tls_suppl_ctx_free(tls_suppl_ctx);
|
||||
if(tls_key)
|
||||
EVP_PKEY_free(tls_key);
|
||||
if(tls_cert)
|
||||
X509_free(tls_cert);
|
||||
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_common_tls_handle_frag_and_handshake
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_common_tls_handle_frag_and_handshake(Ipeap_ctx *ctx, Ipeap_tls_suppl_ctx *tls_suppl_ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ipeap_tls_msg *msg;
|
||||
int msg_len;
|
||||
int rc;
|
||||
int ssl_rc;
|
||||
|
||||
msg = IPEAP_PKT2TLSMSG(in_pkt);
|
||||
ip_assert(msg->code == IPEAP_MSG_REQUEST);
|
||||
|
||||
/* Are we sending a fragmented packet? */
|
||||
if(tls_suppl_ctx->frag_tot_len > 0)
|
||||
return ipeap_common_tls_make_out_frag_pkt(tls_suppl_ctx, out_pkt, IPEAP_MSG_RESPONSE, msg->id, ctx->meth_id);
|
||||
|
||||
/* Write received data to SSL's input BIO */
|
||||
if(msg->flags & IPEAP_TLS_FLAG_LEN_INCL)
|
||||
msg_len = IP_GET_NTOHS(&msg->length) - 10; /* Remove header length*/
|
||||
else
|
||||
msg_len = IP_GET_NTOHS(&msg->length) - 6; /* Remove header length*/
|
||||
if(msg_len > 0)
|
||||
{
|
||||
if(msg->flags & IPEAP_TLS_FLAG_LEN_INCL)
|
||||
rc = BIO_write(tls_suppl_ctx->in_bio, msg->u.len_present.data, msg_len);
|
||||
else
|
||||
rc = BIO_write(tls_suppl_ctx->in_bio, msg->u.data, msg_len);
|
||||
|
||||
if(rc != msg_len)
|
||||
{
|
||||
IPCOM_LOG3(ERR, "%sFailed to write EAP fragment to SSL BIO, rc: %d, msg_len: %d",
|
||||
ctx->syslog_prefix, rc, msg_len);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a fragmented packet, wait for remaining fragments to arrive */
|
||||
if(msg->flags & IPEAP_TLS_FLAG_MORE_FRAG)
|
||||
{
|
||||
rc = ipeap_tls_pkt_set_header(out_pkt, IPEAP_PKT_RESPONSE, msg->id, 6, ctx->meth_id, 0);
|
||||
out_pkt->end += 6;
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
return rc;
|
||||
return IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
|
||||
/* TODO: It should be possible to reset existing SSL context */
|
||||
if(SSL_get_state(tls_suppl_ctx->ssl) == SSL_ST_OK)
|
||||
{
|
||||
if(msg->flags & IPEAP_TLS_FLAG_START)
|
||||
{
|
||||
IPCOM_LOG1(INFO, "%sRenegotiating SSL", ctx->syslog_prefix);
|
||||
SSL_free(tls_suppl_ctx->ssl);
|
||||
if(ipeap_tls_suppl_setup_ssl(tls_suppl_ctx) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sipeap_tls_suppl_setup_ssl() failed", ctx->syslog_prefix);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ctx->state = IPEAP_STATE_HANDSHAKE;
|
||||
}
|
||||
else
|
||||
/* TLS handshake completed => we have received application data over the TLS connection */
|
||||
return IPEAP_TLS_DATA_AVAILABLE;
|
||||
}
|
||||
|
||||
ssl_rc = SSL_do_handshake(tls_suppl_ctx->ssl);
|
||||
if(ssl_rc == 1)
|
||||
{
|
||||
IPCOM_LOG1(INFO, "%sTLS handshake successfully completed", ctx->syslog_prefix);
|
||||
return IPEAP_TLS_HANDSHAKE_COMPLETE;
|
||||
}
|
||||
if(ssl_rc <= 0 && SSL_get_error(tls_suppl_ctx->ssl, ssl_rc) == SSL_ERROR_WANT_READ)
|
||||
rc = ipeap_common_tls_make_out_frag_pkt(tls_suppl_ctx, out_pkt, IPEAP_MSG_RESPONSE, msg->id, ctx->meth_id);
|
||||
else
|
||||
{
|
||||
IPCOM_LOG3(ERR, "%sTLS handshake failed, SSL_get_error(): %d, %s",
|
||||
ctx->syslog_prefix, SSL_get_error(tls_suppl_ctx->ssl, ssl_rc),
|
||||
ERR_error_string(ERR_get_error(), IP_NULL));
|
||||
if(BIO_pending(tls_suppl_ctx->out_bio) > 0)
|
||||
/* There is data in the out_bio, most likely an SSL alert. Send it to peer */
|
||||
rc = ipeap_common_tls_make_out_frag_pkt(tls_suppl_ctx, out_pkt, IPEAP_MSG_RESPONSE, msg->id, ctx->meth_id);
|
||||
else
|
||||
{
|
||||
/* No SSL data to send, make an empty ack packet */
|
||||
rc = ipeap_tls_pkt_set_header(out_pkt, IPEAP_PKT_RESPONSE, msg->id, 6, ctx->meth_id, 0);
|
||||
out_pkt->end += 6;
|
||||
rc = IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
ERR_remove_state(0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_pkt_set_header
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_tls_pkt_set_header(Ipeap_pkt *pkt, Ip_u8 code, Ip_u8 id, Ip_u16 len, Ip_u8 type, Ip_u8 flags)
|
||||
{
|
||||
Ip_err rc;
|
||||
Ipeap_tls_msg* msg;
|
||||
|
||||
rc = ipeap_pkt_set_header(pkt, code, id, len, type);
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
return rc;
|
||||
|
||||
msg = IPEAP_PKT2TLSMSG(pkt);
|
||||
msg->flags = flags;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_common_tls_make_out_frag_pkt
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_common_tls_make_out_frag_pkt(Ipeap_tls_suppl_ctx *ctx, Ipeap_pkt *pkt, Ip_u8 code, Ip_u8 id, Ip_u8 meth_id)
|
||||
{
|
||||
Ipeap_tls_msg* msg;
|
||||
int bytes_left_to_send;
|
||||
int tls_data_len;
|
||||
Ip_u8 *out_buf;
|
||||
Ip_err rc;
|
||||
Ip_u8 flags = 0;
|
||||
int header_size = 6;
|
||||
|
||||
msg = IPEAP_PKT2TLSMSG(pkt);
|
||||
|
||||
bytes_left_to_send = (int)BIO_ctrl_pending(ctx->out_bio);
|
||||
if(bytes_left_to_send > IPEAP_MTU && ctx->frag_tot_len == 0)
|
||||
{
|
||||
/* This message must be fragmented and this is the first fragment */
|
||||
ctx->frag_tot_len = bytes_left_to_send;
|
||||
}
|
||||
|
||||
if(bytes_left_to_send > IPEAP_MTU)
|
||||
flags |= IPEAP_TLS_FLAG_MORE_FRAG;
|
||||
if(ctx->frag_tot_len != 0)
|
||||
{
|
||||
flags |= IPEAP_TLS_FLAG_LEN_INCL;
|
||||
header_size = 10;
|
||||
IP_SET_HTONL(msg->u.len_present.len, ctx->frag_tot_len);
|
||||
out_buf = msg->u.len_present.data;
|
||||
}
|
||||
else
|
||||
out_buf = msg->u.data;
|
||||
|
||||
tls_data_len = IP_MIN(bytes_left_to_send, IPEAP_MTU-header_size);
|
||||
tls_data_len = IP_MIN(tls_data_len, IPEAP_PKT_GET_SPACE_LEFT(pkt));
|
||||
if(BIO_read(ctx->out_bio, out_buf, tls_data_len) != tls_data_len)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipeap_common_tls_make_out_frag_pkt :: failed to read %d bytes from out_bio", tls_data_len);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
rc = ipeap_tls_pkt_set_header(pkt, code, id, (Ip_u16)(tls_data_len+header_size), meth_id, flags);
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
return rc;
|
||||
if(flags & IPEAP_TLS_FLAG_LEN_INCL)
|
||||
IP_SET_HTONL(msg->u.len_present.len, ctx->frag_tot_len);
|
||||
|
||||
if(BIO_ctrl_pending(ctx->out_bio) == 0)
|
||||
ctx->frag_tot_len = 0; /* This is the last fragment, reset frag_tot_len */
|
||||
|
||||
pkt->end += header_size + tls_data_len; /* Add header and payload to length */
|
||||
|
||||
return IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_common_tls_ctx_free
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipeap_common_tls_ctx_free(Ipeap_tls_suppl_ctx *tls_suppl_ctx)
|
||||
{
|
||||
if(tls_suppl_ctx->ssl)
|
||||
SSL_free(tls_suppl_ctx->ssl);
|
||||
if(tls_suppl_ctx->ssl_ctx)
|
||||
SSL_CTX_free(tls_suppl_ctx->ssl_ctx);
|
||||
|
||||
ipcom_free(tls_suppl_ctx);
|
||||
|
||||
ERR_clear_error();
|
||||
ERR_remove_state(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_common_generate_key
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_tls_common_generate_key(Ipeap_tls_suppl_ctx *tls_suppl_ctx, const char* label, Ip_u8* key, int key_len)
|
||||
{
|
||||
Ip_u8 tmp_buf[2*SSL3_RANDOM_SIZE+40];
|
||||
Ip_u8* tmp_out;
|
||||
ip_assert(tls_suppl_ctx);
|
||||
|
||||
ip_assert(ipcom_strlen(label) < 40);
|
||||
|
||||
tmp_out = ipcom_malloc((Ip_size_t)key_len);
|
||||
if(!tmp_out)
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
ipcom_memcpy(tmp_buf, label, ipcom_strlen(label));
|
||||
ipcom_memcpy(tmp_buf+ipcom_strlen(label), tls_suppl_ctx->ssl->s3->client_random, SSL3_RANDOM_SIZE);
|
||||
ipcom_memcpy(tmp_buf+ipcom_strlen(label)+SSL3_RANDOM_SIZE, tls_suppl_ctx->ssl->s3->server_random, SSL3_RANDOM_SIZE);
|
||||
|
||||
#ifdef _WRS_CONFIG_COMPONENT_IPCRYPTO_OPENSSL_1_0_2
|
||||
ipssl_tls1_PRF(TLS1_PRF,
|
||||
tmp_buf, (int)ipcom_strlen(label)+2*SSL3_RANDOM_SIZE,
|
||||
NULL, 0, NULL, 0, NULL, 0, NULL, 0,
|
||||
tls_suppl_ctx->ssl->session->master_key, tls_suppl_ctx->ssl->session->master_key_length,
|
||||
key, tmp_out, key_len);
|
||||
#else
|
||||
ipssl_tls1_PRF(EVP_md5(), EVP_sha1(),
|
||||
tmp_buf, (int)ipcom_strlen(label)+2*SSL3_RANDOM_SIZE,
|
||||
tls_suppl_ctx->ssl->session->master_key, tls_suppl_ctx->ssl->session->master_key_length,
|
||||
key, tmp_out, key_len);
|
||||
#endif
|
||||
|
||||
ipcom_free(tmp_out);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_tls_common_generate_session_id(Ipeap_tls_suppl_ctx *tls_suppl_ctx,Ip_u8 eap_type,Ip_u8 *session_id,Ip_u32 *session_id_len)
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (*session_id_len < IPEAP_TLS_SESSION_ID_LEN)
|
||||
{
|
||||
IPCOM_LOG3(ERR, "ipeap_tls_common_generate_session_id - not enough buffer is available to hold "
|
||||
"the Session_Id for 0x%x , (%d wanted), (%d given )",eap_type,IPEAP_TLS_SESSION_ID_LEN , *session_id_len );
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if(eap_type!=IPEAP_TYPE_TLS && eap_type!= IPEAP_TYPE_TTLS && eap_type!=IPEAP_TYPE_PEAP)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipeap_tls_common_generate_session_id - not a valid EAP TYPE 0x%x",eap_type);
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
||||
ipcom_memset(session_id, 0,*session_id_len);
|
||||
session_id[0] = eap_type;
|
||||
session_id += 1;
|
||||
ipcom_memcpy(session_id, tls_suppl_ctx->ssl->s3->client_random, SSL3_RANDOM_SIZE);
|
||||
ipcom_memcpy(session_id+SSL3_RANDOM_SIZE, tls_suppl_ctx->ssl->s3->server_random, SSL3_RANDOM_SIZE);
|
||||
|
||||
*session_id_len = IPEAP_TLS_SESSION_ID_LEN;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_common_tls.h,v $ $Revision: 1.4.12.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_common_tls.h,v $
|
||||
* $Author: jli7 $ $Date: 2015-01-30 03:27:26 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPEAP_COMMON_TLS_H
|
||||
#define IPEAP_COMMON_TLS_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef IPCRYPTO
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#endif
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
|
||||
#ifdef IPSSL
|
||||
#include <ipssl.h>
|
||||
#endif
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPEAP_TLS_FLAG_LEN_INCL 0x80
|
||||
#define IPEAP_TLS_FLAG_MORE_FRAG 0x40
|
||||
#define IPEAP_TLS_FLAG_START 0x20
|
||||
|
||||
|
||||
#define IPEAP_TLS_HANDSHAKE_COMPLETE 100
|
||||
#define IPEAP_TLS_DATA_AVAILABLE 101
|
||||
|
||||
#define IPEAP_PKT2TLSMSG(pkt) ((Ipeap_tls_msg*)(&((pkt)->data[(pkt)->start])))
|
||||
|
||||
#define IPEAP_TLS_SESSION_ID_LEN (1 + 2*SSL3_RANDOM_SIZE)
|
||||
|
||||
/* copied from openssl/ssl_locl.h */
|
||||
#define SSL_HANDSHAKE_MAC_MD5 0x10
|
||||
#define SSL_HANDSHAKE_MAC_SHA 0x20
|
||||
#define TLS1_PRF_DGST_SHIFT 10
|
||||
#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
|
||||
#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
|
||||
#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct Ipeap_tls_suppl_ctx_st
|
||||
{
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL *ssl;
|
||||
BIO *in_bio;
|
||||
BIO *out_bio;
|
||||
int frag_tot_len;
|
||||
} Ipeap_tls_suppl_ctx;
|
||||
|
||||
|
||||
typedef struct Ipeap_tls_msg_st
|
||||
{
|
||||
Ip_u8 code;
|
||||
Ip_u8 id;
|
||||
Ip_u16 length;
|
||||
Ip_u8 type;
|
||||
Ip_u8 flags;
|
||||
union {
|
||||
struct {
|
||||
Ip_u8 len[4];
|
||||
Ip_u8 data[1];
|
||||
} len_present;
|
||||
Ip_u8 data[1];
|
||||
} u;
|
||||
Ip_u8 pad;
|
||||
} Ipeap_tls_msg;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ipeap_tls_suppl_ctx* ipeap_common_tls_ctx_new(void);
|
||||
IP_GLOBAL void ipeap_common_tls_ctx_free(Ipeap_tls_suppl_ctx *ctx);
|
||||
|
||||
IP_GLOBAL Ip_err ipeap_common_tls_handle_frag_and_handshake(Ipeap_ctx *ctx, Ipeap_tls_suppl_ctx *tls_suppl_ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt);
|
||||
IP_GLOBAL Ip_err ipeap_common_tls_make_out_frag_pkt(Ipeap_tls_suppl_ctx *ctx, Ipeap_pkt *pkt, Ip_u8 code, Ip_u8 id, Ip_u8 meth_id);
|
||||
|
||||
IP_GLOBAL Ip_err ipeap_tls_pkt_set_header(Ipeap_pkt *pkt, Ip_u8 code, Ip_u8 id, Ip_u16 len, Ip_u8 type, Ip_u8 flags);
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_tls_common_generate_key(Ipeap_tls_suppl_ctx *tls_suppl_ctx, const char* label, Ip_u8* key, int key_len);
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_tls_common_generate_session_id(Ipeap_tls_suppl_ctx *tls_suppl_ctx,Ip_u8 eap_type,Ip_u8 *session_id,Ip_u32 *session_id_len);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,478 @@
|
||||
/* ipeap_gtc.c - EAP GTC implementation */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify, or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01d,21may10,hfc update eap as per requirement WIND00198105
|
||||
01c,25mar08,mry Adding a missing return code
|
||||
01b,28feb08,mry Code Inspection Changes
|
||||
01a,04Feb08,mry Created
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This library contains the EAP GTC implementation as described in RFC 3748.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPEAP_GTC_HEADER_LEN 5
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
typedef enum {
|
||||
IPEAP_GTC_WAIT_FOR_CHALLENGE = 0,
|
||||
IPEAP_GTC_WAIT_FOR_USER_INPUT,
|
||||
IPEAP_GTC_WAIT_FOR_SUCCESS,
|
||||
IPEAP_GTC_AUTHENTICATED
|
||||
} Ipeap_gtc_state;
|
||||
|
||||
typedef struct Ipeap_gtc_ctx_st
|
||||
{
|
||||
Ipeap_gtc_state state;
|
||||
Ip_u8 msg_id; /* msg Id of last received request */
|
||||
} Ipeap_gtc_ctx;
|
||||
|
||||
typedef struct Ipeap_gtc_msg_st
|
||||
{
|
||||
Ip_u8 code;
|
||||
Ip_u8 id;
|
||||
Ip_u16 length;
|
||||
Ip_u8 type;
|
||||
Ip_u8 type_data[1]; /* displayable msg of size 1 or more octets based on message length */
|
||||
} Ipeap_gtc_msg;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ip_err ipeap_gtc_process_msg(struct Ipeap_ctx_st *ctx,
|
||||
struct Ipeap_pkt_st *in_pkt,
|
||||
struct Ipeap_pkt_st *reply_pkt);
|
||||
IP_STATIC Ip_err ipeap_gtc_init(struct Ipeap_ctx_st *ctx);
|
||||
IP_STATIC Ip_err ipeap_gtc_free(Ipeap_ctx *ctx);
|
||||
IP_STATIC Ip_err ipeap_gtc_handle_user_input(Ipeap_ctx* ctx,
|
||||
Ipeap_user_input* ui,
|
||||
struct Ipeap_pkt_st *reply_pkt);
|
||||
IP_PUBLIC Ip_err ipeap_gtc_display_status(struct Ipeap_ctx_st* ctx, char *str);
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ipeap_methods ipeap_gtc_methods =
|
||||
{
|
||||
ipeap_gtc_process_msg,
|
||||
ipeap_gtc_init,
|
||||
ipeap_gtc_free,
|
||||
IP_NULL,
|
||||
ipeap_gtc_handle_user_input,
|
||||
ipeap_gtc_display_status,
|
||||
IP_NULL
|
||||
};
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_init
|
||||
*===========================================================================
|
||||
* Description: Initialize EAP gtc context.
|
||||
* Parameters: ctx - The EAP gtc context.
|
||||
* Returns:
|
||||
* IPCOM_SUCCESS
|
||||
* IPCOM_ERR_NO_MEMORY
|
||||
* IPCOM_ERR_INVALID_ARG
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_gtc_init(Ipeap_ctx* ctx)
|
||||
{
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
Ipeap_gtc_ctx* gtc_ctx = IP_NULL;
|
||||
|
||||
gtc_ctx = ipcom_calloc(1, sizeof(*gtc_ctx));
|
||||
if (IP_NULL == gtc_ctx)
|
||||
{
|
||||
IPCOM_LOG1(CRIT, "%sEAP-GTC :: Out of memory", ctx->syslog_prefix);
|
||||
err = IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->mech_data = gtc_ctx;
|
||||
ctx->state = IPEAP_STATE_INIT;
|
||||
gtc_ctx->state = IPEAP_GTC_WAIT_FOR_CHALLENGE;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_free
|
||||
*===========================================================================
|
||||
* Description: Free EAP gtc context.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* Returns: IPCOM_SUCCESS
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_gtc_free(Ipeap_ctx* ctx)
|
||||
{
|
||||
Ipeap_gtc_ctx* gtc_ctx = IP_NULL;
|
||||
|
||||
if ((ctx != IP_NULL) && (ctx->mech_data != IP_NULL))
|
||||
{
|
||||
gtc_ctx = (Ipeap_gtc_ctx*)ctx->mech_data;
|
||||
ipcom_free(gtc_ctx);
|
||||
ctx->mech_data = IP_NULL;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_get_msg_from_pkt
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipeap_gtc_msg*
|
||||
ipeap_gtc_get_msg_from_pkt(Ipeap_pkt* pkt)
|
||||
{
|
||||
return (Ipeap_gtc_msg*)(pkt->data + pkt->start);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_get_msg_max_size
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ip_u32
|
||||
ipeap_gtc_get_msg_max_size(Ipeap_pkt* pkt)
|
||||
{
|
||||
if ((pkt->end - pkt->start) >= pkt->max_len)
|
||||
return 0;
|
||||
return (Ip_u32)(pkt->max_len - (pkt->end - pkt->start));
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_get_msg_typedata_len
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ip_u32
|
||||
ipeap_gtc_get_msg_typedata_len(Ipeap_pkt* pkt)
|
||||
{
|
||||
return (Ip_u32)(pkt->end - pkt->start - IPEAP_GTC_HEADER_LEN);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_suppl_process_msg
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_gtc_process_request(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ip_u8 *prompt_msg;
|
||||
Ip_u32 max_len, prompt_len;
|
||||
Ip_err err = IPEAP_DROPPED_PKT;
|
||||
Ipeap_gtc_msg* in_msg = IP_NULL;
|
||||
Ipeap_gtc_ctx* gtc_ctx = (Ipeap_gtc_ctx*)ctx->mech_data;
|
||||
|
||||
if (gtc_ctx->state == IPEAP_GTC_AUTHENTICATED) {
|
||||
/* redundant message, drop */
|
||||
IPCOM_LOG1(ERR, "%sEAP-GTC :: packet received after success. dropping.", ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
ctx->state = IPEAP_STATE_HANDSHAKE;
|
||||
/* Convert packet to message */
|
||||
in_msg = ipeap_gtc_get_msg_from_pkt(in_pkt);
|
||||
max_len = ipeap_gtc_get_msg_max_size(out_pkt);
|
||||
if (max_len == 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-GTC :: Buffer too small", ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
}
|
||||
else if (in_msg->type != IPEAP_TYPE_GTC)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-GTC :: Only type GTC challenge is supported", ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtc_ctx->msg_id = in_msg->id; /* Save msg id for when we send response */
|
||||
gtc_ctx->state = IPEAP_GTC_WAIT_FOR_USER_INPUT;
|
||||
|
||||
/* We need to get user input. We (ab)use the out_pkt as a store to pass back the challenge prompt */
|
||||
max_len = ipeap_gtc_get_msg_max_size(out_pkt);
|
||||
prompt_len = ipeap_gtc_get_msg_typedata_len(in_pkt);
|
||||
if (prompt_len > max_len-1)
|
||||
prompt_len = max_len-1;
|
||||
prompt_msg = (Ip_u8 *)ipeap_gtc_get_msg_from_pkt(out_pkt);
|
||||
if (prompt_len)
|
||||
memcpy(prompt_msg, in_msg->type_data, prompt_len);
|
||||
prompt_msg[prompt_len] ='\0';
|
||||
out_pkt->end = out_pkt->start + (int)prompt_len + 1;
|
||||
err = IPEAP_PENDING_USER_INPUT;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_process_success
|
||||
*===========================================================================
|
||||
* Description: Process a success message.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* Returns:
|
||||
* IPEAP_SUCCESS
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_gtc_process_success(Ipeap_ctx* ctx)
|
||||
{
|
||||
Ipeap_gtc_ctx* gtc_ctx = (Ipeap_gtc_ctx*)ctx->mech_data;
|
||||
|
||||
if (gtc_ctx->state != IPEAP_GTC_WAIT_FOR_SUCCESS) {
|
||||
/* redundant message, drop */
|
||||
IPCOM_LOG1(ERR, "%sEAP-GTC :: unexpected success packet. dropping.", ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
ctx->state = IPEAP_STATE_AUTHENTICATED;
|
||||
gtc_ctx->state = IPEAP_GTC_AUTHENTICATED;
|
||||
return IPEAP_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_process_msg
|
||||
*===========================================================================
|
||||
* Description: Process a message.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* in_pkt - The request packet (message).
|
||||
* out_pkt - The created response packet (message).
|
||||
* Returns:
|
||||
* IPEAP_SUCCESS
|
||||
* IPEAP_PENDING_SEND_OUT_PKT
|
||||
* IPEAP_FAILURE
|
||||
* IPEAP_DROPPED_PKT
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_gtc_process_msg(
|
||||
Ipeap_ctx* ctx,
|
||||
Ipeap_pkt* in_pkt,
|
||||
Ipeap_pkt* out_pkt)
|
||||
{
|
||||
Ip_err err = IPEAP_FAILURE;
|
||||
Ipeap_gtc_msg* msg = IP_NULL;
|
||||
|
||||
msg = ipeap_gtc_get_msg_from_pkt(in_pkt);
|
||||
|
||||
/* Sanity check, always at least 4 bytes size */
|
||||
if ((in_pkt->end - in_pkt->start) < 4)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-GTC :: Bad in packet", ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
switch (msg->code)
|
||||
{
|
||||
case IPEAP_MSG_REQUEST:
|
||||
IPCOM_LOG1(DEBUG, "%sEAP-GTC :: Received request message", ctx->syslog_prefix);
|
||||
err = ipeap_gtc_process_request(ctx, in_pkt, out_pkt);
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_RESPONSE:
|
||||
IPCOM_LOG1(ERR, "%sEAP-GTC :: Received response message, dropping message", ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_FAILURE:
|
||||
IPCOM_LOG1(ERR, "%sEAP-GTC :: Received failure message, resetting state", ctx->syslog_prefix);
|
||||
(void)ipeap_gtc_free(ctx);
|
||||
ctx->state = IPEAP_STATE_INIT;
|
||||
ctx->cb = IP_NULL;
|
||||
err = IPEAP_FAILURE;
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_SUCCESS:
|
||||
IPCOM_LOG1(INFO, "%sEAP-GTC :: Received EAP success", ctx->syslog_prefix);
|
||||
err = ipeap_gtc_process_success(ctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
IPCOM_LOG2(ERR, "%sEAP-GTC :: Received unknown message type: %d, dropping message", ctx->syslog_prefix, msg->code);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_handle_user_input
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_gtc_handle_user_input(Ipeap_ctx* ctx, Ipeap_user_input* ui, Ipeap_pkt* out_pkt) {
|
||||
Ip_err err = IPEAP_FAILURE;
|
||||
Ipeap_gtc_msg* out_msg = IP_NULL;
|
||||
Ipeap_gtc_ctx* gtc_ctx = (Ipeap_gtc_ctx*)ctx->mech_data;
|
||||
Ip_u32 max_len = 0, resp_len = 0;
|
||||
|
||||
if (gtc_ctx->state != IPEAP_GTC_WAIT_FOR_USER_INPUT) {
|
||||
IPCOM_LOG2(ERR, "EAP-GTC: Unexpected user input in state %d", ctx->syslog_prefix, gtc_ctx->state);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (ui->ui_type != IPEAP_UI_CHALLENGE_RESP_STRING) {
|
||||
IPCOM_LOG1(ERR, "EAP-GTC: Invalid user input type", ctx->syslog_prefix);
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
||||
/* Build a response packet */
|
||||
resp_len = (Ip_u32)strlen(ui->ui_data.challenge_resp_str) ;
|
||||
|
||||
/* Convert packet to message */
|
||||
out_msg = ipeap_gtc_get_msg_from_pkt(out_pkt);
|
||||
max_len = ipeap_gtc_get_msg_max_size(out_pkt);
|
||||
if (max_len < (IPEAP_GTC_HEADER_LEN+resp_len))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-GTC :: Buffer too small for out packet", ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
}
|
||||
else
|
||||
{
|
||||
out_msg->code = IPEAP_MSG_RESPONSE;
|
||||
out_msg->id = gtc_ctx->msg_id; /* Response id from last received msg */
|
||||
out_msg->type = IPEAP_TYPE_GTC;
|
||||
out_msg->length = (Ip_u16)(IPEAP_GTC_HEADER_LEN + resp_len);
|
||||
|
||||
ipcom_memcpy(out_msg->type_data, ui->ui_data.challenge_resp_str, resp_len);
|
||||
out_pkt->end = out_pkt->start + out_msg->length;
|
||||
out_msg->length = ip_htons(out_msg->length);
|
||||
|
||||
gtc_ctx->state = IPEAP_GTC_WAIT_FOR_SUCCESS;
|
||||
err = IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_methods_get
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC Ipeap_methods*
|
||||
ipeap_gtc_methods_get(void)
|
||||
{
|
||||
return &ipeap_gtc_methods;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipeap_gtc_state_name
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC char *Ipeap_gtc_state_name(int state) {
|
||||
if (state == IPEAP_GTC_WAIT_FOR_CHALLENGE)
|
||||
return "IPEAP_GTC_WAIT_FOR_CHALLENGE";
|
||||
else if (state == IPEAP_GTC_WAIT_FOR_USER_INPUT)
|
||||
return "IPEAP_GTC_WAIT_FOR_USER_INPUT";
|
||||
else if (state == IPEAP_GTC_WAIT_FOR_SUCCESS)
|
||||
return "IPEAP_GTC_WAIT_FOR_SUCCESS";
|
||||
else if (state == IPEAP_GTC_AUTHENTICATED)
|
||||
return "IPEAP_GTC_AUTHENTICATED";
|
||||
|
||||
return "UNKNOWN STATE";
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_gtc_display_status
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipeap_gtc_display_status(struct Ipeap_ctx_st* ctx, char *str) {
|
||||
Ipeap_gtc_ctx* gtc_ctx = (Ipeap_gtc_ctx*)ctx->mech_data;
|
||||
|
||||
ipcom_printf(" GTC state = %s\n", Ipeap_gtc_state_name(gtc_ctx->state));
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_h.h,v $ $Revision: 1.11 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_h.h,v $
|
||||
* $Author: ulf $ $Date: 2009-06-08 11:05:00 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPEAP_H_H
|
||||
#define IPEAP_H_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
#include <ipeap.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPEAP
|
||||
#define IPCOM_SYSLOG_PRIORITY IPEAP_SYSLOG_PRIORITY
|
||||
|
||||
#define IPEAP_MAX_MECH 9
|
||||
#define IPEAP_MAX_VENDOR_SPECIFIC 1
|
||||
|
||||
#define IPEAP_MSG_REQUEST 1
|
||||
#define IPEAP_MSG_RESPONSE 2
|
||||
#define IPEAP_MSG_SUCCESS 3
|
||||
#define IPEAP_MSG_FAILURE 4
|
||||
|
||||
#define IPEAP_MTU 1020
|
||||
|
||||
|
||||
/* Radius attribute definitions */
|
||||
#define IPEAP_RAD_ATTR_USER_NAME ((Ip_u32) 1)
|
||||
#define IPEAP_RAD_ATTR_PW ((Ip_u32) 2)
|
||||
#define IPEAP_RAD_ATTR_CHAP_PW ((Ip_u32) 3)
|
||||
#define IPEAP_RAD_ATTR_REPLY_MSG ((Ip_u32) 18)
|
||||
#define IPEAP_RAD_ATTR_CHAP_CHALLANGE ((Ip_u32) 60)
|
||||
#define IPEAP_RAD_ATTR_EAP_MSG ((Ip_u32) 79)
|
||||
|
||||
/* MSCHAPv2 Radius attribute definitions */
|
||||
#define IPEAP_RAD_ATTR_MS_CHAP_ERROR ((Ip_u32) 2)
|
||||
#define IPEAP_RAD_ATTR_MS_CHAP_CHALLENGE ((Ip_u32) 11)
|
||||
#define IPEAP_RAD_ATTR_MS_CHAP2_RESPONSE ((Ip_u32) 25)
|
||||
#define IPEAP_RAD_ATTR_MS_CHAP2_SUCCESS ((Ip_u32) 26)
|
||||
#define IPEAP_RAD_ATTR_MS_CHAP2_CPW ((Ip_u32) 27)
|
||||
|
||||
#define IPEAP_PKT2MSG(pkt) ((Ipeap_msg*)(&((pkt)->data[(pkt)->start])))
|
||||
#define IPEAP_PKT_GET_LEN(pkt) ((pkt)->end-(pkt)->start)
|
||||
#define IPEAP_PKT_GET_SPACE_LEFT(pkt) ((pkt)->max_len-(pkt)->end)
|
||||
#define IPEAP_PKT_GET_END_PTR(pkt) (&((pkt)->data[(pkt)->end]))
|
||||
#define IPEAP_PKT_GET_START_PTR(pkt) (&((pkt)->data[(pkt)->start]))
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct Ipeap_mech_entry_st
|
||||
{
|
||||
Ipeap_methods* methods;
|
||||
Ip_bool enabled;
|
||||
Ip_u8 id;
|
||||
Ipeap_vendor_id vendor_id;
|
||||
Ipeap_vendor_type vendor_type;
|
||||
} Ipeap_mech_entry;
|
||||
|
||||
typedef struct Ipeap_msg_st
|
||||
{
|
||||
Ip_u8 code;
|
||||
Ip_u8 id;
|
||||
Ip_u16 length;
|
||||
Ip_u8 type;
|
||||
Ip_u8 data[1];
|
||||
} Ipeap_msg;
|
||||
|
||||
typedef struct Ipeap_expanded_msg_st
|
||||
{
|
||||
Ip_u8 code;
|
||||
Ip_u8 id;
|
||||
Ip_u16 length;
|
||||
Ip_u8 type;
|
||||
Ipeap_vendor_id vendor_id;
|
||||
Ipeap_vendor_type vendor_type;
|
||||
Ip_u8 data[1];
|
||||
} Ipeap_expanded_msg;
|
||||
|
||||
struct Ipeap_ctx_st
|
||||
{
|
||||
int mode;
|
||||
int state;
|
||||
char identity[IPEAP_IDENTITY_MAX_LEN];
|
||||
char syslog_prefix[16];
|
||||
Ip_u8 meth_id;
|
||||
Ipeap_vendor_id vendor_id; /* for expanded type EAP methods */
|
||||
Ipeap_vendor_type vendor_type; /* for expanded type EAP methods */
|
||||
Ipeap_methods* cb;
|
||||
struct Ipeap_mech_entry_st *mech_map;
|
||||
Ip_bool method_locked; /* No other method other than already selected one can be negotiated */
|
||||
|
||||
/* Resend data */
|
||||
Ip_u8 last_recv_pkt_hdr[5]; /* This is the header from the last packet we received from the peer */
|
||||
Ipeap_pkt last_sent_pkt; /* This is the last packet we sent to the peer */
|
||||
|
||||
void* mech_data;
|
||||
};
|
||||
typedef struct Ipeap_ctx_st Ipeap_ctx;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ip_err ipeap_pkt_set_header(Ipeap_pkt* pkt, Ip_u8 code, Ip_u8 id, Ip_u16 len, Ip_u8 type);
|
||||
IP_GLOBAL Ip_err ipeap_make_identity_response(Ipeap_ctx* ctx, Ipeap_pkt* in_pkt, Ipeap_pkt* out_pkt);
|
||||
IP_GLOBAL Ip_err ipeap_make_nak_response(Ipeap_ctx* ctx, Ipeap_pkt* in_pkt, Ipeap_pkt* out_pkt);
|
||||
IP_GLOBAL Ip_err ipeap_make_expanded_nak_response(Ipeap_ctx* ctx, Ipeap_pkt* in_pkt, Ipeap_pkt* out_pkt);
|
||||
IP_GLOBAL Ip_err ipeap_make_notification_response(Ipeap_ctx* ctx, Ipeap_pkt* in_pkt, Ipeap_pkt* out_pkt);
|
||||
IP_GLOBAL Ipeap_methods* ipeap_mech_cb_get(Ipeap_ctx* ctx, Ip_u8 mech_id,
|
||||
Ipeap_vendor_id vendor_id,
|
||||
Ipeap_vendor_type vendor_type);
|
||||
|
||||
IP_GLOBAL Ipeap_pkt* ipeap_pkt_new(int size);
|
||||
IP_GLOBAL void ipeap_pkt_free(Ipeap_pkt *pkt);
|
||||
|
||||
IP_GLOBAL void ipeap_mschapv2_generate_nt_response(Ip_u8 *auth_challenge, Ip_u8 *peer_challenge,
|
||||
Ip_u8 *username, Ip_size_t username_len,
|
||||
Ip_u8 *password, Ip_size_t password_len,
|
||||
Ip_u8 *response);
|
||||
IP_GLOBAL void ipeap_mschapv2_generate_authenticator_response(Ip_u8 *password, Ip_size_t password_len,
|
||||
Ip_u8 *nt_response,
|
||||
Ip_u8 *peer_challenge,
|
||||
Ip_u8 *auth_challenge,
|
||||
Ip_u8 *username, Ip_size_t username_len,
|
||||
Ip_u8 *response);
|
||||
IP_GLOBAL void ipeap_mschapv2_buf_bin2hex(Ip_u8 *bin_buf, Ip_size_t bin_len, char *hex_buf);
|
||||
IP_GLOBAL char *Ipeap_type_name(int type, Ipeap_vendor_id *vendor_id, Ipeap_vendor_type vendor_type);
|
||||
|
||||
#ifdef IP_DEBUG
|
||||
IP_GLOBAL const char* ipeap_code_str(Ip_u8 code);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,727 @@
|
||||
/* ipeap_leap.c - EAP LEAP implementation */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify, or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01e,13dec10,mry Fix defect WIND00246269.
|
||||
01d,08jul10,hfc Add secure keyDB support
|
||||
01c,21may10,hfc update eap as per requirement WIND00198105
|
||||
01b,25mar08,mry Adding a missing return code
|
||||
01a,28Feb08,mry Created
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This library contains the EAP LEAP implementation.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
#ifdef IPMCRYPTO
|
||||
#include <ip/openssl/md5.h>
|
||||
#else
|
||||
#include <openssl/md5.h>
|
||||
#endif
|
||||
/*
|
||||
#include <openssl/ssl.h>
|
||||
*/
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPEAP_LEAP_HEADER_LEN 8
|
||||
|
||||
#define IPEAP_LEAP_CHALLENGE_SIZE (8)
|
||||
#define IPEAP_LEAP_CHALLENGE_MSG_SIZE (IPEAP_LEAP_HEADER_LEN+IPEAP_LEAP_CHALLENGE_SIZE)
|
||||
#define IPEAP_LEAP_RESPONSE_SIZE (24)
|
||||
#define IPEAP_LEAP_RESPONSE_MSG_SIZE (IPEAP_LEAP_HEADER_LEN+IPEAP_LEAP_RESPONSE_SIZE)
|
||||
#define IPEAP_LEAP_PASSWORD_HASH_SIZE (16)
|
||||
#define IPEAP_LEAP_VERSION (1)
|
||||
#define IPEAP_LEAP_UNUSED (0)
|
||||
#define IPEAP_LEAP_SESSION_KEY_SIZE (16)
|
||||
#define IPEAP_LEAP_SESSION_KEY_INPUT_SIZE (LEAP_PASSWORD_HASH_SIZE \
|
||||
+ 2*LEAP_CHALLENGE_SIZE \
|
||||
+ 2*LEAP_RESPONSE_SIZE)
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
typedef enum {
|
||||
IPEAP_LEAP_WAIT_FOR_CHALLENGE = 0,
|
||||
IPEAP_LEAP_WAIT_FOR_SUCCESS,
|
||||
IPEAP_LEAP_WAIT_FOR_RESPONSE,
|
||||
IPEAP_LEAP_AUTHENTICATED
|
||||
} Ipeap_leap_state;
|
||||
|
||||
typedef struct Ipeap_leap_ctx_st
|
||||
{
|
||||
Ipeap_leap_state state;
|
||||
Ip_u8* user; /* leap username */
|
||||
Ip_u8* pw; /* leap password */
|
||||
Ip_u8 passwordHash[IPEAP_LEAP_PASSWORD_HASH_SIZE]; /* Hashed password */
|
||||
Ip_u8 doublyHashedPW[IPEAP_LEAP_PASSWORD_HASH_SIZE]; /* Doubly Hashed password */
|
||||
Ip_u8 challenge1[IPEAP_LEAP_CHALLENGE_SIZE]; /* Challenge to Supp */
|
||||
Ip_u8 response1[IPEAP_LEAP_RESPONSE_SIZE]; /* Supp's response */
|
||||
Ip_u8 challenge2[IPEAP_LEAP_CHALLENGE_SIZE]; /* Challenge to Auth */
|
||||
Ip_u8 response2[IPEAP_LEAP_RESPONSE_SIZE]; /* Auth. response */
|
||||
} Ipeap_leap_ctx;
|
||||
|
||||
typedef struct Ipeap_leap_msg_st
|
||||
{
|
||||
Ip_u8 code;
|
||||
Ip_u8 id;
|
||||
Ip_u16 length;
|
||||
Ip_u8 type;
|
||||
char version; /* version of LEAP, (0x01) */
|
||||
char unused; /* unused, (0x00) */
|
||||
char dataSize; /* size of data to follow */
|
||||
Ip_u8 type_data[1]; /* beginning of data */
|
||||
} Ipeap_leap_msg;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
extern IP_GLOBAL void ipeap_mschapv2_nt_password_hash(Ip_u8 *password, Ip_size_t password_len, Ip_u8 *password_hash);
|
||||
extern IP_GLOBAL void ipeap_mschapv2_challenge_response(Ip_u8 *challenge, Ip_u8 *password_hash, Ip_u8 * response);
|
||||
extern IP_GLOBAL void ipeap_mschapv2_hash_nt_password_hash(Ip_u8 *password_hash, Ip_u8 *password_hash_hash);
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ip_err ipeap_leap_process_msg(struct Ipeap_ctx_st *ctx,
|
||||
struct Ipeap_pkt_st *in_pkt,
|
||||
struct Ipeap_pkt_st *reply_pkt);
|
||||
IP_STATIC Ip_err ipeap_leap_init(struct Ipeap_ctx_st *ctx);
|
||||
IP_STATIC Ip_err ipeap_leap_free(Ipeap_ctx *ctx);
|
||||
IP_STATIC Ip_err ipeap_leap_get_key(struct Ipeap_ctx_st* ctx, Ip_u8* key, int key_len);
|
||||
IP_PUBLIC Ip_err ipeap_leap_display_status(struct Ipeap_ctx_st* ctx, char *str);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ipeap_methods ipeap_leap_methods =
|
||||
{
|
||||
ipeap_leap_process_msg,
|
||||
ipeap_leap_init,
|
||||
ipeap_leap_free,
|
||||
ipeap_leap_get_key,
|
||||
IP_NULL,
|
||||
ipeap_leap_display_status,
|
||||
IP_NULL
|
||||
};
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_load_config
|
||||
*===========================================================================
|
||||
* Description: Load configuration from system variables.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
* IPCOM_SUCCESS
|
||||
* IPCOM_ERR_INVALID_ARG
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_leap_load_config(Ipeap_leap_ctx* leap_ctx)
|
||||
{
|
||||
Ip_err rc = IPCOM_SUCCESS ;
|
||||
int pass_len = 128;
|
||||
char* leap_pass_id = IP_NULL;
|
||||
|
||||
if(!leap_ctx)
|
||||
{
|
||||
IPCOM_LOG0(DEBUG, "ipeap_leap_load_config :: NULL leap_ctx");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
leap_ctx->user = (Ip_u8 *)ipcom_sysvar_get("ipeap.leap.user", IP_NULL, IP_NULL);
|
||||
|
||||
if(!leap_ctx->user)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "EAP-LEAP: ipeap.leap.user sysvar not set");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
#ifdef IPCOM_USE_KEY_DB
|
||||
if(ipcom_sysvar_get_as_int("ipeap.privacy", 0)==1)
|
||||
{
|
||||
leap_ctx->pw = ipcom_calloc(1,pass_len);
|
||||
if (!leap_ctx->pw)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "EAP-LEAP: out of memory");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if(ipcom_sysvar_get_as_int("ipeap.privacy.retrieve.keydbid", 0)==1)
|
||||
{
|
||||
leap_pass_id = ipcom_sysvar_get("ipeap.leap.pw", IP_NULL, IP_NULL);
|
||||
|
||||
}
|
||||
|
||||
if ((rc = ipcom_key_db_buf_get(leap_pass_id ? leap_pass_id : LEAP_PASS_ID,leap_ctx->pw, &pass_len)) != IPCOM_SUCCESS)
|
||||
{
|
||||
|
||||
ipcom_memset(leap_ctx->pw,0,pass_len);
|
||||
IPCOM_LOG0(ERR, "EAP-LEAP: Unable to retrieve password ");
|
||||
if(rc == IPCOM_ERR_NOT_FOUND)
|
||||
IPCOM_LOG1(ERR, "EAP-LEAP: key ID %s does not exist",
|
||||
leap_pass_id ? leap_pass_id : LEAP_PASS_ID);
|
||||
if(rc == IPCOM_ERR_NO_MEMORY)
|
||||
IPCOM_LOG0(ERR, "EAP-LEAP: out of memory while retrieving password from "
|
||||
"secureDB");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if(leap_pass_id)
|
||||
ipcom_free(leap_pass_id);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
#endif
|
||||
leap_ctx->pw = (Ip_u8 *)ipcom_sysvar_get("ipeap.leap.pw", IP_NULL, IP_NULL);
|
||||
|
||||
if(!leap_ctx->pw)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "EAP-LEAP: ipeap.leap.pw sysvar not set");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
err_out:
|
||||
if(leap_ctx->user) {
|
||||
ipcom_free(leap_ctx->user);
|
||||
leap_ctx->user = IP_NULL;
|
||||
}
|
||||
if(leap_ctx->pw) {
|
||||
ipcom_free(leap_ctx->pw);
|
||||
leap_ctx->pw = IP_NULL;
|
||||
}
|
||||
if(leap_pass_id)
|
||||
ipcom_free(leap_pass_id);
|
||||
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_init
|
||||
*===========================================================================
|
||||
* Description: Initialize EAP leap context.
|
||||
* Parameters: ctx - The EAP leap context.
|
||||
* Returns:
|
||||
* IPCOM_SUCCESS
|
||||
* IPCOM_ERR_NO_MEMORY
|
||||
* IPCOM_ERR_INVALID_ARG
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_leap_init(Ipeap_ctx* ctx)
|
||||
{
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
Ipeap_leap_ctx* leap_ctx = IP_NULL;
|
||||
|
||||
leap_ctx = ipcom_calloc(1, sizeof(*leap_ctx));
|
||||
if (IP_NULL == leap_ctx)
|
||||
{
|
||||
IPCOM_LOG1(CRIT, "%sEAP-LEAP :: Out of memory", ctx->syslog_prefix);
|
||||
err = IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
else if (IPCOM_SUCCESS != (err = ipeap_leap_load_config(leap_ctx)))
|
||||
{
|
||||
ipcom_free(leap_ctx);
|
||||
IPCOM_LOG1(ERR, "%sEAP-LEAP :: Failed to load config", ctx->syslog_prefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->mech_data = leap_ctx;
|
||||
ctx->state = IPEAP_STATE_INIT;
|
||||
leap_ctx->state = IPEAP_LEAP_WAIT_FOR_CHALLENGE;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_free
|
||||
*===========================================================================
|
||||
* Description: Free EAP leap context.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* Returns: IPCOM_SUCCESS
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_leap_free(Ipeap_ctx* ctx)
|
||||
{
|
||||
Ipeap_leap_ctx* leap_ctx = IP_NULL;
|
||||
|
||||
if ((ctx != IP_NULL) && (ctx->mech_data != IP_NULL))
|
||||
{
|
||||
leap_ctx = (Ipeap_leap_ctx*)ctx->mech_data;
|
||||
if(leap_ctx->user)
|
||||
ipcom_free(leap_ctx->user);
|
||||
if(leap_ctx->pw)
|
||||
ipcom_free(leap_ctx->pw);
|
||||
ipcom_free(leap_ctx);
|
||||
ctx->mech_data = IP_NULL;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_get_msg_from_pkt
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipeap_leap_msg*
|
||||
ipeap_leap_get_msg_from_pkt(Ipeap_pkt* pkt)
|
||||
{
|
||||
return (Ipeap_leap_msg*)(pkt->data + pkt->start);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_get_msg_max_size
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ip_u32
|
||||
ipeap_leap_get_msg_max_size(Ipeap_pkt* pkt)
|
||||
{
|
||||
if ((pkt->end - pkt->start) >= pkt->max_len)
|
||||
return 0;
|
||||
return (Ip_u32)(pkt->max_len - (pkt->end - pkt->start));
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_get_msg_typedata_len
|
||||
*===========================================================================
|
||||
*/
|
||||
#if 0
|
||||
IP_STATIC Ip_u32
|
||||
ipeap_leap_get_msg_typedata_len(Ipeap_pkt* pkt)
|
||||
{
|
||||
return (pkt->end - pkt->start - IPEAP_LEAP_HEADER_LEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_gen_challenge
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipeap_leap_gen_challenge(Ip_u8* buf)
|
||||
{
|
||||
int i;
|
||||
long* ptr;
|
||||
long rnd;
|
||||
|
||||
for(i=0; i<(IPEAP_LEAP_CHALLENGE_SIZE/4); i++)
|
||||
{
|
||||
ptr = (long*)&buf[i];
|
||||
rnd = ipcom_random();
|
||||
IP_SET_32ON8(ptr, rnd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_process_request
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_leap_process_request(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ipeap_leap_ctx* leap_ctx = (Ipeap_leap_ctx*)ctx->mech_data;
|
||||
Ipeap_leap_msg* in_msg = IP_NULL;
|
||||
Ipeap_leap_msg* out_msg = IP_NULL;
|
||||
Ip_u32 max_len;
|
||||
Ip_size_t pwlen;
|
||||
|
||||
ip_assert(leap_ctx);
|
||||
|
||||
if (leap_ctx->state != IPEAP_LEAP_WAIT_FOR_CHALLENGE) {
|
||||
/* redundant message, drop */
|
||||
IPCOM_LOG1(ERR, "%sEAP-LEAP :: unexpected request packet. dropping.", ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
out_msg = ipeap_leap_get_msg_from_pkt(out_pkt);
|
||||
max_len = ipeap_leap_get_msg_max_size(out_pkt);
|
||||
if (max_len < IPEAP_LEAP_RESPONSE_MSG_SIZE) {
|
||||
IPCOM_LOG2(CRIT, "ipeap_leap_process_request:: Buffer too small for out packet(is %d, need %d). dropping.",
|
||||
max_len, IPEAP_LEAP_RESPONSE_MSG_SIZE);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
in_msg = ipeap_leap_get_msg_from_pkt(in_pkt);
|
||||
if (in_msg->type != IPEAP_TYPE_LEAP) {
|
||||
IPCOM_LOG2(CRIT, "%sEAP-LEAP :: unexpected EAP Request of type %d. dropping.", ctx->syslog_prefix, in_msg->type);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
if (in_msg->version != IPEAP_LEAP_VERSION) {
|
||||
IPCOM_LOG2(CRIT, "%sEAP-LEAP :: unsupported version (%d) in EAP Request. dropping.", ctx->syslog_prefix, in_msg->version);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
if (in_msg->dataSize != IPEAP_LEAP_CHALLENGE_SIZE) {
|
||||
IPCOM_LOG2(CRIT, "%sEAP-LEAP :: invalid datasize (%d) in EAP-LEAP Request. dropping.", ctx->syslog_prefix, in_msg->dataSize);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
/* Calculate password hash and challenge response */
|
||||
pwlen = ipcom_strlen((char *)leap_ctx->pw);
|
||||
ipeap_mschapv2_nt_password_hash(leap_ctx->pw, pwlen, leap_ctx->passwordHash);
|
||||
ipcom_memcpy(leap_ctx->challenge1, in_msg->type_data, IPEAP_LEAP_CHALLENGE_SIZE);
|
||||
ipeap_mschapv2_challenge_response(leap_ctx->challenge1, leap_ctx->passwordHash, leap_ctx->response1);
|
||||
|
||||
/* create eap response containing challenge response */
|
||||
out_msg->code = IPEAP_MSG_RESPONSE;
|
||||
out_msg->id = in_msg->id;
|
||||
out_msg->type = IPEAP_TYPE_LEAP;
|
||||
out_msg->length = IPEAP_LEAP_RESPONSE_MSG_SIZE+(Ip_u16)strlen((char *)leap_ctx->user);
|
||||
out_msg->version = IPEAP_LEAP_VERSION;
|
||||
out_msg->unused = IPEAP_LEAP_UNUSED;
|
||||
out_msg->dataSize = IPEAP_LEAP_RESPONSE_SIZE;
|
||||
ipcom_memcpy(out_msg->type_data, leap_ctx->response1, IPEAP_LEAP_RESPONSE_SIZE);
|
||||
ipcom_memcpy(out_msg->type_data+IPEAP_LEAP_RESPONSE_SIZE, leap_ctx->user, (Ip_size_t)strlen((char *)leap_ctx->user));
|
||||
out_pkt->end = out_pkt->start + out_msg->length;
|
||||
out_msg->length = ip_htons(out_msg->length);
|
||||
|
||||
/* Update state */
|
||||
ctx->state = IPEAP_STATE_HANDSHAKE;
|
||||
leap_ctx->state = IPEAP_LEAP_WAIT_FOR_SUCCESS;
|
||||
|
||||
return IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_process_success
|
||||
*===========================================================================
|
||||
* Description: Process a success message.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* Returns:
|
||||
* IPEAP_SUCCESS
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_leap_process_success(Ipeap_ctx* ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ipeap_leap_ctx* leap_ctx = (Ipeap_leap_ctx*)ctx->mech_data;
|
||||
Ipeap_leap_msg* in_msg = IP_NULL;
|
||||
Ipeap_leap_msg *out_msg = IP_NULL;
|
||||
Ip_u32 max_len;
|
||||
|
||||
ip_assert(leap_ctx);
|
||||
|
||||
if (leap_ctx->state != IPEAP_LEAP_WAIT_FOR_SUCCESS) {
|
||||
/* redundant message, drop */
|
||||
IPCOM_LOG1(ERR, "%sEAP-LEAP :: unexpected success packet. dropping.", ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
out_msg = ipeap_leap_get_msg_from_pkt(out_pkt);
|
||||
max_len = ipeap_leap_get_msg_max_size(out_pkt);
|
||||
if (max_len < IPEAP_LEAP_CHALLENGE_MSG_SIZE) {
|
||||
IPCOM_LOG2(CRIT, "ipeap_leap_process_request:: Buffer too small for out packet (is %d, need %d). dropping.",
|
||||
max_len, IPEAP_LEAP_CHALLENGE_MSG_SIZE);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
in_msg = ipeap_leap_get_msg_from_pkt(in_pkt);
|
||||
|
||||
/* Create a Request with the challenge to the auth */
|
||||
ipeap_leap_gen_challenge(leap_ctx->challenge2);
|
||||
out_msg->code = IPEAP_MSG_REQUEST;
|
||||
out_msg->id = in_msg->id;
|
||||
out_msg->type = IPEAP_TYPE_LEAP;
|
||||
out_msg->length = IPEAP_LEAP_CHALLENGE_MSG_SIZE+(Ip_u16)strlen((char *)leap_ctx->user);
|
||||
out_msg->version = IPEAP_LEAP_VERSION;
|
||||
out_msg->unused = IPEAP_LEAP_UNUSED;
|
||||
out_msg->dataSize = IPEAP_LEAP_CHALLENGE_SIZE;
|
||||
ipcom_memcpy(out_msg->type_data, leap_ctx->challenge2, IPEAP_LEAP_CHALLENGE_SIZE);
|
||||
ipcom_memcpy(out_msg->type_data+IPEAP_LEAP_CHALLENGE_SIZE, leap_ctx->user, (Ip_size_t)strlen((char *)leap_ctx->user));
|
||||
out_pkt->end = out_pkt->start + out_msg->length;
|
||||
out_msg->length = ip_htons(out_msg->length);
|
||||
|
||||
leap_ctx->state = IPEAP_LEAP_WAIT_FOR_RESPONSE;
|
||||
return IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_process_response
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_leap_process_response(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ipeap_leap_ctx* leap_ctx = (Ipeap_leap_ctx*)ctx->mech_data;
|
||||
Ipeap_leap_msg* in_msg = IP_NULL;
|
||||
|
||||
ip_assert(leap_ctx);
|
||||
|
||||
if (leap_ctx->state != IPEAP_LEAP_WAIT_FOR_RESPONSE) {
|
||||
/* redundant message, drop */
|
||||
IPCOM_LOG1(ERR, "%sEAP-LEAP :: unexpected response packet. dropping.", ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
in_msg = ipeap_leap_get_msg_from_pkt(in_pkt);
|
||||
if (in_msg->type != IPEAP_TYPE_LEAP) {
|
||||
IPCOM_LOG2(CRIT, "%sEAP-LEAP :: unexpected EAP Response of type %d. dropping.", ctx->syslog_prefix, in_msg->type);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
if (in_msg->version != IPEAP_LEAP_VERSION) {
|
||||
IPCOM_LOG2(CRIT, "%sEAP-LEAP :: unsupported version (%d) in EAP Response. dropping.", ctx->syslog_prefix, in_msg->version);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
if (in_msg->dataSize != IPEAP_LEAP_RESPONSE_SIZE) {
|
||||
IPCOM_LOG2(CRIT, "%sEAP-LEAP :: invalid datasize (%d) in EAP-LEAP Response. dropping.", ctx->syslog_prefix, in_msg->dataSize);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
/* Compute the password double hash and corresponding challenge hash and compare to auth response */
|
||||
ipeap_mschapv2_hash_nt_password_hash(leap_ctx->passwordHash, leap_ctx->doublyHashedPW);
|
||||
ipeap_mschapv2_challenge_response(leap_ctx->challenge2, leap_ctx->doublyHashedPW, leap_ctx->response2);
|
||||
if (ipcom_memcmp(leap_ctx->response2, in_msg->type_data, IPEAP_LEAP_RESPONSE_SIZE) != 0) {
|
||||
IPCOM_LOG1(INFO, "%sEAP-LEAP :: Invalid authenticator response. Failing authentication.", ctx->syslog_prefix);
|
||||
(void)ipeap_leap_free(ctx);
|
||||
ctx->state = IPEAP_STATE_INIT;
|
||||
ctx->cb = IP_NULL;
|
||||
return IPEAP_FAILURE;
|
||||
}
|
||||
IPCOM_LOG1(INFO, "%sEAP-LEAP :: Authenticator response verified. Authentication successful.", ctx->syslog_prefix);
|
||||
ctx->state = IPEAP_STATE_AUTHENTICATED;
|
||||
leap_ctx->state = IPEAP_LEAP_AUTHENTICATED;
|
||||
return IPEAP_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_process_msg
|
||||
*===========================================================================
|
||||
* Description: Process a message.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* in_pkt - The request packet (message).
|
||||
* out_pkt - The created response packet (message).
|
||||
* Returns:
|
||||
* IPEAP_SUCCESS
|
||||
* IPEAP_PENDING_SEND_OUT_PKT
|
||||
* IPEAP_FAILURE
|
||||
* IPEAP_DROPPED_PKT
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_leap_process_msg(
|
||||
Ipeap_ctx* ctx,
|
||||
Ipeap_pkt* in_pkt,
|
||||
Ipeap_pkt* out_pkt)
|
||||
{
|
||||
Ip_err err = IPEAP_FAILURE;
|
||||
Ipeap_leap_msg* msg = IP_NULL;
|
||||
|
||||
msg = ipeap_leap_get_msg_from_pkt(in_pkt);
|
||||
|
||||
/* Sanity check, always at least 4 bytes size */
|
||||
if ((in_pkt->end - in_pkt->start) < 4)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-LEAP :: Bad in packet", ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
switch (msg->code)
|
||||
{
|
||||
case IPEAP_MSG_REQUEST:
|
||||
IPCOM_LOG1(DEBUG, "%sEAP-LEAP :: Received request message", ctx->syslog_prefix);
|
||||
err = ipeap_leap_process_request(ctx, in_pkt, out_pkt);
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_RESPONSE:
|
||||
IPCOM_LOG1(DEBUG, "%sEAP-LEAP :: Received response message", ctx->syslog_prefix);
|
||||
err = ipeap_leap_process_response(ctx, in_pkt, out_pkt);
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_FAILURE:
|
||||
IPCOM_LOG1(ERR, "%sEAP-LEAP :: Received failure message, resetting state", ctx->syslog_prefix);
|
||||
(void)ipeap_leap_free(ctx);
|
||||
ctx->state = IPEAP_STATE_INIT;
|
||||
ctx->cb = IP_NULL;
|
||||
err = IPEAP_FAILURE;
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_SUCCESS:
|
||||
IPCOM_LOG1(INFO, "%sEAP-LEAP :: Received EAP success", ctx->syslog_prefix);
|
||||
err = ipeap_leap_process_success(ctx, in_pkt, out_pkt);
|
||||
break;
|
||||
|
||||
default:
|
||||
IPCOM_LOG2(ERR, "%sEAP-LEAP :: Received unknown message type: %d, dropping message", ctx->syslog_prefix, msg->code);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap__get_key
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_leap_get_key(struct Ipeap_ctx_st* ctx, Ip_u8* key, int key_len)
|
||||
{
|
||||
Ipeap_leap_ctx* leap_ctx = (Ipeap_leap_ctx*)ctx->mech_data;
|
||||
MD5_CTX md_ctx = {0};
|
||||
|
||||
if (leap_ctx->state != IPEAP_LEAP_AUTHENTICATED) {
|
||||
IPCOM_LOG0(ERR, "ipeap_leap_get_key :: LEAP not in autenticated state yet, cannot retrieve session key.");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (key_len < MD5_DIGEST_LENGTH)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-LEAP :: Buffer too small for key", ctx->syslog_prefix);
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
{
|
||||
IPCOM_LOG0(WARNING, "ipeap : MD5 is not supported when FIPS mode is enabled!\n");
|
||||
return IPCOM_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
MD5_Init(&md_ctx);
|
||||
MD5_Update(&md_ctx, &leap_ctx->doublyHashedPW , sizeof(leap_ctx->doublyHashedPW));
|
||||
MD5_Update(&md_ctx, &leap_ctx->challenge2 , sizeof(leap_ctx->challenge2));
|
||||
MD5_Update(&md_ctx, &leap_ctx->response2 , sizeof(leap_ctx->response2));
|
||||
MD5_Update(&md_ctx, &leap_ctx->challenge1 , sizeof(leap_ctx->challenge1));
|
||||
MD5_Update(&md_ctx, &leap_ctx->response1 , sizeof(leap_ctx->response1));
|
||||
MD5_Final(key, &md_ctx);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_methods_get
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC Ipeap_methods*
|
||||
ipeap_leap_methods_get(void)
|
||||
{
|
||||
return &ipeap_leap_methods;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipeap_leap_state_name
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC char *Ipeap_leap_state_name(int state) {
|
||||
if (state == IPEAP_LEAP_WAIT_FOR_CHALLENGE)
|
||||
return "IPEAP_LEAP_WAIT_FOR_CHALLENGE";
|
||||
else if (state == IPEAP_LEAP_WAIT_FOR_SUCCESS)
|
||||
return "IPEAP_LEAP_WAIT_FOR_SUCCESS";
|
||||
else if (state == IPEAP_LEAP_WAIT_FOR_RESPONSE)
|
||||
return "IPEAP_LEAP_WAIT_FOR_RESPONSE";
|
||||
else if (state == IPEAP_LEAP_AUTHENTICATED)
|
||||
return "IPEAP_LEAP_AUTHENTICATED";
|
||||
|
||||
return "UNKNOWN STATE";
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_leap_display_status
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipeap_leap_display_status(struct Ipeap_ctx_st* ctx, char *str) {
|
||||
Ipeap_leap_ctx* leap_ctx = (Ipeap_leap_ctx*)ctx->mech_data;
|
||||
|
||||
ipcom_printf(" LEAP state = %s\n", Ipeap_leap_state_name(leap_ctx->state));
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,576 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_md5.c,v $ $Revision: 1.11.12.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_md5.c,v $
|
||||
* $Author: svc-cmnet $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01a,08jul10,hfc Add secure keyDB support
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
#ifdef IPMCRYPTO
|
||||
#include <ip/openssl/md5.h>
|
||||
#else
|
||||
#include <openssl/md5.h>
|
||||
#endif
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
#include "ipeap_md5.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPEAP_MD5_MAX_SECRET 128
|
||||
#define IPEAP_MD5_HEADER_LEN 5
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct Ipeap_md5_ctx_st
|
||||
{
|
||||
char secret[IPEAP_MD5_MAX_SECRET];
|
||||
} Ipeap_md5_ctx;
|
||||
|
||||
typedef struct Ipeap_md5_info_st
|
||||
{
|
||||
Ip_u8* value;
|
||||
Ip_u32 valueLen;
|
||||
Ip_u8* name;
|
||||
Ip_u32 nameLen;
|
||||
} Ipeap_md5_info;
|
||||
|
||||
typedef struct Ipeap_md5_msg_st
|
||||
{
|
||||
Ip_u8 code;
|
||||
Ip_u8 id;
|
||||
Ip_u16 length;
|
||||
Ip_u8 type;
|
||||
Ip_u8 value_size;
|
||||
Ip_u8 value[1];
|
||||
} Ipeap_md5_msg;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_init
|
||||
*===========================================================================
|
||||
* Description: Initialize an EAP MD5 exchange.
|
||||
* Parameters: ctx - The eap context structure.
|
||||
* Returns:
|
||||
* IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_md5_init(
|
||||
Ipeap_ctx* ctx);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_free
|
||||
*===========================================================================
|
||||
* Description: Free an EAP MD5 exchange.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
* IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_md5_free(
|
||||
Ipeap_ctx* ctx);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_process_msg
|
||||
*===========================================================================
|
||||
* Description: Process EAP MD5 messages
|
||||
* Parameters: in_pkt - The incoming message
|
||||
* out_pkt - Will receive the eventual outgoing message
|
||||
* Returns:
|
||||
* IPEAP_PENDING_SEND_OUT_PKT
|
||||
* IPEAP_DROPPED_PKT
|
||||
* IPEAP_SUCCESS
|
||||
* IPEAP_FAILURE
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_md5_process_msg(
|
||||
Ipeap_ctx* ctx,
|
||||
Ipeap_pkt* in_pkt,
|
||||
Ipeap_pkt* out_pkt);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_STATIC Ipeap_methods ipeap_md5_methods =
|
||||
{
|
||||
ipeap_md5_process_msg,
|
||||
ipeap_md5_init,
|
||||
ipeap_md5_free,
|
||||
IP_NULL,
|
||||
IP_NULL,
|
||||
IP_NULL,
|
||||
IP_NULL
|
||||
};
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_get_msg_from_pkt
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipeap_md5_msg*
|
||||
ipeap_md5_get_msg_from_pkt(Ipeap_pkt* pkt)
|
||||
{
|
||||
return (Ipeap_md5_msg*)(pkt->data + pkt->start);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_get_msg_max_size
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ip_u32
|
||||
ipeap_md5_get_msg_max_size(Ipeap_pkt* pkt)
|
||||
{
|
||||
if ((pkt->end - pkt->start) >= pkt->max_len)
|
||||
return 0;
|
||||
return (Ip_u32)(pkt->max_len - (pkt->end - pkt->start));
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_get_msg_info
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ip_bool
|
||||
ipeap_md5_get_msg_info(Ipeap_md5_msg* msg, Ipeap_md5_info* info)
|
||||
{
|
||||
/* Sanity check */
|
||||
if ((msg->value_size + IPEAP_MD5_HEADER_LEN + 1) > ip_htons(msg->length))
|
||||
return IP_FALSE;
|
||||
info->valueLen = msg->value_size;
|
||||
info->value = msg->value;
|
||||
info->nameLen = ip_htons(msg->length) - (info->valueLen + IPEAP_MD5_HEADER_LEN + 1);
|
||||
if (info->nameLen == 0)
|
||||
info->name = IP_NULL;
|
||||
else
|
||||
info->name = info->value + info->valueLen;
|
||||
|
||||
return IP_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_load_config
|
||||
*===========================================================================
|
||||
* Description: Load configuration from system variables.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
* IPCOM_SUCCESS
|
||||
* IPCOM_ERR_INVALID_ARG
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_md5_load_config(
|
||||
Ipeap_md5_ctx* md5_ctx)
|
||||
{
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
char* p = IP_NULL;
|
||||
char* md5_pass_id = IP_NULL;
|
||||
Ip_size_t n = 0;
|
||||
|
||||
n = sizeof(md5_ctx->secret);
|
||||
|
||||
#ifdef IPCOM_USE_KEY_DB
|
||||
if(ipcom_sysvar_get_as_int("ipeap.privacy", 0)==1)
|
||||
{
|
||||
|
||||
if(ipcom_sysvar_get_as_int("ipeap.privacy.retrieve.keydbid", 0)==1)
|
||||
{
|
||||
md5_pass_id = ipcom_sysvar_get("ipeap.md5.secret", IP_NULL, IP_NULL);
|
||||
}
|
||||
|
||||
if ((err = ipcom_key_db_buf_get(md5_pass_id ? md5_pass_id : MD5_PASS_ID,(Ip_u8*)md5_ctx->secret, (int *)&n)) != IPCOM_SUCCESS)
|
||||
{
|
||||
|
||||
IPCOM_LOG0(ERR, "IPEAP-MD5 :: Unable to retrieve password ");
|
||||
if(err == IPCOM_ERR_NOT_FOUND)
|
||||
IPCOM_LOG1(ERR, "IPEAP-MD5 :: key ID %s does not exist",
|
||||
md5_pass_id ? md5_pass_id : MD5_PASS_ID);
|
||||
if(err == IPCOM_ERR_NO_MEMORY)
|
||||
IPCOM_LOG0(ERR, "IPEAP-MD5 :: out of memory while retrieving ket id");
|
||||
|
||||
err= IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if(md5_pass_id)
|
||||
ipcom_free(md5_pass_id);
|
||||
|
||||
return err;
|
||||
}
|
||||
else
|
||||
#endif /* IPCOM_USE_KEY_DB */
|
||||
p = ipcom_sysvar_get("ipeap.md5.secret", md5_ctx->secret, &n);
|
||||
|
||||
if (IP_NULL == p)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "IPEAP-MD5 :: System variable 'ipeap.md5.secret' missing");
|
||||
err = IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_generate_challenge_response
|
||||
*===========================================================================
|
||||
* Description: Generate EAP MD5 challenge response
|
||||
* Parameters:
|
||||
* Returns:
|
||||
* IP_TRUE - Challenge successfully generated
|
||||
* IP_FALSE - Failed to generate challenge
|
||||
*/
|
||||
|
||||
IP_STATIC Ip_bool
|
||||
ipeap_md5_generate_challenge_response(
|
||||
Ipeap_md5_ctx* md5_ctx,
|
||||
Ipeap_md5_msg* in_msg,
|
||||
Ipeap_md5_msg* out_msg,
|
||||
Ip_u32 out_max)
|
||||
{
|
||||
Ip_bool success = IP_FALSE;
|
||||
Ipeap_md5_info info = {0};
|
||||
MD5_CTX md_ctx = {0};
|
||||
|
||||
if ((Ip_u32)(16 + out_msg->length + 1) > out_max)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "EAP-MD5 :: Buffer too small for out packet");
|
||||
}
|
||||
else if (!ipeap_md5_get_msg_info(in_msg, &info))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "EAP-MD5 :: Failed to decode request");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
{
|
||||
IPCOM_LOG0(WARNING, "ipeap : MD5 is not supported when FIPS mode is enabled!\n");
|
||||
return IP_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
out_msg->value_size = (Ip_u8)16;
|
||||
MD5_Init(&md_ctx);
|
||||
MD5_Update(&md_ctx, &in_msg->id, 1);
|
||||
MD5_Update(&md_ctx, md5_ctx->secret, ipcom_strlen(md5_ctx->secret));
|
||||
MD5_Update(&md_ctx, info.value, info.valueLen);
|
||||
MD5_Final(out_msg->value, &md_ctx);
|
||||
success = IP_TRUE;
|
||||
out_msg->length += 16 + 1;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_init
|
||||
*===========================================================================
|
||||
* Description: Initialize EAP MD5 context.
|
||||
* Parameters: ctx - The EAP MD5 context.
|
||||
* Returns:
|
||||
* IPCOM_SUCCESS
|
||||
* IPCOM_ERR_NO_MEMORY
|
||||
* IPCOM_ERR_INVALID_ARG
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_md5_init(
|
||||
Ipeap_ctx* ctx)
|
||||
{
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
Ipeap_md5_ctx* md5_ctx = IP_NULL;
|
||||
|
||||
md5_ctx = ipcom_calloc(1, sizeof(*md5_ctx));
|
||||
if (IP_NULL == md5_ctx)
|
||||
{
|
||||
IPCOM_LOG1(CRIT, "%sEAP-MD5 :: Out of memory", ctx->syslog_prefix);
|
||||
err = IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
else if (IPCOM_SUCCESS != (err = ipeap_md5_load_config(md5_ctx)))
|
||||
{
|
||||
ipcom_free(md5_ctx);
|
||||
IPCOM_LOG1(ERR, "%sEAP-MD5 :: Failed to load config", ctx->syslog_prefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->mech_data = md5_ctx;
|
||||
ctx->state = IPEAP_STATE_INIT;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_free
|
||||
*===========================================================================
|
||||
* Description: Free EAP MD5 context.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* Returns: IPCOM_SUCCESS
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_md5_free(
|
||||
Ipeap_ctx* ctx)
|
||||
{
|
||||
Ipeap_md5_ctx* md5_ctx = IP_NULL;
|
||||
|
||||
if ((ctx != IP_NULL) && (ctx->mech_data != IP_NULL))
|
||||
{
|
||||
md5_ctx = (Ipeap_md5_ctx*)ctx->mech_data;
|
||||
ipcom_free(md5_ctx);
|
||||
ctx->mech_data = IP_NULL;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_process_request
|
||||
*===========================================================================
|
||||
* Description: Process a request message.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* in_pkt - The request packet (message).
|
||||
* out_pkt - The created response packet (message).
|
||||
* Returns:
|
||||
* IPEAP_PENDING_SEND_OUT_PKT
|
||||
* IPEAP_DROPPED_PKT
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_md5_process_request(
|
||||
Ipeap_ctx* ctx,
|
||||
Ipeap_pkt* in_pkt,
|
||||
Ipeap_pkt* out_pkt)
|
||||
{
|
||||
Ip_err err = IPEAP_PENDING_SEND_OUT_PKT;
|
||||
Ipeap_md5_ctx* md5_ctx = IP_NULL;
|
||||
Ipeap_md5_msg* in_msg = IP_NULL;
|
||||
Ipeap_md5_msg* out_msg = IP_NULL;
|
||||
Ip_u32 max_len = 0;
|
||||
|
||||
ctx->state = IPEAP_STATE_HANDSHAKE;
|
||||
md5_ctx = (Ipeap_md5_ctx*)ctx->mech_data;
|
||||
/* Convert packet to message */
|
||||
in_msg = ipeap_md5_get_msg_from_pkt(in_pkt);
|
||||
out_msg = ipeap_md5_get_msg_from_pkt(out_pkt);
|
||||
max_len = ipeap_md5_get_msg_max_size(out_pkt);
|
||||
if (max_len < IPEAP_MD5_HEADER_LEN)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-MD5 :: Buffer too small for out packet", ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
}
|
||||
else if (in_msg->type != IPEAP_TYPE_MD5_CHALLENGE)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-MD5 :: Only type MD5 challenge is supported", ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Response id and type always same as request */
|
||||
out_msg->code = IPEAP_MSG_RESPONSE;
|
||||
out_msg->id = in_msg->id;
|
||||
out_msg->type = in_msg->type;
|
||||
out_msg->length = IPEAP_MD5_HEADER_LEN;
|
||||
if (!ipeap_md5_generate_challenge_response(md5_ctx, in_msg, out_msg, max_len))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-MD5 :: Failed to generate challenge response", ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
}
|
||||
else
|
||||
{
|
||||
out_pkt->end = out_pkt->start + out_msg->length;
|
||||
out_msg->length = ip_htons(out_msg->length);
|
||||
err = IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_process_success
|
||||
*===========================================================================
|
||||
* Description: Process a success message.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* Returns:
|
||||
* IPEAP_SUCCESS
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_md5_process_success(
|
||||
Ipeap_ctx* ctx)
|
||||
{
|
||||
ctx->state = IPEAP_STATE_AUTHENTICATED;
|
||||
|
||||
return IPEAP_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_process_msg
|
||||
*===========================================================================
|
||||
* Description: Process a message.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* in_pkt - The request packet (message).
|
||||
* out_pkt - The created response packet (message).
|
||||
* Returns:
|
||||
* IPEAP_SUCCESS
|
||||
* IPEAP_PENDING_SEND_OUT_PKT
|
||||
* IPEAP_FAILURE
|
||||
* IPEAP_DROPPED_PKT
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_md5_process_msg(
|
||||
Ipeap_ctx* ctx,
|
||||
Ipeap_pkt* in_pkt,
|
||||
Ipeap_pkt* out_pkt)
|
||||
{
|
||||
Ip_err err = IPEAP_FAILURE;
|
||||
Ipeap_md5_msg* msg = IP_NULL;
|
||||
|
||||
msg = ipeap_md5_get_msg_from_pkt(in_pkt);
|
||||
|
||||
/* Sanity check, always at least 4 bytes size */
|
||||
if ((in_pkt->end - in_pkt->start) < 4)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-MD5 :: Bad in packet", ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
switch (msg->code)
|
||||
{
|
||||
case IPEAP_MSG_REQUEST:
|
||||
IPCOM_LOG1(DEBUG, "%sEAP-MD5 :: Received request message", ctx->syslog_prefix);
|
||||
err = ipeap_md5_process_request(ctx, in_pkt, out_pkt);
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_RESPONSE:
|
||||
IPCOM_LOG1(ERR, "%sEAP-MD5 :: Received response message, dropping message", ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_FAILURE:
|
||||
IPCOM_LOG1(ERR, "%sEAP-MD5 :: Received failure message, resetting state", ctx->syslog_prefix);
|
||||
(void)ipeap_md5_free(ctx);
|
||||
ctx->state = IPEAP_STATE_INIT;
|
||||
ctx->cb = IP_NULL;
|
||||
err = IPEAP_FAILURE;
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_SUCCESS:
|
||||
IPCOM_LOG1(INFO, "%sEAP-MD5 :: Received EAP success", ctx->syslog_prefix);
|
||||
err = ipeap_md5_process_success(ctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
IPCOM_LOG2(ERR, "%sEAP-MD5 :: Received unknown message type: %d, dropping message", ctx->syslog_prefix, msg->code);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_methods_get
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC Ipeap_methods*
|
||||
ipeap_md5_methods_get(void)
|
||||
{
|
||||
return &ipeap_md5_methods;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_md5.h,v $ $Revision: 1.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_md5.h,v $
|
||||
* $Author: roger $ $Date: 2005-10-25 08:24:25 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#if !defined(IPEAP_MD5_H) && defined(IPEAP_USE_EAP_MD5)
|
||||
#define IPEAP_MD5_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_md5_methods_get
|
||||
*===========================================================================
|
||||
* Description: Return a structure containing pointer to all functions
|
||||
* required by EAP.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC Ipeap_methods*
|
||||
ipeap_md5_methods_get(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,947 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_peap.c,v $ $Revision: 1.11 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_peap.c,v $
|
||||
* $Author: hchowdhu $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
#include "ipeap_common_tls.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPEAP_PEAP_VERSION_MASK 3
|
||||
#define IPEAP_PEAP_GET_VERSION(flags) (flags & IPEAP_PEAP_VERSION_MASK)
|
||||
#define IPEAP_PEAP_SET_VERSION(flags, version) (((flags) & IPEAP_PEAP_VERSION_MASK) | (version))
|
||||
|
||||
#define IPEAP_PEAP_VERSION_NOTSET (-1)
|
||||
/* Min/Max supported versions + defaults values if sysvar configs are absent or incorrect */
|
||||
#define IPEAP_PEAP_MIN_VERSION 0
|
||||
#define IPEAP_PEAP_MAX_VERSION 1
|
||||
|
||||
#define IPEAP_PEAP_START_MASK 0x20
|
||||
#define IPEAP_PEAP_IS_START(flags) (flags & IPEAP_PEAP_START_MASK)
|
||||
|
||||
#define IPEAP_PEAP_V0_AVP_TYPE_ACK_RESULT 3
|
||||
#define IPEAP_PEAP_V0_AVP_TYPE_STATUS_SUCCESS 1
|
||||
#define IPEAP_PEAP_V0_AVP_TYPE_STATUS_FAILURE 2
|
||||
|
||||
#define IPEAP_PEAP_V1_PRF_LABEL_DEFAULT "client EAP encryption"
|
||||
#define IPEAP_PEAP_V1_PRF_LABEL_ALT "client PEAP encryption"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct Ipeap_peap_ctx_st
|
||||
{
|
||||
int min_ver, max_ver, curr_ver; /* Min/Max/negotiated version */
|
||||
Ipeap_tls_suppl_ctx* tls_ctx;
|
||||
Ipeap_ctx* phase2_ctx;
|
||||
char peap_prefix[16];
|
||||
Ip_u8 msg_id; /* msg Id of last received request */
|
||||
char peapv1_prf_label[32];
|
||||
} Ipeap_peap_ctx;
|
||||
|
||||
typedef struct Ipeap_peap_msg_st
|
||||
{
|
||||
Ip_u8 code;
|
||||
Ip_u8 id;
|
||||
Ip_u16 length;
|
||||
Ip_u8 type;
|
||||
Ip_u8 flags; /* flags & version */
|
||||
Ip_u8 data[1];
|
||||
} Ipeap_peap_msg;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ip_err ipeap_peap_suppl_process_msg(struct Ipeap_ctx_st *ctx,
|
||||
struct Ipeap_pkt_st *in_pkt,
|
||||
struct Ipeap_pkt_st *reply_pkt);
|
||||
IP_STATIC Ip_err ipeap_peap_suppl_init(struct Ipeap_ctx_st *ctx);
|
||||
IP_STATIC Ip_err ipeap_peap_suppl_free(Ipeap_ctx *ctx);
|
||||
IP_STATIC Ip_err ipeap_peap_suppl_get_key(struct Ipeap_ctx_st* ctx, Ip_u8* key, int key_len);
|
||||
|
||||
IP_STATIC Ip_err ipeap_peap_handle_v0(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt);
|
||||
IP_STATIC Ip_err ipeap_peap_handle_v1(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt);
|
||||
IP_STATIC Ip_err ipeap_peap_check_ver(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt);
|
||||
IP_STATIC Ip_err ipeap_peap_get_avp(Ip_u8 *buf, int buf_len, Ip_bool *mandatory, Ip_u16 *type, Ip_u8 *avp, Ip_u16 *avp_len);
|
||||
IP_STATIC Ip_err ipeap_peap_put_avp(Ip_u8 *buf, int buf_len, Ip_bool mandatory, Ip_u16 type, Ip_u8 *avp, Ip_u16 avp_len);
|
||||
IP_PUBLIC Ip_err ipeap_peap_suppl_display_status(struct Ipeap_ctx_st* ctx, char *str);
|
||||
IP_STATIC Ip_err ipeap_peap_handle_user_input(Ipeap_ctx* ctx,
|
||||
Ipeap_user_input* ui,
|
||||
struct Ipeap_pkt_st *reply_pkt);
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ipeap_methods ipeap_peap_suppl_methods =
|
||||
{
|
||||
ipeap_peap_suppl_process_msg,
|
||||
ipeap_peap_suppl_init,
|
||||
ipeap_peap_suppl_free,
|
||||
ipeap_peap_suppl_get_key,
|
||||
ipeap_peap_handle_user_input,
|
||||
ipeap_peap_suppl_display_status,
|
||||
IP_NULL
|
||||
};
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_load_config
|
||||
*===========================================================================
|
||||
* Description: Load configuration from system variables.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
* IPCOM_SUCCESS
|
||||
* IPCOM_ERR_INVALID_ARG
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_load_config(Ipeap_peap_ctx* peap_ctx)
|
||||
{
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
Ip_size_t len = sizeof(peap_ctx->peapv1_prf_label);
|
||||
|
||||
if (!ipcom_sysvar_get("ipeap.peap.v1.prf_label", peap_ctx->peapv1_prf_label, &len)) {
|
||||
IPCOM_LOG1(WARNING, "%sfailed to retrieve ipeap.peap.v1.prf_label sysvar", peap_ctx->peap_prefix);
|
||||
err = IPCOM_ERR_FAILED;
|
||||
} else if ((ipcom_strcmp(peap_ctx->peapv1_prf_label, IPEAP_PEAP_V1_PRF_LABEL_DEFAULT) != 0) &&
|
||||
(ipcom_strcmp(peap_ctx->peapv1_prf_label, IPEAP_PEAP_V1_PRF_LABEL_ALT) != 0)) {
|
||||
IPCOM_LOG2(WARNING, "%sInvalid ipeap.peap.v1.prf_label sysvar value: \"%s\"", peap_ctx->peap_prefix, peap_ctx->peapv1_prf_label);
|
||||
err = IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (err == IPCOM_ERR_FAILED) {
|
||||
ipcom_strncpy(peap_ctx->peapv1_prf_label, IPEAP_PEAP_V1_PRF_LABEL_DEFAULT, sizeof(peap_ctx->peapv1_prf_label));
|
||||
err = IPCOM_SUCCESS;
|
||||
}
|
||||
IPCOM_LOG2(INFO, "%sSetting peapv1 prf label to: \"%s\"", peap_ctx->peap_prefix, peap_ctx->peapv1_prf_label);
|
||||
|
||||
peap_ctx->min_ver = ipcom_sysvar_get_as_int("ipeap.peap.min_version", IPEAP_PEAP_MIN_VERSION);
|
||||
peap_ctx->max_ver = ipcom_sysvar_get_as_int("ipeap.peap.max_version", IPEAP_PEAP_MAX_VERSION);
|
||||
|
||||
if ((peap_ctx->min_ver < IPEAP_PEAP_MIN_VERSION) ||
|
||||
(peap_ctx->max_ver > IPEAP_PEAP_MAX_VERSION) ||
|
||||
(peap_ctx->min_ver > peap_ctx->max_ver)) {
|
||||
IPCOM_LOG3(ERR, "%sInvalid version configuration, using default values: (min_ver=%d, max_ver=%d)",
|
||||
peap_ctx->peap_prefix, IPEAP_PEAP_MIN_VERSION, IPEAP_PEAP_MAX_VERSION);
|
||||
peap_ctx->min_ver = IPEAP_PEAP_MIN_VERSION;
|
||||
peap_ctx->max_ver = IPEAP_PEAP_MAX_VERSION;
|
||||
err = IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_ttls_suppl_process_msg
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_suppl_process_msg(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ip_err rc = IPCOM_SUCCESS;
|
||||
Ipeap_tls_msg *msg;
|
||||
Ipeap_peap_ctx* peap_ctx;
|
||||
|
||||
msg = IPEAP_PKT2TLSMSG(in_pkt);
|
||||
peap_ctx = (Ipeap_peap_ctx*)ctx->mech_data;
|
||||
|
||||
ip_assert(peap_ctx);
|
||||
ip_assert(peap_ctx->tls_ctx);
|
||||
|
||||
switch(msg->code)
|
||||
{
|
||||
case IPEAP_MSG_REQUEST:
|
||||
if (msg->type != IPEAP_TYPE_PEAP)
|
||||
{
|
||||
IPCOM_LOG1(CRIT, "%s: Not a PEAP message!", peap_ctx->peap_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
/* 1st we need to make sure we support the PEAP version sent in the 1st EAP-REQUEST
|
||||
* or negotiate a version
|
||||
*/
|
||||
rc = ipeap_peap_check_ver(ctx, in_pkt, out_pkt);
|
||||
if (rc != IPCOM_SUCCESS)
|
||||
return rc;
|
||||
|
||||
rc = ipeap_common_tls_handle_frag_and_handshake(ctx, peap_ctx->tls_ctx, in_pkt, out_pkt);
|
||||
|
||||
switch(rc)
|
||||
{
|
||||
case IPEAP_TLS_HANDSHAKE_COMPLETE:
|
||||
/* Send empty response packet, wait for EAP packets over the TLS tunnel */
|
||||
if(IPEAP_PKT_GET_SPACE_LEFT(out_pkt) < 6)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "%stoo small out pkt: space left: %d", peap_ctx->peap_prefix, IPEAP_PKT_GET_SPACE_LEFT(out_pkt));
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
rc = ipeap_tls_pkt_set_header(out_pkt, IPEAP_PKT_RESPONSE, msg->id, 6, ctx->meth_id, (Ip_u8)peap_ctx->curr_ver);
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
return rc;
|
||||
out_pkt->end += 6;
|
||||
return IPEAP_PENDING_SEND_OUT_PKT;
|
||||
|
||||
case IPEAP_TLS_DATA_AVAILABLE:
|
||||
/* An EAP packet is received over the TLS tunnel. Process */
|
||||
switch (peap_ctx->curr_ver) {
|
||||
case 0:
|
||||
return ipeap_peap_handle_v0(ctx, in_pkt, out_pkt);
|
||||
case 1:
|
||||
return ipeap_peap_handle_v1(ctx, in_pkt, out_pkt);
|
||||
default:
|
||||
IPCOM_LOG2(CRIT, "%sunexpected curr_ver %d", peap_ctx->peap_prefix, peap_ctx->curr_ver);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* Need to set the proper flags */
|
||||
Ipeap_tls_msg* msg = IPEAP_PKT2TLSMSG(out_pkt);
|
||||
msg->flags = (Ip_u8)IPEAP_PEAP_SET_VERSION(msg->flags, peap_ctx->curr_ver);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_RESPONSE:
|
||||
IPCOM_LOG1(ERR, "%sreceived response msg, dropping msg", peap_ctx->peap_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
|
||||
case IPEAP_MSG_FAILURE:
|
||||
IPCOM_LOG1(INFO, "%sreceived EAP failure", peap_ctx->peap_prefix);
|
||||
return IPEAP_FAILURE;
|
||||
|
||||
case IPEAP_MSG_SUCCESS:
|
||||
ctx->state = IPEAP_STATE_AUTHENTICATED;
|
||||
IPCOM_LOG1(INFO, "%sreceived EAP success", peap_ctx->peap_prefix);
|
||||
return IPEAP_SUCCESS;
|
||||
|
||||
default:
|
||||
IPCOM_LOG1(ERR, "%sreceived unknown msg type: %d, dropping msg", peap_ctx->peap_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_suppl_init
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_suppl_init(Ipeap_ctx *eap_ctx)
|
||||
{
|
||||
Ipeap_peap_ctx *peap_ctx;
|
||||
const char* peap_prefix = "PEAP: ";
|
||||
|
||||
peap_ctx = ipcom_malloc(sizeof(Ipeap_peap_ctx));
|
||||
if(!peap_ctx)
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
ipcom_memset(peap_ctx, 0, sizeof(Ipeap_peap_ctx));
|
||||
ipeap_peap_load_config(peap_ctx);
|
||||
peap_ctx->curr_ver = IPEAP_PEAP_VERSION_NOTSET;
|
||||
eap_ctx->mech_data = peap_ctx;
|
||||
strncpy(peap_ctx->peap_prefix, peap_prefix, sizeof(peap_ctx->peap_prefix));
|
||||
|
||||
peap_ctx->tls_ctx = ipeap_common_tls_ctx_new();
|
||||
if(!peap_ctx->tls_ctx)
|
||||
{
|
||||
ipcom_free(peap_ctx);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
peap_ctx->phase2_ctx = ipeap_ctx_new(IPEAP_MODE_SUPPLICANT);
|
||||
if(!peap_ctx->phase2_ctx)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sfailed to allocate inner EAP context", peap_ctx->peap_prefix);
|
||||
(void)ipeap_peap_suppl_free(eap_ctx);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if(ipcom_strlen(eap_ctx->syslog_prefix)+ipcom_strlen(peap_prefix) < sizeof(eap_ctx->syslog_prefix))
|
||||
{
|
||||
ipcom_strcpy(peap_ctx->phase2_ctx->syslog_prefix, eap_ctx->syslog_prefix);
|
||||
ipcom_strcat(peap_ctx->phase2_ctx->syslog_prefix, peap_prefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipcom_strcpy(peap_ctx->phase2_ctx->syslog_prefix, "<trunc>");
|
||||
ipcom_strcat(peap_ctx->phase2_ctx->syslog_prefix, peap_prefix);
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_suppl_free
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_suppl_free(Ipeap_ctx *ctx)
|
||||
{
|
||||
Ipeap_peap_ctx* peap_ctx = ctx->mech_data;
|
||||
|
||||
ip_assert(peap_ctx);
|
||||
|
||||
if(peap_ctx)
|
||||
{
|
||||
if(peap_ctx->phase2_ctx)
|
||||
ipeap_ctx_free(peap_ctx->phase2_ctx);
|
||||
if(peap_ctx->tls_ctx)
|
||||
ipeap_common_tls_ctx_free(peap_ctx->tls_ctx);
|
||||
ipcom_free(peap_ctx);
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_handle_v0
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_handle_v0(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ipeap_tls_msg *msg;
|
||||
Ipeap_msg *inner_msg;
|
||||
Ipeap_msg *inner_out_msg;
|
||||
Ipeap_pkt* tunneled_in_pkt = IP_NULL;
|
||||
Ipeap_pkt* tunneled_out_pkt = IP_NULL;
|
||||
int ssl_rc;
|
||||
Ip_bool reconstruct_hdr = IP_TRUE;
|
||||
Ipeap_peap_ctx *peap_ctx;
|
||||
|
||||
peap_ctx = (Ipeap_peap_ctx*)ctx->mech_data;
|
||||
msg = IPEAP_PKT2TLSMSG(in_pkt);
|
||||
|
||||
tunneled_in_pkt = ipeap_pkt_new(IPEAP_MTU);
|
||||
if(!tunneled_in_pkt)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sout of memory", peap_ctx->peap_prefix);
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
tunneled_out_pkt = ipeap_pkt_new(IPEAP_MTU);
|
||||
if(!tunneled_out_pkt)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sout of memory", peap_ctx->peap_prefix);
|
||||
rc = IPCOM_ERR_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* In PEAPv0 the code, type and identifier fields are omitted in all packets
|
||||
* except for EAP extension packets (type 33). Leave some room in
|
||||
* tunneled_in_pkt to enable the missing field to be re-created from the
|
||||
* outer packet. */
|
||||
tunneled_in_pkt->start += 4;
|
||||
tunneled_in_pkt->end += 4;
|
||||
|
||||
ssl_rc = SSL_read(peap_ctx->tls_ctx->ssl,
|
||||
IPEAP_PKT_GET_END_PTR(tunneled_in_pkt),
|
||||
IPEAP_PKT_GET_SPACE_LEFT(tunneled_in_pkt));
|
||||
|
||||
if(ssl_rc < 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sfailed to read inner EAP packet", peap_ctx->peap_prefix);
|
||||
goto cleanup;
|
||||
}
|
||||
tunneled_in_pkt->end += ssl_rc;
|
||||
|
||||
inner_msg = IPEAP_PKT2MSG(tunneled_in_pkt);
|
||||
if(IPEAP_PKT_GET_LEN(tunneled_in_pkt)>=5)
|
||||
{
|
||||
/* Assume a full header is received and make some checks if this is the case */
|
||||
if(inner_msg->code == IPEAP_PKT_REQUEST && inner_msg->type == IPEAP_TYPE_EXTENSIONS)
|
||||
reconstruct_hdr = IP_FALSE;
|
||||
/* Freeradius sends a full request-identity in PEAPv0 */
|
||||
else if(IPEAP_PKT_GET_LEN(tunneled_in_pkt)==5
|
||||
&& inner_msg->code == IPEAP_PKT_REQUEST
|
||||
&& inner_msg->type == IPEAP_TYPE_IDENTITY)
|
||||
{
|
||||
reconstruct_hdr = IP_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(reconstruct_hdr)
|
||||
{
|
||||
tunneled_in_pkt->start -= 4;
|
||||
inner_msg = IPEAP_PKT2MSG(tunneled_in_pkt);
|
||||
inner_msg->code = msg->code;
|
||||
inner_msg->id = msg->id;
|
||||
inner_msg->length = ip_htons(ssl_rc+4);
|
||||
}
|
||||
|
||||
IPCOM_LOG5(DEBUG2, "%sreceived inner packet, code: %d, id: %d, len: %d, type: %d",
|
||||
peap_ctx->peap_prefix, inner_msg->code, inner_msg->id, ip_ntohs(inner_msg->length), inner_msg->type);
|
||||
|
||||
/* Process pkt */
|
||||
if(inner_msg->type != IPEAP_TYPE_EXTENSIONS)
|
||||
{
|
||||
rc = ipeap_process_pkt(peap_ctx->phase2_ctx, tunneled_in_pkt, tunneled_out_pkt);
|
||||
tunneled_out_pkt->start += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle extensions packet */
|
||||
Ip_bool mandatory;
|
||||
Ip_u16 avp_type;
|
||||
Ip_u16 avp_len;
|
||||
Ip_u16 status;
|
||||
Ip_u8* avp_buf;
|
||||
int avp_buf_len;
|
||||
|
||||
avp_buf = &IPEAP_PKT_GET_START_PTR(tunneled_in_pkt)[5];
|
||||
avp_buf_len = IPEAP_PKT_GET_LEN(tunneled_in_pkt)-5;
|
||||
avp_len = sizeof(status);
|
||||
if(ipeap_peap_get_avp(avp_buf, avp_buf_len, &mandatory, &avp_type, (Ip_u8*)&status, &avp_len) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sfailed to unpack AVP in extension packet", peap_ctx->peap_prefix);
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
if(avp_type != IPEAP_PEAP_V0_AVP_TYPE_ACK_RESULT)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "%sUnexpected AVP type received in extension packet: %d", peap_ctx->peap_prefix, avp_type);
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
IPCOM_LOG2(DEBUG, "%sReceived extension packet, status: %d", peap_ctx->peap_prefix, ip_ntohs(status));
|
||||
|
||||
switch(ip_ntohs(status))
|
||||
{
|
||||
case IPEAP_PEAP_V0_AVP_TYPE_STATUS_SUCCESS:
|
||||
case IPEAP_PEAP_V0_AVP_TYPE_STATUS_FAILURE:
|
||||
inner_out_msg = IPEAP_PKT2MSG(tunneled_out_pkt);
|
||||
(void)ipeap_pkt_set_header(tunneled_out_pkt, IPEAP_MSG_RESPONSE, inner_msg->id, 11, IPEAP_TYPE_EXTENSIONS);
|
||||
tunneled_out_pkt->end += 5;
|
||||
|
||||
if(ipeap_peap_put_avp(inner_out_msg->data, IPEAP_PKT_GET_SPACE_LEFT(tunneled_out_pkt), mandatory,
|
||||
avp_type, (Ip_u8*)&status, 2) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sfailed to put status AVP in extension packet", peap_ctx->peap_prefix);
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
tunneled_out_pkt->end += 6;
|
||||
rc = IPEAP_PENDING_SEND_OUT_PKT;
|
||||
break;
|
||||
|
||||
default:
|
||||
IPCOM_LOG2(ERR, "%sUnexpected status received in extension packet: %d", peap_ctx->peap_prefix, status);
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if(rc == IPEAP_PENDING_SEND_OUT_PKT)
|
||||
{
|
||||
ssl_rc = SSL_write(peap_ctx->tls_ctx->ssl,
|
||||
IPEAP_PKT_GET_START_PTR(tunneled_out_pkt),
|
||||
IPEAP_PKT_GET_LEN(tunneled_out_pkt));
|
||||
if(ssl_rc != IPEAP_PKT_GET_LEN(tunneled_out_pkt))
|
||||
{
|
||||
IPCOM_LOG3(ERR, "%sfailed to write inner EAP packet, len: %d, ssl_rc: %d",
|
||||
peap_ctx->peap_prefix, IPEAP_PKT_GET_LEN(tunneled_out_pkt), ssl_rc);
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
rc = ipeap_common_tls_make_out_frag_pkt(peap_ctx->tls_ctx, out_pkt, IPEAP_MSG_RESPONSE, msg->id, IPEAP_TYPE_PEAP);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if(tunneled_in_pkt)
|
||||
ipeap_pkt_free(tunneled_in_pkt);
|
||||
if(tunneled_out_pkt)
|
||||
ipeap_pkt_free(tunneled_out_pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_handle_v1
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_handle_v1(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ipeap_tls_msg *in_msg, *out_msg;
|
||||
Ipeap_msg *inner_msg;
|
||||
Ipeap_pkt* tunneled_in_pkt = IP_NULL;
|
||||
Ipeap_pkt* tunneled_out_pkt = IP_NULL;
|
||||
int ssl_rc;
|
||||
Ipeap_peap_ctx *peap_ctx;
|
||||
|
||||
peap_ctx = (Ipeap_peap_ctx*)ctx->mech_data;
|
||||
in_msg = IPEAP_PKT2TLSMSG(in_pkt);
|
||||
|
||||
peap_ctx->msg_id = in_msg->id; /* Save msg id for when we send response */
|
||||
|
||||
tunneled_in_pkt = ipeap_pkt_new(IPEAP_MTU);
|
||||
if(!tunneled_in_pkt)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sout of memory", peap_ctx->peap_prefix);
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
tunneled_out_pkt = ipeap_pkt_new(IPEAP_MTU);
|
||||
if(!tunneled_out_pkt)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sout of memory", peap_ctx->peap_prefix);
|
||||
rc = IPCOM_ERR_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ssl_rc = SSL_read(peap_ctx->tls_ctx->ssl,
|
||||
IPEAP_PKT_GET_END_PTR(tunneled_in_pkt),
|
||||
IPEAP_PKT_GET_SPACE_LEFT(tunneled_in_pkt));
|
||||
if(ssl_rc < 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sfailed to read inner EAP packet", peap_ctx->peap_prefix);
|
||||
goto cleanup;
|
||||
}
|
||||
tunneled_in_pkt->end += ssl_rc;
|
||||
|
||||
inner_msg = IPEAP_PKT2MSG(tunneled_in_pkt);
|
||||
IPCOM_LOG5(DEBUG2, "%sreceived inner packet, code: %d, id: %d, len: %d, type: %d",
|
||||
peap_ctx->peap_prefix, inner_msg->code, inner_msg->id, ip_ntohs(inner_msg->length), inner_msg->type);
|
||||
|
||||
/* Process pkt */
|
||||
rc = ipeap_process_pkt(peap_ctx->phase2_ctx, tunneled_in_pkt, tunneled_out_pkt);
|
||||
|
||||
if(rc == IPEAP_PENDING_SEND_OUT_PKT)
|
||||
{
|
||||
ssl_rc = SSL_write(peap_ctx->tls_ctx->ssl,
|
||||
IPEAP_PKT_GET_START_PTR(tunneled_out_pkt),
|
||||
IPEAP_PKT_GET_LEN(tunneled_out_pkt));
|
||||
if(ssl_rc != IPEAP_PKT_GET_LEN(tunneled_out_pkt))
|
||||
{
|
||||
IPCOM_LOG3(ERR, "%sfailed to write inner EAP packet, len: %d, ssl_rc: %d",
|
||||
peap_ctx->peap_prefix, IPEAP_PKT_GET_LEN(tunneled_out_pkt), ssl_rc);
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
rc = ipeap_common_tls_make_out_frag_pkt(peap_ctx->tls_ctx, out_pkt, IPEAP_MSG_RESPONSE, in_msg->id, IPEAP_TYPE_PEAP);
|
||||
out_msg = IPEAP_PKT2TLSMSG(out_pkt);
|
||||
out_msg->flags = (Ip_u8)IPEAP_PEAP_SET_VERSION(out_msg->flags, peap_ctx->curr_ver);
|
||||
} else if (rc == IPEAP_SUCCESS) {
|
||||
/* for PEAPv1, we need to monitor for an inner EAP success and reply with an unencrypted (non-tunneled) response */
|
||||
if(IPEAP_PKT_GET_SPACE_LEFT(out_pkt) < 6)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "%stoo small out pkt: space left: %d", peap_ctx->peap_prefix, IPEAP_PKT_GET_SPACE_LEFT(out_pkt));
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
rc = ipeap_tls_pkt_set_header(out_pkt, IPEAP_PKT_RESPONSE, in_msg->id, 6, ctx->meth_id, (Ip_u8)peap_ctx->curr_ver);
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
return rc;
|
||||
out_pkt->end += 6;
|
||||
rc = IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if(tunneled_in_pkt)
|
||||
ipeap_pkt_free(tunneled_in_pkt);
|
||||
if(tunneled_out_pkt)
|
||||
ipeap_pkt_free(tunneled_out_pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_check_ver
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Checks the version and performs version negotiation if necessary.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_check_ver(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ipeap_peap_msg *msg;
|
||||
Ipeap_peap_ctx *peap_ctx;
|
||||
int version;
|
||||
const char* peapv0_prefix = "PEAPv0: ";
|
||||
const char* peapv1_prefix = "PEAPv1: ";
|
||||
const char* peap_prefix;
|
||||
|
||||
peap_ctx = (Ipeap_peap_ctx*)ctx->mech_data;
|
||||
msg = (Ipeap_peap_msg *)IPEAP_PKT2MSG(in_pkt);
|
||||
version = IPEAP_PEAP_GET_VERSION(msg->flags);
|
||||
|
||||
if (peap_ctx->curr_ver != IPEAP_PEAP_VERSION_NOTSET) {
|
||||
/* A version was negotiated/set, so verify we are still using this version */
|
||||
if (version != peap_ctx->curr_ver) {
|
||||
IPCOM_LOG3(CRIT, "%s: ipeap_peap_check_ver :: wrong PEAP version %d (expecting %d)!",
|
||||
peap_ctx->peap_prefix, version, peap_ctx->curr_ver);
|
||||
rc = IPEAP_DROPPED_PKT;
|
||||
} else {
|
||||
rc = IPCOM_SUCCESS;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* We never negotiated/set a version, so do so now */
|
||||
if (msg->code != IPEAP_MSG_REQUEST)
|
||||
{
|
||||
IPCOM_LOG1(CRIT, "%s: ipeap_peap_check_ver :: Got non EAP REQUEST before negotiating PEAP version!", peap_ctx->peap_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
if ((version >= peap_ctx->min_ver) && (version <= peap_ctx->max_ver)) {
|
||||
peap_ctx->curr_ver = version;
|
||||
rc = IPCOM_SUCCESS;
|
||||
if (peap_ctx->curr_ver == 0)
|
||||
peap_prefix = peapv0_prefix;
|
||||
else if (peap_ctx->curr_ver == 1)
|
||||
peap_prefix = peapv1_prefix;
|
||||
else
|
||||
return rc;
|
||||
|
||||
strncpy(peap_ctx->peap_prefix, peap_prefix, sizeof(peap_ctx->peap_prefix));
|
||||
if(ipcom_strlen(ctx->syslog_prefix)+ipcom_strlen(peap_prefix) < sizeof(ctx->syslog_prefix))
|
||||
{
|
||||
ipcom_strcpy(peap_ctx->phase2_ctx->syslog_prefix, ctx->syslog_prefix);
|
||||
ipcom_strcat(peap_ctx->phase2_ctx->syslog_prefix, peap_prefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipcom_strcpy(peap_ctx->phase2_ctx->syslog_prefix, "<trunc>");
|
||||
ipcom_strcat(peap_ctx->phase2_ctx->syslog_prefix, peap_prefix);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* server version not supported */
|
||||
if (version < peap_ctx->min_ver) {
|
||||
/* Since according to "draft-josefsson-pppext-eap-tls-eap-05.txt",
|
||||
* the server sends us its highest supported version,
|
||||
* in this case we will not be able to come to an agreement so
|
||||
* we send a NAK suggesting alternate methods
|
||||
*/
|
||||
if(IPEAP_PKT_GET_SPACE_LEFT(out_pkt) < 3)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "%stoo small out pkt: space left: %d", peap_ctx->peap_prefix, IPEAP_PKT_GET_SPACE_LEFT(out_pkt));
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
IPCOM_LOG3(ERR, "%sserver PEAP version %d lower than min supported version %d. Sending NAK.",
|
||||
peap_ctx->peap_prefix, version, peap_ctx->min_ver);
|
||||
ipeap_mech_type_set_enabled(ctx, msg->type, IP_FALSE); /* disable this EAP temporarily for this ctx to avoid endless negotiation loop */
|
||||
ipeap_make_nak_response(ctx, in_pkt, out_pkt);
|
||||
ipeap_mech_type_set_enabled(ctx, msg->type, IP_TRUE); /* Reenable this EAP */
|
||||
return IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
/* Server's version is higher than our max, so indicate highest version we support */
|
||||
if(IPEAP_PKT_GET_SPACE_LEFT(out_pkt) < 6)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "%stoo small out pkt: space left: %d", peap_ctx->peap_prefix, IPEAP_PKT_GET_SPACE_LEFT(out_pkt));
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
rc = ipeap_tls_pkt_set_header(out_pkt, IPEAP_PKT_RESPONSE, msg->id, 6, ctx->meth_id, (Ip_u8)peap_ctx->max_ver);
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
return rc;
|
||||
out_pkt->end += 6;
|
||||
rc = IPEAP_PENDING_SEND_OUT_PKT;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_suppl_get_key
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_suppl_get_key(struct Ipeap_ctx_st* ctx, Ip_u8* key, int key_len)
|
||||
{
|
||||
Ipeap_peap_ctx* peap_ctx;
|
||||
|
||||
peap_ctx = (Ipeap_peap_ctx*)ctx->mech_data;
|
||||
|
||||
if (peap_ctx->curr_ver == 0) {
|
||||
return ipeap_tls_common_generate_key(peap_ctx->tls_ctx, "client EAP encryption", key, key_len);
|
||||
}
|
||||
return ipeap_tls_common_generate_key(peap_ctx->tls_ctx, peap_ctx->peapv1_prf_label, key, key_len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_get_avp
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_get_avp(Ip_u8 *buf, int buf_len, Ip_bool *mandatory, Ip_u16 *type, Ip_u8 *avp, Ip_u16 *avp_len)
|
||||
{
|
||||
Ip_u16 tmp_type;
|
||||
Ip_u16 tmp_len;
|
||||
|
||||
if(buf_len < 4)
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
tmp_len = IP_GET_NTOHS(buf+2);
|
||||
if(tmp_len > *avp_len)
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
if(tmp_len > (buf_len-4))
|
||||
return IPCOM_ERR_FAILED;;
|
||||
|
||||
if(*buf & 0x80)
|
||||
*mandatory = IP_TRUE;
|
||||
else
|
||||
*mandatory = IP_FALSE;
|
||||
|
||||
tmp_type = IP_GET_NTOHS(buf);
|
||||
tmp_type = (Ip_u16)(tmp_type & 0x3fff); /* Remove mandatory and reserved bits */
|
||||
|
||||
*type = tmp_type;
|
||||
*avp_len = tmp_len;
|
||||
ipcom_memcpy(avp, buf+4, tmp_len);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_put_avp
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_put_avp(Ip_u8 *buf, int buf_len, Ip_bool mandatory, Ip_u16 type, Ip_u8 *avp, Ip_u16 avp_len)
|
||||
{
|
||||
|
||||
if(buf_len < (avp_len+4))
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
|
||||
ipcom_memset(buf, 0, (Ip_size_t)(avp_len+4));
|
||||
|
||||
IP_SET_HTONS(buf, type);
|
||||
if(mandatory)
|
||||
buf[0] |= 0x80;
|
||||
IP_SET_HTONS(buf+2, avp_len);
|
||||
ipcom_memcpy(buf+4,avp, avp_len);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_handle_user_input
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_peap_handle_user_input(Ipeap_ctx* ctx, Ipeap_user_input* ui, Ipeap_pkt* out_pkt) {
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ipeap_tls_msg *out_msg;
|
||||
Ipeap_pkt* tunneled_out_pkt = IP_NULL;
|
||||
int ssl_rc;
|
||||
Ipeap_peap_ctx* peap_ctx = (Ipeap_peap_ctx*)ctx->mech_data;
|
||||
|
||||
if (peap_ctx->curr_ver != 1) {
|
||||
IPCOM_LOG1(ERR, "%s doesn't support user input", peap_ctx->peap_prefix);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (!peap_ctx->phase2_ctx) {
|
||||
IPCOM_LOG1(ERR, "%sNo inner type to handle user input", peap_ctx->peap_prefix);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
tunneled_out_pkt = ipeap_pkt_new(IPEAP_MTU);
|
||||
if(!tunneled_out_pkt)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sout of memory", peap_ctx->peap_prefix);
|
||||
rc = IPCOM_ERR_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = ipeap_handle_user_input(peap_ctx->phase2_ctx, ui, tunneled_out_pkt);
|
||||
|
||||
if (rc != IPEAP_PENDING_SEND_OUT_PKT)
|
||||
goto cleanup;
|
||||
|
||||
ssl_rc = SSL_write(peap_ctx->tls_ctx->ssl,
|
||||
IPEAP_PKT_GET_START_PTR(tunneled_out_pkt),
|
||||
IPEAP_PKT_GET_LEN(tunneled_out_pkt));
|
||||
if(ssl_rc != IPEAP_PKT_GET_LEN(tunneled_out_pkt))
|
||||
{
|
||||
IPCOM_LOG3(ERR, "%sfailed to write inner EAP packet, len: %d, ssl_rc: %d",
|
||||
peap_ctx->peap_prefix, IPEAP_PKT_GET_LEN(tunneled_out_pkt), ssl_rc);
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
rc = ipeap_common_tls_make_out_frag_pkt(peap_ctx->tls_ctx, out_pkt, IPEAP_MSG_RESPONSE, peap_ctx->msg_id, IPEAP_TYPE_PEAP);
|
||||
out_msg = IPEAP_PKT2TLSMSG(out_pkt);
|
||||
out_msg->flags = (Ip_u8)IPEAP_PEAP_SET_VERSION(out_msg->flags, peap_ctx->curr_ver);
|
||||
|
||||
cleanup:
|
||||
if(tunneled_out_pkt)
|
||||
ipeap_pkt_free(tunneled_out_pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_suppl_methods_get
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ipeap_methods*
|
||||
ipeap_peap_suppl_methods_get(void)
|
||||
{
|
||||
return &ipeap_peap_suppl_methods;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_peap_suppl_display_status
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipeap_peap_suppl_display_status(struct Ipeap_ctx_st* ctx, char *str) {
|
||||
Ipeap_peap_ctx* peap_ctx;
|
||||
peap_ctx = (Ipeap_peap_ctx*)ctx->mech_data;
|
||||
|
||||
ipcom_printf("%s", peap_ctx->peap_prefix);
|
||||
if (peap_ctx->phase2_ctx) {
|
||||
ipeap_display_status((struct Ipeap_ctx_st*)peap_ctx->phase2_ctx, "Inner ");
|
||||
} else
|
||||
ipcom_printf("INNER EAP NOT CREATED\n");
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_sim.h,v $ $Revision: 1.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_sim.h,v $
|
||||
* $Author: roger $ $Date: 2005-10-25 08:24:25 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#if !defined(IPEAP_SIM_H) && defined(IPEAP_USE_EAP_SIM)
|
||||
#define IPEAP_SIM_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
#include "ipeap_sim_util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPEAP_SIM_VERSION 1
|
||||
|
||||
/* Non-skippable attributes (0-127) */
|
||||
#define IPEAP_SIM_AT_RAND 1
|
||||
#define IPEAP_SIM_AT_PADDING 6 /* only encrypted */
|
||||
#define IPEAP_SIM_AT_NONCE_MT 7 /* only send */
|
||||
#define IPEAP_SIM_AT_PERMANENT_ID_REQ 10
|
||||
#define IPEAP_SIM_AT_MAC 11
|
||||
#define IPEAP_SIM_AT_NOTIFICATION 12
|
||||
#define IPEAP_SIM_AT_ANY_ID_REQ 13
|
||||
#define IPEAP_SIM_AT_IDENTITY 14 /* only send */
|
||||
#define IPEAP_SIM_AT_VERSION_LIST 15
|
||||
#define IPEAP_SIM_AT_SELECTED_VERSION 16
|
||||
#define IPEAP_SIM_AT_FULLAUTH_ID_REQ 17
|
||||
#define IPEAP_SIM_AT_COUNTER 19 /* only encrypted */
|
||||
#define IPEAP_SIM_AT_COUNTER_TOO_SMALL 20 /* only encrypted */
|
||||
#define IPEAP_SIM_AT_NONCE_S 21 /* only encrypted */
|
||||
#define IPEAP_SIM_AT_CLIENT_ERROR_CODE 22 /* only send */
|
||||
#define IPEAP_SIM_AT_IV 129
|
||||
#define IPEAP_SIM_AT_ENCR_DATA 130
|
||||
#define IPEAP_SIM_AT_NEXT_PSEUDONYM 132 /* only encrypted */
|
||||
#define IPEAP_SIM_AT_NEXT_REAUTH_ID 133 /* only encrypted */
|
||||
#define IPEAP_SIM_AT_RESULT_IND 135
|
||||
|
||||
/* Subtypes */
|
||||
#define IPEAP_SIM_SUBTYPE_START 10
|
||||
#define IPEAP_SIM_SUBTYPE_CHALLENGE 11
|
||||
#define IPEAP_SIM_SUBTYPE_NOTIFICATION 12
|
||||
#define IPEAP_SIM_SUBTYPE_REAUTHENTICATION 13
|
||||
#define IPEAP_SIM_SUBTYPE_CLIENT_ERROR 14
|
||||
|
||||
/* AT_CLIENT_ERROR_CODE values */
|
||||
#define IPEAP_SIM_UNABLE_TO_PROCESS_PACKET 0
|
||||
#define IPEAP_SIM_UNSUPPORTED_VERSION 1
|
||||
#define IPEAP_SIM_INSUFFICIENT_NUM_OF_CHAL 2
|
||||
#define IPEAP_SIM_RAND_NOT_FRESH 3
|
||||
|
||||
/* AT_NOTIFICATION values */
|
||||
#define IPEAP_SIM_FAILURE_AFTER_AUTH 0x0000
|
||||
#define IPEAP_SIM_TEMPORARILY_DENIED 0x0402
|
||||
#define IPEAP_SIM_NOT_SUBSCRIBED 0x0407
|
||||
#define IPEAP_SIM_FAILURE_BEFORE_AUTH 0x4000
|
||||
#define IPEAP_SIM_SUCCESS 0x8000
|
||||
|
||||
/* Constants */
|
||||
#define IPEAP_SIM_HEADER_LEN 8
|
||||
#define IPEAP_SIM_NONCE_MT_LEN 16
|
||||
#define IPEAP_SIM_NONCE_S_LEN 16
|
||||
#define IPEAP_SIM_RAND_LEN 16
|
||||
#define IPEAP_SIM_K_AUTH_LEN 16
|
||||
#define IPEAP_SIM_K_ENCR_LEN 16
|
||||
#define IPEAP_SIM_MSK_LEN 64
|
||||
#define IPEAP_SIM_MAC_LEN 16
|
||||
#define IPEAP_SIM_IV_LEN 16
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_methods_get
|
||||
*===========================================================================
|
||||
* Description: Return a structure containing pointer to all functions
|
||||
* required by EAP.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC Ipeap_methods*
|
||||
ipeap_sim_methods_get(void);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_get_identity
|
||||
*===========================================================================
|
||||
* Description: Read identity from card (IMSI number).
|
||||
* Parameters:
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipeap_sim_get_identity(char* identity, Ip_u32 identityLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_sim_card.h,v $ $Revision: 1.4 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_sim_card.h,v $
|
||||
* $Author: dbush $ $Date: 2008-04-06 21:35:02 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#if !defined(IPEAP_SIM_CARD_H) && \
|
||||
(defined(IPEAP_USE_EAP_SIM) || defined(IPEAP_USE_EAP_AKA))
|
||||
#define IPEAP_SIM_CARD_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include "ipeap_sim_reader.h"
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
#include "ipeap_sim_util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPEAP_SIM_CARD_GSM 1
|
||||
#define IPEAP_SIM_CARD_USIM 2
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct Ipeap_sim_card_st
|
||||
{
|
||||
Ip_u32 sim_type;
|
||||
SCARDCONTEXT ctx;
|
||||
Ip_u32 protocol;
|
||||
SCARDHANDLE card;
|
||||
CARD_IO_REQUEST send_pci;
|
||||
CARD_IO_REQUEST recv_pci;
|
||||
} Ipeap_sim_card;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_card_init
|
||||
*===========================================================================
|
||||
* Description: Open a GSM SIM card connection.
|
||||
* Parameters: type - Type of card. Set to IPEAP_SIM_CARD_GSM or
|
||||
* IPEAP_SIM_CARD_USIM. Set to 0 type should be detected.
|
||||
* pin - Optional pin buffer, will be used if needed.
|
||||
* pin_len - Length of pin buffer
|
||||
* Returns: A card context structure or IP_NULL if failure.
|
||||
*/
|
||||
IP_GLOBAL Ipeap_sim_card*
|
||||
ipeap_sim_card_initialize(
|
||||
Ip_u8 type,
|
||||
Ip_u8* pin,
|
||||
Ip_u32 pinLen);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_card_finalize
|
||||
*===========================================================================
|
||||
* Description: Close the GSM card connection.
|
||||
* Parameters: ctx - The context structure recevied at initialize
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipeap_sim_card_finalize(
|
||||
Ipeap_sim_card* ctx);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_card_get_imsi
|
||||
*===========================================================================
|
||||
* Description: Read IMSI number from a GSM SIM card.
|
||||
* Parameters: ctx - a context received from initialize.
|
||||
* imsi - buffer that will receive the imsi number.
|
||||
* imsi_len - length of imsi buffer
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_card_get_imsi(
|
||||
Ipeap_sim_card* ctx,
|
||||
char* imsi,
|
||||
Ip_u32 imsiLen);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_card_gsm_auth
|
||||
*===========================================================================
|
||||
* Description: Get authentication data from GSM card based on random number.
|
||||
* Parameters: ctx - a context received from initialize.
|
||||
* rand - a random number buffer (16 bytes)
|
||||
* sres - buffer that will receive sres data (4 bytes)
|
||||
* kc - buffer that will receive kc data (8 bytes)
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_card_gsm_auth(
|
||||
Ipeap_sim_card* ctx,
|
||||
Ip_u8* rand,
|
||||
Ip_u8* sres,
|
||||
Ip_u8* kc);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_card_umts_auth
|
||||
*===========================================================================
|
||||
* Description: Get authentication data from UMTS card based on random number.
|
||||
* Parameters: ctx - a context received from initialize.
|
||||
* rand - buffer for rand data (16 bytes)
|
||||
* autn - buffer for autn data (16 bytes)
|
||||
* res - buffer that will receive res data (4-16 bytes)
|
||||
* res_len - will receive length of res buffer
|
||||
* ik - buffer that will receive ik data (16 bytes)
|
||||
* ck - buffer that will receive ck data (16 bytes)
|
||||
* auts - buffer that may receive auts data (14 bytes). Have been
|
||||
* set if *reslen = 0.
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_card_umts_auth(
|
||||
Ipeap_sim_card* ctx,
|
||||
Ip_u8* rand,
|
||||
Ip_u8* autn,
|
||||
Ip_u8* res,
|
||||
Ip_u32* res_len,
|
||||
Ip_u8* ik,
|
||||
Ip_u8* ck,
|
||||
Ip_u8* auts);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_sim_reader.c,v $ $Revision: 1.7 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_sim_reader.c,v $
|
||||
* $Author: hchowdhu $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
#include "ipeap_sim.h"
|
||||
#include "ipeap_sim_reader.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Windows have unicode and ansi version in parallell, so all with "char"
|
||||
* arguments, have A or W appended. */
|
||||
#if defined(_WIN32)
|
||||
#define PCSCAPI __stdcall
|
||||
#define SCardListReaders SCardListReadersA
|
||||
#define SCardConnect SCardConnectA
|
||||
#else
|
||||
#define PCSCAPI
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef IPEAP_USE_PCSC
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* SCardEstablishContext
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u32 PCSCAPI
|
||||
SCardEstablishContext(
|
||||
Ip_u32 dwScope,
|
||||
const void* pvReserved1,
|
||||
const void* pvReserved2,
|
||||
LPSCARDCONTEXT phContext);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* SCardReleaseContext
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u32 PCSCAPI
|
||||
SCardReleaseContext(
|
||||
SCARDCONTEXT hContext);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* SCardListReaders
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u32 PCSCAPI
|
||||
SCardListReaders(
|
||||
SCARDCONTEXT hContext,
|
||||
const char* mszGroups,
|
||||
char* mszReaders,
|
||||
Ip_u32* pcchReaders);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* SCardConnect
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u32 PCSCAPI
|
||||
SCardConnect(
|
||||
SCARDCONTEXT hContext,
|
||||
const char* szReader,
|
||||
Ip_u32 dwShareMode,
|
||||
Ip_u32 dwPreferredProtocols,
|
||||
LPSCARDHANDLE phCard,
|
||||
Ip_u32* pdwActiveProtocol);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* SCardDisconnect
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u32 PCSCAPI
|
||||
SCardDisconnect(
|
||||
SCARDHANDLE hCard,
|
||||
Ip_u32 dwDisposition);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* SCardTransmit
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u32 PCSCAPI
|
||||
SCardTransmit(
|
||||
SCARDHANDLE hCard,
|
||||
LPCCARD_IO_REQUEST pioSendPci,
|
||||
const Ip_u8* pbSendBuffer,
|
||||
Ip_u32 cbSendLength,
|
||||
LPCARD_IO_REQUEST pioRecvPci,
|
||||
Ip_u8* pbRecvBuffer,
|
||||
Ip_u32* pcbRecvLength);
|
||||
|
||||
#endif /* IPEAP_USE_PCSC */
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_establish_context
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_establish_context(
|
||||
Ip_u32 dwScope,
|
||||
const void* pvReserved1,
|
||||
const void* pvReserved2,
|
||||
LPSCARDCONTEXT phContext)
|
||||
{
|
||||
Ip_u32 err = 0xffffffff;
|
||||
|
||||
#ifdef IPEAP_USE_PCSC
|
||||
err = SCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext);
|
||||
#else
|
||||
(void)dwScope;
|
||||
(void)pvReserved1;
|
||||
(void)pvReserved2;
|
||||
(void)phContext;
|
||||
|
||||
IPCOM_LOG0(ERR, "ipeap_reader_establish_context - PC/SC unsupported");
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_release_context
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_release_context(
|
||||
SCARDCONTEXT hContext)
|
||||
{
|
||||
Ip_u32 err = 0xffffffff;
|
||||
|
||||
#ifdef IPEAP_USE_PCSC
|
||||
err = SCardReleaseContext(hContext);
|
||||
#else
|
||||
(void)hContext;
|
||||
|
||||
IPCOM_LOG0(ERR, "ipeap_reader_release_context - PC/SC unsupported");
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_list_readers
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_list_readers(
|
||||
SCARDCONTEXT hContext,
|
||||
const char* mszGroups,
|
||||
char* mszReaders,
|
||||
Ip_u32* pcchReaders)
|
||||
{
|
||||
Ip_u32 err = 0xffffffff;
|
||||
|
||||
#ifdef IPEAP_USE_PCSC
|
||||
err = SCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
|
||||
#else
|
||||
(void)hContext;
|
||||
(void)mszGroups;
|
||||
(void)mszReaders;
|
||||
(void)pcchReaders;
|
||||
|
||||
IPCOM_LOG0(ERR, "ipeap_reader_list_readers - PC/SC unsupported");
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_connect
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_connect(
|
||||
SCARDCONTEXT hContext,
|
||||
const char* szReader,
|
||||
Ip_u32 dwShareMode,
|
||||
Ip_u32 dwPreferredProtocols,
|
||||
LPSCARDHANDLE phCard,
|
||||
Ip_u32* pdwActiveProtocol)
|
||||
{
|
||||
Ip_u32 err = 0xffffffff;
|
||||
|
||||
#ifdef IPEAP_USE_PCSC
|
||||
err = SCardConnect(hContext,
|
||||
szReader,
|
||||
dwShareMode,
|
||||
dwPreferredProtocols,
|
||||
phCard,
|
||||
pdwActiveProtocol);
|
||||
#else
|
||||
(void)hContext;
|
||||
(void)szReader;
|
||||
(void)dwShareMode;
|
||||
(void)dwPreferredProtocols;
|
||||
(void)phCard;
|
||||
(void)pdwActiveProtocol;
|
||||
IPCOM_LOG0(ERR, "ipeap_reader_connect - PC/SC unsupported");
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_disconnect
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_disconnect(
|
||||
SCARDHANDLE hCard,
|
||||
Ip_u32 dwDisposition)
|
||||
{
|
||||
Ip_u32 err = 0xffffffff;
|
||||
|
||||
#ifdef IPEAP_USE_PCSC
|
||||
err = SCardDisconnect(hCard, dwDisposition);
|
||||
#else
|
||||
(void)hCard;
|
||||
(void)dwDisposition;
|
||||
|
||||
IPCOM_LOG0(ERR, "ipeap_reader_disconnect - PC/SC unsupported");
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_transmit
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_transmit(
|
||||
SCARDHANDLE hCard,
|
||||
LPCCARD_IO_REQUEST pioSendPci,
|
||||
const Ip_u8* pbSendBuffer,
|
||||
Ip_u32 cbSendLength,
|
||||
LPCARD_IO_REQUEST pioRecvPci,
|
||||
Ip_u8* pbRecvBuffer,
|
||||
Ip_u32* pcbRecvLength)
|
||||
{
|
||||
Ip_u32 err = 0xffffffff;
|
||||
|
||||
#ifdef IPEAP_USE_PCSC
|
||||
err = SCardTransmit(hCard,
|
||||
(void*)pioSendPci,
|
||||
pbSendBuffer,
|
||||
cbSendLength,
|
||||
(void*)pioRecvPci,
|
||||
pbRecvBuffer,
|
||||
pcbRecvLength);
|
||||
#else
|
||||
(void)hCard;
|
||||
(void)pioSendPci;
|
||||
(void)pbSendBuffer;
|
||||
(void)cbSendLength;
|
||||
(void)pioRecvPci;
|
||||
(void)pbRecvBuffer;
|
||||
(void)pcbRecvLength;
|
||||
|
||||
IPCOM_LOG0(ERR, "ipeap_reader_transmit - PC/SC unsupported");
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_sim_reader.h,v $ $Revision: 1.3 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_sim_reader.h,v $
|
||||
* $Author: dbush $ $Date: 2008-04-06 21:35:02 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#if !defined(IPEAP_SIM_READER_H) && \
|
||||
(defined(IPEAP_USE_EAP_SIM) || defined(IPEAP_USE_EAP_AKA))
|
||||
#define IPEAP_SIM_READER_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SCARD_S_SUCCESS
|
||||
#define SCARD_S_SUCCESS 0x00000000
|
||||
#define SCARD_E_CANCELLED 0x80100002
|
||||
#define SCARD_E_CANT_DISPOSE 0x8010000E
|
||||
#define SCARD_E_INSUFFICIENT_BUFFER 0x80100008
|
||||
#define SCARD_E_INVALID_ATR 0x80100015
|
||||
#define SCARD_E_INVALID_HANDLE 0x80100003
|
||||
#define SCARD_E_INVALID_PARAMETER 0x80100004
|
||||
#define SCARD_E_INVALID_TARGET 0x80100005
|
||||
#define SCARD_E_INVALID_VALUE 0x80100011
|
||||
#define SCARD_E_NO_MEMORY 0x80100006
|
||||
#define SCARD_F_COMM_ERROR 0x80100013
|
||||
#define SCARD_F_INTERNAL_ERROR 0x80100001
|
||||
#define SCARD_F_UNKNOWN_ERROR 0x80100014
|
||||
#define SCARD_F_WAITED_TOO_LONG 0x80100007
|
||||
#define SCARD_E_UNKNOWN_READER 0x80100009
|
||||
#define SCARD_E_TIMEOUT 0x8010000A
|
||||
#define SCARD_E_SHARING_VIOLATION 0x8010000B
|
||||
#define SCARD_E_NO_SMARTCARD 0x8010000C
|
||||
#define SCARD_E_UNKNOWN_CARD 0x8010000D
|
||||
#define SCARD_E_PROTO_MISMATCH 0x8010000F
|
||||
#define SCARD_E_NOT_READY 0x80100010
|
||||
#define SCARD_E_SYSTEM_CANCELLED 0x80100012
|
||||
#define SCARD_E_NOT_TRANSACTED 0x80100016
|
||||
#define SCARD_E_READER_UNAVAILABLE 0x80100017
|
||||
#define SCARD_W_UNSUPPORTED_CARD 0x80100065
|
||||
#define SCARD_W_UNRESPONSIVE_CARD 0x80100066
|
||||
#define SCARD_W_UNPOWERED_CARD 0x80100067
|
||||
#define SCARD_W_RESET_CARD 0x80100068
|
||||
#define SCARD_W_REMOVED_CARD 0x80100069
|
||||
#define SCARD_W_INSERTED_CARD 0x8010006A
|
||||
#define SCARD_E_UNSUPPORTED_FEATURE 0x8010001F
|
||||
#define SCARD_E_PCI_TOO_SMALL 0x80100019
|
||||
#define SCARD_E_READER_UNSUPPORTED 0x8010001A
|
||||
#define SCARD_E_DUPLICATE_READER 0x8010001B
|
||||
#define SCARD_E_CARD_UNSUPPORTED 0x8010001C
|
||||
#define SCARD_E_NO_SERVICE 0x8010001D
|
||||
#define SCARD_E_SERVICE_STOPPED 0x8010001E
|
||||
#endif
|
||||
|
||||
#ifndef SCARD_SCOPE_USER
|
||||
#define SCARD_SCOPE_USER 0x0000 /* Scope in user space */
|
||||
#define SCARD_SCOPE_TERMINAL 0x0001 /* Scope in terminal */
|
||||
#define SCARD_SCOPE_SYSTEM 0x0002 /* Scope in system */
|
||||
#define SCARD_SCOPE_GLOBAL 0x0003 /* Scope is global */
|
||||
#endif
|
||||
|
||||
#ifndef SCARD_PROTOCOL_T0
|
||||
#define SCARD_PROTOCOL_T0 0x0001 /* T=0 active protocol. */
|
||||
#define SCARD_PROTOCOL_T1 0x0002 /* T=1 active protocol. */
|
||||
#endif
|
||||
|
||||
#ifndef SCARD_SHARE_EXCLUSIVE
|
||||
#define SCARD_SHARE_EXCLUSIVE 0x0001 /* Exclusive mode only */
|
||||
#define SCARD_SHARE_SHARED 0x0002 /* Shared mode only */
|
||||
#define SCARD_SHARE_DIRECT 0x0003 /* Raw mode only */
|
||||
#endif
|
||||
|
||||
#ifndef SCARD_LEAVE_CARD
|
||||
#define SCARD_LEAVE_CARD 0x0000 /* Do nothing on close */
|
||||
#define SCARD_RESET_CARD 0x0001 /* Reset on close */
|
||||
#define SCARD_UNPOWER_CARD 0x0002 /* Power down on close */
|
||||
#define SCARD_EJECT_CARD 0x0003 /* Eject on close */
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SCARDCONTEXT
|
||||
typedef Ip_u32 SCARDCONTEXT;
|
||||
typedef SCARDCONTEXT *PSCARDCONTEXT, *LPSCARDCONTEXT;
|
||||
#endif
|
||||
|
||||
#ifndef SCARDHANDLE
|
||||
typedef Ip_u32 SCARDHANDLE;
|
||||
typedef SCARDHANDLE *PSCARDHANDLE, *LPSCARDHANDLE;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Ip_u32 dwProtocol; /* Protocol identifier */
|
||||
Ip_u32 cbPciLength; /* Protocol Control Information Length */
|
||||
} CARD_IO_REQUEST, *LPCARD_IO_REQUEST;
|
||||
typedef const CARD_IO_REQUEST *LPCCARD_IO_REQUEST;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_establish_context
|
||||
*===========================================================================
|
||||
* Description: Establish a connection with PC/SC.
|
||||
* Parameters: dwScope - Scope of connection
|
||||
* pvReserved1 - Must be set to IP_NULL
|
||||
* pvReserved2 - Must be set to IP_NULL
|
||||
* phContext - Will get handle to contect if succesful.
|
||||
* Returns: PC/SC error code
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_establish_context(
|
||||
Ip_u32 dwScope,
|
||||
const void* pvReserved1,
|
||||
const void* pvReserved2,
|
||||
LPSCARDCONTEXT phContext);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_release_context
|
||||
*===========================================================================
|
||||
* Description: Release a connection with PC/SC.
|
||||
* Parameters: hContext - Handle to existing context.
|
||||
* Returns: PC/SC error code
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_release_context(
|
||||
SCARDCONTEXT hContext);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_list_readers
|
||||
*===========================================================================
|
||||
* Description: List available PC/SC readers. Will return a list of strings
|
||||
* separated with 0. The last string will end with two 0. May
|
||||
* ask for length of needed buffer: set mszReaders to IP_NULL.
|
||||
* Parameters: hContext - Handle to existing context.
|
||||
* mszGroups - Reader group.
|
||||
* mszReaders - Buffer for reader strings.
|
||||
* pcchReaders - Length of reader strings buffer.
|
||||
* Returns: PC/SC error code
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_list_readers(
|
||||
SCARDCONTEXT hContext,
|
||||
const char* mszGroups,
|
||||
char* mszReaders,
|
||||
Ip_u32* pcchReaders);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_connect
|
||||
*===========================================================================
|
||||
* Description: Open a connection with a card in a PC/SC reader.
|
||||
* Parameters: hContext - Handle to existing context.
|
||||
* szReader - The reader name to connect.
|
||||
* dwShareMode - Share mode for the connection.
|
||||
* dwPreferredProtocols - Prefered protocol used for the
|
||||
* connection.
|
||||
* phCard - Will receive a handle to the card if successful.
|
||||
* pdwActiveProtocol - Will receive the protocol used if
|
||||
* successful.
|
||||
* Returns: PC/SC error code
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_connect(
|
||||
SCARDCONTEXT hContext,
|
||||
const char* szReader,
|
||||
Ip_u32 dwShareMode,
|
||||
Ip_u32 dwPreferredProtocols,
|
||||
LPSCARDHANDLE phCard,
|
||||
Ip_u32* pdwActiveProtocol);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_disconnect
|
||||
*===========================================================================
|
||||
* Description: Close a connection with a card in a PC/SC reader.
|
||||
* Parameters: hCard - Handle to card context.
|
||||
* dwDisposition - How should the connection be closed.
|
||||
* Returns: PC/SC error code
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_disconnect(
|
||||
SCARDHANDLE hCard,
|
||||
Ip_u32 dwDisposition);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_reader_transmit
|
||||
*===========================================================================
|
||||
* Description: Transmit a command towards a card in a PC/SC reader.
|
||||
* Parameters: hCard - Handle to card context.
|
||||
* pioSendPci - Send protocol control information
|
||||
* pbSendBuffer - Send command buffer
|
||||
* cbSendLength - Send command buffer length
|
||||
* pioRecvPci - Receive protocol control information
|
||||
* pbRecvBuffer - Receive command buffer
|
||||
* pcbRecvLength - Receive command buffer length
|
||||
* Returns: PC/SC error code
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_reader_transmit(
|
||||
SCARDHANDLE hCard,
|
||||
LPCCARD_IO_REQUEST pioSendPci,
|
||||
const Ip_u8* pbSendBuffer,
|
||||
Ip_u32 cbSendLength,
|
||||
LPCARD_IO_REQUEST pioRecvPci,
|
||||
Ip_u8* pbRecvBuffer,
|
||||
Ip_u32* pcbRecvLength);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_sim_test.c,v $ $Revision: 1.12 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_sim_test.c,v $
|
||||
* $Author: hchowdhu $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_time.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "ipeap_sim.h"
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct Ipeap_sim_test_st
|
||||
{
|
||||
Ip_u8* req;
|
||||
Ip_u32 req_len;
|
||||
Ip_u8* res;
|
||||
Ip_u32 res_len;
|
||||
} Ipeap_sim_test;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_PUBLIC Ip_bool ipeap_sim_test_vector(void);
|
||||
IP_PUBLIC Ip_bool ipeap_sim_test(void);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Test data from documentation */
|
||||
|
||||
const char IDENTITY[] = "1244070100000001@eapsim.foo";
|
||||
|
||||
static Ip_u8 REQ1[] =
|
||||
{
|
||||
0x01,0x00,0x00,0x05,0x01
|
||||
};
|
||||
#define REQ1_LEN sizeof(REQ1)
|
||||
|
||||
static Ip_u8 RES1[] =
|
||||
{
|
||||
0x02,0x00,0x00,0x20,0x01,0x31,0x32,0x34,
|
||||
0x34,0x30,0x37,0x30,0x31,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x31,0x40,0x65,0x61,
|
||||
0x70,0x73,0x69,0x6d,0x2e,0x66,0x6f,0x6f
|
||||
};
|
||||
#define RES1_LEN sizeof(RES1)
|
||||
|
||||
static Ip_u8 REQ2[] =
|
||||
{
|
||||
0x01,0x01,0x00,0x10,0x12,0x0a,0x00,0x00,
|
||||
0x0f,0x02,0x00,0x02,0x00,0x01,0x00,0x00
|
||||
};
|
||||
#define REQ2_LEN sizeof(REQ2)
|
||||
|
||||
static Ip_u8 RES2[] =
|
||||
{
|
||||
0x02,0x01,0x00,0x20,0x12,0x0a,0x00,0x00,
|
||||
0x07,0x05,0x00,0x00,0x01,0x23,0x45,0x67,
|
||||
0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
|
||||
0x76,0x54,0x32,0x10,0x10,0x01,0x00,0x01
|
||||
};
|
||||
#define RES2_LEN sizeof(RES2)
|
||||
|
||||
static Ip_u8 REQ3[] =
|
||||
{
|
||||
0x01,0x02,0x01,0x18,0x12,0x0b,0x00,0x00,
|
||||
0x01,0x0d,0x00,0x00,0x10,0x11,0x12,0x13,
|
||||
0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
|
||||
0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,
|
||||
0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,
|
||||
0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,
|
||||
0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,
|
||||
0x3c,0x3d,0x3e,0x3f,0x81,0x05,0x00,0x00,
|
||||
0x9e,0x18,0xb0,0xc2,0x9a,0x65,0x22,0x63,
|
||||
0xc0,0x6e,0xfb,0x54,0xdd,0x00,0xa8,0x95,
|
||||
0x82,0x2d,0x00,0x00,0x55,0xf2,0x93,0x9b,
|
||||
0xbd,0xb1,0xb1,0x9e,0xa1,0xb4,0x7f,0xc0,
|
||||
0xb3,0xe0,0xbe,0x4c,0xab,0x2c,0xf7,0x37,
|
||||
0x2d,0x98,0xe3,0x02,0x3c,0x6b,0xb9,0x24,
|
||||
0x15,0x72,0x3d,0x58,0xba,0xd6,0x6c,0xe0,
|
||||
0x84,0xe1,0x01,0xb6,0x0f,0x53,0x58,0x35,
|
||||
0x4b,0xd4,0x21,0x82,0x78,0xae,0xa7,0xbf,
|
||||
0x2c,0xba,0xce,0x33,0x10,0x6a,0xed,0xdc,
|
||||
0x62,0x5b,0x0c,0x1d,0x5a,0xa6,0x7a,0x41,
|
||||
0x73,0x9a,0xe5,0xb5,0x79,0x50,0x97,0x3f,
|
||||
0xc7,0xff,0x83,0x01,0x07,0x3c,0x6f,0x95,
|
||||
0x31,0x50,0xfc,0x30,0x3e,0xa1,0x52,0xd1,
|
||||
0xe1,0x0a,0x2d,0x1f,0x4f,0x52,0x26,0xda,
|
||||
0xa1,0xee,0x90,0x05,0x47,0x22,0x52,0xbd,
|
||||
0xb3,0xb7,0x1d,0x6f,0x0c,0x3a,0x34,0x90,
|
||||
0x31,0x6c,0x46,0x92,0x98,0x71,0xbd,0x45,
|
||||
0xcd,0xfd,0xbc,0xa6,0x11,0x2f,0x07,0xf8,
|
||||
0xbe,0x71,0x79,0x90,0xd2,0x5f,0x6d,0xd7,
|
||||
0xf2,0xb7,0xb3,0x20,0xbf,0x4d,0x5a,0x99,
|
||||
0x2e,0x88,0x03,0x31,0xd7,0x29,0x94,0x5a,
|
||||
0xec,0x75,0xae,0x5d,0x43,0xc8,0xed,0xa5,
|
||||
0xfe,0x62,0x33,0xfc,0xac,0x49,0x4e,0xe6,
|
||||
0x7a,0x0d,0x50,0x4d,0x0b,0x05,0x00,0x00,
|
||||
0xfe,0xf3,0x24,0xac,0x39,0x62,0xb5,0x9f,
|
||||
0x3b,0xd7,0x82,0x53,0xae,0x4d,0xcb,0x6a
|
||||
};
|
||||
#define REQ3_LEN sizeof(REQ3)
|
||||
|
||||
static Ip_u8 RES3[] =
|
||||
{
|
||||
0x02,0x02,0x00,0x1c,0x12,0x0b,0x00,0x00,
|
||||
0x0b,0x05,0x00,0x00,0xf5,0x6d,0x64,0x33,
|
||||
0xe6,0x8e,0xd2,0x97,0x6a,0xc1,0x19,0x37,
|
||||
0xfc,0x3d,0x11,0x54
|
||||
};
|
||||
#define RES3_LEN sizeof(RES3)
|
||||
|
||||
static Ip_u8 REQ4[] =
|
||||
{
|
||||
0x03,0x02,0x00,0x04
|
||||
};
|
||||
#define REQ4_LEN sizeof(REQ4)
|
||||
|
||||
static Ip_u8 REQ5[] =
|
||||
{
|
||||
0x01,0x00,0x00,0x05,0x01
|
||||
};
|
||||
#define REQ5_LEN sizeof(REQ5)
|
||||
|
||||
static Ip_u8 RES5[] =
|
||||
{
|
||||
0x02,0x00,0x00,0x56,0x01,0x59,0x32,0x34,
|
||||
0x66,0x4e,0x53,0x72,0x7a,0x38,0x42,0x50,
|
||||
0x32,0x37,0x34,0x6a,0x4f,0x4a,0x61,0x46,
|
||||
0x31,0x37,0x57,0x66,0x78,0x49,0x38,0x59,
|
||||
0x4f,0x37,0x51,0x58,0x30,0x30,0x70,0x4d,
|
||||
0x58,0x6b,0x39,0x58,0x4d,0x4d,0x56,0x4f,
|
||||
0x77,0x37,0x62,0x72,0x6f,0x61,0x4e,0x68,
|
||||
0x54,0x63,0x7a,0x75,0x46,0x71,0x35,0x33,
|
||||
0x61,0x45,0x70,0x4f,0x6b,0x6b,0x33,0x4c,
|
||||
0x30,0x64,0x6d,0x40,0x65,0x61,0x70,0x73,
|
||||
0x69,0x6d,0x2e,0x66,0x6f,0x6f
|
||||
};
|
||||
#define RES5_LEN sizeof(RES5)
|
||||
|
||||
static Ip_u8 REQ6[] =
|
||||
{
|
||||
0x01,0x01,0x00,0xa4,0x12,0x0d,0x00,0x00,
|
||||
0x81,0x05,0x00,0x00,0xd5,0x85,0xac,0x77,
|
||||
0x86,0xb9,0x03,0x36,0x65,0x7c,0x77,0xb4,
|
||||
0x65,0x75,0xb9,0xc4,0x82,0x1d,0x00,0x00,
|
||||
0x68,0x62,0x91,0xa9,0xd2,0xab,0xc5,0x8c,
|
||||
0xaa,0x32,0x94,0xb6,0xe8,0x5b,0x44,0x84,
|
||||
0x6c,0x44,0xe5,0xdc,0xb2,0xde,0x8b,0x9e,
|
||||
0x80,0xd6,0x9d,0x49,0x85,0x8a,0x5d,0xb8,
|
||||
0x4c,0xdc,0x1c,0x9b,0xc9,0x5c,0x01,0xb9,
|
||||
0x6b,0x6e,0xca,0x31,0x34,0x74,0xae,0xa6,
|
||||
0xd3,0x14,0x16,0xe1,0x9d,0xaa,0x9d,0xf7,
|
||||
0x0f,0x05,0x00,0x88,0x41,0xca,0x80,0x14,
|
||||
0x96,0x4d,0x3b,0x30,0xa4,0x9b,0xcf,0x43,
|
||||
0xe4,0xd3,0xf1,0x8e,0x86,0x29,0x5a,0x4a,
|
||||
0x2b,0x38,0xd9,0x6c,0x97,0x05,0xc2,0xbb,
|
||||
0xb0,0x5c,0x4a,0xac,0xe9,0x7d,0x5e,0xaf,
|
||||
0xf5,0x64,0x04,0x6c,0x8b,0xd3,0x0b,0xc3,
|
||||
0x9b,0xe5,0xe1,0x7a,0xce,0x2b,0x10,0xa6,
|
||||
0x0b,0x05,0x00,0x00,0x48,0x3a,0x17,0x99,
|
||||
0xb8,0x3d,0x7c,0xd3,0xd0,0xa1,0xe4,0x01,
|
||||
0xd9,0xee,0x47,0x70
|
||||
};
|
||||
#define REQ6_LEN sizeof(REQ6)
|
||||
|
||||
static Ip_u8 RES6[] =
|
||||
{
|
||||
0x02,0x01,0x00,0x44,0x12,0x0d,0x00,0x00,
|
||||
0x81,0x05,0x00,0x00,0xcd,0xf7,0xff,0xa6,
|
||||
0x5d,0xe0,0x4c,0x02,0x6b,0x56,0xc8,0x6b,
|
||||
0x76,0xb1,0x02,0xea,0x82,0x05,0x00,0x00,
|
||||
0xb6,0xed,0xd3,0x82,0x79,0xe2,0xa1,0x42,
|
||||
0x3c,0x1a,0xfc,0x5c,0x45,0x5c,0x7d,0x56,
|
||||
0x0b,0x05,0x00,0x00,0xfa,0xf7,0x6b,0x71,
|
||||
0xfb,0xe2,0xd2,0x55,0xb9,0x6a,0x35,0x66,
|
||||
0xc9,0x15,0xc6,0x17
|
||||
};
|
||||
#define RES6_LEN sizeof(RES6)
|
||||
|
||||
static Ip_u8 REQ7[] =
|
||||
{
|
||||
0x03,0x02,0x00,0x04
|
||||
};
|
||||
#define REQ7_LEN sizeof(REQ7)
|
||||
|
||||
static Ipeap_sim_test EAP_SIM_TEST[] =
|
||||
{
|
||||
{REQ1, REQ1_LEN, RES1, RES1_LEN},
|
||||
{REQ2, REQ2_LEN, RES2, RES2_LEN},
|
||||
{REQ3, REQ3_LEN, RES3, RES3_LEN},
|
||||
{REQ4, REQ4_LEN, IP_NULL, 0},
|
||||
{REQ5, REQ5_LEN, RES5, RES5_LEN},
|
||||
{REQ6, REQ6_LEN, RES6, RES6_LEN},
|
||||
{REQ7, REQ7_LEN, IP_NULL, 0},
|
||||
{IP_NULL, 0, IP_NULL, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_test_vector
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC Ip_bool
|
||||
ipeap_sim_test_vector(void)
|
||||
{
|
||||
Ip_bool ok = IP_FALSE;
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
Ipeap_ctx* ctx = IP_NULL;
|
||||
Ipeap_pkt* pkt_in = IP_NULL;
|
||||
Ipeap_pkt* pkt_out = IP_NULL;
|
||||
Ip_u32 i = 0;
|
||||
Ip_u8* req = IP_NULL;
|
||||
Ip_u32 req_len = 0;
|
||||
Ip_u8* res = IP_NULL;
|
||||
Ip_u32 res_len = 0;
|
||||
Ip_bool is_test = IP_TRUE;
|
||||
|
||||
(void)ipcom_sysvar_set("ipeap.sim", "1", IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
if(is_test)
|
||||
(void)ipcom_sysvar_set("ipeap.sim.test", "1" , IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
|
||||
(void)ipcom_sysvar_set("ipeap.sim.pin", "7575", IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
(void)ipcom_sysvar_set("ipeap.sim.realm", "eapsim.foo", IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
(void)ipcom_sysvar_set("ipeap.sim.reader", "omnikey cardman 4040 0", IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
|
||||
if ((IP_NULL == (ctx = ipeap_ctx_new(IPEAP_MODE_SUPPLICANT))) ||
|
||||
(IP_NULL == (pkt_in = ipeap_alloc_pkt(384))) ||
|
||||
(IP_NULL == (pkt_out = ipeap_alloc_pkt(128))))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_test - out of memory");
|
||||
goto cleanup;
|
||||
}
|
||||
(void)ipcom_sysvar_set("ipeap.identity", IDENTITY, IPCOM_SYSVAR_FLAG_OVERWRITE);
|
||||
(void)ipeap_ctx_set_identity_from_sysvar(ctx);
|
||||
|
||||
while (IP_NULL != EAP_SIM_TEST[i].req)
|
||||
{
|
||||
req = EAP_SIM_TEST[i].req;
|
||||
req_len = EAP_SIM_TEST[i].req_len;
|
||||
res = EAP_SIM_TEST[i].res;
|
||||
res_len = EAP_SIM_TEST[i].res_len;
|
||||
i++;
|
||||
IPCOM_LOG1(INFO, "ipeap_sim_test - TEST %d ...", i);
|
||||
ipcom_memset(pkt_in->data, 0xdd, (Ip_size_t)pkt_in->max_len);
|
||||
if (IPCOM_SUCCESS != (err = ipeap_set_pkt_data(pkt_in, req, req_len)))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipeap_sim_test - failed to set data for test (%d)", i);
|
||||
goto cleanup;
|
||||
}
|
||||
pkt_out->start = 32;
|
||||
pkt_out->end = 32;
|
||||
ipcom_memset(pkt_out->data, 0xdd, (Ip_size_t)pkt_out->max_len);
|
||||
err = ipeap_process_pkt(ctx, pkt_in, pkt_out);
|
||||
if ((IPEAP_PENDING_SEND_OUT_PKT != err) &&
|
||||
(IPEAP_SUCCESS != err))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipeap_sim_test - failed to proccess request %d", i);
|
||||
goto cleanup;
|
||||
}
|
||||
else if ((IPEAP_SUCCESS == err) && (res_len != 0))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipeap_sim_test - success to early, expecting a response for %d", i);
|
||||
goto cleanup;
|
||||
}
|
||||
if ((IPEAP_PENDING_SEND_OUT_PKT == err) &&
|
||||
(is_test) &&
|
||||
!ipeap_compare_pkt_data(pkt_out, res, res_len))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipeap_sim_test - response %d not as expected", i);
|
||||
goto cleanup;
|
||||
}
|
||||
IPCOM_LOG1(INFO, "ipeap_sim_test - TEST %d ... SUCCESS", i);
|
||||
}
|
||||
ok = IP_TRUE;
|
||||
|
||||
cleanup:
|
||||
ipeap_ctx_free(ctx);
|
||||
ipeap_free_pkt(pkt_in);
|
||||
ipeap_free_pkt(pkt_out);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_test
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC Ip_bool
|
||||
ipeap_sim_test(void)
|
||||
{
|
||||
Ip_bool ok = IP_FALSE;
|
||||
|
||||
ok = ipeap_sim_test_vector();
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_sim_test.h,v $ $Revision: 1.4 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_sim_test.h,v $
|
||||
* $Author: hchowdhu $ $Date: 2010-06-28 22:04:14 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#if !defined(IPEAP_SIM_TEST_H)
|
||||
#define IPEAP_SIM_TEST_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_test
|
||||
*===========================================================================
|
||||
* Description: Run test vectors for EAP SIM or EAP AKA.
|
||||
* Parameters:
|
||||
* Returns: TRUE if test successful (FALSE otherwise)
|
||||
*/
|
||||
IP_PUBLIC Ip_bool
|
||||
ipeap_sim_test(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,767 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_sim_util.c,v $ $Revision: 1.21 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_sim_util.c,v $
|
||||
* $Author: hchowdhu $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
#include "ipeap_sim.h"
|
||||
#include "ipeap_sim_util.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#ifndef AES_BLOCK_SIZE
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_sha1_transform
|
||||
*===========================================================================
|
||||
* Description: Make a sha-1 transform
|
||||
* Parameters: state - the current state
|
||||
* data - data buffer to transform
|
||||
* Returns:
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipeap_sim_sha1_transform(Ip_u8* state, Ip_u8 data[64]);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_get_cipher
|
||||
*===========================================================================
|
||||
* Description: Get cipher context from cipher name and key length
|
||||
* Parameters: name - the cipher name
|
||||
* key_len - key lengths in bytes
|
||||
* Returns: Cipher context or IP_NULL
|
||||
*/
|
||||
#ifndef IPMCRYPTO
|
||||
IP_STATIC const EVP_CIPHER *
|
||||
ipeap_sim_get_cipher(const char *name, Ip_u32 key_len);
|
||||
#endif /* !IPMCRYPTO */
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_sha1_transform
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipeap_sim_sha1_transform(Ip_u8* state, Ip_u8 data[64])
|
||||
{
|
||||
SHA_CTX ctx;
|
||||
|
||||
ipcom_memset(&ctx, 0, sizeof(ctx));
|
||||
ipcom_memcpy(&ctx.h0, state, 4);
|
||||
ipcom_memcpy(&ctx.h1, state+4, 4);
|
||||
ipcom_memcpy(&ctx.h2, state+8, 4);
|
||||
ipcom_memcpy(&ctx.h3, state+12, 4);
|
||||
ipcom_memcpy(&ctx.h4, state+16, 4);
|
||||
SHA1_Transform(&ctx, data);
|
||||
ipcom_memcpy(state, &ctx.h0, 4);
|
||||
ipcom_memcpy(state+4, &ctx.h1, 4);
|
||||
ipcom_memcpy(state+8, &ctx.h2, 4);
|
||||
ipcom_memcpy(state+12, &ctx.h3, 4);
|
||||
ipcom_memcpy(state+16, &ctx.h4, 4);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_get_cipher
|
||||
*===========================================================================
|
||||
*/
|
||||
#ifndef IPMCRYPTO
|
||||
IP_STATIC const EVP_CIPHER *
|
||||
ipeap_sim_get_cipher(const char *name, Ip_u32 key_len)
|
||||
{
|
||||
const EVP_CIPHER *cipher = IP_NULL;
|
||||
char alg_name[32] = {0};
|
||||
|
||||
ipcom_snprintf(alg_name, sizeof(alg_name), "%s%d", name, key_len*8);
|
||||
cipher = EVP_get_cipherbyname(alg_name);
|
||||
if (cipher == IP_NULL)
|
||||
IPCOM_LOG1(ERR, "ipeap_sim_get_cipher: %s not found", name);
|
||||
|
||||
return cipher;
|
||||
}
|
||||
#endif /* !IPMCRYPTO */
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ip_alloc_value
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ip_alloc_value(Ip_value* value, Ip_u32 len)
|
||||
{
|
||||
value->p = ipcom_calloc(1, len);
|
||||
if (IP_NULL == value->p)
|
||||
return IPCOM_ERR_FAILED;
|
||||
value->n = len;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ip_free_value
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ip_free_value(Ip_value* value)
|
||||
{
|
||||
if (IP_NULL != value->p)
|
||||
ipcom_free(value->p);
|
||||
value->p = IP_NULL;
|
||||
value->n = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ip_set_value
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ip_set_value(Ip_value* value, Ip_u8* ptr, Ip_u32 len)
|
||||
{
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
|
||||
ip_free_value(value);
|
||||
if (IPCOM_SUCCESS != (err = ip_alloc_value(value, len)))
|
||||
return err;
|
||||
ipcom_memcpy(value->p, ptr, len);
|
||||
value->n = len;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ip_append_value
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ip_append_value(Ip_value* value, Ip_u8* ptr, Ip_u32 len)
|
||||
{
|
||||
value->p = ipcom_realloc(value->p, value->n + len);
|
||||
if (IP_NULL == value->p)
|
||||
return IPCOM_ERR_FAILED;
|
||||
ipcom_memcpy(value->p + value->n, ptr, len);
|
||||
value->n += len;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_alloc_pkt
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipeap_pkt*
|
||||
ipeap_alloc_pkt(Ip_u32 size)
|
||||
{
|
||||
Ipeap_pkt* pkt = IP_NULL;
|
||||
|
||||
pkt = (Ipeap_pkt*)ipcom_calloc(1, size+sizeof(*pkt));
|
||||
if (IP_NULL != pkt)
|
||||
{
|
||||
pkt->start = 0;
|
||||
pkt->end = 0;
|
||||
pkt->max_len = (int)size;
|
||||
pkt->data = (Ip_u8*)pkt + sizeof(*pkt);
|
||||
}
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_free_pkt
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipeap_free_pkt(Ipeap_pkt* pkt)
|
||||
{
|
||||
if (IP_NULL != pkt)
|
||||
ipcom_free(pkt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_set_pkt_data
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_set_pkt_data(Ipeap_pkt* pkt, Ip_u8* data, Ip_u32 len)
|
||||
{
|
||||
if ((IP_NULL == pkt) ||
|
||||
((pkt->start + (int)len) > pkt->max_len))
|
||||
return IPCOM_ERR_FAILED;
|
||||
ipcom_memcpy(pkt->data+pkt->start, data, len);
|
||||
pkt->end = pkt->start + (int)len;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_get_pkt_data_size
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_get_pkt_data_size(
|
||||
Ipeap_pkt* pkt)
|
||||
{
|
||||
return (Ip_u32)(pkt->max_len - pkt->end);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_get_pkt_data_buffer
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u8*
|
||||
ipeap_get_pkt_data_buffer(
|
||||
Ipeap_pkt* pkt)
|
||||
{
|
||||
return (Ip_u8*)pkt->data + pkt->start;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_compare_pkt_data
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_bool
|
||||
ipeap_compare_pkt_data(Ipeap_pkt* pkt, Ip_u8* data, Ip_u32 len)
|
||||
{
|
||||
if ((IP_NULL == pkt) ||
|
||||
((pkt->end - pkt->start) != (int)len) ||
|
||||
(ipcom_memcmp(pkt->data+pkt->start, data, len) != 0))
|
||||
return IP_FALSE;
|
||||
|
||||
return IP_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_memory_to_string
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL char*
|
||||
ipeap_memory_to_string(const Ip_u8* ptr, Ip_u32 size, Ip_u8 alignment)
|
||||
{
|
||||
static const char hex_char[] = "0123456789abcdef";
|
||||
static const int byte_per_row = 32;
|
||||
char* buf;
|
||||
int row_size;
|
||||
int i, j, k = 0;
|
||||
int ws_per_row;
|
||||
int full_rows, blr;
|
||||
|
||||
ws_per_row = byte_per_row / alignment;
|
||||
row_size = 2 * byte_per_row + ws_per_row;
|
||||
full_rows = (int)size / byte_per_row;
|
||||
blr = (int)size % byte_per_row;
|
||||
|
||||
buf = ipcom_malloc( (Ip_size_t)(full_rows * row_size + 2 * blr + blr / alignment + 1) );
|
||||
if (IP_NULL == buf)
|
||||
return IP_NULL;
|
||||
|
||||
for (i = 0; i <= full_rows; i++)
|
||||
{
|
||||
k = 0;
|
||||
for (j = 0; j < (i == full_rows ? blr : byte_per_row); j++)
|
||||
{
|
||||
if (j != 0 && j % alignment == 0)
|
||||
buf[i * row_size + 2 * j + k++] = ' ';
|
||||
buf[i * row_size + 2 * j + k] =
|
||||
hex_char[ptr[i * byte_per_row + j] >> 4];
|
||||
buf[i * row_size + 2 * j + k + 1] =
|
||||
hex_char[ptr[i * byte_per_row + j] & 0x0F];
|
||||
}
|
||||
buf[i * row_size + 2 * j + k] = '\n';
|
||||
}
|
||||
buf[full_rows * row_size + 2 * blr + k] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_print_memory
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipeap_print_memory(
|
||||
const char* prefix,
|
||||
const Ip_u8* data,
|
||||
Ip_u32 len)
|
||||
{
|
||||
char* hex_mem = IP_NULL;
|
||||
|
||||
hex_mem = ipeap_memory_to_string(data, len, 4);
|
||||
if (hex_mem == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(CRIT, "ipeap_print_memory: out of memory");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make sure fit into syslog buffer */
|
||||
if ((ipcom_strlen(hex_mem) + ipcom_strlen(prefix)) >= IPCOM_SYSLOG_MAX_SIZE)
|
||||
{
|
||||
len = IPCOM_SYSLOG_MAX_SIZE - (Ip_u32)ipcom_strlen(prefix);
|
||||
hex_mem[len-4] = '.';
|
||||
hex_mem[len-3] = '.';
|
||||
hex_mem[len-2] = '.';
|
||||
hex_mem[len-1] = 0;
|
||||
}
|
||||
IPCOM_LOG2(DEBUG2, "%s%s", prefix, hex_mem);
|
||||
ipcom_free(hex_mem);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_prf
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_prf(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* buf,
|
||||
Ip_u32 buf_len)
|
||||
{
|
||||
Ip_u8 xkey[64] = {0};
|
||||
Ip_u32 t[5] = {0};
|
||||
Ip_u32 _t[5] = {0};
|
||||
Ip_s32 i = 0;
|
||||
Ip_s32 j = 0;
|
||||
Ip_s32 m = 0;
|
||||
Ip_s32 k = 0;
|
||||
Ip_u8* xpos = buf;
|
||||
Ip_u32 carry = 0;
|
||||
|
||||
/* See section 6.4
|
||||
*
|
||||
* Key derivation is based on the random number generation specified in
|
||||
* NIST Federal Information Processing Standards (FIPS) Publication
|
||||
* 186-2 [PRF]. The pseudo-random number generator is specified in the
|
||||
* change notice 1 (2001 October 5) of [PRF] (Algorithm 1) */
|
||||
|
||||
if (key_len >= 64)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipeap_sim_prf: key too long (%d >= 64)", key_len);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
ipcom_memcpy(xkey, key, key_len);
|
||||
ipcom_memset(xkey + key_len, 0, 64 - key_len);
|
||||
t[0] = 0x67452301;
|
||||
t[1] = 0xEFCDAB89;
|
||||
t[2] = 0x98BADCFE;
|
||||
t[3] = 0x10325476;
|
||||
t[4] = 0xC3D2E1F0;
|
||||
|
||||
m = (Ip_s32)buf_len / 40;
|
||||
for (j = 0; j < m; j++)
|
||||
{
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
ipcom_memcpy(_t, t, 20);
|
||||
ipeap_sim_sha1_transform((Ip_u8*)_t, xkey);
|
||||
_t[0] = (Ip_u32)ip_htonl(_t[0]);
|
||||
_t[1] = (Ip_u32)ip_htonl(_t[1]);
|
||||
_t[2] = (Ip_u32)ip_htonl(_t[2]);
|
||||
_t[3] = (Ip_u32)ip_htonl(_t[3]);
|
||||
_t[4] = (Ip_u32)ip_htonl(_t[4]);
|
||||
ipcom_memcpy(xpos, _t, 20);
|
||||
|
||||
carry = 1;
|
||||
for (k = 19; k >= 0; k--)
|
||||
{
|
||||
carry += (Ip_u32)(xkey[k] + xpos[k]);
|
||||
xkey[k] = (Ip_u8)carry;
|
||||
carry >>= 8;
|
||||
}
|
||||
|
||||
xpos += 20;
|
||||
}
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_generate_mac
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_generate_mac(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* data1,
|
||||
Ip_u32 data1_len,
|
||||
Ip_u8* data2,
|
||||
Ip_u32 data2_len,
|
||||
Ip_u8* mac,
|
||||
Ip_u32 mac_len)
|
||||
{
|
||||
const EVP_MD* evp_md = IP_NULL;
|
||||
HMAC_CTX ctx = {0};
|
||||
unsigned int hmac_len = 0;
|
||||
Ip_u8* hmac = IP_NULL;
|
||||
|
||||
evp_md = EVP_get_digestbyname("sha1");
|
||||
if (IP_NULL == evp_md)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_generate_mac: sha1 algorithm not available");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
hmac_len = (unsigned int)EVP_MD_size(evp_md);
|
||||
if (hmac_len < mac_len)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "ipeap_sim_generate_mac: bad mac length (%d < %d)", hmac_len, mac_len);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
hmac = ipcom_malloc(hmac_len);
|
||||
if (IP_NULL == hmac)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_generate_mac: out of memory");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
HMAC_CTX_init(&ctx);
|
||||
HMAC_Init(&ctx, key, (int)key_len, evp_md);
|
||||
if (data1_len > 0)
|
||||
HMAC_Update(&ctx, data1, data1_len);
|
||||
if (data2_len > 0)
|
||||
HMAC_Update(&ctx, data2, data2_len);
|
||||
HMAC_Final(&ctx, hmac, (unsigned int*)&hmac_len);
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
ipcom_memcpy(mac, hmac, mac_len);
|
||||
ipcom_free(hmac);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_verify_mac
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_verify_mac(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* data1,
|
||||
Ip_u32 data1_len,
|
||||
Ip_u8* data2,
|
||||
Ip_u32 data2_len,
|
||||
Ip_u8* mac,
|
||||
Ip_u32 mac_len)
|
||||
{
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
Ip_u8* tmp = IP_NULL;
|
||||
|
||||
tmp = ipcom_malloc(mac_len);
|
||||
if (IP_NULL == tmp)
|
||||
return IPCOM_ERR_FAILED;
|
||||
err = ipeap_sim_generate_mac(key,
|
||||
key_len,
|
||||
data1,
|
||||
data1_len,
|
||||
data2,
|
||||
data2_len,
|
||||
tmp,
|
||||
mac_len);
|
||||
if (IPCOM_SUCCESS != err)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_verify_mac: failed to generate mac");
|
||||
ipcom_free(tmp);
|
||||
return err;
|
||||
}
|
||||
if (ipcom_memcmp(tmp, mac, mac_len) != 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_verify_mac: bad mac value");
|
||||
ipcom_free(tmp);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
ipcom_free(tmp);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_aes_cbc_encrypt
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_aes_cbc_encrypt(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* iv,
|
||||
Ip_u32 iv_len,
|
||||
Ip_u8* data,
|
||||
Ip_u32 data_len)
|
||||
{
|
||||
Ip_err err = IPCOM_ERR_FAILED;
|
||||
|
||||
if (data_len == 0)
|
||||
{
|
||||
err = IPCOM_SUCCESS;
|
||||
}
|
||||
else if ((iv_len == AES_BLOCK_SIZE) && ((data_len % AES_BLOCK_SIZE) == 0))
|
||||
{
|
||||
#if defined(IPMCRYPTO)
|
||||
AES_KEY ctx;
|
||||
ipcom_memset(&ctx, 0, sizeof(ctx));
|
||||
if (AES_set_encrypt_key(key, key_len*8, &ctx) < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_aes_cbc_encrypt: failed to set key");
|
||||
err = IPCOM_ERR_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = IPCOM_SUCCESS;
|
||||
AES_cbc_encrypt(data, data, data_len, &ctx, iv, AES_ENCRYPT);
|
||||
}
|
||||
#else /* defined (IPCRYPTO) */
|
||||
const EVP_CIPHER *cipher = IP_NULL;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
if ((cipher = ipeap_sim_get_cipher("aes", key_len)) != IP_NULL)
|
||||
{
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
if (EVP_EncryptInit(&ctx, cipher, key, iv) &&
|
||||
EVP_CIPHER_CTX_set_padding(&ctx, 0) &&
|
||||
EVP_EncryptUpdate(&ctx, data, (int*)&data_len, data, (int)data_len))
|
||||
{
|
||||
err = IPCOM_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_aes_cbc_encrypt: failed to encrypt");
|
||||
}
|
||||
(void)EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_aes_cbc_decrypt
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_aes_cbc_decrypt(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* iv,
|
||||
Ip_u32 iv_len,
|
||||
Ip_u8* data,
|
||||
Ip_u32 data_len)
|
||||
{
|
||||
Ip_err err = IPCOM_ERR_FAILED;
|
||||
|
||||
if (data_len == 0)
|
||||
{
|
||||
err = IPCOM_SUCCESS;
|
||||
}
|
||||
else if ((iv_len == AES_BLOCK_SIZE) && ((data_len % AES_BLOCK_SIZE) == 0))
|
||||
{
|
||||
#if defined(IPMCRYPTO)
|
||||
AES_KEY ctx;
|
||||
ipcom_memset(&ctx, 0, sizeof(ctx));
|
||||
if (AES_set_decrypt_key(key, key_len*8, &ctx) < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_aes_cbc_decrypt: failed to set key");
|
||||
err = IPCOM_ERR_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = IPCOM_SUCCESS;
|
||||
AES_cbc_encrypt(data, data, data_len, &ctx, iv, AES_DECRYPT);
|
||||
}
|
||||
#else /* defined (IPCRYPTO) */
|
||||
const EVP_CIPHER *cipher = IP_NULL;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
if ((cipher = ipeap_sim_get_cipher("aes", key_len)) != IP_NULL)
|
||||
{
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
if (EVP_DecryptInit(&ctx, cipher, key, iv) &&
|
||||
EVP_CIPHER_CTX_set_padding(&ctx, 0) &&
|
||||
EVP_DecryptUpdate(&ctx, data, (int*)&data_len, data, (int)data_len))
|
||||
{
|
||||
err = IPCOM_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_aes_cbc_decrypt: failed to decrypt");
|
||||
}
|
||||
(void)EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_algorithm_test
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_algorithm_test(void)
|
||||
{
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
|
||||
#ifdef IP_DEBUG
|
||||
Ip_u8 IV[16] = {0};
|
||||
Ip_u8 KEY[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
|
||||
Ip_u8 MSG[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
|
||||
Ip_u8 ENC[16] = {0x69,0xC4,0xE0,0xD8,0x6A,0x7B,0x04,0x30,0xD8,0xCD,0xB7,0x80,0x70,0xB4,0xC5,0x5A};
|
||||
Ip_u8 tmp[16] = {0};
|
||||
|
||||
ipcom_memcpy(tmp, MSG, sizeof(MSG));
|
||||
if (IPCOM_SUCCESS != (err = ipeap_sim_aes_cbc_encrypt(
|
||||
KEY, sizeof(KEY),
|
||||
IV, sizeof(IV),
|
||||
tmp, sizeof(tmp))))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_algorithm_test - AES encrypt not available");
|
||||
}
|
||||
else if (ipcom_memcmp(ENC, tmp, sizeof(ENC)) != 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_algorithm_test - AES bad encrypt value");
|
||||
err = IPCOM_ERR_FAILED;
|
||||
}
|
||||
else if (IPCOM_SUCCESS != (err = ipeap_sim_aes_cbc_decrypt(
|
||||
KEY, sizeof(KEY),
|
||||
IV, sizeof(IV),
|
||||
tmp, sizeof(tmp))))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_algorithm_test - AES decrypt not available");
|
||||
}
|
||||
else if (ipcom_memcmp(MSG, tmp, sizeof(MSG)) != 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_sim_algorithm_test - AES bad decrypt value");
|
||||
err = IPCOM_ERR_FAILED;
|
||||
}
|
||||
#endif /* IP_DEBUG */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK INTERNAL API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_sim_util.h,v $ $Revision: 1.5 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_sim_util.h,v $
|
||||
* $Author: hchowdhu $ $Date: 2010-06-28 22:03:54 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#if !defined(IPEAP_SIM_UTIL_H)
|
||||
#define IPEAP_SIM_UTIL_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct Ip_value_st
|
||||
{
|
||||
Ip_u8* p;
|
||||
Ip_u32 n;
|
||||
} Ip_value;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ip_alloc_value
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ip_alloc_value(
|
||||
Ip_value* value,
|
||||
Ip_u32 len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ip_free_value
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ip_free_value(
|
||||
Ip_value* value);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ip_set_value
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ip_set_value(
|
||||
Ip_value* value,
|
||||
Ip_u8* ptr,
|
||||
Ip_u32 len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ip_append_value
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ip_append_value(
|
||||
Ip_value* value,
|
||||
Ip_u8* ptr,
|
||||
Ip_u32 len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_alloc_pkt
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ipeap_pkt*
|
||||
ipeap_alloc_pkt(
|
||||
Ip_u32 size);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_free_pkt
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipeap_free_pkt(
|
||||
Ipeap_pkt* pkt);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_set_pkt_data
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_set_pkt_data(
|
||||
Ipeap_pkt* pkt,
|
||||
Ip_u8* data,
|
||||
Ip_u32 len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_get_pkt_data_size
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u32
|
||||
ipeap_get_pkt_data_size(
|
||||
Ipeap_pkt* pkt);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_get_pkt_data_buffer
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_u8*
|
||||
ipeap_get_pkt_data_buffer(
|
||||
Ipeap_pkt* pkt);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_compare_pkt_data
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_bool
|
||||
ipeap_compare_pkt_data(
|
||||
Ipeap_pkt* pkt,
|
||||
Ip_u8* data,
|
||||
Ip_u32 len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_memory_to_string
|
||||
*===========================================================================
|
||||
* Description: Convert a byte array to a hexadecimal string.
|
||||
* Parameters: ptr - pointer to a buffer
|
||||
* size - size of buffer
|
||||
* alignment - number of bytes between white space
|
||||
* Returns: A string allocated with ipcom_malloc
|
||||
*/
|
||||
IP_GLOBAL char*
|
||||
ipeap_memory_to_string(
|
||||
const Ip_u8* ptr,
|
||||
Ip_u32 size,
|
||||
Ip_u8 alignment);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_print_memory
|
||||
*===========================================================================
|
||||
* Description: Print a byte array to sys log (level DEBUG2).
|
||||
* Parameters: prefix - Starting string of print out.
|
||||
* data - pointer to buffer
|
||||
* len - length of buffer
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipeap_print_memory(
|
||||
const char* prefix,
|
||||
const Ip_u8* data,
|
||||
Ip_u32 len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_prf
|
||||
*===========================================================================
|
||||
* Description: Pseudo-random-function for EAP SIM.
|
||||
* Parameters: key - buffer to key value
|
||||
* key_len - length of key buffer
|
||||
* buf - buffer for generated value
|
||||
* buf_len - length of buffer for generated value
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_prf(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* buf,
|
||||
Ip_u32 buf_len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_generate_mac
|
||||
*===========================================================================
|
||||
* Description: Generate EAP SIM mac value from data.
|
||||
* Parameters: key - mac key buffer
|
||||
* key_len - length of mac key buffer
|
||||
* dataX - data buffer to generate mac for.
|
||||
* dataX_len - length of data buffer
|
||||
* mac - buffer for generated mac
|
||||
* mac_len - length of mac buffer
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_generate_mac(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* data1,
|
||||
Ip_u32 data1_len,
|
||||
Ip_u8* data2,
|
||||
Ip_u32 data2_len,
|
||||
Ip_u8* mac,
|
||||
Ip_u32 mac_len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_verify_mac
|
||||
*===========================================================================
|
||||
* Description: Verify EAP SIM mac value for specified data.
|
||||
* Parameters: key - mac key buffer
|
||||
* key_len - length of mac key buffer
|
||||
* dataX - data buffer to verify mac for.
|
||||
* dataX_len - length of data buffer
|
||||
* mac - buffer for mac data
|
||||
* mac_len - length of mac buffer
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_verify_mac(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* data1,
|
||||
Ip_u32 data1_len,
|
||||
Ip_u8* data2,
|
||||
Ip_u32 data2_len,
|
||||
Ip_u8* mac,
|
||||
Ip_u32 mac_len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_aes_cbc_encrypt
|
||||
*===========================================================================
|
||||
* Description: Encrypt with AES algorithm
|
||||
* Parameters: key - buffer for key value
|
||||
* key_len - length of key buffer
|
||||
* iv - buffer for iv
|
||||
* iv_len - length of iv buffer
|
||||
* data - data buffer to be encrypted
|
||||
* data_len - length of data buffer
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_aes_cbc_encrypt(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* iv,
|
||||
Ip_u32 iv_len,
|
||||
Ip_u8* data,
|
||||
Ip_u32 data_len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_aes_cbc_decrypt
|
||||
*===========================================================================
|
||||
* Description: Decrypt with AES algorithm
|
||||
* Parameters: key - buffer for key value
|
||||
* key_len - length of key buffer
|
||||
* iv - buffer for iv
|
||||
* iv_len - length of iv buffer
|
||||
* data - data buffer to be decrypted
|
||||
* data_len - length of data buffer
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_aes_cbc_decrypt(
|
||||
Ip_u8* key,
|
||||
Ip_u32 key_len,
|
||||
Ip_u8* iv,
|
||||
Ip_u32 iv_len,
|
||||
Ip_u8* data,
|
||||
Ip_u32 data_len);
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_sim_algorithm_test
|
||||
*===========================================================================
|
||||
* Description: Check algorithms used by mechanism
|
||||
* Parameters:
|
||||
* Returns: IPCOM_SUCCESS
|
||||
* IPCOM_ERR_FAILED
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipeap_sim_algorithm_test(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipeap_tls.c,v $ $Revision: 1.20.12.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipeap/src/ipeap_tls.c,v $
|
||||
* $Author: hxu4 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipeap_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
#include "ipeap_common_tls.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_STATIC Ip_err ipeap_tls_suppl_process_msg(struct Ipeap_ctx_st *ctx,
|
||||
struct Ipeap_pkt_st *in_pkt,
|
||||
struct Ipeap_pkt_st *reply_pkt);
|
||||
|
||||
IP_STATIC Ip_err ipeap_tls_suppl_get_key(struct Ipeap_ctx_st* ctx, Ip_u8* key, int key_len);
|
||||
|
||||
IP_STATIC Ip_err ipeap_tls_suppl_init(struct Ipeap_ctx_st *ctx);
|
||||
IP_STATIC Ip_err ipeap_tls_suppl_free(Ipeap_ctx *ctx);
|
||||
IP_STATIC Ip_err ipeap_tls_suppl_get_session_id(Ipeap_ctx *ctx,Ip_u8 *session_id,Ip_u32 *session_id_len);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
IP_STATIC Ipeap_methods ipeap_tls_suppl_methods =
|
||||
{
|
||||
ipeap_tls_suppl_process_msg,
|
||||
ipeap_tls_suppl_init,
|
||||
ipeap_tls_suppl_free,
|
||||
ipeap_tls_suppl_get_key,
|
||||
IP_NULL,
|
||||
IP_NULL,
|
||||
ipeap_tls_suppl_get_session_id
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_suppl_init
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_tls_suppl_init(Ipeap_ctx *ctx)
|
||||
{
|
||||
Ipeap_tls_suppl_ctx* tls_ctx;
|
||||
|
||||
tls_ctx = ipeap_common_tls_ctx_new();
|
||||
if(!tls_ctx)
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
ctx->mech_data = tls_ctx;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_suppl_free
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_tls_suppl_free(Ipeap_ctx *ctx)
|
||||
{
|
||||
Ipeap_tls_suppl_ctx* tls_ctx;
|
||||
|
||||
tls_ctx = (Ipeap_tls_suppl_ctx*)ctx->mech_data;
|
||||
|
||||
ipeap_common_tls_ctx_free(tls_ctx);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_suppl_get_key
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_tls_suppl_get_key(struct Ipeap_ctx_st* ctx, Ip_u8* key, int key_len)
|
||||
{
|
||||
Ipeap_tls_suppl_ctx *tls_ctx;
|
||||
|
||||
tls_ctx = (Ipeap_tls_suppl_ctx*)ctx->mech_data;
|
||||
|
||||
return ipeap_tls_common_generate_key(tls_ctx, "client EAP encryption", key, key_len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_suppl_process_msg
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_tls_suppl_process_msg(Ipeap_ctx *ctx, Ipeap_pkt *in_pkt, Ipeap_pkt *out_pkt)
|
||||
{
|
||||
Ip_err rc;
|
||||
Ipeap_tls_msg *msg;
|
||||
Ipeap_tls_suppl_ctx* tls_ctx;
|
||||
|
||||
msg = IPEAP_PKT2TLSMSG(in_pkt);
|
||||
tls_ctx = (Ipeap_tls_suppl_ctx*)ctx->mech_data;
|
||||
|
||||
switch(msg->code)
|
||||
{
|
||||
case IPEAP_MSG_REQUEST:
|
||||
rc = ipeap_common_tls_handle_frag_and_handshake(ctx, tls_ctx, in_pkt, out_pkt);
|
||||
|
||||
switch(rc)
|
||||
{
|
||||
case IPEAP_PENDING_SEND_OUT_PKT:
|
||||
break;
|
||||
case IPEAP_TLS_HANDSHAKE_COMPLETE:
|
||||
rc = ipeap_tls_pkt_set_header(out_pkt, IPEAP_PKT_RESPONSE, msg->id, 6, ctx->meth_id, 0);
|
||||
out_pkt->end += 6;
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
return rc;
|
||||
return IPEAP_PENDING_SEND_OUT_PKT;
|
||||
|
||||
case IPEAP_TLS_DATA_AVAILABLE:
|
||||
IPCOM_LOG0(ERR, "EAP-TLS :: Application data received in TLS handshake");
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
default:
|
||||
IPCOM_LOG1(ERR, "EAP-TLS :: Unexpected return code from ipeap_common_tls_handle_frag_and_handshake(): %d", rc);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
break;
|
||||
case IPEAP_MSG_RESPONSE:
|
||||
IPCOM_LOG0(ERR, "EAP-TLS :: received response msg, dropping msg");
|
||||
return IPEAP_DROPPED_PKT;
|
||||
|
||||
case IPEAP_MSG_FAILURE:
|
||||
IPCOM_LOG0(ERR, "EAP-TLS :: received EAP failure");
|
||||
return IPEAP_FAILURE;
|
||||
|
||||
case IPEAP_MSG_SUCCESS:
|
||||
ctx->state = IPEAP_STATE_AUTHENTICATED;
|
||||
IPCOM_LOG0(INFO, "EAP-TLS ::Received EAP success");
|
||||
return IPEAP_SUCCESS;
|
||||
|
||||
default:
|
||||
IPCOM_LOG1(ERR, "EAP-TLS :: received unknown msg type: %d, dropping msg", msg->code);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_suppl_get_session_id
|
||||
*===========================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
IP_STATIC Ip_err
|
||||
ipeap_tls_suppl_get_session_id(
|
||||
Ipeap_ctx *ctx,
|
||||
Ip_u8 *session_id,
|
||||
Ip_u32 *session_id_len
|
||||
)
|
||||
{
|
||||
|
||||
Ip_err rc = IPCOM_SUCCESS;
|
||||
Ipeap_tls_suppl_ctx *tls_ctx = IP_NULL;
|
||||
|
||||
|
||||
IPCOM_LOG0(DEBUG, "IPEAP-TLS :: Get Session-Id :: ");
|
||||
|
||||
if(!ctx)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_tls_suppl_get_session_id - NULL EAP ctx");
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
tls_ctx = (Ipeap_tls_suppl_ctx*)ctx->mech_data;
|
||||
|
||||
if(!tls_ctx)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipeap_tls_suppl_get_session_id - NULL EAP-TLS ctx");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
|
||||
rc = ipeap_tls_common_generate_session_id(tls_ctx,IPEAP_TYPE_TLS,session_id,session_id_len);
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_tls_suppl_methods_get
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ipeap_methods*
|
||||
ipeap_tls_suppl_methods_get(void)
|
||||
{
|
||||
return &ipeap_tls_suppl_methods;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,844 @@
|
||||
/* ipeap_wsc.c - EAP WSC implementation */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify, or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01g,18mar09,dwb Adding IPWPS macros
|
||||
01e,26feb09,dwb More work for fragmentation support
|
||||
01d,17feb09,dwb Adding fragmentation support
|
||||
01c,12feb09,dwb Ongoing development for wsc message handling
|
||||
01b,03feb09,dwb EAP WPS Implementation
|
||||
01a,24Dec08,mry Created
|
||||
*/
|
||||
|
||||
/* DESCRIPTION:
|
||||
* ===========
|
||||
* This library contains the EAP WSC implementation as described in
|
||||
* "WiFi Protected Setup Specification, v1.0h, Dec 2006".
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
#include "ipeap_config.h"
|
||||
|
||||
#ifdef IPEAP_USE_EAP_WSC
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
|
||||
#include "ipeap.h"
|
||||
#include "ipeap_h.h"
|
||||
|
||||
#ifdef IPWPS
|
||||
#include "ipwps_private_api.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPEAP_WSC_HEADER_LEN 14
|
||||
|
||||
#define IPEAP_TYPE_WSC IPEAP_TYPE_EXPANDED
|
||||
#define IPEAP_WSC_VENDOR_TYPE IPEAP_VT_WSC_SIMPLE_CONFIG
|
||||
|
||||
#define IPEAP_WSC_START 0x01
|
||||
#define IPEAP_WSC_ACK 0x02
|
||||
#define IPEAP_WSC_NACK 0x03
|
||||
#define IPEAP_WSC_MSG 0x04
|
||||
#define IPEAP_WSC_DONE 0x05
|
||||
#define IPEAP_WSC_FRAG_ACK 0x06
|
||||
|
||||
#define IPEAP_WSC_FLAGS_MF 0x01 /* More Fragments */
|
||||
#define IPEAP_WSC_FLAGS_LF 0x02 /* Length Field */
|
||||
/* 0x04 to 0x80 are reserved */
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
typedef enum {
|
||||
IPEAP_WSC_STATE_TBD = 0
|
||||
} Ipeap_wsc_state;
|
||||
|
||||
typedef struct Ipeap_wsc_ctx_st
|
||||
{
|
||||
Ipeap_wsc_state state;
|
||||
char peer_identity[IPEAP_IDENTITY_MAX_LEN];
|
||||
Ip_u8 msg_id;
|
||||
Ip_u8 opcode;
|
||||
#ifdef IPWPS
|
||||
Ipwps_proto_data wsc_msg;
|
||||
Ipwps_proto_data *resp_data;
|
||||
#endif
|
||||
Ip_u16 msg_data_tot;
|
||||
Ip_u32 frag_bytes_sent;
|
||||
} Ipeap_wsc_ctx;
|
||||
|
||||
typedef struct Ipeap_wsc_msg_hdr_st {
|
||||
Ipeap_expanded_pkt_hdr exp_eap_hdr;
|
||||
Ip_u8 opcode;
|
||||
Ip_u8 flags;
|
||||
} Ipeap_wsc_msg_hdr;
|
||||
|
||||
typedef struct Ipeap_wsc_msg_st
|
||||
{
|
||||
Ipeap_wsc_msg_hdr hdr;
|
||||
Ip_u8 msg_data[1];
|
||||
} Ipeap_wsc_msg;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_EXTERN Ipeap_vendor_id ipeap_wsc_vendor_id;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ip_err ipeap_wsc_process_msg(struct Ipeap_ctx_st *ctx,
|
||||
struct Ipeap_pkt_st *in_pkt,
|
||||
struct Ipeap_pkt_st *reply_pkt);
|
||||
IP_STATIC Ip_err ipeap_wsc_init(struct Ipeap_ctx_st *ctx);
|
||||
IP_STATIC Ip_err ipeap_wsc_free(Ipeap_ctx *ctx);
|
||||
IP_PUBLIC Ip_err ipeap_wsc_display_status(struct Ipeap_ctx_st* ctx, char *str);
|
||||
#ifdef IPWPS
|
||||
IP_STATIC Ip_err ipeap_wsc_assemble_wsc_msg(struct Ipeap_ctx_st* ctx,
|
||||
Ipeap_wsc_msg *in_msg, Ip_u8 **msg_data, Ip_u16 *msg_len,
|
||||
Ipeap_pkt* out_pkt);
|
||||
IP_STATIC Ip_err ipeap_wsc_fragment_wsc_msg(struct Ipeap_ctx_st* ctx,
|
||||
Ipwps_proto_data **wsc_resp_data, Ip_u8 opcode, Ipeap_pkt* out_pkt);
|
||||
IP_STATIC Ip_err
|
||||
ipeap_wsc_packet_set_wsc_header(Ip_u16 len, Ip_u8 opcode, Ip_u8 flags,
|
||||
Ipeap_pkt* out_pkt);
|
||||
IP_STATIC Ip_err ipeap_wsc_eap_failure(struct Ipeap_ctx_st* ctx,
|
||||
Ipeap_pkt* out_pkt);
|
||||
#endif
|
||||
/*
|
||||
*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ipeap_methods ipeap_wsc_methods =
|
||||
{
|
||||
ipeap_wsc_process_msg,
|
||||
ipeap_wsc_init,
|
||||
ipeap_wsc_free,
|
||||
IP_NULL,
|
||||
IP_NULL,
|
||||
ipeap_wsc_display_status,
|
||||
IP_NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_wsc_init
|
||||
*===========================================================================
|
||||
* Description: Initialize EAP wsc context.
|
||||
* Parameters: ctx - The EAP wsc context.
|
||||
* Returns:
|
||||
* IPCOM_SUCCESS
|
||||
* IPCOM_ERR_NO_MEMORY
|
||||
* IPCOM_ERR_INVALID_ARG
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_wsc_init(Ipeap_ctx* ctx)
|
||||
{
|
||||
#ifndef IPWPS
|
||||
/* EAP WSC is not supported without WPS support being included */
|
||||
IPCOM_LOG1(CRIT, "%sEAP-WSC :: Cannot use EAP-WSC since WPS support missing.", ctx->syslog_prefix);
|
||||
return IPCOM_ERR_NOT_SUPPORTED;
|
||||
#else
|
||||
Ip_err err = IPCOM_SUCCESS;
|
||||
Ipeap_wsc_ctx* wsc_ctx = IP_NULL;
|
||||
|
||||
wsc_ctx = ipcom_calloc(1, sizeof(*wsc_ctx));
|
||||
if (IP_NULL == wsc_ctx)
|
||||
{
|
||||
IPCOM_LOG1(CRIT, "%sEAP-WSC :: Out of memory", ctx->syslog_prefix);
|
||||
err = IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->mech_data = wsc_ctx;
|
||||
ctx->state = IPEAP_STATE_INIT;
|
||||
wsc_ctx->state = IPEAP_WSC_STATE_TBD;
|
||||
wsc_ctx->msg_id = 1;
|
||||
wsc_ctx->wsc_msg.len = 0;
|
||||
wsc_ctx->msg_data_tot = 0;
|
||||
wsc_ctx->resp_data = IP_NULL;
|
||||
}
|
||||
|
||||
return err;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_wsc_free
|
||||
*===========================================================================
|
||||
* Description: Free EAP wsc context.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* Returns: IPCOM_SUCCESS
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_wsc_free(Ipeap_ctx* ctx)
|
||||
{
|
||||
Ipeap_wsc_ctx* wsc_ctx = IP_NULL;
|
||||
|
||||
if ((ctx != IP_NULL) && (ctx->mech_data != IP_NULL))
|
||||
{
|
||||
wsc_ctx = (Ipeap_wsc_ctx*)ctx->mech_data;
|
||||
ipcom_free(wsc_ctx);
|
||||
ctx->mech_data = IP_NULL;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_wsc_process_msg
|
||||
*===========================================================================
|
||||
* Description: Process a message.
|
||||
* Parameters: ctx - The EAP context.
|
||||
* in_pkt - The request packet (message).
|
||||
* out_pkt - The created response packet (message).
|
||||
* Returns:
|
||||
* IPEAP_SUCCESS
|
||||
* IPEAP_PENDING_SEND_OUT_PKT
|
||||
* IPEAP_FAILURE
|
||||
* IPEAP_DROPPED_PKT
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_wsc_process_msg(
|
||||
Ipeap_ctx* ctx,
|
||||
Ipeap_pkt* in_pkt,
|
||||
Ipeap_pkt* out_pkt)
|
||||
{
|
||||
#ifndef IPWPS
|
||||
return IPEAP_DROPPED_PKT;
|
||||
#else
|
||||
Ip_err err = IPEAP_FAILURE;
|
||||
Ipeap_wsc_msg* in_msg = IP_NULL;
|
||||
Ipeap_wsc_ctx* wsc_ctx = (Ipeap_wsc_ctx*)ctx->mech_data;
|
||||
#ifdef IPWPS
|
||||
Ipwps_wsc_proto_msg *event_data = IP_NULL;
|
||||
Ipwps_proto_data *resp_data = IP_NULL;
|
||||
Ipwps_wsc_rc event_rc = IPWPS_WSC_RC_NOT_SET;
|
||||
#endif
|
||||
ip_assert(wsc_ctx);
|
||||
|
||||
in_msg = (Ipeap_wsc_msg*)IPEAP_PKT2MSG(in_pkt);
|
||||
|
||||
/* Sanity check, always at least 4 bytes size */
|
||||
if ((in_pkt->end - in_pkt->start) < 4)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "%sEAP-WSC :: Bad in packet", ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
switch (in_msg->hdr.exp_eap_hdr.code)
|
||||
{
|
||||
case IPEAP_MSG_REQUEST:
|
||||
case IPEAP_MSG_RESPONSE:
|
||||
{
|
||||
Ip_u16 len = 0;
|
||||
int event = -1;
|
||||
Ip_u8 *msg_data = IP_NULL;
|
||||
Ip_u8 wsc_opcode;
|
||||
#if 0
|
||||
Ipeap_wsc_msg_hdr *wsc_msg_hdr;
|
||||
|
||||
wsc_msg_hdr =
|
||||
(Ipeap_wsc_msg_hdr *)IPEAP_PKT2MSG(out_pkt);
|
||||
#endif
|
||||
/* Fix up the eap code and id */
|
||||
if(in_msg->hdr.exp_eap_hdr.code == IPEAP_MSG_REQUEST) {
|
||||
|
||||
(void)ipeap_pkt_set_header(out_pkt, IPEAP_PKT_RESPONSE,
|
||||
in_msg->hdr.exp_eap_hdr.id, IPEAP_WSC_HEADER_LEN,
|
||||
IPEAP_TYPE_EXPANDED);
|
||||
|
||||
} else {
|
||||
|
||||
/* Validate the id */
|
||||
if(in_msg->hdr.exp_eap_hdr.id != wsc_ctx->msg_id) {
|
||||
IPCOM_LOG1(DEBUG, "%sEAP-WSC :: Id mismatch!",
|
||||
ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
wsc_ctx->msg_id++;
|
||||
if((err = ipeap_pkt_set_header(out_pkt, IPEAP_PKT_REQUEST,
|
||||
wsc_ctx->msg_id, IPEAP_WSC_HEADER_LEN,
|
||||
IPEAP_TYPE_EXPANDED)) != IPCOM_SUCCESS)
|
||||
return IPEAP_DROPPED_PKT;
|
||||
|
||||
}
|
||||
|
||||
if ( (in_msg->hdr.exp_eap_hdr.type == IPEAP_TYPE_IDENTITY) &&
|
||||
(in_msg->hdr.exp_eap_hdr.code == IPEAP_MSG_RESPONSE) ) {
|
||||
|
||||
len = IP_GET_NTOHS(&in_msg->hdr.exp_eap_hdr.len);
|
||||
len -= IPEAP_PKT_HDR_LEN;
|
||||
|
||||
if (len >= IPEAP_IDENTITY_MAX_LEN)
|
||||
len = IPEAP_IDENTITY_MAX_LEN-1;
|
||||
|
||||
ipcom_memcpy(wsc_ctx->peer_identity,
|
||||
((Ipeap_msg *)in_msg)->data, len);
|
||||
|
||||
wsc_ctx->peer_identity[len] = '\0';
|
||||
IPCOM_LOG2(DEBUG2, "%sEAP-WSC :: Received EAP"
|
||||
" Response/Identity (%s). Passing to IPWPS"
|
||||
" module.\n",
|
||||
ctx->syslog_prefix, wsc_ctx->peer_identity);
|
||||
|
||||
len++;
|
||||
msg_data = (Ip_u8 *)wsc_ctx->peer_identity;
|
||||
event = IPWPS_WSC_EVENT_RCV_ID_RESP;
|
||||
|
||||
} else if ( in_msg->hdr.exp_eap_hdr.type ==
|
||||
IPEAP_TYPE_EXPANDED ) {
|
||||
|
||||
/* Note, this will send the frag ack */
|
||||
if((err = ipeap_wsc_assemble_wsc_msg(ctx, in_msg, &msg_data, &len,
|
||||
out_pkt)) != IPCOM_SUCCESS)
|
||||
return err;
|
||||
|
||||
switch (in_msg->hdr.opcode) {
|
||||
case IPEAP_WSC_START:
|
||||
event = IPWPS_WSC_EVENT_RCV_WSC_START;
|
||||
break;
|
||||
case IPEAP_WSC_ACK:
|
||||
event = IPWPS_WSC_EVENT_RCV_WSC_ACK;
|
||||
break;
|
||||
case IPEAP_WSC_NACK:
|
||||
event = IPWPS_WSC_EVENT_RCV_WSC_NACK;
|
||||
break;
|
||||
case IPEAP_WSC_MSG:
|
||||
event = IPWPS_WSC_EVENT_RCV_WSC_MSG;
|
||||
break;
|
||||
case IPEAP_WSC_DONE:
|
||||
event = IPWPS_WSC_EVENT_RCV_WSC_DONE;
|
||||
break;
|
||||
case IPEAP_WSC_FRAG_ACK:
|
||||
IPCOM_LOG1(DEBUG2, "\n\n%sEAP-WSC :: ********** Received Frag ACK"
|
||||
" Message **********\n\n",ctx->syslog_prefix);
|
||||
return ipeap_wsc_fragment_wsc_msg(ctx, IP_NULL, 0, out_pkt);
|
||||
default:
|
||||
err = IPEAP_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
IPCOM_LOG2(ERR, "%sEAP-WSC :: Received unexptected"
|
||||
" request/response type: %d, dropping message",
|
||||
ctx->syslog_prefix, in_msg->hdr.exp_eap_hdr.type);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
if( (event >= IPWPS_WSC_EVENT_RCV_ID_RESP) &&
|
||||
(event <= IPWPS_WSC_EVENT_RCV_EAP_FAIL) ) {
|
||||
event_data = ipwps_create_proto_msg_data(event,len, msg_data);
|
||||
}
|
||||
|
||||
if (event_data) {
|
||||
err = ipwps_handle_wsc_event(event_data, &event_rc,
|
||||
&resp_data);
|
||||
if ((err < 0) || (event_rc < 0)) {
|
||||
err = ipeap_wsc_eap_failure(ctx, out_pkt);
|
||||
}
|
||||
|
||||
} else {
|
||||
IPCOM_LOG1(ERR, "%sEAP-WSC :: Failed to allocate wps event "
|
||||
"data structure.", ctx->syslog_prefix);
|
||||
err = ipeap_wsc_eap_failure(ctx, out_pkt);
|
||||
}
|
||||
|
||||
if(err == IPCOM_SUCCESS) {
|
||||
switch(event_rc) {
|
||||
case IPWPS_WSC_RC_OK:
|
||||
break;
|
||||
case IPWPS_WSC_RC_SEND_WSC_START:
|
||||
wsc_opcode = IPEAP_WSC_START;
|
||||
break;
|
||||
case IPWPS_WSC_RC_SEND_WSC_ACK:
|
||||
wsc_opcode = IPEAP_WSC_ACK;
|
||||
break;
|
||||
case IPWPS_WSC_RC_SEND_WSC_NACK:
|
||||
wsc_opcode = IPEAP_WSC_NACK;
|
||||
break;
|
||||
case IPWPS_WSC_RC_SEND_WSC_MSG:
|
||||
wsc_opcode = IPEAP_WSC_MSG;
|
||||
break;
|
||||
|
||||
case IPWPS_WSC_RC_SEND_WSC_DONE:
|
||||
wsc_opcode = IPEAP_WSC_DONE;
|
||||
break;
|
||||
default:
|
||||
wsc_opcode = IPEAP_WSC_START;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Frame up the packet to be sent */
|
||||
if( (event_rc > IPWPS_WSC_RC_OK) &&
|
||||
(event_rc < IPWPS_WSC_RC_TERMINATE_EAP) ) {
|
||||
err = ipeap_wsc_fragment_wsc_msg(ctx, &resp_data,
|
||||
wsc_opcode, out_pkt);
|
||||
|
||||
/* Terminate the conversation */
|
||||
} else if ( (event_rc == IPWPS_WSC_RC_TERMINATE_EAP) ||
|
||||
(event_rc < 0) ) {
|
||||
err = ipeap_wsc_eap_failure(ctx, out_pkt);
|
||||
|
||||
} else if (event_rc == IPWPS_WSC_RC_OK) {
|
||||
/* DO Nothing */
|
||||
IPCOM_LOG1(ERR, "%sEAP-WSC :: IPWPS_WSC_RC_OK event type: doing nothing", ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
} else {
|
||||
IPCOM_LOG2(ERR, "%sEAP-WSC :: unknown event type: %d,"
|
||||
" dropping message", ctx->syslog_prefix,
|
||||
in_msg->hdr.exp_eap_hdr.code);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
} else if (err != IPCOM_SUCCESS) {
|
||||
IPCOM_LOG3(ERR, "%sEAP-WSC :: ipwps_handle_wsc_event not"
|
||||
" successful, err = %d, event_rc = %d",
|
||||
ctx->syslog_prefix, err, event_rc);
|
||||
err = IPEAP_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
if(resp_data) {
|
||||
ipcom_free(resp_data);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
case IPEAP_MSG_FAILURE:
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: Received EAP FAILURE. Passing to"
|
||||
" IPWPS module.",ctx->syslog_prefix);
|
||||
event_data =
|
||||
ipwps_create_proto_msg_data(IPWPS_WSC_EVENT_RCV_EAP_FAIL, 0,
|
||||
IP_NULL);
|
||||
err = ipwps_handle_wsc_event(event_data, &event_rc, &resp_data);
|
||||
if(resp_data) {
|
||||
ipcom_free(resp_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case IPEAP_MSG_SUCCESS:
|
||||
IPCOM_LOG1(ERR, "%sEAP-WSC :: Received Unexpected EAP SUCCESS, dropping.",
|
||||
ctx->syslog_prefix);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
break;
|
||||
|
||||
default:
|
||||
IPCOM_LOG2(ERR, "%sEAP-WSC :: Received unknown message type: %d, dropping message",
|
||||
ctx->syslog_prefix, in_msg->hdr.exp_eap_hdr.code);
|
||||
err = IPEAP_DROPPED_PKT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (event_data)
|
||||
ipcom_free(event_data);
|
||||
return err;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_wsc_methods_get
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC Ipeap_methods*
|
||||
ipeap_wsc_methods_get(void)
|
||||
{
|
||||
return &ipeap_wsc_methods;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* Ipeap_wsc_state_name
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC char *Ipeap_wsc_state_name(int state) {
|
||||
|
||||
return "UNKNOWN STATE";
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_wsc_display_status
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipeap_wsc_display_status(struct Ipeap_ctx_st* ctx, char *str) {
|
||||
Ipeap_wsc_ctx* wsc_ctx = (Ipeap_wsc_ctx*)ctx->mech_data;
|
||||
|
||||
ipcom_printf(" WSC state = %s\n", Ipeap_wsc_state_name(wsc_ctx->state));
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef IPWPS
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_wsc_assemble_wsc_msg
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
|
||||
IP_STATIC Ip_err ipeap_wsc_assemble_wsc_msg(struct Ipeap_ctx_st* ctx,
|
||||
Ipeap_wsc_msg *in_msg, Ip_u8 **wsc_data, Ip_u16 *wsc_len, Ipeap_pkt* out_pkt)
|
||||
{
|
||||
Ip_u16 len;
|
||||
Ip_err err;
|
||||
#if 0
|
||||
Ipeap_wsc_msg_hdr *wsc_msg_hdr;
|
||||
#endif
|
||||
Ip_u8 *msg_data = IP_NULL;
|
||||
Ipeap_wsc_ctx* wsc_ctx = (Ipeap_wsc_ctx*)ctx->mech_data;
|
||||
|
||||
#if 0
|
||||
wsc_msg_hdr =
|
||||
(Ipeap_wsc_msg_hdr *)IPEAP_PKT2MSG(out_pkt);
|
||||
#endif
|
||||
len = IP_GET_NTOHS(&in_msg->hdr.exp_eap_hdr.len);
|
||||
|
||||
if (len < IPEAP_PKT_HDR_LEN+1) {
|
||||
IPCOM_LOG1(DEBUG, "%sEAP-WSC :: Received BAD EAP"
|
||||
" packet. Dropping.\n",
|
||||
ctx->syslog_prefix);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
len -= IPEAP_WSC_HEADER_LEN;
|
||||
msg_data = (Ip_u8 *)(((Ip_u8 *)in_msg)+IPEAP_WSC_HEADER_LEN);
|
||||
|
||||
/* This is not a fragmented message so we're done */
|
||||
if( (wsc_ctx->msg_data_tot == 0) &&
|
||||
!(in_msg->hdr.flags & IPEAP_WSC_FLAGS_MF) ) {
|
||||
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Received non-fragmented"
|
||||
" Message **********",ctx->syslog_prefix);
|
||||
*wsc_data = msg_data;
|
||||
*wsc_len = len;
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
/* Process wsc message fragments */
|
||||
} else if (in_msg->hdr.flags & IPEAP_WSC_FLAGS_MF) {
|
||||
|
||||
/* If this was the first fragment, the LF should be set */
|
||||
if(in_msg->hdr.flags & IPEAP_WSC_FLAGS_LF) {
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Received first "
|
||||
"message fragment **********",ctx->syslog_prefix);
|
||||
len-=2;
|
||||
wsc_ctx->wsc_msg.len = IP_GET_NTOHS(msg_data);
|
||||
msg_data+=2;
|
||||
|
||||
/* Not first fragment but not the last */
|
||||
} else {
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Received middle fragment"
|
||||
" **********",ctx->syslog_prefix);
|
||||
}
|
||||
|
||||
/* Frag Ack for both of the above situations */
|
||||
if((err = ipeap_wsc_packet_set_wsc_header(IPEAP_WSC_HEADER_LEN,
|
||||
IPEAP_WSC_FRAG_ACK,0,out_pkt)) != IPCOM_SUCCESS)
|
||||
return err;
|
||||
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Sending FRAG ACK"
|
||||
" Message **********",
|
||||
ctx->syslog_prefix);
|
||||
|
||||
err = IPEAP_PENDING_SEND_OUT_PKT;
|
||||
|
||||
/* Check if this is the last fragment */
|
||||
} else {
|
||||
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Received last fragment"
|
||||
" **********",ctx->syslog_prefix);
|
||||
|
||||
/* Validate that we haven't got too many bytes */
|
||||
if ((wsc_ctx->msg_data_tot+len) != wsc_ctx->wsc_msg.len) {
|
||||
IPCOM_LOG3(ERR,"%sEAP-WSC :: Expected %d bytes but have"
|
||||
" received (%d bytes)",
|
||||
ctx->syslog_prefix,wsc_ctx->wsc_msg.len,
|
||||
wsc_ctx->msg_data_tot);
|
||||
return IPEAP_DROPPED_PKT;
|
||||
}
|
||||
|
||||
/* Release the message data */
|
||||
*wsc_data = &wsc_ctx->wsc_msg.data[0];
|
||||
*wsc_len = wsc_ctx->wsc_msg.len;
|
||||
|
||||
|
||||
err = IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/* Concat the fragment */
|
||||
if(len <= (IPWPS_PROTO_MSG_DATALEN_MAX-wsc_ctx->msg_data_tot)) {
|
||||
IPCOM_LOG3(DEBUG2, "%sEAP-WSC :: ********** Concating %d bytes of"
|
||||
" data, msg_data_tot: %d **********",ctx->syslog_prefix,
|
||||
len,wsc_ctx->msg_data_tot);
|
||||
ipcom_memcpy(&wsc_ctx->wsc_msg.data[wsc_ctx->msg_data_tot],
|
||||
msg_data,len);
|
||||
wsc_ctx->msg_data_tot += len;
|
||||
|
||||
/* Reset */
|
||||
if(wsc_ctx->msg_data_tot == wsc_ctx->wsc_msg.len) {
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Resetting"
|
||||
" msg_data_tot **********",ctx->syslog_prefix);
|
||||
wsc_ctx->msg_data_tot = 0;
|
||||
wsc_ctx->wsc_msg.len = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Reset */
|
||||
wsc_ctx->msg_data_tot = 0;
|
||||
wsc_ctx->wsc_msg.len = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_wsc_fragment_wsc_msg
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_wsc_fragment_wsc_msg(struct Ipeap_ctx_st* ctx, Ipwps_proto_data **wsc_resp_data,
|
||||
Ip_u8 opcode, Ipeap_pkt* out_pkt)
|
||||
{
|
||||
|
||||
Ip_err err;
|
||||
Ip_u8 flags = 0;
|
||||
Ipwps_proto_data *resp_data = IP_NULL;
|
||||
Ip_u16 resp_data_len = 0;
|
||||
Ip_u32 resp_data_tot = 0;
|
||||
Ip_u16 header_size = IPEAP_WSC_HEADER_LEN;
|
||||
Ipeap_wsc_msg_hdr *wsc_stub;
|
||||
Ipeap_wsc_ctx* wsc_ctx = (Ipeap_wsc_ctx*)ctx->mech_data;
|
||||
|
||||
wsc_stub = (Ipeap_wsc_msg_hdr *)IPEAP_PKT2MSG(out_pkt);
|
||||
|
||||
/* Check for response data or data in the fragment buffer */
|
||||
if(wsc_resp_data != IP_NULL) {
|
||||
resp_data = *wsc_resp_data;
|
||||
if(resp_data != IP_NULL) resp_data_len += resp_data->len;
|
||||
resp_data_tot = resp_data_len;
|
||||
} else if (wsc_ctx->resp_data != IP_NULL) {
|
||||
resp_data_len += (wsc_ctx->resp_data->len - wsc_ctx->frag_bytes_sent);
|
||||
}
|
||||
|
||||
/* We have response data. Fragment it if necessary */
|
||||
if( resp_data_len > IPEAP_MTU ) {
|
||||
|
||||
resp_data_len = IP_MIN(resp_data_len, IPEAP_MTU-header_size);
|
||||
resp_data_len = IP_MIN(resp_data_len, IPEAP_PKT_GET_SPACE_LEFT(out_pkt));
|
||||
|
||||
/* This is the first fragment */
|
||||
if((wsc_ctx->resp_data == IP_NULL) && (resp_data != IP_NULL)) {
|
||||
/* This message must be fragmented and this is the first
|
||||
* fragment. Place the total resp_data length at the end
|
||||
* of the header */
|
||||
wsc_ctx->frag_bytes_sent = 0;
|
||||
flags |= IPEAP_WSC_FLAGS_LF;
|
||||
IP_SET_HTONS((Ip_u8 *)(((Ip_u8 *)wsc_stub)+
|
||||
IPEAP_WSC_HEADER_LEN),resp_data_tot);
|
||||
wsc_ctx->resp_data = resp_data;
|
||||
wsc_ctx->opcode = opcode;
|
||||
header_size+=2;
|
||||
resp_data_len-=2;
|
||||
ipcom_memcpy((Ip_u8 *)(((Ip_u8 *)wsc_stub)+header_size),
|
||||
&(resp_data->data[0]),resp_data_len);
|
||||
|
||||
*wsc_resp_data = IP_NULL;
|
||||
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Sending First Fragment"
|
||||
" **********",
|
||||
ctx->syslog_prefix);
|
||||
|
||||
} else if(wsc_ctx->resp_data != IP_NULL) {
|
||||
ipcom_memcpy((Ip_u8 *)(((Ip_u8 *)wsc_stub)+header_size),
|
||||
&(wsc_ctx->resp_data->data[wsc_ctx->frag_bytes_sent]),
|
||||
resp_data_len);
|
||||
opcode = wsc_ctx->opcode;
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Sending Middle Fragment"
|
||||
" **********",
|
||||
ctx->syslog_prefix);
|
||||
}
|
||||
|
||||
flags |= IPEAP_WSC_FLAGS_MF;
|
||||
wsc_ctx->frag_bytes_sent += resp_data_len;
|
||||
|
||||
/* This is the last fragment */
|
||||
} else if (wsc_ctx->resp_data != IP_NULL) {
|
||||
ipcom_memcpy((Ip_u8 *)(((Ip_u8 *)wsc_stub)+header_size),
|
||||
&(wsc_ctx->resp_data->data[wsc_ctx->frag_bytes_sent]),
|
||||
resp_data_len);
|
||||
opcode = wsc_ctx->opcode;
|
||||
|
||||
ipcom_free(wsc_ctx->resp_data);
|
||||
wsc_ctx->resp_data = IP_NULL;
|
||||
wsc_ctx->frag_bytes_sent = 0;
|
||||
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Sending Last Fragment"
|
||||
" **********",
|
||||
ctx->syslog_prefix);
|
||||
|
||||
ipcom_free(wsc_ctx->resp_data);
|
||||
|
||||
|
||||
|
||||
/* No fragmentation is required */
|
||||
} else if (resp_data_len > 0) {
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: ********** Sending Non-Fragment"
|
||||
" **********",
|
||||
ctx->syslog_prefix);
|
||||
ipcom_memcpy((Ip_u8 *)(((Ip_u8 *)wsc_stub)+header_size),
|
||||
&(resp_data->data[0]), resp_data_len);
|
||||
}
|
||||
|
||||
if((err = ipeap_wsc_packet_set_wsc_header(header_size+resp_data_len,opcode,
|
||||
flags,out_pkt)) != IPCOM_SUCCESS)
|
||||
return err;
|
||||
|
||||
return IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_wsc_packet_set_header
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipeap_wsc_packet_set_wsc_header(Ip_u16 len, Ip_u8 opcode, Ip_u8 flags,
|
||||
Ipeap_pkt* out_pkt)
|
||||
{
|
||||
Ipeap_wsc_msg_hdr *wsc_stub;
|
||||
|
||||
if(out_pkt->max_len - out_pkt->start < 4)
|
||||
return IPEAP_FAILURE;
|
||||
|
||||
wsc_stub = (Ipeap_wsc_msg_hdr *)IPEAP_PKT2MSG(out_pkt);
|
||||
wsc_stub->exp_eap_hdr.type = IPEAP_TYPE_EXPANDED;
|
||||
IP_SET_HTONS(&wsc_stub->exp_eap_hdr.len,len);
|
||||
ipcom_memcpy(&wsc_stub->exp_eap_hdr.vendor_id.smi, &ipeap_wsc_vendor_id,
|
||||
IPEAP_VENDOR_ID_LEN);
|
||||
IP_SET_HTONL(&wsc_stub->exp_eap_hdr.vendor_type,
|
||||
IPEAP_VT_WSC_SIMPLE_CONFIG);
|
||||
wsc_stub->opcode = opcode;
|
||||
wsc_stub->flags = flags;
|
||||
out_pkt->end += len;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipeap_wsc_eap_failure
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err ipeap_wsc_eap_failure(struct Ipeap_ctx_st* ctx, Ipeap_pkt* out_pkt)
|
||||
{
|
||||
|
||||
Ipeap_wsc_msg_hdr * wsc_msg_hdr =
|
||||
(Ipeap_wsc_msg_hdr *)IPEAP_PKT2MSG(out_pkt);
|
||||
|
||||
IPCOM_LOG1(DEBUG2, "%sEAP-WSC :: Sending EAP-Failure",
|
||||
ctx->syslog_prefix);
|
||||
|
||||
if(ipeap_pkt_set_header(out_pkt, IPEAP_MSG_FAILURE,
|
||||
wsc_msg_hdr->exp_eap_hdr.id, IPEAP_PKT_HDR_LEN-1,
|
||||
IPEAP_TYPE_UNDEFINED) != IPCOM_SUCCESS) {
|
||||
return IPEAP_FAILURE;
|
||||
}
|
||||
out_pkt->end += IPEAP_PKT_HDR_LEN-1;
|
||||
|
||||
/* Free the contexts */
|
||||
if(ctx->cb && ctx->cb->free)
|
||||
(void)ctx->cb->free(ctx);
|
||||
ctx->cb = IP_NULL;
|
||||
|
||||
|
||||
return IPEAP_PENDING_SEND_OUT_PKT;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user