summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/ikev2
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa/ikev2')
-rw-r--r--src/libcharon/sa/ikev2/authenticators/eap_authenticator.c9
-rw-r--r--src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c2
-rw-r--r--src/libcharon/sa/ikev2/keymat_v2.c2
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_create.c36
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_rekey.c18
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_rekey.c34
6 files changed, 60 insertions, 41 deletions
diff --git a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
index f1442096c..91f6187f9 100644
--- a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
+++ b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
@@ -448,6 +448,8 @@ static bool verify_auth(private_eap_authenticator_t *this, message_t *message,
identification_t *other_id;
auth_cfg_t *auth;
keymat_v2_t *keymat;
+ eap_type_t type;
+ u_int32_t vendor;
auth_payload = (auth_payload_t*)message->get_payload(message,
PLV2_AUTH);
@@ -478,6 +480,13 @@ static bool verify_auth(private_eap_authenticator_t *this, message_t *message,
this->auth_complete = TRUE;
auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+
+ type = this->method->get_type(this->method, &vendor);
+ auth->add(auth, AUTH_RULE_EAP_TYPE, type);
+ if (vendor)
+ {
+ auth->add(auth, AUTH_RULE_EAP_VENDOR, vendor);
+ }
return TRUE;
}
diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
index 151b49718..2284a484d 100644
--- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
+++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
@@ -321,7 +321,7 @@ METHOD(authenticator_t, build, status_t,
chunk_t auth_data;
status_t status;
auth_payload_t *auth_payload;
- auth_method_t auth_method;
+ auth_method_t auth_method = AUTH_NONE;
id = this->ike_sa->get_my_id(this->ike_sa);
auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c
index 6fedc8eb5..fce0840e3 100644
--- a/src/libcharon/sa/ikev2/keymat_v2.c
+++ b/src/libcharon/sa/ikev2/keymat_v2.c
@@ -112,6 +112,7 @@ static bool derive_ike_aead(private_keymat_v2_t *this, u_int16_t alg,
case ENCR_AES_GCM_ICV12:
case ENCR_AES_GCM_ICV16:
/* RFC 4106 */
+ case ENCR_CHACHA20_POLY1305:
salt_size = 4;
break;
case ENCR_AES_CCM_ICV8:
@@ -527,6 +528,7 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
case ENCR_AES_GCM_ICV16:
case ENCR_AES_CTR:
case ENCR_NULL_AUTH_AES_GMAC:
+ case ENCR_CHACHA20_POLY1305:
enc_size += 4;
break;
default:
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c
index e0f930c3c..e08f3dab1 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.c
+++ b/src/libcharon/sa/ikev2/tasks/child_create.c
@@ -145,6 +145,11 @@ struct private_child_create_t {
ipcomp_transform_t ipcomp_received;
/**
+ * IPsec protocol
+ */
+ protocol_id_t proto;
+
+ /**
* Own allocated SPI
*/
u_int32_t my_spi;
@@ -260,23 +265,23 @@ static bool allocate_spi(private_child_create_t *this)
{
enumerator_t *enumerator;
proposal_t *proposal;
- protocol_id_t proto = PROTO_ESP;
if (this->initiator)
{
+ this->proto = PROTO_ESP;
/* we just get a SPI for the first protocol. TODO: If we ever support
* proposal lists with mixed protocols, we'd need multiple SPIs */
if (this->proposals->get_first(this->proposals,
(void**)&proposal) == SUCCESS)
{
- proto = proposal->get_protocol(proposal);
+ this->proto = proposal->get_protocol(proposal);
}
}
else
{
- proto = this->proposal->get_protocol(this->proposal);
+ this->proto = this->proposal->get_protocol(this->proposal);
}
- this->my_spi = this->child_sa->alloc_spi(this->child_sa, proto);
+ this->my_spi = this->child_sa->alloc_spi(this->child_sa, this->proto);
if (this->my_spi)
{
if (this->initiator)
@@ -1352,20 +1357,16 @@ METHOD(task_t, build_i_delete, status_t,
private_child_create_t *this, message_t *message)
{
message->set_exchange_type(message, INFORMATIONAL);
- if (this->child_sa && this->proposal)
+ if (this->my_spi && this->proto)
{
- protocol_id_t proto;
delete_payload_t *del;
- u_int32_t spi;
- proto = this->proposal->get_protocol(this->proposal);
- spi = this->child_sa->get_spi(this->child_sa, TRUE);
- del = delete_payload_create(PLV2_DELETE, proto);
- del->add_spi(del, spi);
+ del = delete_payload_create(PLV2_DELETE, this->proto);
+ del->add_spi(del, this->my_spi);
message->add_payload(message, (payload_t*)del);
DBG1(DBG_IKE, "sending DELETE for %N CHILD_SA with SPI %.8x",
- protocol_id_names, proto, ntohl(spi));
+ protocol_id_names, this->proto, ntohl(this->my_spi));
}
return NEED_MORE;
}
@@ -1375,9 +1376,13 @@ METHOD(task_t, build_i_delete, status_t,
*/
static status_t delete_failed_sa(private_child_create_t *this)
{
- this->public.task.build = _build_i_delete;
- this->public.task.process = (void*)return_success;
- return NEED_MORE;
+ if (this->my_spi && this->proto)
+ {
+ this->public.task.build = _build_i_delete;
+ this->public.task.process = (void*)return_success;
+ return NEED_MORE;
+ }
+ return SUCCESS;
}
METHOD(task_t, process_i, status_t,
@@ -1596,6 +1601,7 @@ METHOD(task_t, migrate, void,
this->tsi = NULL;
this->tsr = NULL;
this->dh = NULL;
+ this->nonceg = NULL;
this->child_sa = NULL;
this->mode = MODE_TUNNEL;
this->ipcomp = IPCOMP_NONE;
diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c
index c806e19ca..c7a8a1342 100644
--- a/src/libcharon/sa/ikev2/tasks/child_rekey.c
+++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c
@@ -170,13 +170,8 @@ METHOD(task_t, build_i, status_t,
}
config = this->child_sa->get_config(this->child_sa);
- /* we just need the rekey notify ... */
- notify = notify_payload_create_from_protocol_and_type(PLV2_NOTIFY,
- this->protocol, REKEY_SA);
- notify->set_spi(notify, this->spi);
- message->add_payload(message, (payload_t*)notify);
- /* ... our CHILD_CREATE task does the hard work for us. */
+ /* our CHILD_CREATE task does the hard work for us */
if (!this->child_create)
{
this->child_create = child_create_create(this->ike_sa,
@@ -194,6 +189,14 @@ METHOD(task_t, build_i, status_t,
schedule_delayed_rekey(this);
return FAILED;
}
+ if (message->get_exchange_type(message) == CREATE_CHILD_SA)
+ {
+ /* don't add the notify if the CHILD_CREATE task changed the exchange */
+ notify = notify_payload_create_from_protocol_and_type(PLV2_NOTIFY,
+ this->protocol, REKEY_SA);
+ notify->set_spi(notify, this->spi);
+ message->add_payload(message, (payload_t*)notify);
+ }
this->child_sa->set_state(this->child_sa, CHILD_REKEYING);
return NEED_MORE;
@@ -334,8 +337,7 @@ METHOD(task_t, process_i, status_t,
if (this->child_create->task.process(&this->child_create->task,
message) == NEED_MORE)
{
- /* bad DH group while rekeying, try again */
- this->child_create->task.migrate(&this->child_create->task, this->ike_sa);
+ /* bad DH group while rekeying, retry, or failure requiring deletion */
return NEED_MORE;
}
if (message->get_payload(message, PLV2_SECURITY_ASSOCIATION) == NULL)
diff --git a/src/libcharon/sa/ikev2/tasks/ike_rekey.c b/src/libcharon/sa/ikev2/tasks/ike_rekey.c
index 1855517ce..eaba04e3a 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_rekey.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_rekey.c
@@ -116,7 +116,6 @@ static void establish_new(private_ike_rekey_t *this)
lib->processor->queue_job(lib->processor, job);
}
this->new_sa = NULL;
- /* set threads active IKE_SA after checkin */
charon->bus->set_sa(charon->bus, this->ike_sa);
}
}
@@ -229,9 +228,10 @@ METHOD(task_t, build_r, status_t,
if (this->ike_init->task.build(&this->ike_init->task, message) == FAILED)
{
+ charon->bus->set_sa(charon->bus, this->ike_sa);
return SUCCESS;
}
-
+ charon->bus->set_sa(charon->bus, this->ike_sa);
this->ike_sa->set_state(this->ike_sa, IKE_REKEYING);
/* rekeying successful, delete the IKE_SA using a subtask */
@@ -335,15 +335,13 @@ METHOD(task_t, process_i, status_t,
{
charon->ike_sa_manager->checkin(
charon->ike_sa_manager, this->new_sa);
- /* set threads active IKE_SA after checkin */
- charon->bus->set_sa(charon->bus, this->ike_sa);
}
+ charon->bus->set_sa(charon->bus, this->ike_sa);
this->new_sa = NULL;
establish_new(other);
return SUCCESS;
}
}
- /* set threads active IKE_SA after checkin */
charon->bus->set_sa(charon->bus, this->ike_sa);
}
@@ -372,9 +370,13 @@ METHOD(ike_rekey_t, collide, void,
this->collision = other;
}
-METHOD(task_t, migrate, void,
- private_ike_rekey_t *this, ike_sa_t *ike_sa)
+/**
+ * Cleanup the task
+ */
+static void cleanup(private_ike_rekey_t *this)
{
+ ike_sa_t *cur_sa;
+
if (this->ike_init)
{
this->ike_init->task.destroy(&this->ike_init->task);
@@ -383,9 +385,16 @@ METHOD(task_t, migrate, void,
{
this->ike_delete->task.destroy(&this->ike_delete->task);
}
+ cur_sa = charon->bus->get_sa(charon->bus);
DESTROY_IF(this->new_sa);
+ charon->bus->set_sa(charon->bus, cur_sa);
DESTROY_IF(this->collision);
+}
+METHOD(task_t, migrate, void,
+ private_ike_rekey_t *this, ike_sa_t *ike_sa)
+{
+ cleanup(this);
this->collision = NULL;
this->ike_sa = ike_sa;
this->new_sa = NULL;
@@ -396,16 +405,7 @@ METHOD(task_t, migrate, void,
METHOD(task_t, destroy, void,
private_ike_rekey_t *this)
{
- if (this->ike_init)
- {
- this->ike_init->task.destroy(&this->ike_init->task);
- }
- if (this->ike_delete)
- {
- this->ike_delete->task.destroy(&this->ike_delete->task);
- }
- DESTROY_IF(this->new_sa);
- DESTROY_IF(this->collision);
+ cleanup(this);
free(this);
}