aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/plugins/certexpire/Makefile.am3
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_export.c221
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_export.h52
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_listener.c12
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_listener.h7
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_plugin.c10
6 files changed, 299 insertions, 6 deletions
diff --git a/src/libcharon/plugins/certexpire/Makefile.am b/src/libcharon/plugins/certexpire/Makefile.am
index af20490ad..9aac70835 100644
--- a/src/libcharon/plugins/certexpire/Makefile.am
+++ b/src/libcharon/plugins/certexpire/Makefile.am
@@ -12,6 +12,7 @@ plugin_LTLIBRARIES = libstrongswan-certexpire.la
endif
libstrongswan_certexpire_la_SOURCES = certexpire_plugin.h certexpire_plugin.c \
- certexpire_listener.h certexpire_listener.c
+ certexpire_listener.h certexpire_listener.c \
+ certexpire_export.h certexpire_export.c
libstrongswan_certexpire_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/certexpire/certexpire_export.c b/src/libcharon/plugins/certexpire/certexpire_export.c
new file mode 100644
index 000000000..d9b49075f
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_export.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "certexpire_export.h"
+
+#include <debug.h>
+#include <utils/hashtable.h>
+#include <threading/mutex.h>
+#include <credentials/certificates/x509.h>
+
+typedef struct private_certexpire_export_t private_certexpire_export_t;
+
+/**
+ * Private data of an certexpire_export_t object.
+ */
+struct private_certexpire_export_t {
+
+ /**
+ * Public certexpire_export_t interface.
+ */
+ certexpire_export_t public;
+
+ /**
+ * hashtable caching local trustchains, mapping entry_t => entry_t
+ */
+ hashtable_t *local;
+
+ /**
+ * hashtable caching remote trustchains, mapping entry_t => entry_t
+ */
+ hashtable_t *remote;
+
+ /**
+ * Mutex to lock hashtables
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Maximum number of expiration dates we store (for subject + IM CAs + CA)
+ */
+#define MAX_TRUSTCHAIN_LENGTH 7
+
+/**
+ * Hashtable entry
+ */
+typedef struct {
+ /** certificate subject as subjectAltName or CN of a DN */
+ char id[128];
+ /** list of expiration dates, 0 if no certificate */
+ time_t expire[MAX_TRUSTCHAIN_LENGTH];
+} entry_t;
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(entry_t *key)
+{
+ return chunk_hash(chunk_create(key->id, strlen(key->id)));
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(entry_t *a, entry_t *b)
+{
+ return streq(a->id, b->id);
+}
+
+METHOD(certexpire_export_t, add, void,
+ private_certexpire_export_t *this, linked_list_t *trustchain, bool local)
+{
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ int count;
+
+ count = min(trustchain->get_count(trustchain), MAX_TRUSTCHAIN_LENGTH) - 1;
+
+ enumerator = trustchain->create_enumerator(trustchain);
+ /* get subject cert */
+ if (enumerator->enumerate(enumerator, &cert))
+ {
+ identification_t *id;
+ entry_t *entry;
+ int i;
+
+ INIT(entry);
+
+ /* prefer FQDN subjectAltName... */
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ x509_t *x509 = (x509_t*)cert;
+ enumerator_t *sans;
+
+ sans = x509->create_subjectAltName_enumerator(x509);
+ while (sans->enumerate(sans, &id))
+ {
+ if (id->get_type(id) == ID_FQDN)
+ {
+ snprintf(entry->id, sizeof(entry->id), "%Y", id);
+ break;
+ }
+ }
+ sans->destroy(sans);
+ }
+ /* fallback to CN of DN */
+ if (!entry->id[0])
+ {
+ enumerator_t *parts;
+ id_part_t part;
+ chunk_t data;
+
+ id = cert->get_subject(cert);
+ parts = id->create_part_enumerator(id);
+ while (parts->enumerate(parts, &part, &data))
+ {
+ if (part == ID_PART_RDN_CN)
+ {
+ snprintf(entry->id, sizeof(entry->id), "%.*s",
+ (int)data.len, data.ptr);
+ break;
+ }
+ }
+ parts->destroy(parts);
+ }
+ /* no usable identity? skip */
+ if (!entry->id[0])
+ {
+ enumerator->destroy(enumerator);
+ free(entry);
+ return;
+ }
+
+ /* get intermediate CA expiration dates */
+ cert->get_validity(cert, NULL, NULL, &entry->expire[0]);
+ for (i = 1; i < count && enumerator->enumerate(enumerator, &cert); i++)
+ {
+ cert->get_validity(cert, NULL, NULL, &entry->expire[i]);
+ }
+ /* get CA expiration date, as last array entry */
+ if (enumerator->enumerate(enumerator, &cert))
+ {
+ cert->get_validity(cert, NULL, NULL,
+ &entry->expire[MAX_TRUSTCHAIN_LENGTH - 1]);
+ }
+ this->mutex->lock(this->mutex);
+ if (local)
+ {
+ entry = this->local->put(this->local, entry, entry);
+ }
+ else
+ {
+ entry = this->remote->put(this->remote, entry, entry);
+ }
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ {
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(certexpire_export_t, destroy, void,
+ private_certexpire_export_t *this)
+{
+ entry_t *key, *value;
+ enumerator_t *enumerator;
+
+ enumerator = this->local->create_enumerator(this->local);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ free(value);
+ }
+ enumerator->destroy(enumerator);
+ enumerator = this->remote->create_enumerator(this->remote);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ free(value);
+ }
+ enumerator->destroy(enumerator);
+
+ this->local->destroy(this->local);
+ this->remote->destroy(this->remote);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+certexpire_export_t *certexpire_export_create()
+{
+ private_certexpire_export_t *this;
+
+ INIT(this,
+ .public = {
+ .add = _add,
+ .destroy = _destroy,
+ },
+ .local = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 4),
+ .remote = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 32),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/certexpire/certexpire_export.h b/src/libcharon/plugins/certexpire/certexpire_export.h
new file mode 100644
index 000000000..64281d0bd
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_export.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup certexpire_export certexpire_export
+ * @{ @ingroup certexpire
+ */
+
+#ifndef CERTEXPIRE_EXPORT_H_
+#define CERTEXPIRE_EXPORT_H_
+
+typedef struct certexpire_export_t certexpire_export_t;
+
+#include <utils/linked_list.h>
+
+/**
+ * Caches and exports trustchain information to CSV files.
+ */
+struct certexpire_export_t {
+
+ /**
+ * Add trustchain to cache for export.
+ *
+ * @param trustchain trustchain, sorted list of certificate_t
+ * @param local TRUE for own chain, FALSE for remote chain
+ */
+ void (*add)(certexpire_export_t *this, linked_list_t *trustchain, bool local);
+
+ /**
+ * Destroy a certexpire_export_t.
+ */
+ void (*destroy)(certexpire_export_t *this);
+};
+
+/**
+ * Create a certexpire_export instance.
+ */
+certexpire_export_t *certexpire_export_create();
+
+#endif /** CERTEXPIRE_EXPORT_H_ @}*/
diff --git a/src/libcharon/plugins/certexpire/certexpire_listener.c b/src/libcharon/plugins/certexpire/certexpire_listener.c
index 67a9a650b..4c9c6ff3b 100644
--- a/src/libcharon/plugins/certexpire/certexpire_listener.c
+++ b/src/libcharon/plugins/certexpire/certexpire_listener.c
@@ -28,6 +28,11 @@ struct private_certexpire_listener_t {
* Public certexpire_listener_t interface.
*/
certexpire_listener_t public;
+
+ /**
+ * Export facility
+ */
+ certexpire_export_t *export;
};
METHOD(listener_t, authorize, bool,
@@ -80,7 +85,7 @@ METHOD(listener_t, authorize, bool,
}
}
rounds->destroy(rounds);
- /* TODO: handle trustchain expiry information */
+ this->export->add(this->export, trustchain, TRUE);
trustchain->destroy(trustchain);
/* collect remote certificates */
@@ -111,7 +116,7 @@ METHOD(listener_t, authorize, bool,
}
}
rounds->destroy(rounds);
- /* TODO: handle trustchain expiry information */
+ this->export->add(this->export, trustchain, FALSE);
trustchain->destroy(trustchain);
return TRUE;
}
@@ -125,7 +130,7 @@ METHOD(certexpire_listener_t, destroy, void,
/**
* See header
*/
-certexpire_listener_t *certexpire_listener_create()
+certexpire_listener_t *certexpire_listener_create(certexpire_export_t *export)
{
private_certexpire_listener_t *this;
@@ -136,6 +141,7 @@ certexpire_listener_t *certexpire_listener_create()
},
.destroy = _destroy,
},
+ .export = export,
);
return &this->public;
diff --git a/src/libcharon/plugins/certexpire/certexpire_listener.h b/src/libcharon/plugins/certexpire/certexpire_listener.h
index 718743503..8601ff585 100644
--- a/src/libcharon/plugins/certexpire/certexpire_listener.h
+++ b/src/libcharon/plugins/certexpire/certexpire_listener.h
@@ -23,6 +23,8 @@
#include <bus/listeners/listener.h>
+#include "certexpire_export.h"
+
typedef struct certexpire_listener_t certexpire_listener_t;
/**
@@ -43,7 +45,10 @@ struct certexpire_listener_t {
/**
* Create a certexpire_listener instance.
+ *
+ * @param export facility exporting collected trustchains
+ * @return listener instance
*/
-certexpire_listener_t *certexpire_listener_create();
+certexpire_listener_t *certexpire_listener_create(certexpire_export_t *export);
#endif /** CERTEXPIRE_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/certexpire/certexpire_plugin.c b/src/libcharon/plugins/certexpire/certexpire_plugin.c
index 795e8a13d..2b4c0b68b 100644
--- a/src/libcharon/plugins/certexpire/certexpire_plugin.c
+++ b/src/libcharon/plugins/certexpire/certexpire_plugin.c
@@ -16,6 +16,7 @@
#include "certexpire_plugin.h"
#include "certexpire_listener.h"
+#include "certexpire_export.h"
#include <daemon.h>
@@ -35,6 +36,11 @@ struct private_certexpire_plugin_t {
* Listener collecting expire information
*/
certexpire_listener_t *listener;
+
+ /**
+ * Cache and export trustchain expire information
+ */
+ certexpire_export_t *export;
};
METHOD(plugin_t, get_name, char*,
@@ -48,6 +54,7 @@ METHOD(plugin_t, destroy, void,
{
charon->bus->remove_listener(charon->bus, &this->listener->listener);
this->listener->destroy(this->listener);
+ this->export->destroy(this->export);
free(this);
}
@@ -66,8 +73,9 @@ plugin_t *certexpire_plugin_create()
.destroy = _destroy,
},
},
- .listener = certexpire_listener_create(),
+ .export = certexpire_export_create(),
);
+ this->listener = certexpire_listener_create(this->export),
charon->bus->add_listener(charon->bus, &this->listener->listener);
return &this->public.plugin;