summaryrefslogtreecommitdiff
path: root/src/libcharon/bus
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/bus')
-rw-r--r--src/libcharon/bus/bus.c101
-rw-r--r--src/libcharon/bus/bus.h35
-rw-r--r--src/libcharon/bus/listeners/listener.h38
3 files changed, 151 insertions, 23 deletions
diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c
index e17d629d2..6b3cea880 100644
--- a/src/libcharon/bus/bus.c
+++ b/src/libcharon/bus/bus.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2015 Tobias Brunner
+ * Copyright (C) 2011-2016 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -208,6 +208,24 @@ static inline void register_logger(private_bus_t *this, debug_t group,
}
/**
+ * Find the log level of the first registered logger that implements log or
+ * vlog (or both).
+ */
+static bool find_max_levels(log_entry_t *entry, debug_t *group, level_t *level,
+ level_t *vlevel)
+{
+ if (entry->logger->log && *level == LEVEL_SILENT)
+ {
+ *level = entry->levels[*group];
+ }
+ if (entry->logger->vlog && *vlevel == LEVEL_SILENT)
+ {
+ *vlevel = entry->levels[*group];
+ }
+ return *level > LEVEL_SILENT && *vlevel > LEVEL_SILENT;
+}
+
+/**
* Unregister a logger from all log groups (destroys the log_entry_t)
*/
static inline void unregister_logger(private_bus_t *this, logger_t *logger)
@@ -240,18 +258,8 @@ static inline void unregister_logger(private_bus_t *this, logger_t *logger)
{
loggers = this->loggers[group];
loggers->remove(loggers, found, NULL);
-
- if (loggers->get_first(loggers, (void**)&entry) == SUCCESS)
- {
- if (entry->logger->log)
- {
- level = entry->levels[group];
- }
- if (entry->logger->vlog)
- {
- vlevel = entry->levels[group];
- }
- }
+ loggers->find_first(loggers, (linked_list_match_t)find_max_levels, NULL,
+ &group, &level, &vlevel);
set_level(&this->max_level[group], level);
set_level(&this->max_vlevel[group], vlevel);
}
@@ -593,6 +601,38 @@ METHOD(bus_t, ike_keys, void,
this->mutex->unlock(this->mutex);
}
+METHOD(bus_t, ike_derived_keys, void,
+ private_bus_t *this, chunk_t sk_ei, chunk_t sk_er, chunk_t sk_ai,
+ chunk_t sk_ar)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ entry_t *entry;
+ bool keep;
+
+ ike_sa = this->thread_sa->get(this->thread_sa);
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->calling || !entry->listener->ike_derived_keys)
+ {
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->ike_derived_keys(entry->listener, ike_sa, sk_ei,
+ sk_er, sk_ai, sk_ar);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
METHOD(bus_t, child_keys, void,
private_bus_t *this, child_sa_t *child_sa, bool initiator,
diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r)
@@ -625,6 +665,39 @@ METHOD(bus_t, child_keys, void,
this->mutex->unlock(this->mutex);
}
+METHOD(bus_t, child_derived_keys, void,
+ private_bus_t *this, child_sa_t *child_sa, bool initiator,
+ chunk_t encr_i, chunk_t encr_r, chunk_t integ_i, chunk_t integ_r)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ entry_t *entry;
+ bool keep;
+
+ ike_sa = this->thread_sa->get(this->thread_sa);
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->calling || !entry->listener->child_derived_keys)
+ {
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->child_derived_keys(entry->listener, ike_sa,
+ child_sa, initiator, encr_i, encr_r,
+ integ_i, integ_r);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
METHOD(bus_t, child_updown, void,
private_bus_t *this, child_sa_t *child_sa, bool up)
{
@@ -1061,7 +1134,9 @@ bus_t *bus_create()
.child_state_change = _child_state_change,
.message = _message,
.ike_keys = _ike_keys,
+ .ike_derived_keys = _ike_derived_keys,
.child_keys = _child_keys,
+ .child_derived_keys = _child_derived_keys,
.ike_updown = _ike_updown,
.ike_rekey = _ike_rekey,
.ike_update = _ike_update,
diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h
index 305cbe4ae..1e810a499 100644
--- a/src/libcharon/bus/bus.h
+++ b/src/libcharon/bus/bus.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2015 Tobias Brunner
+ * Copyright (C) 2012-2016 Tobias Brunner
* Copyright (C) 2006-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -349,8 +349,8 @@ struct bus_t {
* @param ike_sa IKE_SA this keymat belongs to
* @param dh diffie hellman shared secret
* @param dh_other others DH public value (IKEv1 only)
- * @param nonce_i initiators nonce
- * @param nonce_r responders nonce
+ * @param nonce_i initiator's nonce
+ * @param nonce_r responder's nonce
* @param rekey IKE_SA we are rekeying, if any (IKEv2 only)
* @param shared shared key used for key derivation (IKEv1-PSK only)
*/
@@ -359,18 +359,43 @@ struct bus_t {
ike_sa_t *rekey, shared_key_t *shared);
/**
+ * IKE_SA derived keys hook.
+ *
+ * @param sk_ei SK_ei, or Ka for IKEv1
+ * @param sk_er SK_er
+ * @param sk_ai SK_ai, or SKEYID_a for IKEv1
+ * @param sk_ar SK_ar
+ */
+ void (*ike_derived_keys)(bus_t *this, chunk_t sk_ei, chunk_t sk_er,
+ chunk_t sk_ai, chunk_t sk_ar);
+
+ /**
* CHILD_SA keymat hook.
*
* @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 nonce_i initiators nonce
- * @param nonce_r responders nonce
+ * @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,
diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r);
/**
+ * CHILD_SA derived keys hook.
+ *
+ * @param child_sa CHILD_SA these keys are used for
+ * @param initiator initiator of the CREATE_CHILD_SA exchange
+ * @param encr_i initiator's encryption key
+ * @param encr_o responder's encryption key
+ * @param integ_i initiator's integrity key
+ * @param integ_r responder's integrity key
+ */
+ void (*child_derived_keys)(bus_t *this, child_sa_t *child_sa,
+ bool initiator, chunk_t encr_i, chunk_t encr_r,
+ chunk_t integ_i, chunk_t integ_r);
+
+ /**
* IKE_SA up/down hook.
*
* @param ike_sa IKE_SA coming up/going down
diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h
index be2726ede..be0dfbe21 100644
--- a/src/libcharon/bus/listeners/listener.h
+++ b/src/libcharon/bus/listeners/listener.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2015 Tobias Brunner
+ * Copyright (C) 2011-2016 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -84,8 +84,8 @@ struct listener_t {
* @param ike_sa IKE_SA this keymat belongs to
* @param dh diffie hellman shared secret
* @param dh_other others DH public value (IKEv1 only)
- * @param nonce_i initiators nonce
- * @param nonce_r responders nonce
+ * @param nonce_i initiator's nonce
+ * @param nonce_r responder's nonce
* @param rekey IKE_SA we are rekeying, if any (IKEv2 only)
* @param shared shared key used for key derivation (IKEv1-PSK only)
* @return TRUE to stay registered, FALSE to unregister
@@ -95,14 +95,26 @@ struct listener_t {
ike_sa_t *rekey, shared_key_t *shared);
/**
+ * Hook called with derived IKE_SA keys.
+ *
+ * @param ike_sa IKE_SA these keys belong to
+ * @param sk_ei SK_ei, or Ka for IKEv1
+ * @param sk_er SK_er
+ * @param sk_ai SK_ai, or SKEYID_a for IKEv1
+ * @param sk_ar SK_ar
+ */
+ bool (*ike_derived_keys)(listener_t *this, ike_sa_t *ike_sa, chunk_t sk_ei,
+ chunk_t sk_er, chunk_t sk_ai, chunk_t sk_ar);
+
+ /**
* Hook called with CHILD_SA key material.
*
* @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 nonce_i initiators nonce
- * @param nonce_r responders nonce
+ * @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,
@@ -110,6 +122,22 @@ struct listener_t {
chunk_t nonce_i, chunk_t nonce_r);
/**
+ * Hook called with derived CHILD_SA keys.
+ *
+ * @param ike_sa IKE_SA the child sa belongs to
+ * @param child_sa CHILD_SA these keys are used for
+ * @param initiator initiator of the CREATE_CHILD_SA exchange
+ * @param encr_i initiator's encryption key
+ * @param encr_o responder's encryption key
+ * @param integ_i initiator's integrity key
+ * @param integ_r responder's integrity key
+ */
+ bool (*child_derived_keys)(listener_t *this, ike_sa_t *ike_sa,
+ child_sa_t *child_sa, bool initiator,
+ chunk_t encr_i, chunk_t encr_r,
+ chunk_t integ_i, chunk_t integ_r);
+
+ /**
* Hook called if an IKE_SA gets up or down.
*
* @param ike_sa IKE_SA coming up/going down