864 lines
28 KiB
C
864 lines
28 KiB
C
/*
|
|
******************************************************************************
|
|
* 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
|
|
****************************************************************************
|
|
*/
|