bus: Support multiple key exchanges in ike/child_keys() events

This commit is contained in:
Tobias Brunner 2020-04-09 11:53:45 +02:00
parent 4047aa2ec3
commit ce389ec94b
9 changed files with 42 additions and 27 deletions

View File

@ -573,7 +573,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)
{
@ -590,7 +590,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--;
@ -638,7 +638,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;
@ -657,7 +657,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)
{

View File

@ -29,6 +29,7 @@ typedef struct bus_t bus_t;
#include <stdarg.h>
#include <utils/debug.h>
#include <collections/array.h>
#include <sa/ike_sa.h>
#include <sa/child_sa.h>
#include <processing/jobs/job.h>
@ -347,7 +348,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
@ -355,7 +356,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);
@ -380,12 +381,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.

View File

@ -82,7 +82,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
@ -91,7 +91,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);
@ -118,13 +118,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);
/**

View File

@ -50,10 +50,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();

View File

@ -81,12 +81,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;
@ -94,8 +95,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;
}
@ -141,7 +146,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);

View File

@ -221,6 +221,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)
{
@ -246,9 +247,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;
}

View File

@ -271,6 +271,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);
@ -378,8 +379,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));

View File

@ -813,6 +813,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);
@ -826,9 +828,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);
my_ts = linked_list_create_from_enumerator(
this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
other_ts = linked_list_create_from_enumerator(

View File

@ -775,7 +775,7 @@ static bool derive_keys(private_ike_init_t *this,
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)
@ -799,9 +799,9 @@ static bool derive_keys(private_ike_init_t *this,
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;
}