bus: Support multiple key exchanges in ike/child_keys() events
This commit is contained in:
@@ -574,7 +574,7 @@ METHOD(bus_t, message, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(bus_t, ike_keys, 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,
|
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
|
||||||
ike_sa_t *rekey, shared_key_t *shared, auth_method_t method)
|
ike_sa_t *rekey, shared_key_t *shared, auth_method_t method)
|
||||||
{
|
{
|
||||||
@@ -591,7 +591,7 @@ METHOD(bus_t, ike_keys, void,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
entry->calling++;
|
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,
|
nonce_i, nonce_r, rekey, shared,
|
||||||
method);
|
method);
|
||||||
entry->calling--;
|
entry->calling--;
|
||||||
@@ -639,7 +639,7 @@ METHOD(bus_t, ike_derived_keys, void,
|
|||||||
|
|
||||||
METHOD(bus_t, child_keys, void,
|
METHOD(bus_t, child_keys, void,
|
||||||
private_bus_t *this, child_sa_t *child_sa, bool initiator,
|
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;
|
enumerator_t *enumerator;
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
@@ -658,7 +658,7 @@ METHOD(bus_t, child_keys, void,
|
|||||||
}
|
}
|
||||||
entry->calling++;
|
entry->calling++;
|
||||||
keep = entry->listener->child_keys(entry->listener, ike_sa,
|
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--;
|
entry->calling--;
|
||||||
if (!keep)
|
if (!keep)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ typedef struct bus_t bus_t;
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
#include <collections/array.h>
|
||||||
#include <sa/ike_sa.h>
|
#include <sa/ike_sa.h>
|
||||||
#include <sa/child_sa.h>
|
#include <sa/child_sa.h>
|
||||||
#include <processing/jobs/job.h>
|
#include <processing/jobs/job.h>
|
||||||
@@ -348,7 +349,7 @@ struct bus_t {
|
|||||||
* IKE_SA keymat hook.
|
* IKE_SA keymat hook.
|
||||||
*
|
*
|
||||||
* @param ike_sa IKE_SA this keymat belongs to
|
* @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 dh_other others DH public value (IKEv1 only)
|
||||||
* @param nonce_i initiator's nonce
|
* @param nonce_i initiator's nonce
|
||||||
* @param nonce_r responder'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 shared shared key used for key derivation (IKEv1-PSK only)
|
||||||
* @param method auth method for key derivation (IKEv1-non-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,
|
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
|
||||||
ike_sa_t *rekey, shared_key_t *shared,
|
ike_sa_t *rekey, shared_key_t *shared,
|
||||||
auth_method_t method);
|
auth_method_t method);
|
||||||
@@ -381,12 +382,12 @@ struct bus_t {
|
|||||||
*
|
*
|
||||||
* @param child_sa CHILD_SA this keymat is used for
|
* @param child_sa CHILD_SA this keymat is used for
|
||||||
* @param initiator initiator of the CREATE_CHILD_SA exchange
|
* @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_i initiator's nonce
|
||||||
* @param nonce_r responder's nonce
|
* @param nonce_r responder's nonce
|
||||||
*/
|
*/
|
||||||
void (*child_keys)(bus_t *this, child_sa_t *child_sa, bool initiator,
|
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.
|
* CHILD_SA derived keys hook.
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ struct listener_t {
|
|||||||
* Hook called with IKE_SA key material.
|
* Hook called with IKE_SA key material.
|
||||||
*
|
*
|
||||||
* @param ike_sa IKE_SA this keymat belongs to
|
* @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 dh_other others DH public value (IKEv1 only)
|
||||||
* @param nonce_i initiator's nonce
|
* @param nonce_i initiator's nonce
|
||||||
* @param nonce_r responder'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)
|
* @param method auth method for key derivation (IKEv1-non-PSK only)
|
||||||
* @return TRUE to stay registered, FALSE to unregister
|
* @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,
|
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
|
||||||
ike_sa_t *rekey, shared_key_t *shared,
|
ike_sa_t *rekey, shared_key_t *shared,
|
||||||
auth_method_t method);
|
auth_method_t method);
|
||||||
@@ -119,13 +119,13 @@ struct listener_t {
|
|||||||
* @param ike_sa IKE_SA the child sa belongs to
|
* @param ike_sa IKE_SA the child sa belongs to
|
||||||
* @param child_sa CHILD_SA this keymat is used for
|
* @param child_sa CHILD_SA this keymat is used for
|
||||||
* @param initiator initiator of the CREATE_CHILD_SA exchange
|
* @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_i initiator's nonce
|
||||||
* @param nonce_r responder's nonce
|
* @param nonce_r responder's nonce
|
||||||
* @return TRUE to stay registered, FALSE to unregister
|
* @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 (*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);
|
chunk_t nonce_i, chunk_t nonce_r);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -51,10 +51,10 @@ struct private_ha_child_t {
|
|||||||
|
|
||||||
METHOD(listener_t, child_keys, bool,
|
METHOD(listener_t, child_keys, bool,
|
||||||
private_ha_child_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
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;
|
ha_message_t *m;
|
||||||
chunk_t secret;
|
chunk_t secret, add_secret = chunk_empty;
|
||||||
proposal_t *proposal;
|
proposal_t *proposal;
|
||||||
uint16_t alg, len;
|
uint16_t alg, len;
|
||||||
linked_list_t *local_ts, *remote_ts;
|
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_I, nonce_i);
|
||||||
m->add_attribute(m, HA_NONCE_R, nonce_r);
|
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);
|
m->add_attribute(m, HA_SECRET, secret);
|
||||||
chunk_clear(&secret);
|
chunk_clear(&secret);
|
||||||
|
chunk_clear(&add_secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ts = linked_list_create();
|
local_ts = linked_list_create();
|
||||||
|
|||||||
@@ -82,12 +82,13 @@ static void copy_extensions(ha_message_t *m, ike_sa_t *ike_sa)
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(listener_t, ike_keys, bool,
|
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,
|
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey,
|
||||||
shared_key_t *shared, auth_method_t method)
|
shared_key_t *shared, auth_method_t method)
|
||||||
{
|
{
|
||||||
ha_message_t *m;
|
ha_message_t *m;
|
||||||
chunk_t secret;
|
key_exchange_t *ke;
|
||||||
|
chunk_t secret = chunk_empty, add_secret = chunk_empty;
|
||||||
proposal_t *proposal;
|
proposal_t *proposal;
|
||||||
uint16_t alg, len;
|
uint16_t alg, len;
|
||||||
|
|
||||||
@@ -95,8 +96,12 @@ METHOD(listener_t, ike_keys, bool,
|
|||||||
{ /* do not sync SA between nodes */
|
{ /* do not sync SA between nodes */
|
||||||
return TRUE;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +147,7 @@ METHOD(listener_t, ike_keys, bool,
|
|||||||
chunk_clear(&secret);
|
chunk_clear(&secret);
|
||||||
if (ike_sa->get_version(ike_sa) == IKEV1)
|
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);
|
m->add_attribute(m, HA_LOCAL_DH, secret);
|
||||||
chunk_free(&secret);
|
chunk_free(&secret);
|
||||||
|
|||||||
@@ -220,6 +220,7 @@ METHOD(phase1_t, derive_keys, bool,
|
|||||||
private_phase1_t *this, peer_cfg_t *peer_cfg, auth_method_t method)
|
private_phase1_t *this, peer_cfg_t *peer_cfg, auth_method_t method)
|
||||||
{
|
{
|
||||||
shared_key_t *shared_key = NULL;
|
shared_key_t *shared_key = NULL;
|
||||||
|
array_t *kes = NULL;
|
||||||
|
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
@@ -245,9 +246,11 @@ METHOD(phase1_t, derive_keys, bool,
|
|||||||
DBG1(DBG_IKE, "key derivation for %N failed", auth_method_names, method);
|
DBG1(DBG_IKE, "key derivation for %N failed", auth_method_names, method);
|
||||||
return FALSE;
|
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,
|
this->nonce_i, this->nonce_r, NULL, shared_key,
|
||||||
method);
|
method);
|
||||||
|
array_destroy(kes);
|
||||||
DESTROY_IF(shared_key);
|
DESTROY_IF(shared_key);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ static bool install(private_quick_mode_t *this)
|
|||||||
chunk_t encr_i, encr_r, integ_i, integ_r;
|
chunk_t encr_i, encr_r, integ_i, integ_r;
|
||||||
linked_list_t *tsi, *tsr, *my_ts, *other_ts;
|
linked_list_t *tsi, *tsr, *my_ts, *other_ts;
|
||||||
child_sa_t *old = NULL;
|
child_sa_t *old = NULL;
|
||||||
|
array_t *kes = NULL;
|
||||||
|
|
||||||
this->child_sa->set_proposal(this->child_sa, this->proposal);
|
this->child_sa->set_proposal(this->child_sa, this->proposal);
|
||||||
this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
|
this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
|
||||||
@@ -377,8 +378,13 @@ static bool install(private_quick_mode_t *this)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->dh)
|
||||||
|
{
|
||||||
|
array_insert_create(&kes, ARRAY_HEAD, this->dh);
|
||||||
|
}
|
||||||
charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
|
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(
|
my_ts = linked_list_create_from_enumerator(
|
||||||
this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
|
this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
|
||||||
|
|||||||
@@ -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,
|
charon->bus->child_derived_keys(charon->bus, this->child_sa,
|
||||||
this->initiator, encr_i, encr_r,
|
this->initiator, encr_i, encr_r,
|
||||||
integ_i, integ_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);
|
chunk_clear(&integ_i);
|
||||||
@@ -781,9 +783,6 @@ static status_t select_and_install(private_child_create_t *this,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
|
|
||||||
this->dh, nonce_i, nonce_r);
|
|
||||||
|
|
||||||
#if DEBUG_LEVEL >= 0
|
#if DEBUG_LEVEL >= 0
|
||||||
child_sa_outbound_state_t out_state;
|
child_sa_outbound_state_t out_state;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
pseudo_random_function_t prf_alg = PRF_UNDEFINED;
|
||||||
chunk_t skd = chunk_empty;
|
chunk_t skd = chunk_empty;
|
||||||
ike_sa_id_t *id;
|
ike_sa_id_t *id;
|
||||||
array_t *kes;
|
array_t *kes = NULL;
|
||||||
|
|
||||||
id = this->ike_sa->get_id(this->ike_sa);
|
id = this->ike_sa->get_id(this->ike_sa);
|
||||||
if (this->old_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);
|
array_destroy(kes);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
array_destroy(kes);
|
charon->bus->ike_keys(charon->bus, this->ike_sa, kes, chunk_empty,
|
||||||
charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, chunk_empty,
|
|
||||||
nonce_i, nonce_r, this->old_sa, NULL, AUTH_NONE);
|
nonce_i, nonce_r, this->old_sa, NULL, AUTH_NONE);
|
||||||
|
array_destroy(kes);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user