diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2016-10-20 16:18:38 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2016-10-20 16:18:38 +0200 |
commit | 25663e04c3ab01ef8dc9f906608282319cfea2db (patch) | |
tree | a0ca5e70f66d74dbe552c996a4f3a285cdfc35e4 /src/libcharon/sa/ikev2 | |
parent | bf372706c469764d59e9f29c39e3ecbebd72b8d2 (diff) | |
download | vyos-strongswan-25663e04c3ab01ef8dc9f906608282319cfea2db.tar.gz vyos-strongswan-25663e04c3ab01ef8dc9f906608282319cfea2db.zip |
New upstream version 5.5.1
Diffstat (limited to 'src/libcharon/sa/ikev2')
-rw-r--r-- | src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c | 4 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/keymat_v2.c | 56 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/task_manager_v2.c | 25 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/child_create.c | 69 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/ike_init.c | 8 |
5 files changed, 97 insertions, 65 deletions
diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c index 6fd34e0a6..592f49770 100644 --- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c @@ -161,8 +161,8 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat, if (key_type == KEY_RSA) { signature_scheme_t schemes[] = { - SIGN_RSA_EMSA_PKCS1_SHA384, - SIGN_RSA_EMSA_PKCS1_SHA256, + SIGN_RSA_EMSA_PKCS1_SHA2_384, + SIGN_RSA_EMSA_PKCS1_SHA2_256, SIGN_RSA_EMSA_PKCS1_SHA1, }, contained; bool found; diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c index e37399841..58efdbabe 100644 --- a/src/libcharon/sa/ikev2/keymat_v2.c +++ b/src/libcharon/sa/ikev2/keymat_v2.c @@ -103,7 +103,7 @@ static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg, uint16_t key_size, prf_plus_t *prf_plus) { aead_t *aead_i, *aead_r; - chunk_t key = chunk_empty; + chunk_t sk_ei = chunk_empty, sk_er = chunk_empty; u_int salt_size; switch (alg) @@ -146,23 +146,22 @@ static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg, { goto failure; } - if (!prf_plus->allocate_bytes(prf_plus, key_size, &key)) + if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ei)) { goto failure; } - DBG4(DBG_IKE, "Sk_ei secret %B", &key); - if (!aead_i->set_key(aead_i, key)) + DBG4(DBG_IKE, "Sk_ei secret %B", &sk_ei); + if (!aead_i->set_key(aead_i, sk_ei)) { goto failure; } - chunk_clear(&key); - if (!prf_plus->allocate_bytes(prf_plus, key_size, &key)) + if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_er)) { goto failure; } - DBG4(DBG_IKE, "Sk_er secret %B", &key); - if (!aead_r->set_key(aead_r, key)) + DBG4(DBG_IKE, "Sk_er secret %B", &sk_er); + if (!aead_r->set_key(aead_r, sk_er)) { goto failure; } @@ -178,11 +177,14 @@ static bool derive_ike_aead(private_keymat_v2_t *this, uint16_t alg, this->aead_out = aead_r; } aead_i = aead_r = NULL; + charon->bus->ike_derived_keys(charon->bus, sk_ei, sk_er, chunk_empty, + chunk_empty); failure: DESTROY_IF(aead_i); DESTROY_IF(aead_r); - chunk_clear(&key); + chunk_clear(&sk_ei); + chunk_clear(&sk_er); return this->aead_in && this->aead_out; } @@ -196,7 +198,8 @@ static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg, signer_t *signer_i, *signer_r; iv_gen_t *ivg_i, *ivg_r; size_t key_size; - chunk_t key = chunk_empty; + chunk_t sk_ei = chunk_empty, sk_er = chunk_empty, + sk_ai = chunk_empty, sk_ar = chunk_empty; signer_i = lib->crypto->create_signer(lib->crypto, int_alg); signer_r = lib->crypto->create_signer(lib->crypto, int_alg); @@ -220,48 +223,45 @@ static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg, /* SK_ai/SK_ar used for integrity protection */ key_size = signer_i->get_key_size(signer_i); - if (!prf_plus->allocate_bytes(prf_plus, key_size, &key)) + if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ai)) { goto failure; } - DBG4(DBG_IKE, "Sk_ai secret %B", &key); - if (!signer_i->set_key(signer_i, key)) + DBG4(DBG_IKE, "Sk_ai secret %B", &sk_ai); + if (!signer_i->set_key(signer_i, sk_ai)) { goto failure; } - chunk_clear(&key); - if (!prf_plus->allocate_bytes(prf_plus, key_size, &key)) + if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ar)) { goto failure; } - DBG4(DBG_IKE, "Sk_ar secret %B", &key); - if (!signer_r->set_key(signer_r, key)) + DBG4(DBG_IKE, "Sk_ar secret %B", &sk_ar); + if (!signer_r->set_key(signer_r, sk_ar)) { goto failure; } - chunk_clear(&key); /* SK_ei/SK_er used for encryption */ key_size = crypter_i->get_key_size(crypter_i); - if (!prf_plus->allocate_bytes(prf_plus, key_size, &key)) + if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_ei)) { goto failure; } - DBG4(DBG_IKE, "Sk_ei secret %B", &key); - if (!crypter_i->set_key(crypter_i, key)) + DBG4(DBG_IKE, "Sk_ei secret %B", &sk_ei); + if (!crypter_i->set_key(crypter_i, sk_ei)) { goto failure; } - chunk_clear(&key); - if (!prf_plus->allocate_bytes(prf_plus, key_size, &key)) + if (!prf_plus->allocate_bytes(prf_plus, key_size, &sk_er)) { goto failure; } - DBG4(DBG_IKE, "Sk_er secret %B", &key); - if (!crypter_r->set_key(crypter_r, key)) + DBG4(DBG_IKE, "Sk_er secret %B", &sk_er); + if (!crypter_r->set_key(crypter_r, sk_er)) { goto failure; } @@ -284,9 +284,13 @@ static bool derive_ike_traditional(private_keymat_v2_t *this, uint16_t enc_alg, } signer_i = signer_r = NULL; crypter_i = crypter_r = NULL; + charon->bus->ike_derived_keys(charon->bus, sk_ei, sk_er, sk_ai, sk_ar); failure: - chunk_clear(&key); + chunk_clear(&sk_ai); + chunk_clear(&sk_ar); + chunk_clear(&sk_ei); + chunk_clear(&sk_er); DESTROY_IF(signer_i); DESTROY_IF(signer_r); DESTROY_IF(crypter_i); diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 41a4e1b75..60a262ffc 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -709,7 +709,7 @@ static status_t process_response(private_task_manager_t *this, } enumerator->destroy(enumerator); - if (this->initiating.retransmitted) + if (this->initiating.retransmitted > 1) { packet_t *packet = NULL; array_get(this->initiating.packets, 0, &packet); @@ -1827,15 +1827,22 @@ METHOD(task_manager_t, queue_dpd, void, if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE) && this->ike_sa->has_condition(this->ike_sa, COND_NAT_HERE)) { - /* use mobike enabled DPD to detect NAT mapping changes */ - mobike = ike_mobike_create(this->ike_sa, TRUE); - mobike->dpd(mobike); - queue_task(this, &mobike->task); - } - else - { - queue_task(this, (task_t*)ike_dpd_create(TRUE)); +#ifdef ME + peer_cfg_t *cfg = this->ike_sa->get_peer_cfg(this->ike_sa); + if (cfg->get_peer_id(cfg) || + this->ike_sa->has_condition(this->ike_sa, COND_ORIGINAL_INITIATOR)) +#else + if (this->ike_sa->has_condition(this->ike_sa, COND_ORIGINAL_INITIATOR)) +#endif + { + /* use mobike enabled DPD to detect NAT mapping changes */ + mobike = ike_mobike_create(this->ike_sa, TRUE); + mobike->dpd(mobike); + queue_task(this, &mobike->task); + return; + } } + queue_task(this, (task_t*)ike_dpd_create(TRUE)); } METHOD(task_manager_t, adopt_tasks, void, diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 64a82850b..71cb6b8ea 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -666,10 +666,6 @@ static status_t select_and_install(private_child_create_t *this, FALSE, this->tfcv3, my_ts, other_ts); } } - chunk_clear(&integ_i); - chunk_clear(&integ_r); - chunk_clear(&encr_i); - chunk_clear(&encr_r); if (status_i != SUCCESS || status_o != SUCCESS) { @@ -679,41 +675,62 @@ static status_t select_and_install(private_child_create_t *this, (status_o != SUCCESS) ? "outbound " : ""); charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_SA_FAILED, this->child_sa); - return FAILED; - } - - if (this->initiator) - { - status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts); + status = FAILED; } else { - /* use a copy of the traffic selectors, as the POST hook should not - * change payloads */ - my_ts = this->tsr->clone_offset(this->tsr, + if (this->initiator) + { + status = this->child_sa->add_policies(this->child_sa, + my_ts, other_ts); + } + else + { + /* use a copy of the traffic selectors, as the POST hook should not + * change payloads */ + my_ts = this->tsr->clone_offset(this->tsr, offsetof(traffic_selector_t, clone)); - other_ts = this->tsi->clone_offset(this->tsi, + other_ts = this->tsi->clone_offset(this->tsi, offsetof(traffic_selector_t, clone)); - charon->bus->narrow(charon->bus, this->child_sa, - NARROW_RESPONDER_POST, my_ts, other_ts); - if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0) + charon->bus->narrow(charon->bus, this->child_sa, + NARROW_RESPONDER_POST, my_ts, other_ts); + if (my_ts->get_count(my_ts) == 0 || + other_ts->get_count(other_ts) == 0) + { + status = FAILED; + } + else + { + status = this->child_sa->add_policies(this->child_sa, + my_ts, other_ts); + } + my_ts->destroy_offset(my_ts, + offsetof(traffic_selector_t, destroy)); + other_ts->destroy_offset(other_ts, + offsetof(traffic_selector_t, destroy)); + } + if (status != SUCCESS) { - status = FAILED; + DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel"); + charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_POLICY_FAILED, + this->child_sa); + status = NOT_FOUND; } else { - status = this->child_sa->add_policies(this->child_sa, - my_ts, other_ts); + charon->bus->child_derived_keys(charon->bus, this->child_sa, + this->initiator, encr_i, encr_r, + integ_i, integ_r); } - my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); - other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); } + chunk_clear(&integ_i); + chunk_clear(&integ_r); + chunk_clear(&encr_i); + chunk_clear(&encr_r); + if (status != SUCCESS) { - DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel"); - charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_POLICY_FAILED, - this->child_sa); - return NOT_FOUND; + return status; } charon->bus->child_keys(charon->bus, this->child_sa, this->initiator, diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index 801b6d8f3..d82e206b8 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -457,6 +457,11 @@ static void process_payloads(private_ike_init_t *this, message_t *message) } enumerator->destroy(enumerator); + if (this->proposal) + { + this->ike_sa->set_proposal(this->ike_sa, this->proposal); + } + if (ke_payload && this->proposal && this->proposal->has_dh_group(this->proposal, this->dh_group)) { @@ -614,7 +619,6 @@ METHOD(task_t, build_r, status_t, message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); return FAILED; } - this->ike_sa->set_proposal(this->ike_sa, this->proposal); /* check if we'd have to redirect the client */ if (!this->old_sa && @@ -651,6 +655,7 @@ METHOD(task_t, build_r, status_t, else { DBG1(DBG_IKE, "no acceptable proposal found"); + message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); } return FAILED; } @@ -849,7 +854,6 @@ METHOD(task_t, process_i, status_t, DBG1(DBG_IKE, "peers proposal selection invalid"); return FAILED; } - this->ike_sa->set_proposal(this->ike_sa, this->proposal); if (this->dh == NULL || !this->proposal->has_dh_group(this->proposal, this->dh_group)) |