aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.c115
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.h8
2 files changed, 121 insertions, 2 deletions
diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c
index a64f43173..78744edd5 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.c
+++ b/src/libstrongswan/credentials/sets/mem_cred.c
@@ -36,12 +36,117 @@ struct private_mem_cred_t {
rwlock_t *lock;
/**
+ * List of trusted certificates, certificate_t
+ */
+ linked_list_t *trusted;
+
+ /**
+ * List of trusted and untrusted certificates, certificate_t
+ */
+ linked_list_t *untrusted;
+
+ /**
* List of shared keys, as shared_entry_t
*/
linked_list_t *shared;
};
/**
+ * Data for the certificate enumerator
+ */
+typedef struct {
+ rwlock_t *lock;
+ certificate_type_t cert;
+ key_type_t key;
+ identification_t *id;
+} cert_data_t;
+
+/**
+ * destroy cert_data
+ */
+static void cert_data_destroy(cert_data_t *data)
+{
+ data->lock->unlock(data->lock);
+ free(data);
+}
+
+/**
+ * filter function for certs enumerator
+ */
+static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t **out)
+{
+ public_key_t *public;
+ certificate_t *cert = *in;
+
+ if (data->cert == CERT_ANY || data->cert == cert->get_type(cert))
+ {
+ public = cert->get_public_key(cert);
+ if (public)
+ {
+ if (data->key == KEY_ANY || data->key == public->get_type(public))
+ {
+ if (public->has_fingerprint(public,
+ data->id->get_encoding(data->id)))
+ {
+ public->destroy(public);
+ *out = *in;
+ return TRUE;
+ }
+ }
+ public->destroy(public);
+ }
+ else if (data->key != KEY_ANY)
+ {
+ return FALSE;
+ }
+ if (data->id == NULL || cert->has_subject(cert, data->id))
+ {
+ *out = *in;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+ private_mem_cred_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ cert_data_t *data;
+ enumerator_t *enumerator;
+
+ INIT(data,
+ .lock = this->lock,
+ .cert = cert,
+ .key = key,
+ .id = id,
+ );
+ this->lock->read_lock(this->lock);
+ if (trusted)
+ {
+ enumerator = this->trusted->create_enumerator(this->trusted);
+ }
+ else
+ {
+ enumerator = this->untrusted->create_enumerator(this->untrusted);
+ }
+ return enumerator_create_filter(enumerator, (void*)certs_filter, data,
+ (void*)cert_data_destroy);
+}
+
+METHOD(mem_cred_t, add_cert, void,
+ private_mem_cred_t *this, bool trusted, certificate_t *cert)
+{
+ this->lock->write_lock(this->lock);
+ if (trusted)
+ {
+ this->trusted->insert_last(this->trusted, cert->get_ref(cert));
+ }
+ this->untrusted->insert_last(this->untrusted, cert);
+ this->lock->unlock(this->lock);
+}
+
+/**
* Shared key entry
*/
typedef struct {
@@ -190,10 +295,13 @@ METHOD(mem_cred_t, add_shared, void,
this->lock->unlock(this->lock);
}
-
METHOD(mem_cred_t, destroy, void,
private_mem_cred_t *this)
{
+ this->trusted->destroy_offset(this->trusted,
+ offsetof(certificate_t, destroy));
+ this->untrusted->destroy_offset(this->untrusted,
+ offsetof(certificate_t, destroy));
this->shared->destroy_function(this->shared, (void*)shared_entry_destroy);
this->lock->destroy(this->lock);
free(this);
@@ -211,13 +319,16 @@ mem_cred_t *mem_cred_create()
.set = {
.create_shared_enumerator = _create_shared_enumerator,
.create_private_enumerator = (void*)return_null,
- .create_cert_enumerator = (void*)return_null,
+ .create_cert_enumerator = _create_cert_enumerator,
.create_cdp_enumerator = (void*)return_null,
.cache_cert = (void*)nop,
},
+ .add_cert = _add_cert,
.add_shared = _add_shared,
.destroy = _destroy,
},
+ .trusted = linked_list_create(),
+ .untrusted = linked_list_create(),
.shared = linked_list_create(),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h
index 18b42b900..5863cc857 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.h
+++ b/src/libstrongswan/credentials/sets/mem_cred.h
@@ -36,6 +36,14 @@ struct mem_cred_t {
credential_set_t set;
/**
+ * Add a certificate to the credential set.
+ *
+ * @param trusted TRUE to serve certificate as trusted
+ * @param cert certificate, reference gets owned by set
+ */
+ void (*add_cert)(mem_cred_t *this, bool trusted, certificate_t *cert);
+
+ /**
* Add a shared key to the credential set.
*
* @param shared shared key to add, gets owned by set