Implemented first two exchanges of Main Mode as initiator
This commit is contained in:
+43
-27
@@ -44,6 +44,7 @@
|
|||||||
#include <sa/tasks/child_create.h>
|
#include <sa/tasks/child_create.h>
|
||||||
#include <sa/tasks/child_delete.h>
|
#include <sa/tasks/child_delete.h>
|
||||||
#include <sa/tasks/child_rekey.h>
|
#include <sa/tasks/child_rekey.h>
|
||||||
|
#include <sa/tasks/main_mode.h>
|
||||||
#include <processing/jobs/retransmit_job.h>
|
#include <processing/jobs/retransmit_job.h>
|
||||||
#include <processing/jobs/delete_ike_sa_job.h>
|
#include <processing/jobs/delete_ike_sa_job.h>
|
||||||
#include <processing/jobs/send_dpd_job.h>
|
#include <processing/jobs/send_dpd_job.h>
|
||||||
@@ -1129,31 +1130,39 @@ METHOD(ike_sa_t, initiate, status_t,
|
|||||||
|
|
||||||
set_condition(this, COND_ORIGINAL_INITIATOR, TRUE);
|
set_condition(this, COND_ORIGINAL_INITIATOR, TRUE);
|
||||||
|
|
||||||
task = (task_t*)ike_vendor_create(&this->public, TRUE);
|
if (this->version == IKEV1)
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
|
||||||
task = (task_t*)ike_init_create(&this->public, TRUE, NULL);
|
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
|
||||||
task = (task_t*)ike_natd_create(&this->public, TRUE);
|
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
|
||||||
task = (task_t*)ike_cert_pre_create(&this->public, TRUE);
|
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
|
||||||
task = (task_t*)ike_auth_create(&this->public, TRUE);
|
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
|
||||||
task = (task_t*)ike_cert_post_create(&this->public, TRUE);
|
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
|
||||||
task = (task_t*)ike_config_create(&this->public, TRUE);
|
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
|
||||||
task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
|
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
|
||||||
if (this->peer_cfg->use_mobike(this->peer_cfg))
|
|
||||||
{
|
{
|
||||||
task = (task_t*)ike_mobike_create(&this->public, TRUE);
|
task = (task_t*)main_mode_create(&this->public, TRUE);
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
task = (task_t*)ike_vendor_create(&this->public, TRUE);
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
task = (task_t*)ike_init_create(&this->public, TRUE, NULL);
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
task = (task_t*)ike_natd_create(&this->public, TRUE);
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
task = (task_t*)ike_cert_pre_create(&this->public, TRUE);
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
task = (task_t*)ike_auth_create(&this->public, TRUE);
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
task = (task_t*)ike_cert_post_create(&this->public, TRUE);
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
task = (task_t*)ike_config_create(&this->public, TRUE);
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
if (this->peer_cfg->use_mobike(this->peer_cfg))
|
||||||
|
{
|
||||||
|
task = (task_t*)ike_mobike_create(&this->public, TRUE);
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
}
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
task = (task_t*)ike_me_create(&this->public, TRUE);
|
task = (task_t*)ike_me_create(&this->public, TRUE);
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
@@ -1172,15 +1181,22 @@ METHOD(ike_sa_t, initiate, status_t,
|
|||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
{
|
{
|
||||||
/* normal IKE_SA with CHILD_SA */
|
/* normal IKE_SA with CHILD_SA */
|
||||||
task = (task_t*)child_create_create(&this->public, child_cfg, FALSE,
|
if (this->version == IKEV2)
|
||||||
tsi, tsr);
|
|
||||||
child_cfg->destroy(child_cfg);
|
|
||||||
if (reqid)
|
|
||||||
{
|
{
|
||||||
child_create_t *child_create = (child_create_t*)task;
|
task = (task_t*)child_create_create(&this->public, child_cfg, FALSE,
|
||||||
child_create->use_reqid(child_create, reqid);
|
tsi, tsr);
|
||||||
|
if (reqid)
|
||||||
|
{
|
||||||
|
child_create_t *child_create = (child_create_t*)task;
|
||||||
|
child_create->use_reqid(child_create, reqid);
|
||||||
|
}
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
}
|
}
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
else
|
||||||
|
{
|
||||||
|
/* TODO-IKEv1: create quick mode task */
|
||||||
|
}
|
||||||
|
child_cfg->destroy(child_cfg);
|
||||||
|
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
if (this->peer_cfg->get_mediated_by(this->peer_cfg))
|
if (this->peer_cfg->get_mediated_by(this->peer_cfg))
|
||||||
|
|||||||
@@ -154,10 +154,155 @@ METHOD(task_manager_t, retransmit, status_t,
|
|||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* move a task of a specific type from the queue to the active list
|
||||||
|
*/
|
||||||
|
static bool activate_task(private_task_manager_t *this, task_type_t type)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
task_t *task;
|
||||||
|
bool found = FALSE;
|
||||||
|
|
||||||
|
enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
|
||||||
|
while (enumerator->enumerate(enumerator, (void**)&task))
|
||||||
|
{
|
||||||
|
if (task->get_type(task) == type)
|
||||||
|
{
|
||||||
|
DBG2(DBG_IKE, " activating %N task", task_type_names, type);
|
||||||
|
this->queued_tasks->remove_at(this->queued_tasks, enumerator);
|
||||||
|
this->active_tasks->insert_last(this->active_tasks, task);
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(task_manager_t, initiate, status_t,
|
METHOD(task_manager_t, initiate, status_t,
|
||||||
private_task_manager_t *this)
|
private_task_manager_t *this)
|
||||||
{
|
{
|
||||||
return FAILED;
|
enumerator_t *enumerator;
|
||||||
|
task_t *task;
|
||||||
|
message_t *message;
|
||||||
|
host_t *me, *other;
|
||||||
|
status_t status;
|
||||||
|
exchange_type_t exchange = 0;
|
||||||
|
|
||||||
|
if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED)
|
||||||
|
{
|
||||||
|
DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress",
|
||||||
|
exchange_type_names, this->initiating.type);
|
||||||
|
/* do not initiate if we already have a message in the air */
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->active_tasks->get_count(this->active_tasks) == 0)
|
||||||
|
{
|
||||||
|
DBG2(DBG_IKE, "activating new tasks");
|
||||||
|
switch (this->ike_sa->get_state(this->ike_sa))
|
||||||
|
{
|
||||||
|
case IKE_CREATED:
|
||||||
|
if (activate_task(this, MAIN_MODE))
|
||||||
|
{
|
||||||
|
exchange = ID_PROT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG2(DBG_IKE, "reinitiating already active tasks");
|
||||||
|
enumerator = this->active_tasks->create_enumerator(this->active_tasks);
|
||||||
|
while (enumerator->enumerate(enumerator, (void**)&task))
|
||||||
|
{
|
||||||
|
DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
|
||||||
|
switch (task->get_type(task))
|
||||||
|
{
|
||||||
|
case MAIN_MODE:
|
||||||
|
exchange = ID_PROT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exchange == 0)
|
||||||
|
{
|
||||||
|
DBG2(DBG_IKE, "nothing to initiate");
|
||||||
|
/* nothing to do yet... */
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
me = this->ike_sa->get_my_host(this->ike_sa);
|
||||||
|
other = this->ike_sa->get_other_host(this->ike_sa);
|
||||||
|
|
||||||
|
message = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION);
|
||||||
|
if (exchange != ID_PROT)
|
||||||
|
{
|
||||||
|
/* TODO-IKEv1: Set random message id */
|
||||||
|
}
|
||||||
|
message->set_source(message, me->clone(me));
|
||||||
|
message->set_destination(message, other->clone(other));
|
||||||
|
message->set_exchange_type(message, exchange);
|
||||||
|
this->initiating.type = exchange;
|
||||||
|
this->initiating.retransmitted = 0;
|
||||||
|
|
||||||
|
enumerator = this->active_tasks->create_enumerator(this->active_tasks);
|
||||||
|
while (enumerator->enumerate(enumerator, (void*)&task))
|
||||||
|
{
|
||||||
|
switch (task->build(task, message))
|
||||||
|
{
|
||||||
|
case SUCCESS:
|
||||||
|
/* task completed, remove it */
|
||||||
|
this->active_tasks->remove_at(this->active_tasks, enumerator);
|
||||||
|
task->destroy(task);
|
||||||
|
break;
|
||||||
|
case NEED_MORE:
|
||||||
|
/* processed, but task needs another exchange */
|
||||||
|
break;
|
||||||
|
case FAILED:
|
||||||
|
default:
|
||||||
|
if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
|
||||||
|
{
|
||||||
|
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||||
|
}
|
||||||
|
/* FALL */
|
||||||
|
case DESTROY_ME:
|
||||||
|
/* critical failure, destroy IKE_SA */
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
message->destroy(message);
|
||||||
|
flush(this);
|
||||||
|
return DESTROY_ME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
/* update exchange type if a task changed it */
|
||||||
|
this->initiating.type = message->get_exchange_type(message);
|
||||||
|
|
||||||
|
status = this->ike_sa->generate_message(this->ike_sa, message,
|
||||||
|
&this->initiating.packet);
|
||||||
|
if (status != SUCCESS)
|
||||||
|
{
|
||||||
|
/* message generation failed. There is nothing more to do than to
|
||||||
|
* close the SA */
|
||||||
|
message->destroy(message);
|
||||||
|
flush(this);
|
||||||
|
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||||
|
return DESTROY_ME;
|
||||||
|
}
|
||||||
|
message->destroy(message);
|
||||||
|
|
||||||
|
charon->sender->send(charon->sender,
|
||||||
|
this->initiating.packet->clone(this->initiating.packet));
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -310,11 +455,62 @@ static status_t process_request(private_task_manager_t *this,
|
|||||||
return build_response(this, message);
|
return build_response(this, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle an incoming response message
|
||||||
|
*/
|
||||||
|
static status_t process_response(private_task_manager_t *this,
|
||||||
|
message_t *message)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
task_t *task;
|
||||||
|
|
||||||
|
if (message->get_exchange_type(message) != this->initiating.type)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "received %N response, but expected %N",
|
||||||
|
exchange_type_names, message->get_exchange_type(message),
|
||||||
|
exchange_type_names, this->initiating.type);
|
||||||
|
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||||
|
return DESTROY_ME;
|
||||||
|
}
|
||||||
|
|
||||||
|
enumerator = this->active_tasks->create_enumerator(this->active_tasks);
|
||||||
|
while (enumerator->enumerate(enumerator, (void*)&task))
|
||||||
|
{
|
||||||
|
switch (task->process(task, message))
|
||||||
|
{
|
||||||
|
case SUCCESS:
|
||||||
|
/* task completed, remove it */
|
||||||
|
this->active_tasks->remove_at(this->active_tasks, enumerator);
|
||||||
|
task->destroy(task);
|
||||||
|
break;
|
||||||
|
case NEED_MORE:
|
||||||
|
/* processed, but task needs another exchange */
|
||||||
|
break;
|
||||||
|
case FAILED:
|
||||||
|
default:
|
||||||
|
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||||
|
/* FALL */
|
||||||
|
case DESTROY_ME:
|
||||||
|
/* critical failure, destroy IKE_SA */
|
||||||
|
this->active_tasks->remove_at(this->active_tasks, enumerator);
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
task->destroy(task);
|
||||||
|
return DESTROY_ME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
|
||||||
|
this->initiating.packet->destroy(this->initiating.packet);
|
||||||
|
this->initiating.packet = NULL;
|
||||||
|
|
||||||
|
return initiate(this);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(task_manager_t, process_message, status_t,
|
METHOD(task_manager_t, process_message, status_t,
|
||||||
private_task_manager_t *this, message_t *msg)
|
private_task_manager_t *this, message_t *msg)
|
||||||
{
|
{
|
||||||
/* TODO-IKEv1: detect request/response */
|
if (this->active_tasks->get_count(this->active_tasks) == 0)
|
||||||
if (TRUE)
|
|
||||||
{
|
{
|
||||||
/* TODO-IKEv1: detect mainmode retransmission */
|
/* TODO-IKEv1: detect mainmode retransmission */
|
||||||
charon->bus->message(charon->bus, msg, TRUE);
|
charon->bus->message(charon->bus, msg, TRUE);
|
||||||
@@ -326,8 +522,12 @@ METHOD(task_manager_t, process_message, status_t,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* TODO-IKEv1: handle response */
|
charon->bus->message(charon->bus, msg, FALSE);
|
||||||
return DESTROY_ME;
|
if (process_response(this, msg) != SUCCESS)
|
||||||
|
{
|
||||||
|
flush(this);
|
||||||
|
return DESTROY_ME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ struct private_main_mode_t {
|
|||||||
/**
|
/**
|
||||||
* IKE config to establish
|
* IKE config to establish
|
||||||
*/
|
*/
|
||||||
ike_cfg_t *config;
|
ike_cfg_t *ike_cfg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* selected IKE proposal
|
* selected IKE proposal
|
||||||
@@ -87,8 +87,74 @@ struct private_main_mode_t {
|
|||||||
METHOD(task_t, build_i, status_t,
|
METHOD(task_t, build_i, status_t,
|
||||||
private_main_mode_t *this, message_t *message)
|
private_main_mode_t *this, message_t *message)
|
||||||
{
|
{
|
||||||
/* TODO-IKEv1: initiate mainmode */
|
switch (this->state)
|
||||||
return FAILED;
|
{
|
||||||
|
case MM_INIT:
|
||||||
|
{
|
||||||
|
sa_payload_t *sa_payload;
|
||||||
|
linked_list_t *proposals;
|
||||||
|
|
||||||
|
this->ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
|
||||||
|
DBG0(DBG_IKE, "initiating IKE_SA %s[%d] to %H",
|
||||||
|
this->ike_sa->get_name(this->ike_sa),
|
||||||
|
this->ike_sa->get_unique_id(this->ike_sa),
|
||||||
|
this->ike_sa->get_other_host(this->ike_sa));
|
||||||
|
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
|
||||||
|
|
||||||
|
proposals = this->ike_cfg->get_proposals(this->ike_cfg);
|
||||||
|
|
||||||
|
sa_payload = sa_payload_create_from_proposal_list(
|
||||||
|
SECURITY_ASSOCIATION_V1, proposals);
|
||||||
|
proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
|
||||||
|
|
||||||
|
message->add_payload(message, &sa_payload->payload_interface);
|
||||||
|
|
||||||
|
this->state = MM_SA;
|
||||||
|
return NEED_MORE;
|
||||||
|
}
|
||||||
|
case MM_SA:
|
||||||
|
{
|
||||||
|
ke_payload_t *ke_payload;
|
||||||
|
nonce_payload_t *nonce_payload;
|
||||||
|
u_int16_t group;
|
||||||
|
rng_t *rng;
|
||||||
|
|
||||||
|
if (!this->proposal->get_algorithm(this->proposal,
|
||||||
|
DIFFIE_HELLMAN_GROUP, &group, NULL))
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "DH group selection failed");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
this->dh = lib->crypto->create_dh(lib->crypto, group);
|
||||||
|
if (!this->dh)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "negotiated DH group not supported");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
ke_payload = ke_payload_create_from_diffie_hellman(KEY_EXCHANGE_V1,
|
||||||
|
this->dh);
|
||||||
|
message->add_payload(message, &ke_payload->payload_interface);
|
||||||
|
|
||||||
|
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||||
|
if (!rng)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "no RNG found to create nonce");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
/* TODO-IKEv1: nonce size? */
|
||||||
|
rng->allocate_bytes(rng, 20, &this->nonce_i);
|
||||||
|
rng->destroy(rng);
|
||||||
|
|
||||||
|
nonce_payload = nonce_payload_create(NONCE_V1);
|
||||||
|
nonce_payload->set_nonce(nonce_payload, this->nonce_i);
|
||||||
|
message->add_payload(message, &nonce_payload->payload_interface);
|
||||||
|
|
||||||
|
this->state = MM_KE;
|
||||||
|
return NEED_MORE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(task_t, process_r, status_t,
|
METHOD(task_t, process_r, status_t,
|
||||||
@@ -102,7 +168,7 @@ METHOD(task_t, process_r, status_t,
|
|||||||
linked_list_t *list;
|
linked_list_t *list;
|
||||||
sa_payload_t *sa_payload;
|
sa_payload_t *sa_payload;
|
||||||
|
|
||||||
this->config = this->ike_sa->get_ike_cfg(this->ike_sa);
|
this->ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
|
||||||
DBG0(DBG_IKE, "%H is initiating a Main Mode",
|
DBG0(DBG_IKE, "%H is initiating a Main Mode",
|
||||||
message->get_source(message));
|
message->get_source(message));
|
||||||
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
|
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
|
||||||
@@ -115,8 +181,8 @@ METHOD(task_t, process_r, status_t,
|
|||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
list = sa_payload->get_proposals(sa_payload);
|
list = sa_payload->get_proposals(sa_payload);
|
||||||
this->proposal = this->config->select_proposal(this->config,
|
this->proposal = this->ike_cfg->select_proposal(this->ike_cfg,
|
||||||
list, FALSE);
|
list, FALSE);
|
||||||
list->destroy_offset(list, offsetof(proposal_t, destroy));
|
list->destroy_offset(list, offsetof(proposal_t, destroy));
|
||||||
if (!this->proposal)
|
if (!this->proposal)
|
||||||
{
|
{
|
||||||
@@ -222,8 +288,62 @@ METHOD(task_t, build_r, status_t,
|
|||||||
METHOD(task_t, process_i, status_t,
|
METHOD(task_t, process_i, status_t,
|
||||||
private_main_mode_t *this, message_t *message)
|
private_main_mode_t *this, message_t *message)
|
||||||
{
|
{
|
||||||
/* TODO-IKEv1: process main mode as initiator */
|
switch (this->state)
|
||||||
return FAILED;
|
{
|
||||||
|
case MM_SA:
|
||||||
|
{
|
||||||
|
linked_list_t *list;
|
||||||
|
sa_payload_t *sa_payload;
|
||||||
|
|
||||||
|
sa_payload = (sa_payload_t*)message->get_payload(message,
|
||||||
|
SECURITY_ASSOCIATION_V1);
|
||||||
|
if (!sa_payload)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "SA payload missing");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
list = sa_payload->get_proposals(sa_payload);
|
||||||
|
this->proposal = this->ike_cfg->select_proposal(this->ike_cfg,
|
||||||
|
list, FALSE);
|
||||||
|
list->destroy_offset(list, offsetof(proposal_t, destroy));
|
||||||
|
if (!this->proposal)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "no proposal found");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
return NEED_MORE;
|
||||||
|
}
|
||||||
|
case MM_KE:
|
||||||
|
{
|
||||||
|
ke_payload_t *ke_payload;
|
||||||
|
nonce_payload_t *nonce_payload;
|
||||||
|
|
||||||
|
ke_payload = (ke_payload_t*)message->get_payload(message,
|
||||||
|
KEY_EXCHANGE_V1);
|
||||||
|
if (!ke_payload)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "KE payload missing");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
this->dh_value = ke_payload->get_key_exchange_data(ke_payload);
|
||||||
|
this->dh_value = chunk_clone(this->dh_value);
|
||||||
|
this->dh->set_other_public_value(this->dh, this->dh_value);
|
||||||
|
|
||||||
|
nonce_payload = (nonce_payload_t*)message->get_payload(message,
|
||||||
|
NONCE_V1);
|
||||||
|
if (!nonce_payload)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "Nonce payload missing");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
this->nonce_r = nonce_payload->get_nonce(nonce_payload);
|
||||||
|
/* TODO-IKEv1: verify nonce length */
|
||||||
|
|
||||||
|
return NEED_MORE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(task_t, get_type, task_type_t,
|
METHOD(task_t, get_type, task_type_t,
|
||||||
|
|||||||
Reference in New Issue
Block a user