summaryrefslogtreecommitdiff
path: root/src/libcharon/sa
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa')
-rw-r--r--src/libcharon/sa/ike_sa_manager.c4
-rw-r--r--src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c2
-rw-r--r--src/libcharon/sa/ikev1/task_manager_v1.c5
-rw-r--r--src/libcharon/sa/ikev2/authenticators/eap_authenticator.c2
-rw-r--r--src/libcharon/sa/ikev2/authenticators/psk_authenticator.c2
-rw-r--r--src/libcharon/sa/ikev2/keymat_v2.c15
-rw-r--r--src/libcharon/sa/ikev2/task_manager_v2.c18
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_create.c43
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_init.c53
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_mobike.c2
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_vendor.c10
11 files changed, 96 insertions, 60 deletions
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index 13fc74ff7..938f7848f 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -1737,7 +1737,8 @@ static void adopt_children_and_vips(ike_sa_t *old, ike_sa_t *new)
host_t *vip;
int chcount = 0, vipcount = 0;
-
+ charon->bus->children_migrate(charon->bus, new->get_id(new),
+ new->get_unique_id(new));
enumerator = old->create_child_sa_enumerator(old);
while (enumerator->enumerate(enumerator, &child_sa))
{
@@ -1760,6 +1761,7 @@ static void adopt_children_and_vips(ike_sa_t *old, ike_sa_t *new)
/* ...trigger the analogous event on the new SA */
charon->bus->set_sa(charon->bus, new);
charon->bus->assign_vips(charon->bus, new, TRUE);
+ charon->bus->children_migrate(charon->bus, NULL, 0);
charon->bus->set_sa(charon->bus, old);
if (chcount || vipcount)
diff --git a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
index bb187f07c..5debeeb37 100644
--- a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
+++ b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
@@ -124,7 +124,7 @@ METHOD(authenticator_t, process, status_t,
return FAILED;
}
free(dh.ptr);
- if (chunk_equals(hash, hash_payload->get_hash(hash_payload)))
+ if (chunk_equals_const(hash, hash_payload->get_hash(hash_payload)))
{
free(hash.ptr);
if (!this->hybrid)
diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c
index cb22bf606..ed547c4c2 100644
--- a/src/libcharon/sa/ikev1/task_manager_v1.c
+++ b/src/libcharon/sa/ikev1/task_manager_v1.c
@@ -1475,6 +1475,8 @@ METHOD(task_manager_t, queue_ike_reauth, void,
}
enumerator->destroy(enumerator);
+ charon->bus->children_migrate(charon->bus, new->get_id(new),
+ new->get_unique_id(new));
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
while (enumerator->enumerate(enumerator, &child_sa))
{
@@ -1482,6 +1484,9 @@ METHOD(task_manager_t, queue_ike_reauth, void,
new->add_child_sa(new, child_sa);
}
enumerator->destroy(enumerator);
+ charon->bus->set_sa(charon->bus, new);
+ charon->bus->children_migrate(charon->bus, NULL, 0);
+ charon->bus->set_sa(charon->bus, this->ike_sa);
if (!new->get_child_count(new))
{ /* check if a Quick Mode task is queued (UNITY_LOAD_BALANCE case) */
diff --git a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
index ebef31930..f1442096c 100644
--- a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
+++ b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
@@ -464,7 +464,7 @@ static bool verify_auth(private_eap_authenticator_t *this, message_t *message,
return FALSE;
}
recv_auth_data = auth_payload->get_data(auth_payload);
- if (!auth_data.len || !chunk_equals(auth_data, recv_auth_data))
+ if (!auth_data.len || !chunk_equals_const(auth_data, recv_auth_data))
{
DBG1(DBG_IKE, "verification of AUTH payload with%s EAP MSK failed",
this->msk.ptr ? "" : "out");
diff --git a/src/libcharon/sa/ikev2/authenticators/psk_authenticator.c b/src/libcharon/sa/ikev2/authenticators/psk_authenticator.c
index c6a4b6ba4..535581068 100644
--- a/src/libcharon/sa/ikev2/authenticators/psk_authenticator.c
+++ b/src/libcharon/sa/ikev2/authenticators/psk_authenticator.c
@@ -123,7 +123,7 @@ METHOD(authenticator_t, process, status_t,
{
continue;
}
- if (auth_data.len && chunk_equals(auth_data, recv_auth_data))
+ if (auth_data.len && chunk_equals_const(auth_data, recv_auth_data))
{
DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
other_id, auth_method_names, AUTH_PSK);
diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c
index f70f5cfed..6fedc8eb5 100644
--- a/src/libcharon/sa/ikev2/keymat_v2.c
+++ b/src/libcharon/sa/ikev2/keymat_v2.c
@@ -193,6 +193,7 @@ static bool derive_ike_traditional(private_keymat_v2_t *this, u_int16_t enc_alg,
{
crypter_t *crypter_i = NULL, *crypter_r = NULL;
signer_t *signer_i, *signer_r;
+ iv_gen_t *ivg_i, *ivg_r;
size_t key_size;
chunk_t key = chunk_empty;
@@ -264,15 +265,21 @@ static bool derive_ike_traditional(private_keymat_v2_t *this, u_int16_t enc_alg,
goto failure;
}
+ ivg_i = iv_gen_create_for_alg(enc_alg);
+ ivg_r = iv_gen_create_for_alg(enc_alg);
+ if (!ivg_i || !ivg_r)
+ {
+ goto failure;
+ }
if (this->initiator)
{
- this->aead_in = aead_create(crypter_r, signer_r);
- this->aead_out = aead_create(crypter_i, signer_i);
+ this->aead_in = aead_create(crypter_r, signer_r, ivg_r);
+ this->aead_out = aead_create(crypter_i, signer_i, ivg_i);
}
else
{
- this->aead_in = aead_create(crypter_i, signer_i);
- this->aead_out = aead_create(crypter_r, signer_r);
+ this->aead_in = aead_create(crypter_i, signer_i, ivg_i);
+ this->aead_out = aead_create(crypter_r, signer_r, ivg_r);
}
signer_i = signer_r = NULL;
crypter_i = crypter_r = NULL;
diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c
index 298167703..4676867df 100644
--- a/src/libcharon/sa/ikev2/task_manager_v2.c
+++ b/src/libcharon/sa/ikev2/task_manager_v2.c
@@ -1184,15 +1184,17 @@ static status_t parse_message(private_task_manager_t *this, message_t *msg)
enumerator = msg->create_payload_enumerator(msg);
while (enumerator->enumerate(enumerator, &payload))
{
- unknown = (unknown_payload_t*)payload;
- type = payload->get_type(payload);
- if (!payload_is_known(type, msg->get_major_version(msg)) &&
- unknown->is_critical(unknown))
+ if (payload->get_type(payload) == PL_UNKNOWN)
{
- DBG1(DBG_ENC, "payload type %N is not supported, "
- "but its critical!", payload_type_names, type);
- status = NOT_SUPPORTED;
- break;
+ unknown = (unknown_payload_t*)payload;
+ if (unknown->is_critical(unknown))
+ {
+ type = unknown->get_type(unknown);
+ DBG1(DBG_ENC, "payload type %N is not supported, "
+ "but its critical!", payload_type_names, type);
+ status = NOT_SUPPORTED;
+ break;
+ }
}
}
enumerator->destroy(enumerator);
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c
index 6d9132a68..e0f930c3c 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.c
+++ b/src/libcharon/sa/ikev2/tasks/child_create.c
@@ -65,6 +65,11 @@ struct private_child_create_t {
chunk_t other_nonce;
/**
+ * nonce generator
+ */
+ nonce_gen_t *nonceg;
+
+ /**
* config to create the CHILD_SA from
*/
child_cfg_t *config;
@@ -214,25 +219,21 @@ static status_t get_nonce(message_t *message, chunk_t *nonce)
/**
* generate a new nonce to include in a CREATE_CHILD_SA message
*/
-static status_t generate_nonce(private_child_create_t *this)
+static bool generate_nonce(private_child_create_t *this)
{
- nonce_gen_t *nonceg;
-
- nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
- if (!nonceg)
+ this->nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
+ if (!this->nonceg)
{
DBG1(DBG_IKE, "no nonce generator found to create nonce");
- return FAILED;
+ return FALSE;
}
- if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &this->my_nonce))
+ if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE,
+ &this->my_nonce))
{
DBG1(DBG_IKE, "nonce allocation failed");
- nonceg->destroy(nonceg);
- return FAILED;
+ return FALSE;
}
- nonceg->destroy(nonceg);
-
- return SUCCESS;
+ return TRUE;
}
/**
@@ -933,9 +934,10 @@ METHOD(task_t, build_i, status_t,
case IKE_SA_INIT:
return get_nonce(message, &this->my_nonce);
case CREATE_CHILD_SA:
- if (generate_nonce(this) != SUCCESS)
+ if (!generate_nonce(this))
{
- message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
+ message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
+ chunk_empty);
return SUCCESS;
}
if (!this->retry)
@@ -1092,7 +1094,10 @@ METHOD(task_t, process_r, status_t,
static void handle_child_sa_failure(private_child_create_t *this,
message_t *message)
{
- if (message->get_exchange_type(message) == IKE_AUTH &&
+ bool is_first;
+
+ is_first = message->get_exchange_type(message) == IKE_AUTH;
+ if (is_first &&
lib->settings->get_bool(lib->settings,
"%s.close_ike_on_child_failure", FALSE, lib->ns))
{
@@ -1106,7 +1111,8 @@ static void handle_child_sa_failure(private_child_create_t *this,
else
{
DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
- charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE);
+ charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE,
+ is_first);
}
}
@@ -1190,7 +1196,7 @@ METHOD(task_t, build_r, status_t,
case IKE_SA_INIT:
return get_nonce(message, &this->my_nonce);
case CREATE_CHILD_SA:
- if (generate_nonce(this) != SUCCESS )
+ if (!generate_nonce(this))
{
message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
chunk_empty);
@@ -1575,6 +1581,7 @@ METHOD(task_t, migrate, void,
}
DESTROY_IF(this->child_sa);
DESTROY_IF(this->proposal);
+ DESTROY_IF(this->nonceg);
DESTROY_IF(this->dh);
this->dh_failed = FALSE;
if (this->proposals)
@@ -1627,6 +1634,7 @@ METHOD(task_t, destroy, void,
}
DESTROY_IF(this->config);
+ DESTROY_IF(this->nonceg);
free(this);
}
@@ -1678,6 +1686,5 @@ child_create_t *child_create_create(ike_sa_t *ike_sa,
this->public.task.process = _process_r;
this->initiator = FALSE;
}
-
return &this->public;
}
diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c
index 0d5700ef2..1ff643d62 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_init.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_init.c
@@ -90,6 +90,11 @@ struct private_ike_init_t {
chunk_t other_nonce;
/**
+ * nonce generator
+ */
+ nonce_gen_t *nonceg;
+
+ /**
* Negotiated proposal used for IKE_SA
*/
proposal_t *proposal;
@@ -116,6 +121,25 @@ struct private_ike_init_t {
};
/**
+ * Allocate our own nonce value
+ */
+static bool generate_nonce(private_ike_init_t *this)
+{
+ if (!this->nonceg)
+ {
+ DBG1(DBG_IKE, "no nonce generator found to create nonce");
+ return FALSE;
+ }
+ if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE,
+ &this->my_nonce))
+ {
+ DBG1(DBG_IKE, "nonce allocation failed");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
* Notify the peer about the hash algorithms we support or expect,
* as per RFC 7427
*/
@@ -428,21 +452,10 @@ METHOD(task_t, build_i, status_t,
/* generate nonce only when we are trying the first time */
if (this->my_nonce.ptr == NULL)
{
- nonce_gen_t *nonceg;
-
- nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
- if (!nonceg)
+ if (!generate_nonce(this))
{
- DBG1(DBG_IKE, "no nonce generator found to create nonce");
return FAILED;
}
- if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &this->my_nonce))
- {
- DBG1(DBG_IKE, "nonce allocation failed");
- nonceg->destroy(nonceg);
- return FAILED;
- }
- nonceg->destroy(nonceg);
}
if (this->cookie.ptr)
@@ -471,25 +484,14 @@ METHOD(task_t, build_i, status_t,
METHOD(task_t, process_r, status_t,
private_ike_init_t *this, message_t *message)
{
- nonce_gen_t *nonceg;
-
this->config = this->ike_sa->get_ike_cfg(this->ike_sa);
DBG0(DBG_IKE, "%H is initiating an IKE_SA", message->get_source(message));
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
- nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
- if (!nonceg)
+ if (!generate_nonce(this))
{
- DBG1(DBG_IKE, "no nonce generator found to create nonce");
return FAILED;
}
- if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &this->my_nonce))
- {
- DBG1(DBG_IKE, "nonce allocation failed");
- nonceg->destroy(nonceg);
- return FAILED;
- }
- nonceg->destroy(nonceg);
#ifdef ME
{
@@ -756,6 +758,7 @@ METHOD(task_t, destroy, void,
{
DESTROY_IF(this->dh);
DESTROY_IF(this->proposal);
+ DESTROY_IF(this->nonceg);
chunk_free(&this->my_nonce);
chunk_free(&this->other_nonce);
chunk_free(&this->cookie);
@@ -800,6 +803,7 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa)
.signature_authentication = lib->settings->get_bool(lib->settings,
"%s.signature_authentication", TRUE, lib->ns),
);
+ this->nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
if (initiator)
{
@@ -811,6 +815,5 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa)
this->public.task.build = _build_r;
this->public.task.process = _process_r;
}
-
return &this->public;
}
diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c
index 6295d7960..11b0bb281 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c
@@ -537,7 +537,7 @@ METHOD(task_t, process_i, status_t,
cookie2 = this->cookie2;
this->cookie2 = chunk_empty;
process_payloads(this, message);
- if (!chunk_equals(cookie2, this->cookie2))
+ if (!chunk_equals_const(cookie2, this->cookie2))
{
chunk_free(&cookie2);
DBG1(DBG_IKE, "COOKIE2 mismatch, closing IKE_SA");
diff --git a/src/libcharon/sa/ikev2/tasks/ike_vendor.c b/src/libcharon/sa/ikev2/tasks/ike_vendor.c
index d536af218..cb3c270dc 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_vendor.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_vendor.c
@@ -76,6 +76,16 @@ static vid_data_t vids[] = {
"CISCO(COPYRIGHT)&Copyright (c) 2009 Cisco Systems, Inc." },
{ "FRAGMENTATION", 0, 16,
"\x40\x48\xb7\xd5\x6e\xbc\xe8\x85\x25\xe7\xde\x7f\x00\xd6\xc2\xd3"},
+ { "MS NT5 ISAKMPOAKLEY v7", 0, 20,
+ "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x07"},
+ { "MS NT5 ISAKMPOAKLEY v8", 0, 20,
+ "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x08"},
+ { "MS NT5 ISAKMPOAKLEY v9", 0, 20,
+ "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x09"},
+ { "MS-Negotiation Discovery Capable", 0, 16,
+ "\xfb\x1d\xe3\xcd\xf3\x41\xb7\xea\x16\xb7\xe5\xbe\x08\x55\xf1\x20"},
+ { "Vid-Initial-Contact", 0, 16,
+ "\x26\x24\x4d\x38\xed\xdb\x61\xb3\x17\x2a\x36\xe3\xd0\xcf\xb8\x19"},
};
METHOD(task_t, build, status_t,