original files of m241
This commit is contained in:
@@ -0,0 +1,863 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipike2_payload_authentication.c,v $ $Revision: 1.26.10.7 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipike/src/ipike2_payload_authentication.c,v $
|
||||
* $Author: zan $ $Date: 2013-08-05 10:04:01 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Authentication payload (IKE version 2) */
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
#include "ipike_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef IPIKE_USE_VERSION2
|
||||
|
||||
#include "ipike_h.h"
|
||||
#include "ipike_attributes.h"
|
||||
#include "ipike2_payload_authentication.h"
|
||||
#include "ipike_util.h"
|
||||
#include "ipike_sadb.h"
|
||||
#include "ipike_crypto.h"
|
||||
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_key_db.h>
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_data
|
||||
*===========================================================================
|
||||
* Description: Returns a pointer to the authentication data in the payload.
|
||||
* Parameters: auth - a authentication payload.
|
||||
* Returns: A pointer to the authentication data.
|
||||
*/
|
||||
IP_STATIC Ip_u8*
|
||||
ipike_payload_authentication_data(Ipike2_auth_payload* auth)
|
||||
{
|
||||
return (Ip_u8*)auth + sizeof(Ipike2_auth_payload);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_data_length
|
||||
*===========================================================================
|
||||
* Description: Returns the length of the authentication data.
|
||||
* Parameters: auth - authentication payload.
|
||||
* Returns: The length of the authentication data (in bytes).
|
||||
*/
|
||||
IP_STATIC Ip_u16
|
||||
ipike_payload_authentication_data_length(Ipike2_auth_payload* auth)
|
||||
{
|
||||
return IPIKE_PAYLOAD_DATA_LENGTH(auth->header.length, sizeof(Ipike2_auth_payload));
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_get_digest_info
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipike_error
|
||||
ipike_payload_authentication_get_digest_info(
|
||||
Ipike_config_auth* conf,
|
||||
Ipike_value* msg,
|
||||
Ipike_value* digest)
|
||||
{
|
||||
Ipike_error err;
|
||||
Ipike_value data;
|
||||
Ipike_value hash;
|
||||
Ip_u8 alg;
|
||||
|
||||
digest->value = IP_NULL;
|
||||
data.value = IP_NULL;
|
||||
hash.value = IP_NULL;
|
||||
alg = ipike_crypto_hash_algorithm_from_cert(conf->certificate);
|
||||
|
||||
if (IPIKE_SUCCESS != (err = ipike_crypto_hash(alg, msg, &hash)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_get_digest_info() :: failed generate hash");
|
||||
}
|
||||
else if (IPIKE_SUCCESS != (err = ipike_crypto_create_digest_info(alg, &hash, digest)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_get_digest_info() :: failed encode digest info");
|
||||
}
|
||||
if (IP_NULL != data.value)
|
||||
ipcom_free(data.value);
|
||||
if (IP_NULL != hash.value)
|
||||
ipcom_free(hash.value);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_verify_certificate
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipike_error
|
||||
ipike_payload_authentication_verify_certificate(
|
||||
Ipike_config_auth* conf,
|
||||
Ipike_cert* cert)
|
||||
{
|
||||
Ipike_error err = IPIKE_SUCCESS;
|
||||
X509** trusted = IP_NULL;
|
||||
X509** ca = IP_NULL;
|
||||
X509_CRL** crls = IP_NULL;
|
||||
|
||||
trusted = ipike_crypto_get_trusted_certs(conf->trusted_ca_store);
|
||||
ca = ipike_crypto_get_intermediate_ca_certs(cert, conf->intermediate_ca_store);
|
||||
|
||||
if (trusted == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_verify_certificate() :: failed to read trusted certificate");
|
||||
err = IPIKE_INVALID_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef IPIKE_USE_OCSP
|
||||
err = ipike_crypto_verify_certificate_ocsp(trusted, ca, cert->peer, cert->crls, cert->resp_peer);
|
||||
#else
|
||||
err = ipike_crypto_verify_certificate(trusted, ca, cert->peer, cert->crls);
|
||||
#endif
|
||||
}
|
||||
ipike_array_free((void**) trusted, (void(*)(void*)) X509_free);
|
||||
ipike_array_free((void**) ca, (void(*)(void*)) X509_free);
|
||||
ipike_array_free((void**) crls, (void(*)(void*)) X509_CRL_free);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_generate_pre_shared
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipike_error
|
||||
ipike_payload_authentication_generate_pre_shared(Ip_u16 prf_alg,
|
||||
Ipike_config_auth* conf,
|
||||
Ipike_value* msg,
|
||||
Ipike_value* auth)
|
||||
{
|
||||
Ipike_error err = IPIKE_SUCCESS;
|
||||
Ip_u8* psk_buf = IP_NULL;
|
||||
int psk_buf_len = 0;
|
||||
const char* psk_id = conf->psk_id;
|
||||
Ip_u8* shared_key = (Ip_u8 *) conf->shared_key;
|
||||
Ip_size_t shared_key_len = shared_key ? ipcom_strlen(conf->shared_key) : 0;
|
||||
|
||||
if (psk_id)
|
||||
{
|
||||
if (ipcom_key_db_buf_get(psk_id, IP_NULL, &psk_buf_len) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipike_payload_authentication_generate_pre_shared()"\
|
||||
" :: failed to get psk_id: %s, from secure key db", psk_id);
|
||||
}
|
||||
psk_buf = ipcom_malloc((Ip_size_t)psk_buf_len);
|
||||
|
||||
if (psk_buf == IP_NULL)
|
||||
return IPIKE_OUT_OF_MEMORY;
|
||||
|
||||
if (ipcom_key_db_buf_get(psk_id, psk_buf, &psk_buf_len) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipike_payload_authentication_generate_pre_shared()"\
|
||||
" :: failed to get psk_id: %s, from secure key db", psk_id);
|
||||
}
|
||||
shared_key = psk_buf;
|
||||
shared_key_len = (Ip_size_t) psk_buf_len;
|
||||
}
|
||||
else if ( ipike_util_str_is_hex(conf->shared_key) )
|
||||
{
|
||||
|
||||
psk_buf = ipike_util_str_hex2bin(conf->shared_key, &shared_key_len);
|
||||
|
||||
if (psk_buf == IP_NULL)
|
||||
return IPIKE_OUT_OF_MEMORY;
|
||||
|
||||
shared_key = psk_buf;
|
||||
}
|
||||
|
||||
err = ipike_crypto_compute_auth_pre_shared_secret(prf_alg,
|
||||
shared_key,
|
||||
shared_key_len,
|
||||
msg,
|
||||
auth);
|
||||
|
||||
if (IPIKE_SUCCESS != err)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_generate_pre_shared() ::"\
|
||||
" failed to generate eap auth");
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
|
||||
#ifdef IP_DEBUG
|
||||
(void)ipike_print_memory(IPCOM_LOG_DEBUG, "Auth:\n", auth->value, auth->len);
|
||||
#endif
|
||||
|
||||
if (psk_buf != IP_NULL)
|
||||
ipcom_free(psk_buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_verify_pre_shared
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipike_error
|
||||
ipike_payload_authentication_verify_pre_shared(
|
||||
Ip_u16 prf_alg,
|
||||
Ipike_config_auth* conf,
|
||||
Ipike_value* msg,
|
||||
Ipike_value* auth)
|
||||
{
|
||||
Ipike_error err;
|
||||
Ipike_value auth2;
|
||||
|
||||
auth2.value = IP_NULL;
|
||||
err = ipike_payload_authentication_generate_pre_shared(prf_alg,
|
||||
conf,
|
||||
msg,
|
||||
&auth2);
|
||||
|
||||
if (IPIKE_SUCCESS != err)
|
||||
return err;
|
||||
|
||||
if (auth->len != auth2.len ||
|
||||
ipcom_memcmp(auth->value, auth2.value, auth2.len))
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
|
||||
ipcom_free(auth2.value);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_generate_rsa_signature
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipike_error
|
||||
ipike_payload_authentication_generate_rsa_signature(
|
||||
Ipike_config_auth* conf,
|
||||
Ipike_value* msg,
|
||||
Ipike_value* auth)
|
||||
{
|
||||
Ipike_error err;
|
||||
Ipike_value digest;
|
||||
|
||||
digest.value = IP_NULL;
|
||||
err = ipike_payload_authentication_get_digest_info(conf,
|
||||
msg,
|
||||
&digest);
|
||||
if (IPIKE_SUCCESS != err)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_generate_rsa_signature() :: failed to generate digest");
|
||||
}
|
||||
else if (IPIKE_SUCCESS != (err = ipike_crypto_compute_rsa_sign(conf->key_id,
|
||||
conf->private_key,
|
||||
&digest,
|
||||
auth)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_generate_rsa_signature() :: failed to compute signature");
|
||||
}
|
||||
if (IP_NULL != digest.value)
|
||||
ipcom_free(digest.value);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_verify_rsa_signature
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipike_error
|
||||
ipike_payload_authentication_verify_rsa_signature(
|
||||
Ipike_config_auth* conf,
|
||||
Ipike_value* msg,
|
||||
Ipike_cert* cert,
|
||||
Ipike_value* auth)
|
||||
{
|
||||
Ipike_error err;
|
||||
Ipike_value digest;
|
||||
|
||||
digest.value = IP_NULL;
|
||||
digest.len = 0;
|
||||
if (IPIKE_SUCCESS != (err = ipike_crypto_verify_recover_rsa_sign(
|
||||
cert->peer,
|
||||
auth,
|
||||
&digest)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to recover digest from signature");
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
else if (IPIKE_SUCCESS != (err = ipike_crypto_verify_data(msg, &digest)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to verify signature");
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
else if (IPIKE_SUCCESS != (err = ipike_payload_authentication_verify_certificate(
|
||||
conf,
|
||||
cert)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to verify certificate");
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
if (IP_NULL != digest.value)
|
||||
ipcom_free(digest.value);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_generate_dsa_signature
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipike_error
|
||||
ipike_payload_authentication_generate_dsa_signature(
|
||||
Ipike_config_auth* conf,
|
||||
Ipike_value* msg,
|
||||
Ipike_value* auth)
|
||||
{
|
||||
Ipike_error err;
|
||||
Ip_u8 alg;
|
||||
Ipike_value hash;
|
||||
|
||||
alg = IPIKE_ATTR_HASH_SHA1; /* always */
|
||||
hash.value = IP_NULL;
|
||||
|
||||
if (IPIKE_SUCCESS != (err = ipike_crypto_hash(alg, msg, &hash)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_generate_dsa_signature() :: failed generate hash");
|
||||
}
|
||||
else if (IPIKE_SUCCESS != (err = ipike_crypto_compute_dsa_sign(conf->key_id,
|
||||
conf->private_key,
|
||||
&hash,
|
||||
auth)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_generate_dsa_signature() :: failed to compute signature");
|
||||
}
|
||||
if (IP_NULL != hash.value)
|
||||
ipcom_free(hash.value);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_verify_dsa_signature
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipike_error
|
||||
ipike_payload_authentication_verify_dsa_signature(
|
||||
Ipike_config_auth* conf,
|
||||
Ipike_value* msg,
|
||||
Ipike_cert* cert,
|
||||
Ipike_value* auth)
|
||||
{
|
||||
Ipike_error err;
|
||||
Ip_u8 alg;
|
||||
Ipike_value hash;
|
||||
|
||||
hash.value = IP_NULL;
|
||||
alg = IPIKE_ATTR_HASH_SHA1; /* always */
|
||||
|
||||
if (IPIKE_SUCCESS != (err = ipike_crypto_hash(alg, msg, &hash)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_verify_dsa_signature() :: failed generate hash");
|
||||
}
|
||||
else if (IPIKE_SUCCESS != (err = ipike_crypto_verify_dsa_sign(
|
||||
cert->peer,
|
||||
&hash,
|
||||
auth)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to verify signature");
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
else if (IPIKE_SUCCESS != (err = ipike_payload_authentication_verify_certificate(
|
||||
conf,
|
||||
cert)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "Failed to verify certificate");
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
if (IP_NULL != hash.value)
|
||||
ipcom_free(hash.value);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_create
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipike_error
|
||||
ipike_payload_authentication_create(
|
||||
Ipike2_auth* auth,
|
||||
Ipike2_auth_payload** payload)
|
||||
{
|
||||
Ipike2_auth_payload* auth_payload;
|
||||
|
||||
if ((auth->data.value == IP_NULL) || (auth->data.len == 0))
|
||||
{
|
||||
*payload = IP_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IP_NULL == (auth_payload = ipcom_calloc(1, sizeof(Ipike2_auth_payload) + auth->data.len)))
|
||||
{
|
||||
IP_PANIC();
|
||||
return IPIKE_OUT_OF_MEMORY;
|
||||
}
|
||||
auth_payload->header.length = ip_htons((Ip_u16)(sizeof(*auth_payload) + auth->data.len));
|
||||
auth_payload->header.next_payload = IPIKE2_PAYLOAD_AUTHENTICATION;
|
||||
auth_payload->method = auth->method;
|
||||
ipcom_memcpy(ipike_payload_authentication_data(auth_payload), auth->data.value, auth->data.len);
|
||||
*payload = auth_payload;
|
||||
}
|
||||
/* Free auth, so it may not be resued */
|
||||
ipike_payload_authentication_free(auth);
|
||||
|
||||
return IPIKE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_free
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipike_payload_authentication_free(Ipike2_auth* auth)
|
||||
{
|
||||
IPIKE_FREEP(auth->data.value);
|
||||
ipcom_memset(auth, 0, sizeof(*auth));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_check
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipike_error
|
||||
ipike_payload_authentication_check(Ipike2_auth_payload* auth)
|
||||
{
|
||||
switch (auth->method)
|
||||
{
|
||||
case IPIKE2_AUTH_PRE_SHARED_KEY:
|
||||
case IPIKE2_AUTH_DSS_SIGNATURE:
|
||||
case IPIKE2_AUTH_RSA_SIGNATURE:
|
||||
return IPIKE_SUCCESS;
|
||||
}
|
||||
IPCOM_LOG2(ERR,
|
||||
"ipike_payload_authentication_check() :: %s (%d) is a unsupported authentication method",
|
||||
ipike_attribute_auth_method_to_string(auth->method),
|
||||
auth->method);
|
||||
|
||||
return IPIKE_INVALID_VALUE;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_print
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipike_payload_authentication_print(Ipike2_auth_payload* auth)
|
||||
{
|
||||
IPCOM_LOG1(DEBUG2, " method: '%s'",
|
||||
ipike_attribute_auth_method_to_string_v2(auth->method));
|
||||
|
||||
(void)ipike_print_memory(IPCOM_LOG_DEBUG2, " data: \n",
|
||||
ipike_payload_authentication_data(auth),
|
||||
ipike_payload_authentication_data_length(auth));
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_extract
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipike_error
|
||||
ipike_payload_authentication_extract(
|
||||
Ipike2_auth_payload* payload,
|
||||
Ipike2_auth* auth)
|
||||
{
|
||||
auth->method = payload->method;
|
||||
auth->data.len = ipike_payload_authentication_data_length(payload);
|
||||
ipcom_free(auth->data.value);
|
||||
|
||||
if (IP_NULL == (auth->data.value = ipcom_malloc(auth->data.len)))
|
||||
{
|
||||
IP_PANIC();
|
||||
return IPIKE_OUT_OF_MEMORY;
|
||||
}
|
||||
ipcom_memcpy(auth->data.value, ipike_payload_authentication_data(payload), auth->data.len);
|
||||
|
||||
return IPIKE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_generate_message
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ipike_error
|
||||
ipike_payload_authentication_generate_message(
|
||||
Ipike2_id* id,
|
||||
Ipike_value* key,
|
||||
Ipike_value* nonce,
|
||||
Ipike_value* data,
|
||||
Ipike_value* msg,
|
||||
Ip_u16 prf_alg)
|
||||
{
|
||||
Ipike_value tmp;
|
||||
|
||||
#ifdef IP_DEBUG
|
||||
(void)ipike_print_memory(IPCOM_LOG_DEBUG2, "Id:\n", id->data.value, id->data.len);
|
||||
(void)ipike_print_memory(IPCOM_LOG_DEBUG2, "Key:\n", key->value, key->len);
|
||||
(void)ipike_print_memory(IPCOM_LOG_DEBUG2, "Nonce:\n", nonce->value, nonce->len);
|
||||
#endif
|
||||
|
||||
(void)ipike_set_value(msg, data);
|
||||
(void)ipike_append_value(msg, nonce);
|
||||
tmp.len = 4;
|
||||
tmp.value = ipcom_malloc(tmp.len);
|
||||
if (tmp.value ==IP_NULL)
|
||||
return IPIKE_FAILED;
|
||||
ipcom_memset(tmp.value, 0, tmp.len);
|
||||
tmp.value[0] = id->info.id_type;
|
||||
ipcom_memcpy(tmp.value + 1, id->info.reserved, 3);
|
||||
|
||||
(void)ipike_append_value(&tmp, &id->data);
|
||||
(void)ipike_crypto_compute_prf(prf_alg, key, &tmp, IP_NULL, IP_NULL, &tmp);
|
||||
(void)ipike_append_value(msg, &tmp);
|
||||
IPIKE_FREEP(tmp.value);
|
||||
|
||||
(void)ipike_print_memory(IPCOM_LOG_DEBUG2, "Message:\n", msg->value, msg->len);
|
||||
|
||||
return IPIKE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_generate
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipike_error
|
||||
ipike_payload_authentication_generate(
|
||||
Ip_u8 auth_method,
|
||||
Ip_u16 prf_alg,
|
||||
Ipike_config_auth* conf,
|
||||
Ipike2_id* id,
|
||||
Ipike_value* key,
|
||||
Ipike_value* nonce,
|
||||
Ipike_value* msg,
|
||||
Ipike2_auth* auth)
|
||||
{
|
||||
Ipike_error err = IPIKE_SUCCESS;
|
||||
Ipike_value data = {0};
|
||||
|
||||
if (IPIKE_SUCCESS != (err = ipike_payload_authentication_generate_message(
|
||||
id, key, nonce, msg, &data, prf_alg)))
|
||||
return err;
|
||||
msg = &data;
|
||||
|
||||
auth->method = auth_method;
|
||||
ipcom_free(auth->data.value);
|
||||
auth->data.value = IP_NULL;
|
||||
auth->data.len = 0;
|
||||
|
||||
switch (auth->method)
|
||||
{
|
||||
case IPIKE2_AUTH_PRE_SHARED_KEY:
|
||||
err = ipike_payload_authentication_generate_pre_shared(prf_alg,
|
||||
conf,
|
||||
msg,
|
||||
&auth->data);
|
||||
break;
|
||||
case IPIKE2_AUTH_RSA_SIGNATURE:
|
||||
err = ipike_payload_authentication_generate_rsa_signature(
|
||||
conf,
|
||||
msg,
|
||||
&auth->data);
|
||||
break;
|
||||
case IPIKE2_AUTH_DSS_SIGNATURE:
|
||||
err = ipike_payload_authentication_generate_dsa_signature(
|
||||
conf,
|
||||
msg,
|
||||
&auth->data);
|
||||
break;
|
||||
default:
|
||||
IPCOM_LOG1(ERR,
|
||||
"ipike_payload_authentication_generate() :: Unsupported authentication method %d",
|
||||
auth->method);
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
break;
|
||||
}
|
||||
ipcom_free(data.value);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_generate_eap
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipike_error
|
||||
ipike_payload_authentication_generate_eap(
|
||||
Ip_u8* shared_key,
|
||||
Ip_u32 shared_key_len,
|
||||
Ip_u16 prf_alg,
|
||||
Ipike2_id* id,
|
||||
Ipike_value* key,
|
||||
Ipike_value* nonce,
|
||||
Ipike_value* msg,
|
||||
Ipike2_auth* auth)
|
||||
{
|
||||
Ipike_error err = IPIKE_SUCCESS;
|
||||
Ipike_value data;
|
||||
|
||||
if (shared_key == IP_NULL || shared_key_len == 0)
|
||||
{
|
||||
shared_key = key->value;
|
||||
shared_key_len = (Ip_u32) key->len;
|
||||
}
|
||||
|
||||
err = ipike_payload_authentication_generate_message(id, key, nonce,
|
||||
msg, &data, prf_alg);
|
||||
if (IPIKE_SUCCESS != err)
|
||||
return err;
|
||||
|
||||
msg = &data;
|
||||
|
||||
auth->method = IPIKE2_AUTH_PRE_SHARED_KEY;
|
||||
ipcom_free(auth->data.value);
|
||||
auth->data.value = IP_NULL;
|
||||
auth->data.len = 0;
|
||||
|
||||
|
||||
err = ipike_crypto_compute_auth_pre_shared_secret(prf_alg,
|
||||
shared_key,
|
||||
shared_key_len,
|
||||
msg,
|
||||
&auth->data);
|
||||
|
||||
if (IPIKE_SUCCESS != err)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_generate_eap() ::"\
|
||||
" failed to generate eap auth");
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
|
||||
IPIKE_FREEP(data.value);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_accept_authentication_method
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ip_bool
|
||||
ipike_payload_accept_authentication_method(
|
||||
const char* str_methods,
|
||||
Ip_u8 method)
|
||||
{
|
||||
char* str = IP_NULL;
|
||||
Ip_u8 n = 0xff;
|
||||
|
||||
while ((n != method) &&
|
||||
(str_methods[0] != 0) &&
|
||||
(ipike_parse_get_string(&str_methods, ',', &str) == IPIKE_SUCCESS))
|
||||
{
|
||||
if (IPIKE_SUCCESS != ipike_attribute_auth_method_from_string_v2(str, &n))
|
||||
n = 0xff;
|
||||
ipcom_free(str);
|
||||
}
|
||||
|
||||
return (n == method);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_verify
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipike_error
|
||||
ipike_payload_authentication_verify(
|
||||
Ip_u16 prf_alg,
|
||||
Ipike_config_auth* conf,
|
||||
Ipike2_id* id,
|
||||
Ipike_value* key,
|
||||
Ipike_value* nonce,
|
||||
Ipike_value* msg,
|
||||
Ipike_cert* cert,
|
||||
Ipike2_auth* auth)
|
||||
{
|
||||
Ipike_error err = IPIKE_SUCCESS;
|
||||
Ipike_value data;
|
||||
|
||||
if (!ipike_payload_accept_authentication_method(conf->method, auth->method))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_verify() :: Authentication method not accepted");
|
||||
return IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
if (IPIKE_SUCCESS != (err = ipike_payload_authentication_generate_message(
|
||||
id, key, nonce, msg, &data, prf_alg)))
|
||||
return err;
|
||||
msg = &data;
|
||||
|
||||
switch (auth->method)
|
||||
{
|
||||
case IPIKE2_AUTH_PRE_SHARED_KEY:
|
||||
err = ipike_payload_authentication_verify_pre_shared(prf_alg, conf, msg, &auth->data);
|
||||
break;
|
||||
case IPIKE2_AUTH_RSA_SIGNATURE:
|
||||
err = ipike_payload_authentication_verify_rsa_signature(conf, msg, cert, &auth->data);
|
||||
break;
|
||||
case IPIKE2_AUTH_DSS_SIGNATURE:
|
||||
err = ipike_payload_authentication_verify_dsa_signature(conf, msg, cert, &auth->data);
|
||||
break;
|
||||
default:
|
||||
IPCOM_LOG1(ERR,
|
||||
"ipike_payload_authentication_verify() :: Unsupported authentication method %d",
|
||||
auth->method);
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
break;
|
||||
}
|
||||
IPIKE_FREEP(data.value);
|
||||
/* Free auth, so it may not be resued */
|
||||
ipike_payload_authentication_free(auth);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipike_payload_authentication_verify_eap
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_GLOBAL Ipike_error
|
||||
ipike_payload_authentication_verify_eap(
|
||||
Ip_u8* shared_key,
|
||||
Ip_u32 shared_key_len,
|
||||
Ip_u16 prf_alg,
|
||||
Ipike2_id* id,
|
||||
Ipike_value* key,
|
||||
Ipike_value* nonce,
|
||||
Ipike_value* msg,
|
||||
Ipike2_auth* auth)
|
||||
{
|
||||
Ipike_error err = IPIKE_SUCCESS;
|
||||
Ipike2_auth auth2 = {0};
|
||||
|
||||
err = ipike_payload_authentication_generate_eap(shared_key,
|
||||
shared_key_len,
|
||||
prf_alg,
|
||||
id,
|
||||
key,
|
||||
nonce,
|
||||
msg,
|
||||
&auth2);
|
||||
if (err != IPIKE_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_verify() :: Failed to generate AUTH payload");
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((auth->method != auth2.method) ||
|
||||
(auth->data.len != auth2.data.len) ||
|
||||
(memcmp(auth->data.value, auth2.data.value, auth->data.len) != 0))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipike_payload_authentication_verify() :: Failed to verify AUTH payload");
|
||||
err = IPIKE_ISAKMP_AUTHENTICATION_FAILED;
|
||||
}
|
||||
ipike_payload_authentication_free(&auth2);
|
||||
}
|
||||
/* Free auth, so it may not be resued */
|
||||
ipike_payload_authentication_free(auth);
|
||||
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
|
||||
int ipike_payload_authentication_empty_file = 0;
|
||||
|
||||
#endif /* IPIKE_USE_VERSION2 */
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
Reference in New Issue
Block a user