1239 lines
43 KiB
C
1239 lines
43 KiB
C
/*
|
|
******************************************************************************
|
|
* SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipike_exchange_aggressive_mode.c,v $ $Revision: 1.21.10.11 $
|
|
* $Source: /home/interpeak/CVSRoot/ipike/src/ipike_exchange_aggressive_mode.c,v $
|
|
* $Author: zan $ $Date: 2013-08-01 02:00:39 $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
#include "ipike_config.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPIKE_USE_AGGRESSIVE_MODE
|
|
|
|
#include "ipike_h.h"
|
|
#include "ipike_exchange_aggressive_mode.h"
|
|
#include "ipike_exchange_main_mode.h"
|
|
#include "ipike_exchange_informational.h"
|
|
#include "ipike_crypto.h"
|
|
#include "ipike_payload.h"
|
|
#include "ipike_attributes.h"
|
|
#include "ipike_payload_sa.h"
|
|
#include "ipike_payload_certificate.h"
|
|
#include "ipike_payload_key_exchange.h"
|
|
#include "ipike_payload_nonce.h"
|
|
#include "ipike_payload_identification.h"
|
|
#include "ipike_payload_notification.h"
|
|
#include "ipike_payload_hash.h"
|
|
#include "ipike_payload_sign.h"
|
|
#include "ipike_payload_transform.h"
|
|
#include "ipike_payload_vendor_id.h"
|
|
#include "ipike_payload_nat.h"
|
|
#include "ipike_util.h"
|
|
#include "ipike_sadb.h"
|
|
#include "ipike_ipsec.h"
|
|
#include "ipike_configuration.h"
|
|
#include "ipike_policy.h"
|
|
|
|
#include <openssl/x509.h>
|
|
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_sock2.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_sock2.h>
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 LOCAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_authentication_add
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_aggressive_mode_authentication_add(Ipike_isakmp_exchange* ie)
|
|
{
|
|
Ipike_error err;
|
|
Ip_u16 auth_meth;
|
|
Ip_u16 hash_alg;
|
|
Ipike_value* hash;
|
|
Ipike_value* sign;
|
|
Ipike_transform_ike *transform_ike;
|
|
transform_ike=ipike_transform_ike_from_exch(ie);
|
|
if (transform_ike==IP_NULL)
|
|
return IPIKE_FAILED;
|
|
auth_meth = transform_ike->authentication_method;
|
|
if (auth_meth == IPIKE_ATTR_AUTH_DSS_SIGNATURES)
|
|
hash_alg = IPIKE_ATTR_HASH_SHA1;
|
|
else
|
|
hash_alg = ipike_transform_ike_from_exch(ie)->hash_algorithm;
|
|
|
|
if (ie->ike_sa->is_initiator)
|
|
{
|
|
hash = &ie->ike_sa->hash_i;
|
|
sign = &ie->ike_sa->sign_i;
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_hash_i(hash_alg, ie->ike_sa, hash)))
|
|
return err;
|
|
}
|
|
else
|
|
{
|
|
hash = &ie->ike_sa->hash_r;
|
|
sign = &ie->ike_sa->sign_r;
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_hash_r(hash_alg, ie->ike_sa, hash)))
|
|
return err;
|
|
}
|
|
|
|
if (auth_meth == IPIKE_ATTR_AUTH_DSS_SIGNATURES)
|
|
err = ipike_crypto_compute_dsa_sign(ie->ike_conf->authentication.key_id,
|
|
ie->ike_conf->authentication.private_key,
|
|
hash,
|
|
sign);
|
|
else if (auth_meth == IPIKE_ATTR_AUTH_RSA_SIGNATURES)
|
|
err = ipike_crypto_compute_rsa_sign(ie->ike_conf->authentication.key_id,
|
|
ie->ike_conf->authentication.private_key,
|
|
hash,
|
|
sign);
|
|
if (IPIKE_SUCCESS == err)
|
|
return err;
|
|
|
|
return err;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_authentication_check
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_aggressive_mode_authentication_check(Ipike_isakmp_exchange* ie)
|
|
{
|
|
return ipike_main_mode_authentication_check(ie);
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_cert_update_responder_config
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC void
|
|
ipike_aggressive_mode_update_responder_config(Ipike_isakmp_exchange *ie)
|
|
{
|
|
ipike_main_mode_update_responder_config(ie);
|
|
}
|
|
|
|
|
|
|
|
/* This IKE daemon is responder */
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_update_after_msg_1
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_aggressive_mode_update_after_msg_1(Ipike_isakmp_exchange* ie)
|
|
{
|
|
Ipike_error err;
|
|
Ipike_transform_ike* transform;
|
|
|
|
/* Check if there is a more suitable IKE SA config */
|
|
ipike_aggressive_mode_update_responder_config(ie);
|
|
|
|
err = ipike_policy_select_ike_sa_param(ie->ike_conf,
|
|
&ie->ike_sa->sa,
|
|
&ie->ike_sa->selected,
|
|
IP_FALSE);
|
|
|
|
if (IPIKE_SUCCESS != err)
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_1() :: "\
|
|
"select SA failed");
|
|
IPIKE_EVENT_LOG(IKE_PHASE_I_FAIL, PROPOSAL_MISMATCH,
|
|
&ie->ike_sa->peer_addr, &ie->ike_sa->local_addr,
|
|
0, IP_NULL);
|
|
/* Log and return */
|
|
return err;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_payload_nonce_generate(&ie->ike_sa->nr)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_before_msg_1() :: "\
|
|
"nonce generation failed");
|
|
goto errout;
|
|
}
|
|
transform = ipike_transform_ike_from_exch(ie);
|
|
if (transform==IP_NULL)
|
|
{
|
|
err=IPIKE_FAILED;
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_generate_dh_key(
|
|
transform->dh_prime,
|
|
transform->dh_generator,
|
|
&ie->dh,
|
|
&ie->ike_sa->g_xr)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_before_msg_1() ::"\
|
|
" DH key generation failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_dh_key(
|
|
ie->dh,
|
|
&ie->ike_sa->g_xi,
|
|
&ie->ike_sa->g_xy)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_1() :: "\
|
|
"compute DH key failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_skeyid(
|
|
ie->ike_conf,
|
|
ie->ike_sa)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_1() :: "\
|
|
" compute skeyid failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_phase1_secret_key(ie)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_1() :: "\
|
|
" compute phase1 failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_initial_phase1_iv(
|
|
ie->ike_sa,
|
|
&ie->iv)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_1() :: "\
|
|
"compute initial iv failed");
|
|
goto errout;
|
|
}
|
|
if ((IP_NULL == ie->ike_conf->local_id) ||
|
|
(IPIKE_SUCCESS != ipike_identification_generate(ie->ike_conf->local_id, &ie->ike_sa->idir)))
|
|
{
|
|
if (IPIKE_SUCCESS != (err = ipike_ipsec_set_idix(&ie->ike_sa->local_addr, &ie->ike_sa->idir)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_before_msg_1() :: "\
|
|
"id initialize failed");
|
|
goto errout;
|
|
}
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_aggressive_mode_authentication_add(ie)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_before_msg_1() :: "\
|
|
"add authentication failed");
|
|
goto errout;
|
|
}
|
|
|
|
return IPIKE_SUCCESS;
|
|
|
|
errout:
|
|
|
|
/* Log general IKE error */
|
|
IPIKE_EVENT_LOG(IKE_PHASE_I_FAIL, IKE_INTERNAL_ERROR,
|
|
&ie->ike_sa->peer_addr, &ie->ike_sa->local_addr,
|
|
0, IP_NULL);
|
|
|
|
return err;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_update_after_msg_3
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_aggressive_mode_update_after_msg_3(Ipike_isakmp_exchange* ie)
|
|
{
|
|
Ipike_error err;
|
|
|
|
if (IPIKE_SUCCESS != (err = ipike_aggressive_mode_authentication_check(ie)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_3() :: "\
|
|
"authentication check failed");
|
|
IPIKE_EVENT_LOG(IKE_PHASE_I_FAIL, AUTHENTICATION_ERROR,
|
|
&ie->ike_sa->peer_addr, &ie->ike_sa->local_addr,
|
|
0, IP_NULL);
|
|
return err;
|
|
}
|
|
/* Everything should be encrypted from now on */
|
|
ie->isakmp_flags = IPIKE_ISAKMP_ENCRYPTION;
|
|
|
|
return IPIKE_SUCCESS;
|
|
}
|
|
|
|
/* This IKE daemon is initiator */
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_update_before_msg_1
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_aggressive_mode_update_before_msg_1(Ipike_isakmp_exchange* ie)
|
|
{
|
|
Ipike_error err;
|
|
Ipike_transform_ike* transform;
|
|
|
|
/* Try to use id from configuration, use ip-address if fails */
|
|
if ((IP_NULL == ie->ike_conf->local_id) ||
|
|
(IPIKE_SUCCESS != ipike_identification_generate(ie->ike_conf->local_id, &ie->ike_sa->idii)))
|
|
{
|
|
if (IPIKE_SUCCESS != (err = ipike_ipsec_set_idix(&ie->ike_sa->local_addr, &ie->ike_sa->idii)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_before_msg_1() ::"\
|
|
"id initialize failed");
|
|
goto errout;
|
|
}
|
|
}
|
|
/* Initialize SA */
|
|
if (IPIKE_SUCCESS != (err = ipike_sa_ike_initialize(ie->ike_conf, &ie->ike_sa->sa)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_before_msg_1() :: "\
|
|
"SA initialize failed");
|
|
goto errout;
|
|
}
|
|
/* Initialize KE */
|
|
transform = &ie->ike_sa->sa.proposals[0]->transforms[0]->ike;
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_generate_dh_key(
|
|
transform->dh_prime,
|
|
transform->dh_generator,
|
|
&ie->dh,
|
|
&ie->ike_sa->g_xi)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_before_msg_1() :: "\
|
|
"DH key generation failed");
|
|
goto errout;
|
|
}
|
|
/* Initialize NONCE */
|
|
if (IPIKE_SUCCESS != (err = ipike_payload_nonce_generate(&ie->ike_sa->ni)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_before_msg_1() :: "\
|
|
"nonce generation failed");
|
|
goto errout;
|
|
}
|
|
|
|
return IPIKE_SUCCESS;
|
|
|
|
errout:
|
|
|
|
/* Log general IKE error */
|
|
IPIKE_EVENT_LOG(IKE_PHASE_I_FAIL, IKE_INTERNAL_ERROR,
|
|
&ie->ike_sa->peer_addr, &ie->ike_sa->local_addr,
|
|
0, IP_NULL);
|
|
|
|
return err;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_update_after_msg_2
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_aggressive_mode_update_after_msg_2(Ipike_isakmp_exchange* ie)
|
|
{
|
|
Ipike_sadb_entry* ike_sa = ie->ike_sa;
|
|
Ipike_error err;
|
|
|
|
err = ipike_policy_select_ike_sa_param(ie->ike_conf,
|
|
&ike_sa->sa,
|
|
&ike_sa->selected,
|
|
IP_TRUE);
|
|
|
|
if (IPIKE_SUCCESS != err)
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_2() :: "\
|
|
"select SA failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_dh_key(
|
|
ie->dh,
|
|
&ike_sa->g_xr,
|
|
&ike_sa->g_xy)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_2() :: "\
|
|
"compute DH key failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_skeyid(
|
|
ie->ike_conf,
|
|
ike_sa)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_2() :: "\
|
|
"compute skeyid failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_phase1_secret_key(ie)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_2() :: "\
|
|
"compute phase1 failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_compute_initial_phase1_iv(
|
|
ike_sa,
|
|
&ie->iv)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_2() :: "\
|
|
"compute initial iv failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_aggressive_mode_authentication_check(ie)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_after_msg_2() :: "\
|
|
"authentication check failed");
|
|
goto errout;
|
|
}
|
|
if (IPIKE_SUCCESS != (err = ipike_aggressive_mode_authentication_add(ie)))
|
|
{
|
|
IPCOM_LOG0(DEBUG, "ipike_aggressive_mode_update_before_msg_1() :: "\
|
|
"add authentication failed");
|
|
goto errout;
|
|
}
|
|
/* Everything should be encrypted from now on */
|
|
ie->isakmp_flags = IPIKE_ISAKMP_ENCRYPTION;
|
|
|
|
return IPIKE_SUCCESS;
|
|
|
|
errout:
|
|
|
|
/* Log general IKE error */
|
|
IPIKE_EVENT_LOG(IKE_PHASE_I_FAIL, IKE_INTERNAL_ERROR,
|
|
&ie->ike_sa->peer_addr, &ie->ike_sa->local_addr,
|
|
0, IP_NULL);
|
|
|
|
return err;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_update_state
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_aggressive_mode_update_state(Ipike_isakmp_exchange* ie)
|
|
{
|
|
switch (ie->message_number)
|
|
{
|
|
/* We are responder */
|
|
case 1: return ipike_aggressive_mode_update_after_msg_1(ie);
|
|
case 3: return ipike_aggressive_mode_update_after_msg_3(ie);
|
|
|
|
/* We are initiator */
|
|
case 0: return ipike_aggressive_mode_update_before_msg_1(ie);
|
|
case 2: return ipike_aggressive_mode_update_after_msg_2(ie);
|
|
|
|
}
|
|
IPCOM_LOG1(ERR,
|
|
"IKE aggressive mode has 3 messages, this was %d",
|
|
ie->message_number);
|
|
|
|
IPIKE_EVENT_LOG(IKE_PACKET_DISCARD, ISAKMP_PACKET_ERROR,
|
|
&ie->ike_sa->peer_addr, &ie->ike_sa->local_addr,
|
|
0, IP_NULL);
|
|
|
|
return IPIKE_INVALID_MESSAGE_NUMBER;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_store_sai_b
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_aggressive_mode_store_sai_b(Ipike_value* sai_b, Ipike_sa_payload* payload)
|
|
{
|
|
sai_b->len = ip_ntohs(payload->header.length) - IPIKE_PAYLOAD_HEADER_LENGTH;
|
|
if (IP_NULL == (sai_b->value = ipcom_malloc(sai_b->len)))
|
|
{
|
|
IP_PANIC();
|
|
return IPIKE_OUT_OF_MEMORY;
|
|
}
|
|
ipcom_memcpy(sai_b->value, (Ip_u8 *) payload + IPIKE_PAYLOAD_HEADER_LENGTH, sai_b->len);
|
|
|
|
return IPIKE_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_cert_create
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_aggressive_mode_cert_create(
|
|
Ipike_config_ike_sa* conf,
|
|
Ipike_cert_payload** payload)
|
|
{
|
|
Ipike_error err;
|
|
Ipike_cert cert;
|
|
|
|
cert.peer = ipike_crypto_read_cert(conf->authentication.certificate);
|
|
err = ipike_payload_certificate_create(cert.peer, IP_NULL, payload);
|
|
X509_free(cert.peer);
|
|
return err;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_on_new_exchange_initiator
|
|
*===========================================================================
|
|
*/
|
|
IP_PUBLIC Ipike_error
|
|
ipike_aggressive_mode_on_new_exchange_initiator(
|
|
Ipike_isakmp_exchange* ie,
|
|
Ipike_sadb_entry* ike_sa,
|
|
const void* option1,
|
|
const void* trigger_flow)
|
|
{
|
|
Ipike_error err;
|
|
Ip_u8 initiator_cookie[IPIKE_ISAKMP_COOKIE_SIZE];
|
|
Ip_u8 responder_cookie[IPIKE_ISAKMP_COOKIE_SIZE];
|
|
union Ip_sockaddr_union peer_addr;
|
|
union Ip_sockaddr_union local_addr;
|
|
Ipike_config_flow *flow = IP_NULL;
|
|
|
|
/* IKE v1 */
|
|
ie->version = 1 << 4;
|
|
|
|
/* Store option1, only establish IKE SA if set */
|
|
ie->option1 = option1;
|
|
|
|
if (trigger_flow != IP_NULL)
|
|
{
|
|
/* Make a copy of the flow information, we will need to pass this
|
|
* further to the IPsec SA establishment */
|
|
|
|
flow = ipike_config_flow_duplicate(trigger_flow);
|
|
|
|
if ( flow == IP_NULL )
|
|
{
|
|
IP_PANIC();
|
|
return IPIKE_OUT_OF_MEMORY;
|
|
}
|
|
|
|
/* Store the flow in the place holder for option2*/
|
|
ie->option2 = flow;
|
|
}
|
|
|
|
ipcom_microtime(&ie->start);
|
|
ipcom_memset(responder_cookie, 0, IPIKE_ISAKMP_COOKIE_SIZE);
|
|
|
|
err = ipike_crypto_generate_cookie(initiator_cookie);
|
|
|
|
if (IPIKE_SUCCESS != err)
|
|
return err;
|
|
|
|
/* Do we have an IKE SA, i.e. this is a reauthentication */
|
|
if (ike_sa != IP_NULL)
|
|
{
|
|
/* Use the same addresses and ports as the old IKE SA */
|
|
err = ipike_addr_copy(&local_addr, &ike_sa->local_addr);
|
|
|
|
if (IPIKE_SUCCESS != err)
|
|
return err;
|
|
|
|
err = ipike_addr_copy(&peer_addr, &ike_sa->peer_addr);
|
|
|
|
if (IPIKE_SUCCESS != err)
|
|
return err;
|
|
}
|
|
else
|
|
{
|
|
/* Use local address from configuration */
|
|
err = ipike_addr_copy(&local_addr, &ie->ike_conf->local_address);
|
|
|
|
if (IPIKE_SUCCESS != err)
|
|
return err;
|
|
|
|
/* Check if we have a valid host address in the configuration */
|
|
if ( ipike_config_netobj_is_host(&ie->ike_conf->remote_address) )
|
|
{
|
|
/* Use remote address from configuration */
|
|
err = ipike_addr_copy(&peer_addr,
|
|
&ie->ike_conf->remote_address.addr);
|
|
|
|
if (IPIKE_SUCCESS != err)
|
|
return err;
|
|
}
|
|
/* Was this negotiation triggered by a flow */
|
|
else if (flow != IP_NULL)
|
|
{
|
|
/* Use remote address from the trigger flow */
|
|
err = ipike_addr_copy(&peer_addr, &flow->dst[0]->addr);
|
|
|
|
if (IPIKE_SUCCESS != err)
|
|
return err;
|
|
}
|
|
else
|
|
{
|
|
/* No idea of the remote address */
|
|
return IPIKE_CONF_INVALID_VALUE;
|
|
}
|
|
|
|
/* Reset destination port to default IKE port (500) */
|
|
ipike_addr_set_port(&peer_addr, ipike.port);
|
|
}
|
|
|
|
if (ipike_addr_is_any(&local_addr))
|
|
{
|
|
/* Try to figure out our local address based on the peer address */
|
|
err = ipike_dispatcher_socket_local_addr_get(&local_addr,
|
|
&peer_addr);
|
|
if (err != IPIKE_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(NOTICE,
|
|
"ipike_aggressive_mode_on_new_exchange_initiator() ::"\
|
|
" failed to get local address");
|
|
/* Ignore error, the stack will find out the address
|
|
* eventually, however NAT-T will fail because of
|
|
* mismatching hashes */
|
|
}
|
|
}
|
|
|
|
err = ipike_sadb_add(initiator_cookie,
|
|
responder_cookie,
|
|
&local_addr,
|
|
&peer_addr,
|
|
&ie->ike_sa);
|
|
|
|
if (err != IPIKE_SUCCESS)
|
|
return err;
|
|
|
|
ie->is_phase1 = IP_TRUE;
|
|
ie->exchange_initiator = IP_TRUE;
|
|
|
|
ie->ike_sa->is_initiator = IP_TRUE;
|
|
ie->ike_sa->id = ipcom_strdup(ie->ike_conf->ike_id);
|
|
ie->ike_sa->version = ie->version;
|
|
ie->ike_sa->has_got_natt_capability = IP_FALSE;
|
|
|
|
return ipike_aggressive_mode_update_state(ie);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_on_new_exchange_responder
|
|
*===========================================================================
|
|
*/
|
|
IP_PUBLIC Ipike_error
|
|
ipike_aggressive_mode_on_new_exchange_responder(
|
|
Ipike_isakmp_exchange* ie,
|
|
Ipike_isakmp_header* first_isakmp,
|
|
union Ip_sockaddr_union* local_addr,
|
|
union Ip_sockaddr_union* peer_addr)
|
|
{
|
|
Ipike_error err;
|
|
Ip_u8 responder_cookie[IPIKE_ISAKMP_COOKIE_SIZE];
|
|
Ip_u8 retry;
|
|
|
|
ipcom_microtime(&ie->start);
|
|
|
|
/* IKE version 1 */
|
|
ie->version = 1 << 4;
|
|
|
|
if (first_isakmp->message_id != 0)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipike_aggressive_mode_on_new_exchange_responder: message id must be zero in this exchange");
|
|
err = IPIKE_ISAKMP_INVALID_MESSAGE_ID;
|
|
}
|
|
else
|
|
{
|
|
retry = 0;
|
|
do {
|
|
if (retry++ > 100)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipike_aggressive_mode_on_new_exchange_responder: too many retries");
|
|
return IPIKE_FAILED;
|
|
}
|
|
/* Generate responder cookie until the initiator/responder
|
|
* cookie pair is unique */
|
|
if (IPIKE_SUCCESS != (err = ipike_crypto_generate_cookie(responder_cookie)))
|
|
return err;
|
|
} while (ipike_sadb_exist(first_isakmp->initiator_cookie, responder_cookie));
|
|
|
|
if (IPIKE_SUCCESS != (err = ipike_sadb_add(first_isakmp->initiator_cookie,
|
|
responder_cookie,
|
|
local_addr,
|
|
peer_addr,
|
|
&ie->ike_sa)))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipike_aggressive_mode_on_new_exchange_responder: failed to add sa");
|
|
}
|
|
else
|
|
{
|
|
ie->is_phase1 = IP_TRUE;
|
|
ie->ike_sa->is_initiator = IP_FALSE;
|
|
ie->ike_sa->id = ipcom_strdup(ie->ike_conf->ike_id);
|
|
ie->ike_sa->version = ie->version;
|
|
ie->ike_sa->has_got_natt_capability=IP_FALSE;
|
|
}
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_on_delete_exchange
|
|
*===========================================================================
|
|
*/
|
|
IP_PUBLIC void
|
|
ipike_aggressive_mode_on_delete_exchange(Ipike_isakmp_exchange* ie)
|
|
{
|
|
if (ie->ike_sa == IP_NULL)
|
|
return;
|
|
|
|
if (ie->message_number < ipike_isakmp_exchange_message_count(ie))
|
|
{
|
|
IPCOM_LOG0(WARNING,
|
|
"ipike_aggressive_mode_on_delete_exchange: the exchange was not finished,"
|
|
" removing (incomplete) IKE SA");
|
|
(void)ipike_sadb_set_state(ie, ie->ike_sa, IPIKE_SA_DYING);
|
|
}
|
|
|
|
if (ie->option2)
|
|
ipike_config_flow_destroy((Ipike_config_flow *)ie->option2);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_get_payload_order
|
|
*===========================================================================
|
|
*/
|
|
IP_PUBLIC const Ip_u16 *
|
|
ipike_aggressive_mode_get_payload_order(Ipike_isakmp_exchange* ie)
|
|
{
|
|
static Ip_u16 aggressive_mode_exchange[] =
|
|
{
|
|
/* message # 1 */
|
|
IPIKE_PAYLOAD_SECURITY_ASSOCIATION,
|
|
IPIKE_PAYLOAD_KEY_EXCHANGE,
|
|
IPIKE_PAYLOAD_NONCE,
|
|
IPIKE_PAYLOAD_IDENTFICATION,
|
|
IPIKE_PAYLOAD_CERTIFICATE_REQUEST | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_VENDOR_ID | IPIKE_PAYLOAD_OPT | IPIKE_PAYLOAD_ADD,
|
|
IPIKE_PAYLOAD_NONE,
|
|
|
|
/* message # 2 */
|
|
IPIKE_PAYLOAD_SECURITY_ASSOCIATION,
|
|
IPIKE_PAYLOAD_KEY_EXCHANGE,
|
|
IPIKE_PAYLOAD_NONCE,
|
|
IPIKE_PAYLOAD_IDENTFICATION,
|
|
IPIKE_PAYLOAD_HASH | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_CERTIFICATE_REQUEST | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_CERTIFICATE | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_SIGNATURE | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_VENDOR_ID | IPIKE_PAYLOAD_OPT | IPIKE_PAYLOAD_ADD,
|
|
IPIKE_PAYLOAD_NAT_DISCOVERY | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_NONE,
|
|
|
|
/* message # 3 */
|
|
IPIKE_PAYLOAD_HASH | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_CERTIFICATE_REQUEST | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_CERTIFICATE | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_SIGNATURE | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_NAT_DISCOVERY | IPIKE_PAYLOAD_OPT,
|
|
IPIKE_PAYLOAD_NONE,
|
|
};
|
|
int i = 1;
|
|
Ip_u16 n = 0;
|
|
Ip_u16* ret = aggressive_mode_exchange;
|
|
Ip_u16 auth_method = 0;
|
|
|
|
|
|
while (i != ie->message_number)
|
|
if (*ret++ == IPIKE_PAYLOAD_NONE)
|
|
i++;
|
|
|
|
/* Some optional must be added depending on authentication mechanism */
|
|
ipike_attribute_auth_method_from_string(ie->ike_conf->authentication.method,
|
|
&auth_method);
|
|
|
|
i = 0;
|
|
while (ret[i] != IPIKE_PAYLOAD_NONE)
|
|
{
|
|
n = (Ip_u16)(ret[i] & 0x3FFF);
|
|
|
|
|
|
if ( auth_method == IPIKE_ATTR_AUTH_PRE_SHARED_KEY )
|
|
{
|
|
switch (n)
|
|
{
|
|
case IPIKE_PAYLOAD_HASH:
|
|
ret[i] |= IPIKE_PAYLOAD_ADD;
|
|
break;
|
|
case IPIKE_PAYLOAD_CERTIFICATE:
|
|
case IPIKE_PAYLOAD_CERTIFICATE_REQUEST:
|
|
case IPIKE_PAYLOAD_SIGNATURE:
|
|
ret[i] = (Ip_u16)(ret[i] & ~IPIKE_PAYLOAD_ADD);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (n)
|
|
{
|
|
case IPIKE_PAYLOAD_HASH:
|
|
ret[i] = (Ip_u16)(ret[i] & ~IPIKE_PAYLOAD_ADD);
|
|
break;
|
|
case IPIKE_PAYLOAD_CERTIFICATE:
|
|
if ( ipike_isakmp_should_send_certificate(ie) )
|
|
ret[i] |= IPIKE_PAYLOAD_ADD;
|
|
else
|
|
ret[i] = (Ip_u16)(ret[i] & ~IPIKE_PAYLOAD_ADD);
|
|
break;
|
|
case IPIKE_PAYLOAD_CERTIFICATE_REQUEST:
|
|
if ( ipike_isakmp_should_send_certificate_req(ie) )
|
|
ret[i] |= IPIKE_PAYLOAD_ADD;
|
|
else
|
|
ret[i] = (Ip_u16)(ret[i] & ~IPIKE_PAYLOAD_ADD);
|
|
break;
|
|
case IPIKE_PAYLOAD_SIGNATURE:
|
|
ret[i] |= IPIKE_PAYLOAD_ADD;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
|
|
/* Some optional must be added depending on NAT Traversal */
|
|
i = 0;
|
|
while (ret[i] != IPIKE_PAYLOAD_NONE)
|
|
{
|
|
n = (Ip_u16)(ret[i] & 0x3FFF);
|
|
if (n == IPIKE_PAYLOAD_NAT_DISCOVERY)
|
|
{
|
|
if (ipike.port_nat != 0 && ie->ike_sa->has_got_natt_capability)
|
|
ret[i] |= IPIKE_PAYLOAD_ADD;
|
|
else
|
|
ret[i] = (Ip_u16)(ret[i] & ~IPIKE_PAYLOAD_ADD);
|
|
}
|
|
i++;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_process_payloads
|
|
*===========================================================================
|
|
*/
|
|
IP_PUBLIC Ipike_error
|
|
ipike_aggressive_mode_process_payloads(
|
|
Ipike_isakmp_exchange *ie,
|
|
Ipike_isakmp_header *isakmp)
|
|
{
|
|
Ipike_payload_header *payload;
|
|
Ip_u8 this_payload;
|
|
Ipike_error err;
|
|
Ipike_payload_enum ctx;
|
|
|
|
/* Process payloads */
|
|
this_payload = isakmp->next_payload;
|
|
payload = ipike_first_payload(isakmp, &ctx);
|
|
err = IPIKE_SUCCESS;
|
|
|
|
while (payload != IP_NULL)
|
|
{
|
|
switch (this_payload)
|
|
{
|
|
case IPIKE_PAYLOAD_SECURITY_ASSOCIATION:
|
|
/* RFC2409 Section 5,
|
|
* The SA payload MUST precede all other payloads in a
|
|
* phase 1 exchange. */
|
|
if (IPIKE_PAYLOAD_SECURITY_ASSOCIATION != isakmp->next_payload)
|
|
return IPIKE_WRONG_PAYLOAD;
|
|
|
|
if (ie->ike_sa->is_initiator)
|
|
/* Free the SA that was sent to the responder */
|
|
ipike_sa_free(&ie->ike_sa->sa, IP_NULL);
|
|
else
|
|
{
|
|
err = ipike_aggressive_mode_store_sai_b(
|
|
&ie->ike_sa->sai_b,
|
|
(Ipike_sa_payload*) payload);
|
|
|
|
/* Store the binary encoding of the SA from the initiator */
|
|
if (IPIKE_SUCCESS != err)
|
|
break;
|
|
}
|
|
err = ipike_sa_extract(ie,
|
|
(Ipike_sa_payload*) payload,
|
|
&ie->ike_sa->sa);
|
|
break;
|
|
case IPIKE_PAYLOAD_KEY_EXCHANGE:
|
|
err = ipike_key_exchange_extract((Ipike_ke_payload*) payload,
|
|
ie->ike_sa->is_initiator ?
|
|
&ie->ike_sa->g_xr :
|
|
&ie->ike_sa->g_xi);
|
|
break;
|
|
case IPIKE_PAYLOAD_NONCE:
|
|
err = ipike_payload_nonce_extract((Ipike_nonce_payload*) payload,
|
|
ie->ike_sa->is_initiator ?
|
|
&ie->ike_sa->nr :
|
|
&ie->ike_sa->ni);
|
|
break;
|
|
case IPIKE_PAYLOAD_IDENTFICATION:
|
|
err = ipike_identification_ike_extract((Ipike_id_payload*) payload,
|
|
ie->ike_sa->sa.doi,
|
|
ie->ike_sa->is_initiator ?
|
|
&ie->ike_sa->idir :
|
|
&ie->ike_sa->idii);
|
|
break;
|
|
case IPIKE_PAYLOAD_HASH:
|
|
err = ipike_hash_extract((Ipike_hash_payload*) payload,
|
|
ie->ike_sa->is_initiator ?
|
|
&ie->ike_sa->hash_r :
|
|
&ie->ike_sa->hash_i);
|
|
break;
|
|
case IPIKE_PAYLOAD_NOTIFICATION:
|
|
err = ipike_notification_process_message(
|
|
ie,
|
|
(Ipike_notification_payload*) payload);
|
|
break;
|
|
case IPIKE_PAYLOAD_CERTIFICATE:
|
|
err = ipike_payload_certificate_extract(
|
|
(Ipike_cert_payload*) payload,
|
|
&ie->ike_sa->cert);
|
|
break;
|
|
case IPIKE_PAYLOAD_CERTIFICATE_REQUEST:
|
|
ie->certificate_requested = IP_TRUE;
|
|
err = ipike_payload_certificate_req_extract_v1(
|
|
(Ipike_cert_req_payload*) payload,
|
|
&ie->ike_sa->cert);
|
|
break;
|
|
case IPIKE_PAYLOAD_SIGNATURE:
|
|
err = ipike_sign_extract((Ipike_sign_payload*) payload,
|
|
ie->ike_sa->is_initiator ?
|
|
&ie->ike_sa->sign_r :
|
|
&ie->ike_sa->sign_i);
|
|
break;
|
|
case IPIKE_PAYLOAD_VENDOR_ID:
|
|
err = ipike_payload_vendor_id_process(
|
|
ie->ike_sa,
|
|
(Ipike_vendor_id_payload*) payload);
|
|
break;
|
|
case IPIKE_PAYLOAD_NAT_DISCOVERY:
|
|
err = ipike_nat_discovery_process(
|
|
ie->ike_sa,
|
|
(Ipike_nat_discovery_payload*) payload);
|
|
break;
|
|
default:
|
|
IPCOM_LOG2(ERR,
|
|
"ipike_aggressive_mode_process_payloads() :: "\
|
|
"'%s' (%d) is an unsupported payload type",
|
|
ipike_payload_type_to_string(this_payload),
|
|
this_payload);
|
|
err = IPIKE_ISAKMP_UNSUPPORTED_PAYLOAD;
|
|
break;
|
|
}
|
|
|
|
if (err != IPIKE_SUCCESS)
|
|
break;
|
|
|
|
this_payload = payload->next_payload;
|
|
payload = ipike_next_payload(&ctx);
|
|
}
|
|
|
|
ipike_free_payload_enumerator(&ctx);
|
|
|
|
if (err != IPIKE_SUCCESS)
|
|
{
|
|
IPIKE_EVENT_LOG(IKE_PACKET_DISCARD, ISAKMP_PACKET_ERROR,
|
|
&ie->ike_sa->peer_addr, &ie->ike_sa->local_addr,
|
|
0, IP_NULL);
|
|
return err;
|
|
}
|
|
|
|
return ipike_aggressive_mode_update_state(ie);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_add_reply_payloads
|
|
*===========================================================================
|
|
*/
|
|
IP_PUBLIC Ipike_error
|
|
ipike_aggressive_mode_add_reply_payloads(
|
|
Ipike_isakmp_exchange* ie,
|
|
Ipike_payload_header*** reply_payloads)
|
|
{
|
|
Ipike_error err = IPIKE_SUCCESS;
|
|
const Ip_u16* payload_ids = IP_NULL;
|
|
int i = 0;
|
|
Ipike_transform_ike *transform_ike;
|
|
|
|
payload_ids = ipike_aggressive_mode_get_payload_order(ie);
|
|
|
|
ip_assert(payload_ids != IP_NULL);
|
|
|
|
for (i = 0; payload_ids[i] != IPIKE_PAYLOAD_NONE; i++)
|
|
{
|
|
Ipike_payload_header* reply_payload = IP_NULL;
|
|
Ip_u8 payload_type;
|
|
|
|
if (IP_BIT_ISSET(payload_ids[i], IPIKE_PAYLOAD_OPT) &&
|
|
IP_BIT_ISSET(payload_ids[i], IPIKE_PAYLOAD_ADD) == IP_FALSE)
|
|
/* Only add the optional payload that had the IPIKE_PAYLOAD_ADD bit set */
|
|
continue;
|
|
|
|
payload_type = (Ip_u8) payload_ids[i];
|
|
|
|
switch (payload_type)
|
|
{
|
|
case IPIKE_PAYLOAD_SECURITY_ASSOCIATION:
|
|
err = ipike_sa_create(&ie->ike_sa->sa,
|
|
(Ipike_sa_payload**) &reply_payload);
|
|
if (err == IPIKE_SUCCESS && ie->ike_sa->is_initiator)
|
|
{
|
|
err = ipike_aggressive_mode_store_sai_b(&ie->ike_sa->sai_b,
|
|
(Ipike_sa_payload*) reply_payload);
|
|
if (err != IPIKE_SUCCESS)
|
|
ipcom_free(reply_payload);
|
|
}
|
|
break;
|
|
case IPIKE_PAYLOAD_KEY_EXCHANGE:
|
|
err = ipike_key_exchange_create(ie->ike_sa->is_initiator ? &ie->ike_sa->g_xi : &ie->ike_sa->g_xr,
|
|
(Ipike_ke_payload**) &reply_payload);
|
|
break;
|
|
case IPIKE_PAYLOAD_IDENTFICATION:
|
|
err = ipike_identification_create(ie->ike_sa->is_initiator ? &ie->ike_sa->idii : &ie->ike_sa->idir,
|
|
(Ipike_id_payload**) &reply_payload);
|
|
break;
|
|
case IPIKE_PAYLOAD_HASH:
|
|
err = ipike_hash_create(ie->ike_sa->is_initiator ? &ie->ike_sa->hash_i : &ie->ike_sa->hash_r,
|
|
(Ipike_hash_payload**) &reply_payload);
|
|
break;
|
|
case IPIKE_PAYLOAD_NONCE:
|
|
err = ipike_payload_nonce_create(ie->ike_sa->is_initiator ? &ie->ike_sa->ni : &ie->ike_sa->nr,
|
|
(Ipike_nonce_payload**) &reply_payload);
|
|
break;
|
|
case IPIKE_PAYLOAD_CERTIFICATE:
|
|
err = ipike_aggressive_mode_cert_create(ie->ike_conf,
|
|
(Ipike_cert_payload**) &reply_payload);
|
|
break;
|
|
case IPIKE_PAYLOAD_SIGNATURE:
|
|
err = ipike_sign_create(ie->ike_sa->is_initiator ? &ie->ike_sa->sign_i : &ie->ike_sa->sign_r,
|
|
(Ipike_sign_payload**) &reply_payload);
|
|
break;
|
|
case IPIKE_PAYLOAD_VENDOR_ID:
|
|
if ((IPIKE_SUCCESS == err) && (ipike.port_nat != 0))
|
|
{
|
|
err = ipike_payload_vendor_id_create(IPIKE_VENDOR_ID_NAT_T, (Ipike_vendor_id_payload**) &reply_payload);
|
|
if (IPIKE_SUCCESS == err)
|
|
{
|
|
err = ipike_array_add((void***) reply_payloads, reply_payload);
|
|
if (IPIKE_SUCCESS != err)
|
|
ipcom_free(reply_payload);
|
|
}
|
|
}
|
|
if (IPIKE_SUCCESS == err)
|
|
{
|
|
err = ipike_payload_vendor_id_create(IPIKE_VENDOR_ID_DPD, (Ipike_vendor_id_payload**) &reply_payload);
|
|
if (IPIKE_SUCCESS == err)
|
|
{
|
|
err = ipike_array_add((void***) reply_payloads, reply_payload);
|
|
if (IPIKE_SUCCESS != err)
|
|
ipcom_free(reply_payload);
|
|
}
|
|
}
|
|
reply_payload = IP_NULL;
|
|
break;
|
|
case IPIKE_PAYLOAD_NAT_DISCOVERY:
|
|
/* Always two payloads (local and peer) */
|
|
transform_ike = ipike_transform_ike_from_exch(ie);
|
|
if (transform_ike==IP_NULL)
|
|
{
|
|
err=IPIKE_FAILED;
|
|
break;
|
|
}
|
|
|
|
err = ipike_nat_discovery_create(&ie->ike_sa->local_addr,
|
|
ie->ike_sa->initiator_cookie,
|
|
ie->ike_sa->responder_cookie,
|
|
transform_ike->hash_algorithm,
|
|
(Ipike_nat_discovery_payload**) &reply_payload);
|
|
if (IPIKE_SUCCESS == err)
|
|
err = ipike_array_add((void***) reply_payloads, reply_payload);
|
|
if (IPIKE_SUCCESS == err)
|
|
{
|
|
err = ipike_nat_discovery_create(&ie->ike_sa->peer_addr,
|
|
ie->ike_sa->initiator_cookie,
|
|
ie->ike_sa->responder_cookie,
|
|
transform_ike->hash_algorithm,
|
|
(Ipike_nat_discovery_payload**) &reply_payload);
|
|
}
|
|
break;
|
|
case IPIKE_PAYLOAD_CERTIFICATE_REQUEST:
|
|
/* Request certificate if do not already have the peers certificate */
|
|
if ( !ie->ike_sa->cert.peer )
|
|
err = ipike_main_mode_add_cert_request(ie->ike_conf, reply_payloads);
|
|
break;
|
|
case IPIKE_PAYLOAD_NOTIFICATION:
|
|
case IPIKE_PAYLOAD_DELETE:
|
|
IPCOM_LOG1(ERR,
|
|
"Payload creation for '%s' is not implemented",
|
|
ipike_payload_type_to_string(payload_type));
|
|
err = IPIKE_NOT_IMPLEMENTED;
|
|
goto error;
|
|
default:
|
|
IPCOM_LOG1(ERR,
|
|
"Payload creation failed since %d is a unknown payload type",
|
|
payload_type);
|
|
err = IPIKE_ISAKMP_UNSUPPORTED_PAYLOAD;
|
|
goto error;
|
|
}
|
|
|
|
if (err != IPIKE_SUCCESS)
|
|
goto error;
|
|
if (reply_payload != IP_NULL)
|
|
{
|
|
if (IPIKE_SUCCESS != (err = ipike_array_add((void***) reply_payloads, reply_payload)))
|
|
{
|
|
ipcom_free(reply_payload);
|
|
goto error;
|
|
}
|
|
}
|
|
}
|
|
|
|
return IPIKE_SUCCESS;
|
|
error:
|
|
ipike_array_free((void**) *reply_payloads, ipcom_free); /*lint !e123 */
|
|
*reply_payloads = IP_NULL;
|
|
return err;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_cleartext_outgoing_message
|
|
*===========================================================================
|
|
*/
|
|
IP_PUBLIC Ipike_error
|
|
ipike_aggressive_mode_cleartext_outgoing_message(
|
|
Ipike_isakmp_exchange* ie,
|
|
Ipike_isakmp_header** outgoing_isakmp)
|
|
{
|
|
(void) ie;
|
|
(void) outgoing_isakmp;
|
|
|
|
return IPIKE_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_aggressive_mode_exchange_done
|
|
*===========================================================================
|
|
*/
|
|
IP_PUBLIC Ipike_error
|
|
ipike_aggressive_mode_exchange_done(Ipike_isakmp_exchange* ie)
|
|
{
|
|
Ipike_error err;
|
|
|
|
ipike_sadb_free_intermediate(ie->ike_sa);
|
|
if (IPIKE_SUCCESS != (err = ipike_cpy_value(&ie->ike_sa->base_iv, &ie->iv)))
|
|
return err;
|
|
if (IPIKE_SUCCESS != (err = ipike_sadb_set_state(ie, ie->ike_sa, IPIKE_SA_ACTIVE)))
|
|
return err;
|
|
|
|
/* Set liveness */
|
|
ie->ike_sa->liveness.timeout = (Ip_u32) ie->ike_conf->liveness;
|
|
|
|
ipcom_microtime(&ie->stop);
|
|
IPCOM_LOG3(INFO, "Aggressive mode exchange done in %d ms (peer: %s, Message ID: %d)",
|
|
(ie->stop.tv_sec - ie->start.tv_sec) * 1000 + (ie->stop.tv_usec - ie->start.tv_usec) / 1000,
|
|
ipike_addr_to_str(&ie->ike_sa->peer_addr),
|
|
ie->message_id);
|
|
|
|
(void)ipike_print_memory(IPCOM_LOG_DEBUG, "Final phase 1 (aggressive mode) IV: ",
|
|
ie->iv.value, ie->iv.len);
|
|
|
|
if (ie->ike_conf->initial_contact && (ie->rekey_spi.len == 0))
|
|
ipike_informational_report_initial_contact(ie->ike_sa);
|
|
|
|
/* Initiate a quick mode exchange if we are the initiator and
|
|
* if option1 (only IKE) is not set */
|
|
if (ie->ike_sa->is_initiator && !ie->option1)
|
|
(void)ipike_isakmp_initiate_ipsec_exchanges(ie->ike_sa, IP_NULL, ie->option2);
|
|
|
|
return IPIKE_SUCCESS;
|
|
}
|
|
|
|
#endif /* IPIKE_USE_AGGRESSIVE_MODE */
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|