From: Tobias Brunner Date: Thu, 9 Apr 2020 09:53:45 +0000 (+0200) Subject: bus: Support multiple key exchanges in ike/child_keys() events X-Git-Tag: 6.0.0rc1~56^2~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eff0c43a17dcd6cc04ac3f9ba36a4bc42e96a7ef;p=thirdparty%2Fstrongswan.git bus: Support multiple key exchanges in ike/child_keys() events --- diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index 57eaaac895..99387d5e06 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -574,7 +574,7 @@ METHOD(bus_t, message, void, } METHOD(bus_t, ike_keys, void, - private_bus_t *this, ike_sa_t *ike_sa, key_exchange_t *dh, + private_bus_t *this, ike_sa_t *ike_sa, array_t *kes, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey, shared_key_t *shared, auth_method_t method) { @@ -591,7 +591,7 @@ METHOD(bus_t, ike_keys, void, continue; } entry->calling++; - keep = entry->listener->ike_keys(entry->listener, ike_sa, dh, dh_other, + keep = entry->listener->ike_keys(entry->listener, ike_sa, kes, dh_other, nonce_i, nonce_r, rekey, shared, method); entry->calling--; @@ -639,7 +639,7 @@ METHOD(bus_t, ike_derived_keys, void, METHOD(bus_t, child_keys, void, private_bus_t *this, child_sa_t *child_sa, bool initiator, - key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r) + array_t *kes, chunk_t nonce_i, chunk_t nonce_r) { enumerator_t *enumerator; ike_sa_t *ike_sa; @@ -658,7 +658,7 @@ METHOD(bus_t, child_keys, void, } entry->calling++; keep = entry->listener->child_keys(entry->listener, ike_sa, - child_sa, initiator, dh, nonce_i, nonce_r); + child_sa, initiator, kes, nonce_i, nonce_r); entry->calling--; if (!keep) { diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h index 5e809f04fc..d814d09e34 100644 --- a/src/libcharon/bus/bus.h +++ b/src/libcharon/bus/bus.h @@ -30,6 +30,7 @@ typedef struct bus_t bus_t; #include #include +#include #include #include #include @@ -348,7 +349,7 @@ struct bus_t { * IKE_SA keymat hook. * * @param ike_sa IKE_SA this keymat belongs to - * @param dh diffie hellman shared secret + * @param kes array of key_exchange_t* * @param dh_other others DH public value (IKEv1 only) * @param nonce_i initiator's nonce * @param nonce_r responder's nonce @@ -356,7 +357,7 @@ struct bus_t { * @param shared shared key used for key derivation (IKEv1-PSK only) * @param method auth method for key derivation (IKEv1-non-PSK only) */ - void (*ike_keys)(bus_t *this, ike_sa_t *ike_sa, key_exchange_t *dh, + void (*ike_keys)(bus_t *this, ike_sa_t *ike_sa, array_t *kes, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey, shared_key_t *shared, auth_method_t method); @@ -381,12 +382,12 @@ struct bus_t { * * @param child_sa CHILD_SA this keymat is used for * @param initiator initiator of the CREATE_CHILD_SA exchange - * @param dh diffie hellman shared secret + * @param kes array of key_exchange_t*, or NULL * @param nonce_i initiator's nonce * @param nonce_r responder's nonce */ void (*child_keys)(bus_t *this, child_sa_t *child_sa, bool initiator, - key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r); + array_t *kes, chunk_t nonce_i, chunk_t nonce_r); /** * CHILD_SA derived keys hook. diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h index bec48d1877..42297e2f4c 100644 --- a/src/libcharon/bus/listeners/listener.h +++ b/src/libcharon/bus/listeners/listener.h @@ -83,7 +83,7 @@ struct listener_t { * Hook called with IKE_SA key material. * * @param ike_sa IKE_SA this keymat belongs to - * @param dh diffie hellman shared secret + * @param kes array of key_exchange_t* * @param dh_other others DH public value (IKEv1 only) * @param nonce_i initiator's nonce * @param nonce_r responder's nonce @@ -92,7 +92,7 @@ struct listener_t { * @param method auth method for key derivation (IKEv1-non-PSK only) * @return TRUE to stay registered, FALSE to unregister */ - bool (*ike_keys)(listener_t *this, ike_sa_t *ike_sa, key_exchange_t *dh, + bool (*ike_keys)(listener_t *this, ike_sa_t *ike_sa, array_t *kes, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey, shared_key_t *shared, auth_method_t method); @@ -119,13 +119,13 @@ struct listener_t { * @param ike_sa IKE_SA the child sa belongs to * @param child_sa CHILD_SA this keymat is used for * @param initiator initiator of the CREATE_CHILD_SA exchange - * @param dh diffie hellman shared secret + * @param kes array of key_exchange_t*, or NULL * @param nonce_i initiator's nonce * @param nonce_r responder's nonce * @return TRUE to stay registered, FALSE to unregister */ bool (*child_keys)(listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, - bool initiator, key_exchange_t *dh, + bool initiator, array_t *kes, chunk_t nonce_i, chunk_t nonce_r); /** diff --git a/src/libcharon/plugins/ha/ha_child.c b/src/libcharon/plugins/ha/ha_child.c index 1081986dd1..364fe1d5f5 100644 --- a/src/libcharon/plugins/ha/ha_child.c +++ b/src/libcharon/plugins/ha/ha_child.c @@ -51,10 +51,10 @@ struct private_ha_child_t { METHOD(listener_t, child_keys, bool, private_ha_child_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, - bool initiator, key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r) + bool initiator, array_t *kes, chunk_t nonce_i, chunk_t nonce_r) { ha_message_t *m; - chunk_t secret; + chunk_t secret, add_secret = chunk_empty; proposal_t *proposal; uint16_t alg, len; linked_list_t *local_ts, *remote_ts; @@ -101,10 +101,11 @@ METHOD(listener_t, child_keys, bool, } m->add_attribute(m, HA_NONCE_I, nonce_i); m->add_attribute(m, HA_NONCE_R, nonce_r); - if (dh && dh->get_shared_secret(dh, &secret)) + if (kes && key_exchange_concat_secrets(kes, &secret, &add_secret)) { m->add_attribute(m, HA_SECRET, secret); chunk_clear(&secret); + chunk_clear(&add_secret); } local_ts = linked_list_create(); diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c index 6535e4a1e0..e6dab84579 100644 --- a/src/libcharon/plugins/ha/ha_ike.c +++ b/src/libcharon/plugins/ha/ha_ike.c @@ -82,12 +82,13 @@ static void copy_extensions(ha_message_t *m, ike_sa_t *ike_sa) } METHOD(listener_t, ike_keys, bool, - private_ha_ike_t *this, ike_sa_t *ike_sa, key_exchange_t *dh, + private_ha_ike_t *this, ike_sa_t *ike_sa, array_t *kes, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey, shared_key_t *shared, auth_method_t method) { ha_message_t *m; - chunk_t secret; + key_exchange_t *ke; + chunk_t secret = chunk_empty, add_secret = chunk_empty; proposal_t *proposal; uint16_t alg, len; @@ -95,8 +96,12 @@ METHOD(listener_t, ike_keys, bool, { /* do not sync SA between nodes */ return TRUE; } - if (!dh->get_shared_secret(dh, &secret)) + if (!key_exchange_concat_secrets(kes, &secret, &add_secret) || + !array_get(kes, ARRAY_HEAD, &ke) || + add_secret.len > 0) { + chunk_clear(&secret); + chunk_clear(&add_secret); return TRUE; } @@ -142,7 +147,7 @@ METHOD(listener_t, ike_keys, bool, chunk_clear(&secret); if (ike_sa->get_version(ike_sa) == IKEV1) { - if (dh->get_public_key(dh, &secret)) + if (ke->get_public_key(ke, &secret)) { m->add_attribute(m, HA_LOCAL_DH, secret); chunk_free(&secret); diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c index 2520b6a93e..61c400580b 100644 --- a/src/libcharon/sa/ikev1/phase1.c +++ b/src/libcharon/sa/ikev1/phase1.c @@ -220,6 +220,7 @@ METHOD(phase1_t, derive_keys, bool, private_phase1_t *this, peer_cfg_t *peer_cfg, auth_method_t method) { shared_key_t *shared_key = NULL; + array_t *kes = NULL; switch (method) { @@ -245,9 +246,11 @@ METHOD(phase1_t, derive_keys, bool, DBG1(DBG_IKE, "key derivation for %N failed", auth_method_names, method); return FALSE; } - charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, this->dh_value, + array_insert_create(&kes, ARRAY_HEAD, this->dh); + charon->bus->ike_keys(charon->bus, this->ike_sa, kes, this->dh_value, this->nonce_i, this->nonce_r, NULL, shared_key, method); + array_destroy(kes); DESTROY_IF(shared_key); return TRUE; } diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 3612f0d6ad..8436c66dc6 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -270,6 +270,7 @@ static bool install(private_quick_mode_t *this) chunk_t encr_i, encr_r, integ_i, integ_r; linked_list_t *tsi, *tsr, *my_ts, *other_ts; child_sa_t *old = NULL; + array_t *kes = NULL; this->child_sa->set_proposal(this->child_sa, this->proposal); this->child_sa->set_state(this->child_sa, CHILD_INSTALLING); @@ -377,8 +378,13 @@ static bool install(private_quick_mode_t *this) return FALSE; } + if (this->dh) + { + array_insert_create(&kes, ARRAY_HEAD, this->dh); + } charon->bus->child_keys(charon->bus, this->child_sa, this->initiator, - this->dh, this->nonce_i, this->nonce_r); + kes, this->nonce_i, this->nonce_r); + array_destroy(kes); my_ts = linked_list_create_from_enumerator( this->child_sa->create_ts_enumerator(this->child_sa, TRUE)); diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 39632e7869..acc1a928f4 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -768,6 +768,8 @@ static status_t select_and_install(private_child_create_t *this, charon->bus->child_derived_keys(charon->bus, this->child_sa, this->initiator, encr_i, encr_r, integ_i, integ_r); + charon->bus->child_keys(charon->bus, this->child_sa, + this->initiator, kes, nonce_i, nonce_r); } } chunk_clear(&integ_i); @@ -781,9 +783,6 @@ static status_t select_and_install(private_child_create_t *this, return status; } - charon->bus->child_keys(charon->bus, this->child_sa, this->initiator, - this->dh, nonce_i, nonce_r); - #if DEBUG_LEVEL >= 0 child_sa_outbound_state_t out_state; diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index 2ef721ddc5..8ace416094 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -802,7 +802,7 @@ static bool derive_keys_internal(private_ike_init_t *this, chunk_t nonce_i, pseudo_random_function_t prf_alg = PRF_UNDEFINED; chunk_t skd = chunk_empty; ike_sa_id_t *id; - array_t *kes; + array_t *kes = NULL; id = this->ike_sa->get_id(this->ike_sa); if (this->old_sa) @@ -818,9 +818,9 @@ static bool derive_keys_internal(private_ike_init_t *this, chunk_t nonce_i, array_destroy(kes); return FALSE; } - array_destroy(kes); - charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, chunk_empty, + charon->bus->ike_keys(charon->bus, this->ike_sa, kes, chunk_empty, nonce_i, nonce_r, this->old_sa, NULL, AUTH_NONE); + array_destroy(kes); return TRUE; }