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/ikev1 | |
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/ikev1')
-rw-r--r-- | src/libcharon/sa/ikev1/keymat_v1.c | 25 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/task_manager_v1.c | 17 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/isakmp_vendor.c | 3 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/quick_mode.c | 40 |
4 files changed, 54 insertions, 31 deletions
diff --git a/src/libcharon/sa/ikev1/keymat_v1.c b/src/libcharon/sa/ikev1/keymat_v1.c index be6b03bef..d1d4cbd9b 100644 --- a/src/libcharon/sa/ikev1/keymat_v1.c +++ b/src/libcharon/sa/ikev1/keymat_v1.c @@ -75,11 +75,6 @@ struct private_keymat_v1_t { hasher_t *hasher; /** - * Key used for authentication during main mode - */ - chunk_t skeyid; - - /** * Key to derive key material from for non-ISAKMP SAs, rekeying */ chunk_t skeyid_d; @@ -269,12 +264,12 @@ static bool expand_skeyid_e(chunk_t skeyid_e, size_t key_size, prf_t *prf, * Create a simple implementation of the aead_t interface which only encrypts * or decrypts data. */ -static aead_t *create_aead(proposal_t *proposal, prf_t *prf, chunk_t skeyid_e) +static aead_t *create_aead(proposal_t *proposal, prf_t *prf, chunk_t skeyid_e, + chunk_t *ka) { private_aead_t *this; uint16_t alg, key_size; crypter_t *crypter; - chunk_t ka; if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &key_size)) @@ -292,17 +287,16 @@ static aead_t *create_aead(proposal_t *proposal, prf_t *prf, chunk_t skeyid_e) return NULL; } key_size = crypter->get_key_size(crypter); - if (!expand_skeyid_e(skeyid_e, crypter->get_key_size(crypter), prf, &ka)) + if (!expand_skeyid_e(skeyid_e, crypter->get_key_size(crypter), prf, ka)) { return NULL; } - DBG4(DBG_IKE, "encryption key Ka %B", &ka); - if (!crypter->set_key(crypter, ka)) + DBG4(DBG_IKE, "encryption key Ka %B", ka); + if (!crypter->set_key(crypter, *ka)) { - chunk_clear(&ka); + chunk_clear(ka); return NULL; } - chunk_clear(&ka); INIT(this, .aead = { @@ -392,7 +386,7 @@ METHOD(keymat_v1_t, derive_ike_keys, bool, auth_method_t auth, shared_key_t *shared_key) { chunk_t g_xy, g_xi, g_xr, dh_me, spi_i, spi_r, nonces, data, skeyid_e; - chunk_t skeyid; + chunk_t skeyid, ka; uint16_t alg; spi_i = chunk_alloca(sizeof(uint64_t)); @@ -550,11 +544,14 @@ METHOD(keymat_v1_t, derive_ike_keys, bool, } chunk_clear(&skeyid); - this->aead = create_aead(proposal, this->prf, skeyid_e); + this->aead = create_aead(proposal, this->prf, skeyid_e, &ka); if (!this->aead) { return FALSE; } + charon->bus->ike_derived_keys(charon->bus, ka, chunk_empty, this->skeyid_a, + chunk_empty); + chunk_clear(&ka); if (!this->hasher && !this->public.create_hasher(&this->public, proposal)) { return FALSE; diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index b0c4f5f84..3b0c1cfd1 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -515,13 +515,13 @@ METHOD(task_manager_t, initiate, status_t, new_mid = TRUE; break; } - if (activate_task(this, TASK_ISAKMP_DELETE)) + if (activate_task(this, TASK_QUICK_DELETE)) { exchange = INFORMATIONAL_V1; new_mid = TRUE; break; } - if (activate_task(this, TASK_QUICK_DELETE)) + if (activate_task(this, TASK_ISAKMP_DELETE)) { exchange = INFORMATIONAL_V1; new_mid = TRUE; @@ -547,6 +547,14 @@ METHOD(task_manager_t, initiate, status_t, break; } break; + case IKE_REKEYING: + if (activate_task(this, TASK_ISAKMP_DELETE)) + { + exchange = INFORMATIONAL_V1; + new_mid = TRUE; + break; + } + break; default: break; } @@ -1181,7 +1189,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); @@ -1661,6 +1669,9 @@ METHOD(task_manager_t, queue_ike_delete, void, enumerator_t *enumerator; child_sa_t *child_sa; + /* cancel any currently active task to get the DELETE done quickly */ + flush_queue(this, TASK_QUEUE_ACTIVE); + enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa); while (enumerator->enumerate(enumerator, &child_sa)) { diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c b/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c index f28b83e8a..dc86fc504 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c @@ -102,6 +102,7 @@ static struct { { "DPD", EXT_DPD, TRUE, 16, "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00"}, + /* CISCO-UNITY, similar to DPD the last two bytes indicate the version */ { "Cisco Unity", EXT_CISCO_UNITY, FALSE, 16, "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00"}, @@ -190,6 +191,8 @@ static bool is_known_vid(chunk_t data, int i) break; case EXT_MS_WINDOWS: return data.len == 20 && memeq(data.ptr, vendor_ids[i].id, 16); + case EXT_CISCO_UNITY: + return data.len == 16 && memeq(data.ptr, vendor_ids[i].id, 14); default: return chunk_equals(data, chunk_create(vendor_ids[i].id, vendor_ids[i].len)); diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index bbd1cb09f..6b896416a 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -348,10 +348,6 @@ static bool install(private_quick_mode_t *this) this->initiator, FALSE, FALSE, tsr, tsi); } } - chunk_clear(&integ_i); - chunk_clear(&integ_r); - chunk_clear(&encr_i); - chunk_clear(&encr_r); if (status_i != SUCCESS || status_o != SUCCESS) { @@ -361,22 +357,38 @@ static bool install(private_quick_mode_t *this) (status_o != SUCCESS) ? "outbound " : ""); tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy)); - return FALSE; - } - - if (this->initiator) - { - status = this->child_sa->add_policies(this->child_sa, tsi, tsr); + status = FAILED; } else { - status = this->child_sa->add_policies(this->child_sa, tsr, tsi); + if (this->initiator) + { + status = this->child_sa->add_policies(this->child_sa, tsi, tsr); + } + else + { + status = this->child_sa->add_policies(this->child_sa, tsr, tsi); + } + tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); + tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy)); + if (status != SUCCESS) + { + DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel"); + } + else + { + charon->bus->child_derived_keys(charon->bus, this->child_sa, + this->initiator, encr_i, encr_r, + integ_i, integ_r); + } } - tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); - tsr->destroy_offset(tsr, 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"); return FALSE; } |